summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.circleci/config.yml13
-rw-r--r--.codecov.yml7
-rw-r--r--.dependabot/config.yml9
-rw-r--r--.gitattributes106
-rw-r--r--.github/CONTRIBUTING.md2
-rw-r--r--.github/ISSUE_TEMPLATE/bug-report.md2
-rw-r--r--.github/ISSUE_TEMPLATE/feature-request.md2
-rw-r--r--.github/ISSUE_TEMPLATE/post-install.md2
-rw-r--r--.github/PULL_REQUEST_TEMPLATE.md32
-rw-r--r--.github/dependabot.yml22
-rw-r--r--.github/workflows/build_test.yml87
-rw-r--r--.github/workflows/cygwin.yml67
-rw-r--r--.github/workflows/docker.yml57
-rw-r--r--.github/workflows/gitpod.yml57
-rw-r--r--.gitignore12
-rw-r--r--.gitmodules3
-rw-r--r--.gitpod.yml63
-rw-r--r--.hadolint.yaml7
-rw-r--r--.mailmap643
-rw-r--r--.travis.yml14
-rw-r--r--INSTALL.rst.txt2
-rw-r--r--LICENSE.txt2
-rw-r--r--LICENSES_bundled.txt5
-rw-r--r--MANIFEST.in23
-rw-r--r--README.md55
-rw-r--r--azure-pipelines.yml111
-rw-r--r--azure-steps-windows.yml28
-rw-r--r--benchmarks/README.rst2
-rw-r--r--benchmarks/asv.conf.json2
-rw-r--r--benchmarks/asv_compare.conf.json.tpl6
-rw-r--r--benchmarks/asv_pip_nopep517.py15
-rw-r--r--benchmarks/benchmarks/__init__.py52
-rw-r--r--benchmarks/benchmarks/bench_app.py4
-rw-r--r--benchmarks/benchmarks/bench_core.py11
-rw-r--r--benchmarks/benchmarks/bench_function_base.py8
-rw-r--r--benchmarks/benchmarks/bench_lib.py24
-rw-r--r--benchmarks/benchmarks/bench_linalg.py4
-rw-r--r--benchmarks/benchmarks/bench_ufunc.py17
-rw-r--r--benchmarks/benchmarks/bench_ufunc_strides.py (renamed from benchmarks/benchmarks/bench_avx.py)52
-rw-r--r--benchmarks/benchmarks/common.py4
-rw-r--r--branding/logo/logoguidelines.md4
-rw-r--r--branding/logo/logomark/numpylogoicon.svg2
-rw-r--r--branding/logo/primary/numpylogo.svg2
-rw-r--r--branding/logo/secondary/numpylogo2.svg2
-rw-r--r--doc/DISTUTILS.rst.txt2
-rw-r--r--doc/HOWTO_RELEASE.rst.txt33
-rw-r--r--doc/Makefile9
-rw-r--r--doc/RELEASE_WALKTHROUGH.rst.txt14
-rw-r--r--doc/TESTS.rst.txt54
-rw-r--r--doc/changelog/1.17.0-changelog.rst3
-rw-r--r--doc/changelog/1.18.0-changelog.rst55
-rw-r--r--doc/changelog/1.18.5-changelog.rst18
-rw-r--r--doc/changelog/1.19.0-changelog.rst100
-rw-r--r--doc/changelog/1.19.5-changelog.rst32
-rw-r--r--doc/changelog/1.20.0-changelog.rst96
-rw-r--r--doc/changelog/1.20.1-changelog.rst36
-rw-r--r--doc/changelog/1.20.2-changelog.rst40
-rw-r--r--doc/changelog/1.20.3-changelog.rst35
-rw-r--r--doc/changelog/1.21.0-changelog.rst769
-rw-r--r--doc/changelog/1.21.1-changelog.rst51
-rw-r--r--doc/neps/_static/nep-0047-casting-rules-lattice.pngbin0 -> 65646 bytes
-rw-r--r--doc/neps/_static/nep-0047-library-dependencies.pngbin0 -> 68120 bytes
-rw-r--r--doc/neps/_static/nep-0047-scope-of-array-API.pngbin0 -> 85530 bytes
-rw-r--r--doc/neps/nep-0000.rst2
-rw-r--r--doc/neps/nep-0001-npy-format.rst2
-rw-r--r--doc/neps/nep-0010-new-iterator-ufunc.rst10
-rw-r--r--doc/neps/nep-0013-ufunc-overrides.rst16
-rw-r--r--doc/neps/nep-0014-dropping-python2.7-proposal.rst2
-rw-r--r--doc/neps/nep-0016-abstract-array.rst2
-rw-r--r--doc/neps/nep-0023-backwards-compatibility.rst419
-rw-r--r--doc/neps/nep-0024-missing-data-2.rst2
-rw-r--r--doc/neps/nep-0025-missing-data-3.rst18
-rw-r--r--doc/neps/nep-0026-missing-data-summary.rst8
-rw-r--r--doc/neps/nep-0027-zero-rank-arrarys.rst4
-rw-r--r--doc/neps/nep-0028-website-redesign.rst6
-rw-r--r--doc/neps/nep-0029-deprecation_policy.rst32
-rw-r--r--doc/neps/nep-0032-remove-financial-functions.rst14
-rw-r--r--doc/neps/nep-0035-array-creation-dispatch-with-array-function.rst17
-rw-r--r--doc/neps/nep-0036-fair-play.rst66
-rw-r--r--doc/neps/nep-0040-legacy-datatype-impl.rst2
-rw-r--r--doc/neps/nep-0042-new-dtypes.rst53
-rw-r--r--doc/neps/nep-0043-extensible-ufuncs.rst111
-rw-r--r--doc/neps/nep-0046-sponsorship-guidelines.rst256
-rw-r--r--doc/neps/nep-0047-array-api-standard.rst590
-rw-r--r--doc/neps/nep-0048-spending-project-funds.rst458
-rw-r--r--doc/neps/nep-0049.rst321
-rw-r--r--doc/neps/roadmap.rst81
-rw-r--r--doc/release/upcoming_changes/18536.improvement.rst7
-rw-r--r--doc/release/upcoming_changes/19062.new_feature.rst21
-rw-r--r--doc/release/upcoming_changes/19135.change.rst10
-rw-r--r--doc/release/upcoming_changes/19151.improvement.rst6
-rw-r--r--doc/release/upcoming_changes/19211.new_feature.rst7
-rw-r--r--doc/release/upcoming_changes/19259.c_api.rst12
-rw-r--r--doc/release/upcoming_changes/19356.change.rst7
-rw-r--r--doc/release/upcoming_changes/19459.new_feature.rst4
-rw-r--r--doc/release/upcoming_changes/19462.change.rst3
-rw-r--r--doc/release/upcoming_changes/19479.compatibility.rst7
-rw-r--r--doc/release/upcoming_changes/19513.new_feature.rst4
-rw-r--r--doc/release/upcoming_changes/README.rst2
-rw-r--r--doc/source/_static/favicon/apple-touch-icon.pngbin0 -> 23752 bytes
-rw-r--r--doc/source/_static/favicon/favicon-16x16.pngbin0 -> 843 bytes
-rw-r--r--doc/source/_static/favicon/favicon-32x32.pngbin0 -> 2292 bytes
-rw-r--r--doc/source/_static/favicon/favicon.icobin0 -> 15406 bytes
-rw-r--r--doc/source/_static/numpy.css8
-rw-r--r--doc/source/_static/numpylogo.svg46
m---------doc/source/_static/scipy-mathjax0
-rw-r--r--doc/source/_templates/autosummary/module.rst40
-rw-r--r--doc/source/_templates/indexcontent.html36
-rw-r--r--doc/source/conf.py42
-rw-r--r--doc/source/dev/development_advanced_debugging.rst190
-rw-r--r--doc/source/dev/development_environment.rst56
-rw-r--r--doc/source/dev/development_gitpod.rst271
-rw-r--r--doc/source/dev/development_workflow.rst50
-rw-r--r--doc/source/dev/gitpod-imgs/NumPy-github.pngbin0 -> 5368 bytes
-rw-r--r--doc/source/dev/gitpod-imgs/NumPy-gitpod-branches.pngbin0 -> 138394 bytes
-rw-r--r--doc/source/dev/gitpod-imgs/gitpod-dashboard-stop.pngbin0 -> 14185 bytes
-rw-r--r--doc/source/dev/gitpod-imgs/gitpod-edit-permissions-gh.pngbin0 -> 23308 bytes
-rw-r--r--doc/source/dev/gitpod-imgs/gitpod-edit-permissions-repo.pngbin0 -> 5505 bytes
-rw-r--r--doc/source/dev/gitpod-imgs/gitpod-workspace.pngbin0 -> 201069 bytes
-rw-r--r--doc/source/dev/gitpod-imgs/installing-gitpod-io.pngbin0 -> 33186 bytes
-rw-r--r--doc/source/dev/gitpod-imgs/rst-rendering.pngbin0 -> 228437 bytes
-rw-r--r--doc/source/dev/gitpod-imgs/vscode-rst.pngbin0 -> 16443 bytes
-rw-r--r--doc/source/dev/gitpod-imgs/vscode-statusbar.pngbin0 -> 4492 bytes
-rw-r--r--doc/source/dev/gitwash/development_setup.rst22
-rw-r--r--doc/source/dev/gitwash/dot2_dot3.rst10
-rw-r--r--doc/source/dev/gitwash/git_links.inc2
-rw-r--r--doc/source/dev/governance/governance.rst8
-rw-r--r--doc/source/dev/governance/index.rst1
-rw-r--r--doc/source/dev/governance/people.rst65
-rw-r--r--doc/source/dev/howto-docs.rst79
-rw-r--r--doc/source/dev/index.rst65
-rw-r--r--doc/source/dev/releasing.rst2
-rw-r--r--doc/source/dev/reviewer_guidelines.rst72
-rw-r--r--doc/source/docs/howto_build_docs.rst113
-rw-r--r--doc/source/glossary.rst7
-rw-r--r--doc/source/index.rst (renamed from doc/source/contents.rst)1
-rw-r--r--doc/source/reference/arrays.classes.rst2
-rw-r--r--doc/source/reference/arrays.datetime.rst16
-rw-r--r--doc/source/reference/arrays.ndarray.rst6
-rw-r--r--doc/source/reference/arrays.scalars.rst148
-rw-r--r--doc/source/reference/c-api/array.rst131
-rw-r--r--doc/source/reference/c-api/coremath.rst18
-rw-r--r--doc/source/reference/c-api/dtype.rst134
-rw-r--r--doc/source/reference/c-api/iterator.rst564
-rw-r--r--doc/source/reference/c-api/types-and-structures.rst38
-rw-r--r--doc/source/reference/c-api/ufunc.rst14
-rw-r--r--doc/source/reference/global_state.rst14
-rw-r--r--doc/source/reference/index.rst5
-rw-r--r--doc/source/reference/random/bit_generators/index.rst50
-rw-r--r--doc/source/reference/random/bit_generators/mt19937.rst3
-rw-r--r--doc/source/reference/random/bit_generators/pcg64.rst3
-rw-r--r--doc/source/reference/random/bit_generators/pcg64dxsm.rst32
-rw-r--r--doc/source/reference/random/bit_generators/philox.rst3
-rw-r--r--doc/source/reference/random/bit_generators/sfc64.rst3
-rw-r--r--doc/source/reference/random/c-api.rst12
-rw-r--r--doc/source/reference/random/generator.rst17
-rw-r--r--doc/source/reference/random/index.rst30
-rw-r--r--doc/source/reference/random/legacy.rst3
-rw-r--r--doc/source/reference/random/new-or-different.rst22
-rw-r--r--doc/source/reference/random/parallel.rst13
-rw-r--r--doc/source/reference/random/performance.py15
-rw-r--r--doc/source/reference/random/performance.rst138
-rw-r--r--doc/source/reference/random/upgrading-pcg64.rst152
-rw-r--r--doc/source/reference/routines.array-creation.rst4
-rw-r--r--doc/source/reference/routines.ctypeslib.rst7
-rw-r--r--doc/source/reference/routines.linalg.rst16
-rw-r--r--doc/source/reference/routines.other.rst9
-rw-r--r--doc/source/reference/routines.polynomials.classes.rst6
-rw-r--r--doc/source/reference/routines.polynomials.rst164
-rw-r--r--doc/source/reference/routines.testing.rst16
-rw-r--r--doc/source/reference/simd/simd-optimizations.py8
-rw-r--r--doc/source/reference/simd/simd-optimizations.rst4
-rw-r--r--doc/source/reference/ufuncs.rst51
-rw-r--r--doc/source/release.rst7
-rw-r--r--doc/source/release/1.18.5-notes.rst31
-rw-r--r--doc/source/release/1.19.5-notes.rst42
-rw-r--r--doc/source/release/1.20.0-notes.rst152
-rw-r--r--doc/source/release/1.20.1-notes.rst53
-rw-r--r--doc/source/release/1.20.2-notes.rst48
-rw-r--r--doc/source/release/1.20.3-notes.rst43
-rw-r--r--doc/source/release/1.21.0-notes.rst573
-rw-r--r--doc/source/release/1.21.1-notes.rst69
-rw-r--r--doc/source/release/1.22.0-notes.rst45
-rw-r--r--doc/source/user/absolute_beginners.rst46
-rw-r--r--doc/source/user/basics.broadcasting.rst186
-rw-r--r--doc/source/user/basics.creation.rst386
-rw-r--r--doc/source/user/basics.dispatch.rst18
-rw-r--r--doc/source/user/basics.indexing.rst6
-rw-r--r--doc/source/user/basics.rst14
-rw-r--r--doc/source/user/basics.subclassing.rst16
-rw-r--r--doc/source/user/basics.types.rst72
-rw-r--r--doc/source/user/broadcasting_1.svg669
-rw-r--r--doc/source/user/broadcasting_2.svg1308
-rw-r--r--doc/source/user/broadcasting_3.svg708
-rw-r--r--doc/source/user/broadcasting_4.svg1330
-rw-r--r--doc/source/user/broadcasting_5.svg344
-rw-r--r--doc/source/user/building.rst99
-rw-r--r--doc/source/user/c-info.beyond-basics.rst12
-rw-r--r--doc/source/user/c-info.how-to-extend.rst10
-rw-r--r--doc/source/user/depending_on_numpy.rst147
-rw-r--r--doc/source/user/explanations_index.rst14
-rw-r--r--doc/source/user/how-to-how-to.rst233
-rw-r--r--doc/source/user/how-to-io.rst656
-rw-r--r--doc/source/user/images/np_create_matrix.pngbin36296 -> 10556 bytes
-rw-r--r--doc/source/user/images/np_indexing.pngbin64363 -> 148808 bytes
-rw-r--r--doc/source/user/index.rst4
-rw-r--r--doc/source/user/install.rst12
-rw-r--r--doc/source/user/misc.rst11
-rw-r--r--doc/source/user/plots/matplotlib3.py3
-rw-r--r--doc/source/user/quickstart.rst439
-rw-r--r--doc/source/user/theory.broadcast_1.gifbin2987 -> 0 bytes
-rw-r--r--doc/source/user/theory.broadcast_2.gifbin6641 -> 0 bytes
-rw-r--r--doc/source/user/theory.broadcast_3.gifbin4681 -> 0 bytes
-rw-r--r--doc/source/user/theory.broadcast_4.gifbin7287 -> 0 bytes
-rw-r--r--doc/source/user/theory.broadcast_5.pngbin16721 -> 0 bytes
-rw-r--r--doc/source/user/theory.broadcasting.rst216
-rw-r--r--doc/source/user/tutorial-ma.rst386
-rw-r--r--doc/source/user/tutorial-svd.rst524
-rw-r--r--doc/source/user/tutorials_index.rst16
-rw-r--r--doc/source/user/who_covid_19_sit_rep_time_series.csv115
-rw-r--r--doc_requirements.txt4
-rw-r--r--environment.yml36
-rw-r--r--linter_requirements.txt2
-rw-r--r--numpy/__init__.cython-30.pxd2
-rw-r--r--numpy/__init__.pxd2
-rw-r--r--numpy/__init__.py111
-rw-r--r--numpy/__init__.pyi4265
-rw-r--r--numpy/_globals.py18
-rw-r--r--numpy/_pytesttester.py16
-rw-r--r--numpy/_pytesttester.pyi18
-rw-r--r--numpy/_version.py523
-rw-r--r--numpy/char.pyi110
-rw-r--r--numpy/compat/py3k.py7
-rw-r--r--numpy/core/__init__.py26
-rw-r--r--numpy/core/__init__.pyi2
-rw-r--r--numpy/core/_add_newdocs.py353
-rw-r--r--numpy/core/_add_newdocs_scalars.py12
-rw-r--r--numpy/core/_asarray.py275
-rw-r--r--numpy/core/_asarray.pyi32
-rw-r--r--numpy/core/_exceptions.py96
-rw-r--r--numpy/core/_internal.py93
-rw-r--r--numpy/core/_internal.pyi38
-rw-r--r--numpy/core/_methods.py17
-rw-r--r--numpy/core/_type_aliases.py3
-rw-r--r--numpy/core/_ufunc_config.py28
-rw-r--r--numpy/core/arrayprint.py105
-rw-r--r--numpy/core/arrayprint.pyi147
-rw-r--r--numpy/core/code_generators/cversions.txt2
-rw-r--r--numpy/core/code_generators/genapi.py9
-rw-r--r--numpy/core/code_generators/generate_numpy_api.py3
-rw-r--r--numpy/core/code_generators/generate_umath.py108
-rw-r--r--numpy/core/code_generators/ufunc_docstrings.py39
-rw-r--r--numpy/core/defchararray.py183
-rw-r--r--numpy/core/einsumfunc.py8
-rw-r--r--numpy/core/einsumfunc.pyi142
-rw-r--r--numpy/core/fromnumeric.py144
-rw-r--r--numpy/core/fromnumeric.pyi386
-rw-r--r--numpy/core/function_base.py2
-rw-r--r--numpy/core/function_base.pyi15
-rw-r--r--numpy/core/getlimits.py214
-rw-r--r--numpy/core/getlimits.pyi58
-rw-r--r--numpy/core/include/numpy/libdivide/LICENSE.txt21
-rw-r--r--numpy/core/include/numpy/libdivide/libdivide.h2079
-rw-r--r--numpy/core/include/numpy/ndarraytypes.h66
-rw-r--r--numpy/core/include/numpy/npy_3kcompat.h12
-rw-r--r--numpy/core/include/numpy/npy_common.h6
-rw-r--r--numpy/core/include/numpy/npy_cpu.h21
-rw-r--r--numpy/core/include/numpy/npy_math.h15
-rw-r--r--numpy/core/include/numpy/numpyconfig.h1
-rw-r--r--numpy/core/include/numpy/random/distributions.h15
-rw-r--r--numpy/core/include/numpy/ufuncobject.h45
-rw-r--r--numpy/core/machar.py14
-rw-r--r--numpy/core/memmap.py16
-rw-r--r--numpy/core/multiarray.py67
-rw-r--r--numpy/core/multiarray.pyi1002
-rw-r--r--numpy/core/numeric.py47
-rw-r--r--numpy/core/numeric.pyi89
-rw-r--r--numpy/core/numerictypes.py22
-rw-r--r--numpy/core/numerictypes.pyi186
-rw-r--r--numpy/core/overrides.py6
-rw-r--r--numpy/core/records.py48
-rw-r--r--numpy/core/setup.py40
-rw-r--r--numpy/core/setup_common.py11
-rw-r--r--numpy/core/shape_base.py47
-rw-r--r--numpy/core/shape_base.pyi69
-rw-r--r--numpy/core/src/_simd/_simd.dispatch.c.src240
-rw-r--r--numpy/core/src/_simd/_simd_easyintrin.inc34
-rw-r--r--numpy/core/src/_simd/_simd_vector.inc21
-rw-r--r--numpy/core/src/common/lowlevel_strided_loops.h154
-rw-r--r--numpy/core/src/common/npy_argparse.c421
-rw-r--r--numpy/core/src/common/npy_argparse.h96
-rw-r--r--numpy/core/src/common/npy_config.h45
-rw-r--r--numpy/core/src/common/npy_cpu_dispatch.h6
-rw-r--r--numpy/core/src/common/npy_cpu_features.c.src49
-rw-r--r--numpy/core/src/common/npy_cpuinfo_parser.h524
-rw-r--r--numpy/core/src/common/npy_hashtable.c220
-rw-r--r--numpy/core/src/common/npy_hashtable.h32
-rw-r--r--numpy/core/src/common/npy_pycompat.h16
-rw-r--r--numpy/core/src/common/simd/avx2/arithmetic.h208
-rw-r--r--numpy/core/src/common/simd/avx2/avx2.h6
-rw-r--r--numpy/core/src/common/simd/avx2/conversion.h45
-rw-r--r--numpy/core/src/common/simd/avx2/math.h70
-rw-r--r--numpy/core/src/common/simd/avx2/operators.h22
-rw-r--r--numpy/core/src/common/simd/avx2/reorder.h32
-rw-r--r--numpy/core/src/common/simd/avx512/arithmetic.h280
-rw-r--r--numpy/core/src/common/simd/avx512/avx512.h2
-rw-r--r--numpy/core/src/common/simd/avx512/conversion.h84
-rw-r--r--numpy/core/src/common/simd/avx512/maskop.h54
-rw-r--r--numpy/core/src/common/simd/avx512/math.h66
-rw-r--r--numpy/core/src/common/simd/avx512/operators.h69
-rw-r--r--numpy/core/src/common/simd/avx512/reorder.h56
-rw-r--r--numpy/core/src/common/simd/emulate_maskop.h44
-rw-r--r--numpy/core/src/common/simd/intdiv.h475
-rw-r--r--numpy/core/src/common/simd/neon/arithmetic.h186
-rw-r--r--numpy/core/src/common/simd/neon/conversion.h101
-rw-r--r--numpy/core/src/common/simd/neon/math.h72
-rw-r--r--numpy/core/src/common/simd/neon/neon.h5
-rw-r--r--numpy/core/src/common/simd/neon/operators.h37
-rw-r--r--numpy/core/src/common/simd/neon/reorder.h9
-rw-r--r--numpy/core/src/common/simd/simd.h12
-rw-r--r--numpy/core/src/common/simd/sse/arithmetic.h222
-rw-r--r--numpy/core/src/common/simd/sse/conversion.h46
-rw-r--r--numpy/core/src/common/simd/sse/math.h106
-rw-r--r--numpy/core/src/common/simd/sse/misc.h25
-rw-r--r--numpy/core/src/common/simd/sse/operators.h22
-rw-r--r--numpy/core/src/common/simd/sse/reorder.h41
-rw-r--r--numpy/core/src/common/simd/sse/sse.h7
-rw-r--r--numpy/core/src/common/simd/sse/utils.h19
-rw-r--r--numpy/core/src/common/simd/vsx/arithmetic.h166
-rw-r--r--numpy/core/src/common/simd/vsx/conversion.h91
-rw-r--r--numpy/core/src/common/simd/vsx/math.h36
-rw-r--r--numpy/core/src/common/simd/vsx/operators.h30
-rw-r--r--numpy/core/src/common/simd/vsx/reorder.h41
-rw-r--r--numpy/core/src/common/simd/vsx/vsx.h11
-rw-r--r--numpy/core/src/common/umathmodule.h3
-rw-r--r--numpy/core/src/multiarray/_multiarray_tests.c.src152
-rw-r--r--numpy/core/src/multiarray/abstractdtypes.c195
-rw-r--r--numpy/core/src/multiarray/abstractdtypes.h2
-rw-r--r--numpy/core/src/multiarray/array_assign_array.c45
-rw-r--r--numpy/core/src/multiarray/array_assign_scalar.c46
-rw-r--r--numpy/core/src/multiarray/array_coercion.c118
-rw-r--r--numpy/core/src/multiarray/array_coercion.h1
-rw-r--r--numpy/core/src/multiarray/array_method.c403
-rw-r--r--numpy/core/src/multiarray/array_method.h42
-rw-r--r--numpy/core/src/multiarray/arrayfunction_override.c125
-rw-r--r--numpy/core/src/multiarray/arrayfunction_override.h4
-rw-r--r--numpy/core/src/multiarray/arrayobject.c96
-rw-r--r--numpy/core/src/multiarray/arraytypes.c.src226
-rw-r--r--numpy/core/src/multiarray/buffer.c1
-rw-r--r--numpy/core/src/multiarray/calculation.c206
-rw-r--r--numpy/core/src/multiarray/calculation.h6
-rw-r--r--numpy/core/src/multiarray/common.c4
-rw-r--r--numpy/core/src/multiarray/common.h32
-rw-r--r--numpy/core/src/multiarray/common_dtype.c318
-rw-r--r--numpy/core/src/multiarray/common_dtype.h17
-rw-r--r--numpy/core/src/multiarray/compiled_base.c186
-rw-r--r--numpy/core/src/multiarray/conversion_utils.c78
-rw-r--r--numpy/core/src/multiarray/conversion_utils.h14
-rw-r--r--numpy/core/src/multiarray/convert_datatype.c1112
-rw-r--r--numpy/core/src/multiarray/convert_datatype.h28
-rw-r--r--numpy/core/src/multiarray/ctors.c229
-rw-r--r--numpy/core/src/multiarray/datetime.c204
-rw-r--r--numpy/core/src/multiarray/datetime_busday.c12
-rw-r--r--numpy/core/src/multiarray/datetime_busdaycal.c4
-rw-r--r--numpy/core/src/multiarray/descriptor.c60
-rw-r--r--numpy/core/src/multiarray/descriptor.h6
-rw-r--r--numpy/core/src/multiarray/dragon4.c131
-rw-r--r--numpy/core/src/multiarray/dragon4.h15
-rw-r--r--numpy/core/src/multiarray/dtype_transfer.c3391
-rw-r--r--numpy/core/src/multiarray/dtype_transfer.h205
-rw-r--r--numpy/core/src/multiarray/dtypemeta.c136
-rw-r--r--numpy/core/src/multiarray/dtypemeta.h58
-rw-r--r--numpy/core/src/multiarray/einsum.c.src4
-rw-r--r--numpy/core/src/multiarray/einsum_sumprod.c.src1195
-rw-r--r--numpy/core/src/multiarray/flagsobject.c89
-rw-r--r--numpy/core/src/multiarray/getset.c90
-rw-r--r--numpy/core/src/multiarray/item_selection.c270
-rw-r--r--numpy/core/src/multiarray/iterators.c49
-rw-r--r--numpy/core/src/multiarray/legacy_dtype_implementation.c185
-rw-r--r--numpy/core/src/multiarray/legacy_dtype_implementation.h32
-rw-r--r--numpy/core/src/multiarray/lowlevel_strided_loops.c.src268
-rw-r--r--numpy/core/src/multiarray/mapping.c151
-rw-r--r--numpy/core/src/multiarray/methods.c331
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.c890
-rw-r--r--numpy/core/src/multiarray/multiarraymodule.h7
-rw-r--r--numpy/core/src/multiarray/nditer_api.c119
-rw-r--r--numpy/core/src/multiarray/nditer_constr.c142
-rw-r--r--numpy/core/src/multiarray/nditer_impl.h32
-rw-r--r--numpy/core/src/multiarray/nditer_pywrap.c110
-rw-r--r--numpy/core/src/multiarray/number.c106
-rw-r--r--numpy/core/src/multiarray/number.h2
-rw-r--r--numpy/core/src/multiarray/scalartypes.c.src69
-rw-r--r--numpy/core/src/multiarray/temp_elide.c13
-rw-r--r--numpy/core/src/multiarray/temp_elide.h2
-rw-r--r--numpy/core/src/multiarray/usertypes.c12
-rw-r--r--numpy/core/src/npymath/npy_math_internal.h.src94
-rw-r--r--numpy/core/src/npysort/timsort.c.src4
-rw-r--r--numpy/core/src/umath/_scaled_float_dtype.c720
-rw-r--r--numpy/core/src/umath/_umath_tests.c.src4
-rw-r--r--numpy/core/src/umath/_umath_tests.dispatch.c1
-rw-r--r--numpy/core/src/umath/dispatching.c690
-rw-r--r--numpy/core/src/umath/dispatching.h25
-rw-r--r--numpy/core/src/umath/fast_loop_macros.h142
-rw-r--r--numpy/core/src/umath/legacy_array_method.c258
-rw-r--r--numpy/core/src/umath/legacy_array_method.h33
-rw-r--r--numpy/core/src/umath/loops.c.src596
-rw-r--r--numpy/core/src/umath/loops.h.src115
-rw-r--r--numpy/core/src/umath/loops_arithm_fp.dispatch.c.src777
-rw-r--r--numpy/core/src/umath/loops_arithmetic.dispatch.c.src262
-rw-r--r--numpy/core/src/umath/loops_exponent_log.dispatch.c.src1305
-rw-r--r--numpy/core/src/umath/loops_trigonometric.dispatch.c.src230
-rw-r--r--numpy/core/src/umath/loops_utils.h42
-rw-r--r--numpy/core/src/umath/loops_utils.h.src224
-rw-r--r--numpy/core/src/umath/npy_simd_data.h24
-rw-r--r--numpy/core/src/umath/override.c524
-rw-r--r--numpy/core/src/umath/override.h7
-rw-r--r--numpy/core/src/umath/reduction.c46
-rw-r--r--numpy/core/src/umath/scalarmath.c.src69
-rw-r--r--numpy/core/src/umath/simd.inc.src2128
-rw-r--r--numpy/core/src/umath/ufunc_object.c3199
-rw-r--r--numpy/core/src/umath/ufunc_object.h14
-rw-r--r--numpy/core/src/umath/ufunc_type_resolution.c688
-rw-r--r--numpy/core/src/umath/ufunc_type_resolution.h11
-rw-r--r--numpy/core/src/umath/umathmodule.c43
-rw-r--r--numpy/core/tests/data/generate_umath_validation_data.cpp157
-rw-r--r--numpy/core/tests/data/umath-validation-set-README.txt (renamed from numpy/core/tests/data/umath-validation-set-README)4
-rw-r--r--numpy/core/tests/data/umath-validation-set-arccos.csv1429
-rw-r--r--numpy/core/tests/data/umath-validation-set-arccosh.csv1429
-rw-r--r--numpy/core/tests/data/umath-validation-set-arcsin.csv1429
-rw-r--r--numpy/core/tests/data/umath-validation-set-arcsinh.csv1429
-rw-r--r--numpy/core/tests/data/umath-validation-set-arctan.csv1429
-rw-r--r--numpy/core/tests/data/umath-validation-set-arctanh.csv1429
-rw-r--r--numpy/core/tests/data/umath-validation-set-cbrt.csv1429
-rw-r--r--numpy/core/tests/data/umath-validation-set-cos665
-rw-r--r--numpy/core/tests/data/umath-validation-set-cos.csv1375
-rw-r--r--numpy/core/tests/data/umath-validation-set-cosh.csv1429
-rw-r--r--numpy/core/tests/data/umath-validation-set-exp.csv (renamed from numpy/core/tests/data/umath-validation-set-exp)0
-rw-r--r--numpy/core/tests/data/umath-validation-set-exp2.csv1429
-rw-r--r--numpy/core/tests/data/umath-validation-set-expm1.csv1429
-rw-r--r--numpy/core/tests/data/umath-validation-set-log.csv (renamed from numpy/core/tests/data/umath-validation-set-log)0
-rw-r--r--numpy/core/tests/data/umath-validation-set-log10.csv1629
-rw-r--r--numpy/core/tests/data/umath-validation-set-log1p.csv1429
-rw-r--r--numpy/core/tests/data/umath-validation-set-log2.csv1629
-rw-r--r--numpy/core/tests/data/umath-validation-set-sin660
-rw-r--r--numpy/core/tests/data/umath-validation-set-sin.csv1370
-rw-r--r--numpy/core/tests/data/umath-validation-set-sinh.csv1429
-rw-r--r--numpy/core/tests/data/umath-validation-set-tan.csv1429
-rw-r--r--numpy/core/tests/data/umath-validation-set-tanh.csv1429
-rw-r--r--numpy/core/tests/test__exceptions.py30
-rw-r--r--numpy/core/tests/test_api.py15
-rw-r--r--numpy/core/tests/test_argparse.py62
-rw-r--r--numpy/core/tests/test_array_coercion.py63
-rw-r--r--numpy/core/tests/test_arraymethod.py58
-rw-r--r--numpy/core/tests/test_arrayprint.py13
-rw-r--r--numpy/core/tests/test_casting_unittests.py439
-rw-r--r--numpy/core/tests/test_cpu_features.py7
-rw-r--r--numpy/core/tests/test_custom_dtypes.py135
-rw-r--r--numpy/core/tests/test_datetime.py59
-rw-r--r--numpy/core/tests/test_deprecations.py407
-rw-r--r--numpy/core/tests/test_dtype.py154
-rw-r--r--numpy/core/tests/test_getlimits.py26
-rw-r--r--numpy/core/tests/test_half.py15
-rw-r--r--numpy/core/tests/test_hashtable.py30
-rw-r--r--numpy/core/tests/test_indexing.py57
-rw-r--r--numpy/core/tests/test_longdouble.py1
-rw-r--r--numpy/core/tests/test_mem_overlap.py7
-rw-r--r--numpy/core/tests/test_memmap.py19
-rw-r--r--numpy/core/tests/test_multiarray.py972
-rw-r--r--numpy/core/tests/test_nditer.py349
-rw-r--r--numpy/core/tests/test_numeric.py333
-rw-r--r--numpy/core/tests/test_overrides.py95
-rw-r--r--numpy/core/tests/test_regression.py66
-rw-r--r--numpy/core/tests/test_scalar_methods.py3
-rw-r--r--numpy/core/tests/test_scalarmath.py183
-rw-r--r--numpy/core/tests/test_scalarprint.py72
-rw-r--r--numpy/core/tests/test_shape_base.py27
-rw-r--r--numpy/core/tests/test_simd.py360
-rw-r--r--numpy/core/tests/test_ufunc.py160
-rw-r--r--numpy/core/tests/test_umath.py512
-rw-r--r--numpy/core/tests/test_umath_accuracy.py12
-rw-r--r--numpy/core/tests/test_umath_complex.py6
-rw-r--r--numpy/ctypeslib.py9
-rw-r--r--numpy/ctypeslib.pyi20
-rw-r--r--numpy/distutils/ccompiler.py13
-rw-r--r--numpy/distutils/ccompiler_opt.py330
-rw-r--r--numpy/distutils/checks/cpu_avx.c17
-rw-r--r--numpy/distutils/checks/cpu_avx2.c17
-rw-r--r--numpy/distutils/checks/cpu_avx512_clx.c18
-rw-r--r--numpy/distutils/checks/cpu_avx512_cnl.c20
-rw-r--r--numpy/distutils/checks/cpu_avx512_icl.c18
-rw-r--r--numpy/distutils/checks/cpu_avx512_knl.c18
-rw-r--r--numpy/distutils/checks/cpu_avx512_knm.c19
-rw-r--r--numpy/distutils/checks/cpu_avx512_skx.c18
-rw-r--r--numpy/distutils/checks/cpu_avx512cd.c17
-rw-r--r--numpy/distutils/checks/cpu_avx512f.c17
-rw-r--r--numpy/distutils/checks/cpu_f16c.c19
-rw-r--r--numpy/distutils/checks/cpu_fma3.c18
-rw-r--r--numpy/distutils/checks/cpu_fma4.c5
-rw-r--r--numpy/distutils/checks/cpu_popcnt.c35
-rw-r--r--numpy/distutils/checks/cpu_sse.c13
-rw-r--r--numpy/distutils/checks/cpu_sse2.c13
-rw-r--r--numpy/distutils/checks/cpu_sse3.c13
-rw-r--r--numpy/distutils/checks/cpu_sse41.c13
-rw-r--r--numpy/distutils/checks/cpu_sse42.c13
-rw-r--r--numpy/distutils/checks/cpu_ssse3.c13
-rw-r--r--numpy/distutils/checks/extra_avx512dq_mask.c16
-rw-r--r--numpy/distutils/checks/extra_avx512f_reduce.c2
-rw-r--r--numpy/distutils/checks/extra_vsx_asm.c36
-rw-r--r--numpy/distutils/command/build_clib.py74
-rw-r--r--numpy/distutils/command/build_ext.py83
-rw-r--r--numpy/distutils/command/build_src.py8
-rw-r--r--numpy/distutils/command/config.py7
-rw-r--r--numpy/distutils/conv_template.py11
-rw-r--r--numpy/distutils/extension.py4
-rw-r--r--numpy/distutils/fcompiler/__init__.py16
-rw-r--r--numpy/distutils/fcompiler/compaq.py8
-rw-r--r--numpy/distutils/fcompiler/fujitsu.py46
-rw-r--r--numpy/distutils/fcompiler/gnu.py7
-rw-r--r--numpy/distutils/fcompiler/ibm.py2
-rw-r--r--numpy/distutils/fcompiler/intel.py16
-rw-r--r--numpy/distutils/fcompiler/nag.py2
-rw-r--r--numpy/distutils/fcompiler/nv.py2
-rw-r--r--numpy/distutils/from_template.py3
-rw-r--r--numpy/distutils/intelccompiler.py2
-rw-r--r--numpy/distutils/mingw32ccompiler.py2
-rw-r--r--numpy/distutils/misc_util.py128
-rw-r--r--numpy/distutils/system_info.py99
-rw-r--r--numpy/distutils/tests/test_build_ext.py72
-rw-r--r--numpy/distutils/tests/test_ccompiler_opt.py6
-rw-r--r--numpy/distutils/tests/test_ccompiler_opt_conf.py4
-rw-r--r--numpy/distutils/tests/test_system_info.py4
-rw-r--r--numpy/distutils/unixccompiler.py4
-rw-r--r--numpy/emath.pyi11
-rw-r--r--numpy/f2py/__init__.py49
-rw-r--r--numpy/f2py/__init__.pyi46
-rw-r--r--numpy/f2py/auxfuncs.py5
-rw-r--r--numpy/f2py/capi_maps.py2
-rw-r--r--numpy/f2py/cb_rules.py9
-rw-r--r--numpy/f2py/cfuncs.py192
-rwxr-xr-xnumpy/f2py/crackfortran.py145
-rwxr-xr-xnumpy/f2py/f2py2e.py10
-rw-r--r--numpy/f2py/f90mod_rules.py3
-rw-r--r--numpy/f2py/func2subr.py9
-rwxr-xr-xnumpy/f2py/rules.py63
-rw-r--r--numpy/f2py/src/fortranobject.c4
-rw-r--r--numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c2
-rw-r--r--numpy/f2py/tests/test_abstract_interface.py66
-rw-r--r--numpy/f2py/tests/test_array_from_pyobj.py103
-rw-r--r--numpy/f2py/tests/test_assumed_shape.py2
-rw-r--r--numpy/f2py/tests/test_callback.py113
-rw-r--r--numpy/f2py/tests/test_crackfortran.py83
-rw-r--r--numpy/f2py/tests/test_regression.py20
-rw-r--r--numpy/f2py/tests/test_return_character.py6
-rw-r--r--numpy/f2py/tests/test_string.py148
-rw-r--r--numpy/fft/__init__.py4
-rw-r--r--numpy/fft/__init__.pyi44
-rw-r--r--numpy/fft/_pocketfft.py39
-rw-r--r--numpy/lib/__init__.pyi423
-rw-r--r--numpy/lib/_datasource.py6
-rw-r--r--numpy/lib/_version.py6
-rw-r--r--numpy/lib/_version.pyi19
-rw-r--r--numpy/lib/arraypad.pyi94
-rw-r--r--numpy/lib/arraysetops.py27
-rw-r--r--numpy/lib/arraysetops.pyi12
-rw-r--r--numpy/lib/arrayterator.pyi53
-rw-r--r--numpy/lib/format.py26
-rw-r--r--numpy/lib/format.pyi28
-rw-r--r--numpy/lib/function_base.py170
-rw-r--r--numpy/lib/function_base.pyi57
-rw-r--r--numpy/lib/histograms.py5
-rw-r--r--numpy/lib/histograms.pyi7
-rw-r--r--numpy/lib/index_tricks.py37
-rw-r--r--numpy/lib/index_tricks.pyi171
-rw-r--r--numpy/lib/mixins.pyi62
-rw-r--r--numpy/lib/nanfunctions.py22
-rw-r--r--numpy/lib/nanfunctions.pyi54
-rw-r--r--numpy/lib/npyio.py218
-rw-r--r--numpy/lib/npyio.pyi104
-rw-r--r--numpy/lib/polynomial.py27
-rw-r--r--numpy/lib/polynomial.pyi19
-rw-r--r--numpy/lib/scimath.py8
-rw-r--r--numpy/lib/scimath.pyi13
-rw-r--r--numpy/lib/shape_base.py22
-rw-r--r--numpy/lib/shape_base.pyi215
-rw-r--r--numpy/lib/stride_tricks.py5
-rw-r--r--numpy/lib/stride_tricks.pyi16
-rw-r--r--numpy/lib/tests/test__version.py2
-rw-r--r--numpy/lib/tests/test_arraysetops.py90
-rw-r--r--numpy/lib/tests/test_format.py2
-rw-r--r--numpy/lib/tests/test_function_base.py89
-rw-r--r--numpy/lib/tests/test_index_tricks.py15
-rw-r--r--numpy/lib/tests/test_io.py5
-rw-r--r--numpy/lib/tests/test_nanfunctions.py50
-rw-r--r--numpy/lib/tests/test_polynomial.py31
-rw-r--r--numpy/lib/tests/test_regression.py2
-rw-r--r--numpy/lib/tests/test_utils.py11
-rw-r--r--numpy/lib/twodim_base.py116
-rw-r--r--numpy/lib/twodim_base.pyi255
-rw-r--r--numpy/lib/type_check.py39
-rw-r--r--numpy/lib/type_check.pyi235
-rw-r--r--numpy/lib/ufunclike.py8
-rw-r--r--numpy/lib/ufunclike.pyi66
-rw-r--r--numpy/lib/utils.py63
-rw-r--r--numpy/lib/utils.pyi99
-rw-r--r--numpy/linalg/__init__.py3
-rw-r--r--numpy/linalg/__init__.pyi51
-rw-r--r--numpy/linalg/lapack_lite/clapack_scrub.py2
-rw-r--r--numpy/linalg/lapack_lite/fortran.py2
-rwxr-xr-xnumpy/linalg/lapack_lite/make_lite.py8
-rw-r--r--numpy/linalg/linalg.py177
-rw-r--r--numpy/linalg/setup.py5
-rw-r--r--numpy/linalg/tests/test_build.py4
-rw-r--r--numpy/linalg/tests/test_linalg.py84
-rw-r--r--numpy/linalg/umath_linalg.c.src750
-rw-r--r--numpy/ma/__init__.pyi459
-rw-r--r--numpy/ma/core.py225
-rw-r--r--numpy/ma/core.pyi468
-rw-r--r--numpy/ma/extras.py12
-rw-r--r--numpy/ma/extras.pyi84
-rw-r--r--numpy/ma/mrecords.py42
-rw-r--r--numpy/ma/mrecords.pyi88
-rw-r--r--numpy/ma/tests/test_core.py104
-rw-r--r--numpy/ma/tests/test_extras.py17
-rw-r--r--numpy/ma/tests/test_mrecords.py2
-rw-r--r--numpy/ma/tests/test_subclassing.py18
-rw-r--r--numpy/ma/testutils.py4
-rw-r--r--numpy/ma/timer_comparison.py13
-rw-r--r--numpy/matrixlib/__init__.pyi19
-rw-r--r--numpy/polynomial/__init__.py51
-rw-r--r--numpy/polynomial/__init__.pyi33
-rw-r--r--numpy/polynomial/_polybase.py15
-rw-r--r--numpy/polynomial/_polybase.pyi69
-rw-r--r--numpy/polynomial/chebyshev.py16
-rw-r--r--numpy/polynomial/chebyshev.pyi51
-rw-r--r--numpy/polynomial/hermite.py9
-rw-r--r--numpy/polynomial/hermite.pyi46
-rw-r--r--numpy/polynomial/hermite_e.py9
-rw-r--r--numpy/polynomial/hermite_e.pyi46
-rw-r--r--numpy/polynomial/laguerre.py9
-rw-r--r--numpy/polynomial/laguerre.pyi46
-rw-r--r--numpy/polynomial/legendre.py15
-rw-r--r--numpy/polynomial/legendre.pyi46
-rw-r--r--numpy/polynomial/polynomial.py15
-rw-r--r--numpy/polynomial/polynomial.pyi41
-rw-r--r--numpy/polynomial/polyutils.py68
-rw-r--r--numpy/polynomial/polyutils.pyi12
-rw-r--r--numpy/polynomial/tests/test_legendre.py12
-rw-r--r--numpy/polynomial/tests/test_polynomial.py7
-rw-r--r--numpy/polynomial/tests/test_polyutils.py15
-rw-r--r--numpy/polynomial/tests/test_printing.py13
-rw-r--r--numpy/random/__init__.py6
-rw-r--r--numpy/random/__init__.pyi131
-rw-r--r--numpy/random/_bounded_integers.pyx.in27
-rw-r--r--numpy/random/_common.pxd2
-rw-r--r--numpy/random/_common.pyx51
-rw-r--r--numpy/random/_examples/cffi/parse.py11
-rw-r--r--numpy/random/_examples/cython/setup.py15
-rw-r--r--numpy/random/_examples/numba/extending.py2
-rw-r--r--numpy/random/_generator.pyi651
-rw-r--r--numpy/random/_generator.pyx174
-rw-r--r--numpy/random/_mt19937.pyi28
-rw-r--r--numpy/random/_pcg64.pyi48
-rw-r--r--numpy/random/_pcg64.pyx250
-rw-r--r--numpy/random/_philox.pyi42
-rw-r--r--numpy/random/_philox.pyx5
-rw-r--r--numpy/random/_pickle.py9
-rw-r--r--numpy/random/_sfc64.pyi34
-rw-r--r--numpy/random/bit_generator.pyi121
-rw-r--r--numpy/random/bit_generator.pyx9
-rw-r--r--numpy/random/include/legacy-distributions.h4
-rw-r--r--numpy/random/mtrand.pyi579
-rw-r--r--numpy/random/mtrand.pyx122
-rw-r--r--numpy/random/setup.py7
-rw-r--r--numpy/random/src/distributions/distributions.c69
-rw-r--r--numpy/random/src/legacy/legacy-distributions.c123
-rw-r--r--numpy/random/src/pcg64/pcg64.c18
-rw-r--r--numpy/random/src/pcg64/pcg64.h134
-rw-r--r--numpy/random/src/philox/philox.h8
-rw-r--r--numpy/random/tests/data/pcg64dxsm-testset-1.csv1001
-rw-r--r--numpy/random/tests/data/pcg64dxsm-testset-2.csv1001
-rw-r--r--numpy/random/tests/test_direct.py32
-rw-r--r--numpy/random/tests/test_generator_mt19937.py125
-rw-r--r--numpy/random/tests/test_generator_mt19937_regressions.py4
-rw-r--r--numpy/random/tests/test_random.py54
-rw-r--r--numpy/random/tests/test_randomstate.py23
-rw-r--r--numpy/random/tests/test_smoke.py14
-rw-r--r--numpy/rec.pyi68
-rw-r--r--numpy/testing/__init__.py2
-rw-r--r--numpy/testing/__init__.pyi100
-rw-r--r--numpy/testing/_private/decorators.py47
-rw-r--r--numpy/testing/_private/parameterized.py16
-rw-r--r--numpy/testing/_private/utils.py51
-rw-r--r--numpy/testing/_private/utils.pyi396
-rwxr-xr-xnumpy/testing/setup.py1
-rw-r--r--numpy/testing/tests/test_decorators.py210
-rw-r--r--numpy/testing/tests/test_utils.py13
-rw-r--r--numpy/testing/utils.py3
-rw-r--r--numpy/tests/test_numpy_version.py35
-rw-r--r--numpy/tests/test_public_api.py8
-rw-r--r--numpy/tests/test_reloading.py19
-rw-r--r--numpy/typing/__init__.py198
-rw-r--r--numpy/typing/_add_docstring.py57
-rw-r--r--numpy/typing/_array_like.py134
-rw-r--r--numpy/typing/_callable.py249
-rw-r--r--numpy/typing/_char_codes.py171
-rw-r--r--numpy/typing/_dtype_like.py189
-rw-r--r--numpy/typing/_extended_precision.py42
-rw-r--r--numpy/typing/_generic_alias.py216
-rw-r--r--numpy/typing/_nbit.py16
-rw-r--r--numpy/typing/_scalars.py26
-rw-r--r--numpy/typing/_shape.py14
-rw-r--r--numpy/typing/_ufunc.pyi403
-rw-r--r--numpy/typing/mypy_plugin.py194
-rw-r--r--numpy/typing/tests/data/fail/arithmetic.py104
-rw-r--r--numpy/typing/tests/data/fail/array_constructors.py10
-rw-r--r--numpy/typing/tests/data/fail/array_like.py4
-rw-r--r--numpy/typing/tests/data/fail/array_pad.py6
-rw-r--r--numpy/typing/tests/data/fail/arrayprint.py13
-rw-r--r--numpy/typing/tests/data/fail/arrayterator.py14
-rw-r--r--numpy/typing/tests/data/fail/comparisons.py28
-rw-r--r--numpy/typing/tests/data/fail/constants.py3
-rw-r--r--numpy/typing/tests/data/fail/datasource.py15
-rw-r--r--numpy/typing/tests/data/fail/dtype.py14
-rw-r--r--numpy/typing/tests/data/fail/einsumfunc.py15
-rw-r--r--numpy/typing/tests/data/fail/fromnumeric.py112
-rw-r--r--numpy/typing/tests/data/fail/index_tricks.py14
-rw-r--r--numpy/typing/tests/data/fail/lib_utils.py13
-rw-r--r--numpy/typing/tests/data/fail/lib_version.py6
-rw-r--r--numpy/typing/tests/data/fail/modules.py9
-rw-r--r--numpy/typing/tests/data/fail/multiarray.py49
-rw-r--r--numpy/typing/tests/data/fail/ndarray_misc.py16
-rw-r--r--numpy/typing/tests/data/fail/numerictypes.py8
-rw-r--r--numpy/typing/tests/data/fail/random.py61
-rw-r--r--numpy/typing/tests/data/fail/scalars.py18
-rw-r--r--numpy/typing/tests/data/fail/testing.py26
-rw-r--r--numpy/typing/tests/data/fail/twodim_base.py37
-rw-r--r--numpy/typing/tests/data/fail/type_check.py13
-rw-r--r--numpy/typing/tests/data/fail/ufunclike.py21
-rw-r--r--numpy/typing/tests/data/fail/ufuncs.py40
-rw-r--r--numpy/typing/tests/data/fail/warnings_and_errors.py8
-rw-r--r--numpy/typing/tests/data/misc/extended_precision.py17
-rw-r--r--numpy/typing/tests/data/mypy.ini3
-rw-r--r--numpy/typing/tests/data/pass/arithmetic.py337
-rw-r--r--numpy/typing/tests/data/pass/array_constructors.py16
-rw-r--r--numpy/typing/tests/data/pass/array_like.py12
-rw-r--r--numpy/typing/tests/data/pass/arrayprint.py37
-rw-r--r--numpy/typing/tests/data/pass/arrayterator.py27
-rw-r--r--numpy/typing/tests/data/pass/comparisons.py96
-rw-r--r--numpy/typing/tests/data/pass/dtype.py24
-rw-r--r--numpy/typing/tests/data/pass/einsumfunc.py36
-rw-r--r--numpy/typing/tests/data/pass/flatiter.py2
-rw-r--r--numpy/typing/tests/data/pass/index_tricks.py64
-rw-r--r--numpy/typing/tests/data/pass/lib_utils.py26
-rw-r--r--numpy/typing/tests/data/pass/lib_version.py18
-rw-r--r--numpy/typing/tests/data/pass/modules.py43
-rw-r--r--numpy/typing/tests/data/pass/multiarray.py77
-rw-r--r--numpy/typing/tests/data/pass/ndarray_misc.py32
-rw-r--r--numpy/typing/tests/data/pass/numerictypes.py18
-rw-r--r--numpy/typing/tests/data/pass/random.py1497
-rw-r--r--numpy/typing/tests/data/pass/scalars.py89
-rw-r--r--numpy/typing/tests/data/pass/ufunclike.py46
-rw-r--r--numpy/typing/tests/data/pass/ufuncs.py3
-rw-r--r--numpy/typing/tests/data/pass/warnings_and_errors.py3
-rw-r--r--numpy/typing/tests/data/reveal/arithmetic.py685
-rw-r--r--numpy/typing/tests/data/reveal/array_constructors.py229
-rw-r--r--numpy/typing/tests/data/reveal/arraypad.py22
-rw-r--r--numpy/typing/tests/data/reveal/arrayprint.py19
-rw-r--r--numpy/typing/tests/data/reveal/arrayterator.py24
-rw-r--r--numpy/typing/tests/data/reveal/bitwise_ops.py136
-rw-r--r--numpy/typing/tests/data/reveal/comparisons.py77
-rw-r--r--numpy/typing/tests/data/reveal/constants.py52
-rw-r--r--numpy/typing/tests/data/reveal/ctypeslib.py3
-rw-r--r--numpy/typing/tests/data/reveal/datasource.py21
-rw-r--r--numpy/typing/tests/data/reveal/dtype.py65
-rw-r--r--numpy/typing/tests/data/reveal/einsumfunc.py32
-rw-r--r--numpy/typing/tests/data/reveal/flatiter.py21
-rw-r--r--numpy/typing/tests/data/reveal/fromnumeric.py432
-rw-r--r--numpy/typing/tests/data/reveal/getlimits.py73
-rw-r--r--numpy/typing/tests/data/reveal/index_tricks.py64
-rw-r--r--numpy/typing/tests/data/reveal/lib_utils.py30
-rw-r--r--numpy/typing/tests/data/reveal/lib_version.py18
-rw-r--r--numpy/typing/tests/data/reveal/mod.py234
-rw-r--r--numpy/typing/tests/data/reveal/modules.py31
-rw-r--r--numpy/typing/tests/data/reveal/multiarray.py125
-rw-r--r--numpy/typing/tests/data/reveal/nbit_base_example.py13
-rw-r--r--numpy/typing/tests/data/reveal/ndarray_conversion.py53
-rw-r--r--numpy/typing/tests/data/reveal/ndarray_misc.py273
-rw-r--r--numpy/typing/tests/data/reveal/nditer.py19
-rw-r--r--numpy/typing/tests/data/reveal/numeric.py62
-rw-r--r--numpy/typing/tests/data/reveal/numerictypes.py40
-rw-r--r--numpy/typing/tests/data/reveal/random.py1539
-rw-r--r--numpy/typing/tests/data/reveal/scalars.py162
-rw-r--r--numpy/typing/tests/data/reveal/shape_base.py57
-rw-r--r--numpy/typing/tests/data/reveal/testing.py173
-rw-r--r--numpy/typing/tests/data/reveal/twodim_base.py72
-rw-r--r--numpy/typing/tests/data/reveal/type_check.py73
-rw-r--r--numpy/typing/tests/data/reveal/ufunclike.py29
-rw-r--r--numpy/typing/tests/data/reveal/ufuncs.py68
-rw-r--r--numpy/typing/tests/data/reveal/warnings_and_errors.py3
-rw-r--r--numpy/typing/tests/test_generic_alias.py128
-rw-r--r--numpy/typing/tests/test_isfile.py1
-rw-r--r--numpy/typing/tests/test_runtime.py90
-rw-r--r--numpy/typing/tests/test_typing.py263
-rw-r--r--numpy/typing/tests/test_typing_extensions.py35
-rw-r--r--numpy/version.py12
-rw-r--r--pavement.py50
-rw-r--r--pyproject.toml4
-rw-r--r--pytest.ini3
-rwxr-xr-xruntests.py86
-rw-r--r--setup.cfg11
-rwxr-xr-xsetup.py209
-rw-r--r--shippable.yml67
-rw-r--r--site.cfg.example11
-rw-r--r--test_requirements.txt20
-rwxr-xr-xtools/changelog.py55
-rwxr-xr-xtools/ci/push_docs_to_repo.py5
-rwxr-xr-xtools/ci/test_all_newsfragments_used.py2
-rw-r--r--tools/commitstats.py2
-rwxr-xr-xtools/cythonize.py10
-rwxr-xr-xtools/functions_missing_types.py2
-rw-r--r--tools/gitpod/Dockerfile101
-rw-r--r--tools/gitpod/gitpod.Dockerfile47
-rw-r--r--tools/gitpod/settings.json9
-rw-r--r--tools/gitpod/workspace_config58
-rw-r--r--tools/lint_diff.ini4
-rw-r--r--tools/linter.py83
-rw-r--r--tools/list_installed_dll_dependencies_cygwin.sh38
-rw-r--r--tools/npy_tempita/__init__.py2
-rw-r--r--tools/openblas_support.py202
-rw-r--r--tools/refguide_check.py21
-rw-r--r--tools/swig/numpy.i152
-rwxr-xr-xtools/travis-before-install.sh1
-rwxr-xr-xtools/travis-sorter.py2
-rwxr-xr-xtools/travis-test.sh18
-rw-r--r--tox.ini2
-rw-r--r--versioneer.py1852
836 files changed, 95121 insertions, 24059 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
index 9324de943..8cf18d809 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -40,9 +40,9 @@ jobs:
name: create release notes
command: |
. venv/bin/activate
- pip install git+https://github.com/hawkowl/towncrier.git@master
+ pip install towncrier
VERSION=$(python -c "import setup; print(setup.VERSION)")
- towncrier --version $VERSION --yes
+ towncrier build --version $VERSION --yes
./tools/ci/test_all_newsfragments_used.py
- run:
@@ -62,6 +62,7 @@ jobs:
- run:
name: build devdocs
+ no_output_timeout: 30m
command: |
. venv/bin/activate
cd doc
@@ -90,7 +91,7 @@ jobs:
- run:
name: deploy devdocs
command: |
- if [ "${CIRCLE_BRANCH}" == "master" ]; then
+ if [ "${CIRCLE_BRANCH}" == "main" ]; then
touch doc/build/html/.nojekyll
./tools/ci/push_docs_to_repo.py doc/build/html \
@@ -100,7 +101,7 @@ jobs:
--message "Docs build of $CIRCLE_SHA1" \
--force
else
- echo "Not on the master branch; skipping deployment"
+ echo "Not on the main branch; skipping deployment"
fi
- add_ssh_keys:
@@ -119,7 +120,7 @@ jobs:
- run:
name: deploy neps
command: |
- if [ "${CIRCLE_BRANCH}" == "master" ]; then
+ if [ "${CIRCLE_BRANCH}" == "main" ]; then
touch doc/neps/_build/html/.nojekyll
./tools/ci/push_docs_to_repo.py doc/neps/_build/html \
@@ -129,5 +130,5 @@ jobs:
--message "Docs build of $CIRCLE_SHA1" \
--force
else
- echo "Not on the master branch; skipping deployment"
+ echo "Not on the main branch; skipping deployment"
fi
diff --git a/.codecov.yml b/.codecov.yml
index 8c19f9e8e..165b3099d 100644
--- a/.codecov.yml
+++ b/.codecov.yml
@@ -6,8 +6,9 @@ coverage:
status:
project:
default:
- # Require 1% coverage, i.e., always succeed
- target: 1
- patch: true
+ informational: true
+ patch:
+ default:
+ informational: true
changes: false
comment: off
diff --git a/.dependabot/config.yml b/.dependabot/config.yml
deleted file mode 100644
index 160ec85cf..000000000
--- a/.dependabot/config.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-version: 1
-update_configs:
- - package_manager: "python"
- directory: "/"
- update_schedule: "weekly"
- commit_message:
- prefix: "MAINT"
- default_labels:
- - "03 - Maintenance"
diff --git a/.gitattributes b/.gitattributes
index bce3dbe6d..8723dd9dc 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -1,21 +1,109 @@
-# Numerical data files
-numpy/lib/tests/data/*.npy binary
-
-# Release notes, reduce number of conflicts.
-doc/release/*.rst merge=union
-
# Highlight our custom templating language as C, since it's hopefully better
# than nothing. This also affects repo statistics.
-*.c.src linguist-language=C
-*.inc.src linguist-language=C
-*.h.src linguist-language=C
+*.c.src text linguist-language=C
+*.inc.src text linguist-language=C
+*.h.src text linguist-language=C
+*.pyx.in text linguist-language=Python
+*.pxd.in text linguist-language=Python
# Mark some files as vendored
numpy/linalg/lapack_lite/f2c.c linguist-vendored
numpy/linalg/lapack_lite/f2c.h linguist-vendored
tools/npy_tempita/* linguist-vendored
+numpy/core/include/numpy/libdivide/* linguist-vendored
# Mark some files as generated
numpy/linalg/lapack_lite/f2c_*.c linguist-generated
numpy/linalg/lapack_lite/lapack_lite_names.h linguist-generated
+numpy/_version.py export-subst
+
+# Configuration files
+*.ini text
+*.cfg text
+./MANIFEST.in text
+./numpy/core/npymath.ini.in text
+./numpy/core/mlib.ini.in text
+./site.cfg.example text
+
+# Python sources
+*.py text diff=python
+*.pxd text diff=python
+*.pyx text diff=python
+*.pyi text diff=python
+
+# C/C++ sources
+*.c text diff=c
+*.h text diff=c
+*.cc text diff=cpp
+*.cxx text diff=cpp
+*.cpp text diff=cpp
+*.hpp text diff=cpp
+*.hh text diff=cpp
+
+# Fortran sources
+*.f text diff=fortran
+*.for text diff=fortran
+*.f90 text diff=fortran
+*.f95 text diff=fortran
+*.f03 text diff=fortran
+
+# JavaScript
+*.js text
+
+# F2py
+./doc/source/f2py/*.pyf text
+./doc/source/f2py/*.dat text
+./numpy/f2py/tests/src/module_data/mod.mod binary
+
+# Documents
+*.md text diff=markdown
+*.txt text
+*.rst text
+*.pdf binary
+*.css text diff=css
+*.html text diff=html
+
+# Graphics
+*.png binary
+*.ico binary
+*.dia binary
+*.gif binary
+*.odg binary
+*.fig text
+*.svg text
+# SVG is treated as an asset (binary) by default. If you want
+# to treat it as binary, use the following line instead.
+# *.svg binary
+
+# Scripts
+*.sh text eol=lf
+*.sed text
+# These are explicitly windows files and should use crlf
+*.bat text eol=crlf
+*.cmd text eol=crlf
+
+# Serialisation
+*.json text
+*.toml text
+*.xml text
+*.yaml text
+*.yml text
+
+# Data files
+*.csv text
+*.pkl binary
+*.fits binary
+*.npy binary
+*.npz binary
+
+# Misc.
+*.swg text
+*.patch text
+./doc/neps/index.rst.tmpl text
+./benchmarks/asv_compare.conf.json.tpl text
+./tools/swig/test/*.i text
+./tools/gitpod/gitpod.Dockerfile text
+./doc/source/dev/gitwash/git_links.inc text
+./doc/source/reference/simd/*.inc text
+./numpy/core/src/_simd/*.inc text diff=c
diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md
index da5990956..8f16950f7 100644
--- a/.github/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -8,7 +8,7 @@ also include a brief, self-contained code example that demonstrates the problem.
If you are reporting a segfault please include a GDB traceback, which you can
generate by following
-[these instructions.](https://github.com/numpy/numpy/blob/master/doc/source/dev/development_environment.rst#debugging)
+[these instructions.](https://github.com/numpy/numpy/blob/main/doc/source/dev/development_environment.rst#debugging)
## Contributing code
diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md
index 78ffc1063..6da1f7370 100644
--- a/.github/ISSUE_TEMPLATE/bug-report.md
+++ b/.github/ISSUE_TEMPLATE/bug-report.md
@@ -20,7 +20,7 @@ import numpy as np
<!-- If you are reporting a segfault please include a GDB traceback, which you
can generate by following
-https://github.com/numpy/numpy/blob/master/doc/source/dev/development_environment.rst#debugging -->
+https://github.com/numpy/numpy/blob/main/doc/source/dev/development_environment.rst#debugging -->
<!-- Full error message, if any (starting from line Traceback: ...) -->
diff --git a/.github/ISSUE_TEMPLATE/feature-request.md b/.github/ISSUE_TEMPLATE/feature-request.md
index 00c6f59c5..68872ec06 100644
--- a/.github/ISSUE_TEMPLATE/feature-request.md
+++ b/.github/ISSUE_TEMPLATE/feature-request.md
@@ -12,5 +12,5 @@ post your idea on the [numpy-discussion mailing list]
(https://mail.python.org/mailman/listinfo/numpy-discussion) to explain your
reasoning in addition to opening an issue or pull request. You can also check
out our [Contributor Guide]
-(https://github.com/numpy/numpy/blob/master/doc/source/dev/index.rst) if you
+(https://github.com/numpy/numpy/blob/main/doc/source/dev/index.rst) if you
need more information. -->
diff --git a/.github/ISSUE_TEMPLATE/post-install.md b/.github/ISSUE_TEMPLATE/post-install.md
index c0ec7896a..11b91384c 100644
--- a/.github/ISSUE_TEMPLATE/post-install.md
+++ b/.github/ISSUE_TEMPLATE/post-install.md
@@ -15,7 +15,7 @@ labels: 32 - Installation
<!-- If you are reporting a segfault please include a GDB traceback, which you
can generate by following
-https://github.com/numpy/numpy/blob/master/doc/source/dev/development_environment.rst#debugging -->
+https://github.com/numpy/numpy/blob/main/doc/source/dev/development_environment.rst#debugging -->
<!-- Full error message, if any (starting from line Traceback: ...) -->
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 508c8c034..704d2d16f 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,16 +1,16 @@
-<!-- ----------------------------------------------------------------
- MAKE SURE YOUR PR GETS THE ATTENTION IT DESERVES!
- ----------------------------------------------------------------
-
-* FORMAT IT RIGHT:
- http://www.numpy.org/devdocs/dev/development_workflow.html#writing-the-commit-message
-
-* IF IT'S A NEW FEATURE OR API CHANGE, TEST THE WATERS:
- http://www.numpy.org/devdocs/dev/development_workflow.html#get-the-mailing-list-s-opinion
-
-* HIT ALL THE GUIDELINES:
- https://numpy.org/devdocs/dev/index.html#guidelines
-
-* WHAT TO DO IF WE HAVEN'T GOTTEN BACK TO YOU:
- http://www.numpy.org/devdocs/dev/development_workflow.html#getting-your-pr-reviewed
--->
+<!-- ----------------------------------------------------------------
+ MAKE SURE YOUR PR GETS THE ATTENTION IT DESERVES!
+ ----------------------------------------------------------------
+
+* FORMAT IT RIGHT:
+ http://www.numpy.org/devdocs/dev/development_workflow.html#writing-the-commit-message
+
+* IF IT'S A NEW FEATURE OR API CHANGE, TEST THE WATERS:
+ http://www.numpy.org/devdocs/dev/development_workflow.html#get-the-mailing-list-s-opinion
+
+* HIT ALL THE GUIDELINES:
+ https://numpy.org/devdocs/dev/index.html#guidelines
+
+* WHAT TO DO IF WE HAVEN'T GOTTEN BACK TO YOU:
+ http://www.numpy.org/devdocs/dev/development_workflow.html#getting-your-pr-reviewed
+-->
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 000000000..16ce0846c
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,22 @@
+version: 2
+updates:
+- package-ecosystem: pip
+ directory: "/"
+ schedule:
+ interval: weekly
+ open-pull-requests-limit: 10
+ labels:
+ - 03 - Maintenance
+ ignore:
+ - dependency-name: gitpython
+ versions:
+ - "> 3.1.13, < 3.2"
+ - dependency-name: pydata-sphinx-theme
+ versions:
+ - 0.6.0
+ - 0.6.1
+ - dependency-name: hypothesis
+ versions:
+ - 6.3.0
+ commit-message:
+ prefix: MAINT
diff --git a/.github/workflows/build_test.yml b/.github/workflows/build_test.yml
index ee43561bf..bfd77ddb0 100644
--- a/.github/workflows/build_test.yml
+++ b/.github/workflows/build_test.yml
@@ -1,6 +1,14 @@
name: Build_Test
-on: [push, pull_request]
+on:
+ push:
+ branches:
+ - main
+ - maintenance/**
+ pull_request:
+ branches:
+ - main
+ - maintenance/**
defaults:
run:
@@ -8,10 +16,30 @@ defaults:
env:
DOWNLOAD_OPENBLAS: 1
- PYTHON_VERSION: 3.7
+ PYTHON_VERSION: 3.8
jobs:
+ lint:
+ if: "github.repository == 'numpy/numpy' && github.ref != 'refs/heads/main' && !contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[skip github]')"
+ runs-on: ubuntu-latest
+ continue-on-error: true
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ submodules: recursive
+ fetch-depth: 0
+ - uses: actions/setup-python@v2
+ with:
+ python-version: ${{ env.PYTHON_VERSION }}
+ - name: Install linter requirements
+ run:
+ python -m pip install -r linter_requirements.txt
+ - name: Run linter on PR diff
+ run:
+ python tools/linter.py --branch origin/${{ github.base_ref }}
+
smoke_test:
+ if: "github.repository == 'numpy/numpy' && !contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[skip github]')"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
@@ -24,11 +52,11 @@ jobs:
- uses: ./.github/actions
basic:
- needs: smoke_test
+ needs: [smoke_test]
runs-on: ubuntu-latest
strategy:
matrix:
- python-version: [3.8, 3.9]
+ python-version: [3.7, 3.9, 3.10.0-beta.4]
steps:
- uses: actions/checkout@v2
with:
@@ -40,7 +68,7 @@ jobs:
- uses: ./.github/actions
debug:
- needs: smoke_test
+ needs: [smoke_test]
runs-on: ubuntu-20.04
env:
USE_DEBUG: 1
@@ -55,7 +83,7 @@ jobs:
- uses: ./.github/actions
blas64:
- needs: smoke_test
+ needs: [smoke_test]
runs-on: ubuntu-latest
env:
NPY_USE_BLAS_ILP64: 1
@@ -70,8 +98,8 @@ jobs:
- uses: ./.github/actions
full:
- needs: smoke_test
- runs-on: ubuntu-latest
+ needs: [smoke_test]
+ runs-on: ubuntu-18.04
env:
USE_WHEEL: 1
RUN_FULL_TESTS: 1
@@ -88,7 +116,7 @@ jobs:
- uses: ./.github/actions
benchmark:
- needs: smoke_test
+ needs: [smoke_test]
runs-on: ubuntu-latest
env:
PYTHONOPTIMIZE: 2
@@ -109,7 +137,7 @@ jobs:
- uses: ./.github/actions
no_relaxed_strides:
- needs: smoke_test
+ needs: [smoke_test]
runs-on: ubuntu-latest
env:
NPY_RELAXED_STRIDES_CHECKING: 0
@@ -126,7 +154,7 @@ jobs:
- uses: ./.github/actions
use_wheel:
- needs: smoke_test
+ needs: [smoke_test]
runs-on: ubuntu-latest
env:
USE_WHEEL: 1
@@ -142,7 +170,7 @@ jobs:
- uses: ./.github/actions
no_array_func:
- needs: smoke_test
+ needs: [smoke_test]
runs-on: ubuntu-latest
env:
NUMPY_EXPERIMENTAL_ARRAY_FUNCTION: 0
@@ -157,7 +185,7 @@ jobs:
- uses: ./.github/actions
no_openblas:
- needs: smoke_test
+ needs: [smoke_test]
runs-on: ubuntu-latest
env:
BLAS: None
@@ -175,27 +203,30 @@ jobs:
- uses: ./.github/actions
pypy37:
- needs: smoke_test
+ needs: [smoke_test]
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
with:
submodules: recursive
fetch-depth: 0
- - name: get_pypy
- run: |
- wget -q https://downloads.python.org/pypy/pypy3.7-v7.3.3-linux64.tar.bz2 -O pypy.tar.bz2
- mkdir -p pypy3
- (cd pypy3; tar --strip-components=1 -xf ../pypy.tar.bz2)
- pypy3/bin/pypy3 -mensurepip
- pypy3/bin/pypy3 -m pip install --upgrade pip wheel
- if [ ! -e pypy3/bin/python ]
- then
- pushd pypy3/bin
- ln -s pypy3 python
- popd
- fi
- echo $PWD/pypy3/bin >> $GITHUB_PATH
+ - uses: actions/setup-python@v2
+ with:
+ python-version: pypy-3.7-v7.3.4
+ - uses: ./.github/actions
+ sdist:
+ needs: [smoke_test]
+ runs-on: ubuntu-latest
+ env:
+ USE_SDIST: 1
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ submodules: recursive
+ fetch-depth: 0
+ - uses: actions/setup-python@v2
+ with:
+ python-version: ${{ env.PYTHON_VERSION }}
- uses: ./.github/actions
diff --git a/.github/workflows/cygwin.yml b/.github/workflows/cygwin.yml
new file mode 100644
index 000000000..930ce39ff
--- /dev/null
+++ b/.github/workflows/cygwin.yml
@@ -0,0 +1,67 @@
+name: Test on Cygwin
+on:
+ push:
+ branches:
+ - main
+ pull_request:
+ branches:
+ - main
+jobs:
+ cygwin_build_test:
+ runs-on: windows-latest
+ steps:
+ - uses: actions/checkout@v2
+ with:
+ submodules: recursive
+ fetch-depth: 0
+ - name: Install Cygwin
+ uses: egor-tensin/setup-cygwin@v3
+ with:
+ platform: x64
+ install-dir: 'C:\tools\cygwin'
+ packages: >
+ python38-devel python38-zipp python38-importlib-metadata
+ python38-cython python38-pip python38-wheel python38-cffi
+ python38-pytz python38-setuptools python38-pytest
+ python38-hypothesis liblapack-devel libopenblas
+ gcc-fortran git dash
+ - name: Set Windows PATH
+ uses: egor-tensin/cleanup-path@v1
+ with:
+ dirs: 'C:\tools\cygwin\bin;C:\tools\cygwin\lib\lapack'
+ - name: Verify that bash is Cygwin bash
+ run: |
+ command bash
+ bash -c "uname -svrmo"
+ - name: Update with Cygwin git
+ # fetch-depth=0 above should make this short.
+ run: |
+ dash -c "which git; /usr/bin/git fetch --all -p"
+ - name: Verify python version
+ # Make sure it's the Cygwin one, not a Windows one
+ run: |
+ dash -c "which python3.8; /usr/bin/python3.8 --version -V"
+ - name: Build NumPy wheel
+ run: |
+ dash -c "/usr/bin/python3.8 -m pip install 'setuptools<49.2.0' pytest pytz cffi pickle5 importlib_metadata typing_extensions"
+ dash -c "/usr/bin/python3.8 -m pip install -r test_requirements.txt"
+ dash -c "/usr/bin/python3.8 setup.py bdist_wheel"
+ - name: Install new NumPy
+ run: |
+ bash -c "/usr/bin/python3.8 -m pip install dist/numpy-*cp38*.whl"
+ - name: Run NumPy test suite
+ run: >-
+ dash -c "/usr/bin/python3.8 runtests.py -n -vv"
+ - name: Upload wheel if tests fail
+ uses: actions/upload-artifact@v2
+ if: failure()
+ with:
+ name: numpy-cygwin-wheel
+ path: dist/numpy-*cp38*.whl
+ - name: On failure check the extension modules
+ if: failure()
+ run: |
+ dash -c "/usr/bin/python3.8 -m pip show numpy"
+ dash -c "/usr/bin/python3.8 -m pip show -f numpy | grep .dll"
+ dash -c "/bin/tr -d '\r' <tools/list_installed_dll_dependencies_cygwin.sh >list_dlls_unix.sh"
+ dash "list_dlls_unix.sh"
diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml
new file mode 100644
index 000000000..cc4950590
--- /dev/null
+++ b/.github/workflows/docker.yml
@@ -0,0 +1,57 @@
+name: Build Base Docker Image
+
+on:
+ push:
+ branches:
+ - main
+ paths:
+ - 'environment.yml'
+
+jobs:
+ build:
+ name: Build base Docker image
+ runs-on: ubuntu-latest
+ environment: numpy-dev
+ if: "github.repository_owner == 'numpy' && !contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[skip github]')"
+ steps:
+ - name: Clone repository
+ uses: actions/checkout@v2
+ - name: Lint Docker
+ uses: brpaz/hadolint-action@v1.2.1
+ with:
+ dockerfile: ./tools/gitpod/Dockerfile
+ - name: Get refs
+ shell: bash
+ run: |
+ export raw_branch=${GITHUB_REF#refs/heads/}
+ echo "::set-output name=branch::${raw_branch//\//-}"
+ echo "::set-output name=date::$(date +'%Y%m%d')"
+ echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
+ id: getrefs
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v1
+ - name: Cache Docker layers
+ uses: actions/cache@v2
+ with:
+ path: /tmp/.buildx-cache
+ key: ${{ runner.os }}-buildx-${{ github.sha }}
+ restore-keys: ${{ runner.os }}-buildx-
+ - name: Login to Docker Hub
+ uses: docker/login-action@v1
+ with:
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
+ - name: Build and push
+ id: docker_build
+ uses: docker/build-push-action@v2
+ with:
+ context: "."
+ file: "./tools/gitpod/Dockerfile"
+ push: ${{ github.event_name != 'pull_request' }}
+ cache-from: type=local,src=/tmp/.buildx-cache
+ cache-to: type=local,dest=/tmp/.buildx-cache
+ tags: |
+ numpy/numpy-dev:${{ steps.getrefs.outputs.date }}-${{ steps.getrefs.outputs.branch}}-${{ steps.getrefs.outputs.sha8 }}, numpy/numpy-dev:latest
+ - name: Image digest
+ # Return details of the image build: sha and shell
+ run: echo ${{ steps.docker_build.outputs.digest }}
diff --git a/.github/workflows/gitpod.yml b/.github/workflows/gitpod.yml
new file mode 100644
index 000000000..bbca92865
--- /dev/null
+++ b/.github/workflows/gitpod.yml
@@ -0,0 +1,57 @@
+name: Build Gitpod Docker image
+
+on:
+ push:
+ branches:
+ - main
+
+jobs:
+ build:
+ name: Build Gitpod Docker image
+ runs-on: ubuntu-latest
+ environment: numpy-dev
+ if: "github.repository_owner == 'numpy' && !contains(github.event.head_commit.message, '[ci skip]') && !contains(github.event.head_commit.message, '[skip ci]') && !contains(github.event.head_commit.message, '[skip github]')"
+ steps:
+ - name: Clone repository
+ uses: actions/checkout@v2
+ with:
+ fetch-depth: 0
+ - name: Lint Docker
+ uses: brpaz/hadolint-action@v1.2.1
+ with:
+ dockerfile: ./tools/gitpod/gitpod.Dockerfile
+ - name: Get refs
+ shell: bash
+ run: |
+ export raw_branch=${GITHUB_REF#refs/heads/}
+ echo "::set-output name=branch::${raw_branch//\//-}"
+ echo "::set-output name=date::$(date +'%Y%m%d')"
+ echo "::set-output name=sha8::$(echo ${GITHUB_SHA} | cut -c1-8)"
+ id: getrefs
+ - name: Set up Docker Buildx
+ uses: docker/setup-buildx-action@v1
+ - name: Cache Docker layers
+ uses: actions/cache@v2
+ with:
+ path: /tmp/.buildx-cache
+ key: ${{ runner.os }}-buildx-${{ github.sha }}
+ restore-keys: ${{ runner.os }}-buildx-
+ - name: Login to Docker Hub
+ uses: docker/login-action@v1
+ with:
+ username: ${{ secrets.DOCKERHUB_USERNAME }}
+ password: ${{ secrets.DOCKERHUB_TOKEN }}
+ - name: Build and push
+ id: docker_build
+ uses: docker/build-push-action@v2
+ with:
+ context: "."
+ file: "./tools/gitpod/gitpod.Dockerfile"
+ push: ${{ github.event_name != 'pull_request' }}
+ cache-from: type=local,src=/tmp/.buildx-cache
+ cache-to: type=local,dest=/tmp/.buildx-cache
+ tags: |
+ numpy/numpy-gitpod:${{ steps.getrefs.outputs.date }}-${{ steps.getrefs.outputs.branch}}-${{ steps.getrefs.outputs.sha8 }}, numpy/numpy-gitpod:latest
+ - name: Image digest
+ # Return details of the image build: sha and shell
+ run: echo ${{ steps.docker_build.outputs.digest }}
diff --git a/.gitignore b/.gitignore
index f85c57764..d85676249 100644
--- a/.gitignore
+++ b/.gitignore
@@ -76,6 +76,7 @@ doc/cdoc/build
MANIFEST
.cache
pip-wheel-metadata
+.python-version
# Paver generated files #
#########################
@@ -120,9 +121,7 @@ numpy/__config__.py
numpy/core/include/numpy/__multiarray_api.h
numpy/core/include/numpy/__ufunc_api.h
numpy/core/include/numpy/_numpyconfig.h
-numpy/version.py
site.cfg
-setup.cfg
.tox
numpy/core/include/numpy/__multiarray_api.c
numpy/core/include/numpy/__ufunc_api.c
@@ -172,6 +171,7 @@ numpy/core/src/umath/simd.inc
numpy/core/src/umath/struct_ufunc_test.c
numpy/core/src/umath/test_rational.c
numpy/core/src/umath/umath_tests.c
+numpy/core/src/umath/loops_utils.h
numpy/distutils/__config__.py
numpy/linalg/umath_linalg.c
doc/source/**/generated/
@@ -188,6 +188,7 @@ numpy/random/legacy/*.c
numpy/random/_mtrand/randint_helpers.pxi
numpy/random/bounded_integers.pyx
numpy/random/bounded_integers.pxd
+numpy/random/lib/npyrandom.lib
tools/swig/test/Array_wrap.cxx
tools/swig/test/Farray_wrap.cxx
tools/swig/test/Farray.py
@@ -205,9 +206,6 @@ tools/swig/test/Array.py
# SIMD generated files #
###################################
-# the main config header, contains all the definitions and
-# headers of instruction-sets
-numpy/core/src/common/_cpu_dispatch.h
# config headers of dispatchable sources
*.dispatch.h
# wrapped sources of dispatched targets, e.g. *.dispatch.avx2.c
@@ -218,3 +216,7 @@ numpy/core/src/_simd/_simd_data.inc
numpy/core/src/_simd/_simd_inc.h
# umath module
numpy/core/src/umath/loops_unary_fp.dispatch.c
+numpy/core/src/umath/loops_arithm_fp.dispatch.c
+numpy/core/src/umath/loops_arithmetic.dispatch.c
+numpy/core/src/umath/loops_trigonometric.dispatch.c
+numpy/core/src/umath/loops_exponent_log.dispatch.c
diff --git a/.gitmodules b/.gitmodules
index e69de29bb..0d6857868 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -0,0 +1,3 @@
+[submodule "doc/source/_static/scipy-mathjax"]
+ path = doc/source/_static/scipy-mathjax
+ url = https://github.com/scipy/scipy-mathjax.git
diff --git a/.gitpod.yml b/.gitpod.yml
new file mode 100644
index 000000000..dfbee831a
--- /dev/null
+++ b/.gitpod.yml
@@ -0,0 +1,63 @@
+# Rebuilding NumPy on init - rather than on prebuild: this ensures
+# that even forks do have a usable freshly built NumPy
+# Might delegate this later to prebuild with Q2 improvements on gitpod
+# https://www.gitpod.io/docs/config-start-tasks/#configuring-the-terminal
+# -------------------------------------------------------------------------
+
+image: numpy/numpy-gitpod:latest
+tasks:
+ - name: Prepare development
+ init: |
+ mkdir -p .vscode
+ cp tools/gitpod/settings.json .vscode/settings.json
+ conda activate numpy-dev
+ python setup.py build_ext --inplace
+ echo "🛠 Completed rebuilding NumPy!! 🛠 "
+ echo "📖 Building docs 📖 "
+ git submodule update --init
+ cd doc
+ make html
+ echo "✨ Pre-build complete! You can close this terminal ✨ "
+
+
+# --------------------------------------------------------
+# exposing ports for liveserve
+ports:
+ - port: 5500
+ onOpen: notify
+
+# --------------------------------------------------------
+# some useful extensions to have
+vscode:
+ extensions:
+ - eamodio.gitlens
+ - njpwerner.autodocstring
+ - lextudio.restructuredtext
+ - ritwickdey.liveserver
+ - ms-python.python
+ - yzhang.markdown-all-in-one
+ - bungcip.better-toml
+ - mhutchie.git-graph
+
+# --------------------------------------------------------
+# using prebuilds for the container - note: atm this only
+# works for the NumPy repo
+# With this configuration the prebuild will happen on push to master
+github:
+ prebuilds:
+ # enable for main/default branch
+ master: true
+ # enable for other branches (defaults to false)
+ branches: false
+ # enable for pull requests coming from this repo (defaults to true)
+ pullRequests: false
+ # enable for pull requests coming from forks (defaults to false)
+ pullRequestsFromForks: false
+ # add a check to pull requests (defaults to true)
+ addCheck: false
+ # add a "Review in Gitpod" button as a comment to pull requests (defaults to false)
+ addComment: false
+ # add a "Review in Gitpod" button to the pull request's description (defaults to false)
+ addBadge: false
+ # add a label once the prebuild is ready to pull requests (defaults to false)
+ addLabel: false \ No newline at end of file
diff --git a/.hadolint.yaml b/.hadolint.yaml
new file mode 100644
index 000000000..0188ba2cf
--- /dev/null
+++ b/.hadolint.yaml
@@ -0,0 +1,7 @@
+---
+ignored:
+ - DL3006
+ - DL3008
+ - SC2016
+ - DL3004
+ - DL3007 \ No newline at end of file
diff --git a/.mailmap b/.mailmap
index f3fd63519..3f45904fc 100644
--- a/.mailmap
+++ b/.mailmap
@@ -8,294 +8,429 @@
# This file is up-to-date if the command git log --format="%aN <%aE>" | sort -u
# gives no duplicates.
-Aaron Baecker <abaecker@localhost> abaecker <abaecker@localhost>
-Aarthi Agurusa <agurusa@gmail.com> agurusa <agurusa@gmail.com>
-Alan Fontenot <logeaux@yahoo.com> logeaux <logeaux@yahoo.com>
-Alan Fontenot <logeaux@yahoo.com> logeaux <36168460+logeaux@users.noreply.github.com>
-Abdul Muneer <abdulmuneer@gmail.com> abdulmuneer <abdulmuneer@gmail.com>
-Abhilash Barigidad <abhilash.ub@gmail.com> abhilash42 <64172584+abhilash42@users.noreply.github.com>
-Abhinav Reddy <abhinav071197@gmail.com> tabhi0797 <abhinav071197@gmail.com>
-Adam Ginsburg <adam.g.ginsburg@gmail.com> Adam Ginsburg <keflavich@gmail.com>
-Albert Jornet Puig <albert.jornet@ic3.cat> jurnix <albert.jornet@ic3.cat>
-Alex Rockhill <aprockhill206@gmail.com> Alex <aprockhill206@gmail.com>
-Alex Griffing <argriffi@ncsu.edu> alex <argriffi@ncsu.edu>
-Alex Griffing <argriffi@ncsu.edu> argriffing <argriffi@ncsu.edu>
-Alex Griffing <argriffi@ncsu.edu> argriffing <argriffing@gmail.com>
-Alex Griffing <argriffi@ncsu.edu> argriffing <argriffing@users.noreply.github.com>
-Alex Thomas <alexthomas93@users.noreply.github.com> alexthomas93 <alexthomas93@users.noreply.github.com>
-Alexander Belopolsky <abalkin@enlnt.com> Alexander Belopolsky <a@enlnt.com>
-Alexander Belopolsky <abalkin@enlnt.com> Alexander Belopolsky <a@enlnt.com>
+@8bitmp3 <19637339+8bitmp3@users.noreply.github.com>
+@DWesl <22566757+DWesl@users.noreply.github.com>
+@Endolith <endolith@gmail.com>
+@Illviljan <14371165+Illviljan@users.noreply.github.com>
+@LSchroefl <65246829+LSchroefl@users.noreply.github.com>
+@Lbogula <bogulala7@gmail.com>
+@Lisa <34400837+lyzlisa@users.noreply.github.com>
+@Patrick <39380924+xamm@users.noreply.github.com>
+@Scian <65375075+hoony6134@users.noreply.github.com>
+@h-vetinari <h.vetinari@gmx.com>
+@h6197627 <44726212+h6197627@users.noreply.github.com>
+@jbCodeHub <besselingcodehub@gmail.com>
+@legoffant <58195095+legoffant@users.noreply.github.com>
+@luzpaz <kunda@scribus.net>
+@luzpaz <kunda@scribus.net> <luzpaz@users.noreply.github.com>
+@sfolje0 <sfolje0@github>
+@spacescientist <aspacescientist@protonmail.com> <spacescientist@pm.me>
+@tautaus <sunt9751@gmail.com>
+@xoviat <49173759+xoviat@users.noreply.github.com>
+@xoviat <49173759+xoviat@users.noreply.github.com> <xoviat@users.noreply.github.com>
+@yetanothercheer <yetanothercheer@protonmail.com>
+Aaron Baecker <abaecker@localhost>
+Aarthi Agurusa <agurusa@gmail.com>
+Alan Fontenot <logeaux@yahoo.com>
+Alan Fontenot <logeaux@yahoo.com> <36168460+logeaux@users.noreply.github.com>
+Abdul Muneer <abdulmuneer@gmail.com>
+Abhilash Barigidad <abhilash.ub@gmail.com>
+Abhilash Barigidad <abhilash.ub@gmail.com> <64172584+abhilash42@users.noreply.github.com>
+Abhinav Reddy <abhinav071197@gmail.com>
+Adam Ginsburg <adam.g.ginsburg@gmail.com> <keflavich@gmail.com>
+Aerik Pawson <45904740+aerikpawson@users.noreply.github.com>
+Albert Jornet Puig <albert.jornet@ic3.cat>
+Alex Rockhill <aprockhill206@gmail.com>
+Alex Griffing <argriffi@ncsu.edu>
+Alex Griffing <argriffi@ncsu.edu> <argriffing@gmail.com>
+Alex Griffing <argriffi@ncsu.edu> <argriffing@users.noreply.github.com>
+Alex Henrie <alexhenrie24@gmail.com> <alex.henrie@utah.edu>
+Alex Rogozhnikov <iamfullofspam@gmail.com> <arogozhnikov@users.noreply.github.com>
+Alex Thomas <alexthomas93@users.noreply.github.com>
+Alexander Belopolsky <abalkin@enlnt.com>
+Alexander Belopolsky <abalkin@enlnt.com> <a@enlnt.com>
+Alexander Belopolsky <abalkin@enlnt.com> <abalkin@users.noreply.github.com>
Alexander Belopolsky <abalkin@enlnt.com> sasha <sasha@localhost>
-Alexander Jung <kontakt@ajung.name> aleju <kontakt@ajung.name>
-Alexander Shadchin <alexandr.shadchin@gmail.com> Alexandr Shadchin <alexandr.shadchin@gmail.com>
-Alexander Shadchin <alexandr.shadchin@gmail.com> shadchin <alexandr.shadchin@gmail.com>
-Allan Haldane <allan.haldane@gmail.com> ahaldane <ealloc@gmail.com>
+Alexander Hunt <alexander.l.hunt951@gmail.com>
+Alexander Jung <kontakt@ajung.name>
+Alexander Shadchin <alexandr.shadchin@gmail.com>
+Alexander Shadchin <alexandr.shadchin@gmail.com> <shadchin@yandex-team.ru>
+Alizé Papp <68250865+alize-papp@users.noreply.github.com>
+Allan Haldane <allan.haldane@gmail.com> <ealloc@gmail.com>
+Al-Baraa El-Hag <a.elhag01@gmail.com> <48454648+a-elhag@users.noreply.github.com>
Alok Singhal <gandalf013@gmail.com> Alok Singhal <alok@merfinllc.com>
-Alyssa Quek <alyssaquek@gmail.com> alyssaq <alyssaquek@gmail.com>
-Amir Sarabadani <ladsgroup@gmail.com> amir <ladsgroup@gmail.com>
-Anatoly Techtonik <techtonik@gmail.com> anatoly techtonik <techtonik@gmail.com>
-Andras Deak <deak.andris@gmail.com> adeak <adeak@users.noreply.github.com>
-Andrea Olivo andryandrew@gmail.com andryandrew <andryandrew@gmail.com>
-Andrea Pattori <andrea.pattori@gmail.com> patto90 <andrea.pattori@gmail.com>
-Andrea Sangalli <and-sang@outlook.com> and-sang <53617841+and-sang@users.noreply.github.com>
-Andrei Kucharavy <ank@andreikucharavy.com> chiffa <ank@andreikucharavy.com>
-Anne Archibald <peridot.faceted@gmail.com> aarchiba <peridot.faceted@gmail.com>
-Anne Archibald <peridot.faceted@gmail.com> Anne Archibald <archibald@astron.nl>
-Anže Starič <anze.staric@gmail.com> astaric <anze.staric@gmail.com>
-Aron Ahmadia <aron@ahmadia.net> ahmadia <aron@ahmadia.net>
-Arun Persaud <apersaud@lbl.gov> Arun Persaud <arun@nubati.net>
-Ashutosh Singh <ashutoshsinghrkt@gmail.com> ashutosh619-sudo <ashutoshsinghrkt@gmail.com>
-Ashutosh Singh <ashutoshsinghrkt@gmail.com> Ashutosh singh <55102089+Ashutosh619-sudo@users.noreply.github.com>
-Åsmund Hjulstad <ahju@statoil.com> Åsmund Hjulstad <asmund@hjulstad.com>
-Auke Wiggers <wiggers.auke@gmail.com> auke <wiggers.auke@gmail.com>
-Badhri Narayanan Krishnakumar <badhrinarayanan.k@gmail.com> badhrink <badhrinarayanan.k@gmail.com>
-Bangcheng Yang <bangchengyang@hotmail.com> DumbMice <bangchengyang@hotmail.com>
-Behzad Nouri <behzadnouri@gmail.com> behzad nouri <behzadnouri@gmail.com>
-Ben Nathanson <github@bigriver.xyz> bjnath <github@bigriver.xyz>
-Benjamin Root <ben.v.root@gmail.com> Ben Root <ben.v.root@gmail.com>
+Alyssa Quek <alyssaquek@gmail.com>
+Amir Sarabadani <ladsgroup@gmail.com>
+Anas Khan <anasalimkhan@gmail.com> <anas.khan96@outlook.com>
+Anatoly Techtonik <techtonik@gmail.com>
+Andras Deak <deak.andris@gmail.com> <adeak@users.noreply.github.com>
+Andrea Olivo <andryandrew@gmail.com>
+Andrea Pattori <andrea.pattori@gmail.com>
+Andrea Sangalli <and-sang@outlook.com> <53617841+and-sang@users.noreply.github.com>
+Andreas Klöckner <inform@tiker.net>
+Andreas Schwab <schwab@suse.de> <schwab@linux-m68k.org>
+Andrei Kucharavy <ank@andreikucharavy.com>
+Andrew Lawson <andrew.lawson@nag.co.uk> <andrewl@olney.nag.co.uk>
+Anirudh Subramanian <anirudh2290@ufl.edu>
+Anne Archibald <peridot.faceted@gmail.com>
+Anne Archibald <peridot.faceted@gmail.com> <archibald@astron.nl>
+Anne Bonner <bonn0062@yahoo.com> <35413198+bonn0062@users.noreply.github.com>
+Anthony Vo <anthonyhvo12@gmail.com> <43098273+anthonyhvo12@users.noreply.github.com>
+Antoine Pitrou <antoine@python.org> <pitrou@free.fr>
+Anže Starič <anze.staric@gmail.com>
+Aron Ahmadia <aron@ahmadia.net>
+Arun Persaud <apersaud@lbl.gov> <arun@nubati.net>
+Ashutosh Singh <ashutoshsinghrkt@gmail.com>
+Ashutosh Singh <ashutoshsinghrkt@gmail.com> <55102089+Ashutosh619-sudo@users.noreply.github.com>
+Åsmund Hjulstad <ahju@statoil.com> <asmund@hjulstad.com>
+Auke Wiggers <wiggers.auke@gmail.com>
+Badhri Narayanan Krishnakumar <badhrinarayanan.k@gmail.com>
+Bangcheng Yang <bangchengyang@hotmail.com>
+Bhargav V <12525622+brpy@users.noreply.github.com>
+Bas van Beek <b.f.van.beek@vu.nl> <43369155+BvB93@users.noreply.github.com>
+Behzad Nouri <behzadnouri@gmail.com>
+Ben Nathanson <github@bigriver.xyz>
+Benjamin Root <ben.v.root@gmail.com>
Benjamin Root <ben.v.root@gmail.com> weathergod <?@?>
-Bernardt Duvenhage <bernardt.duvenhage@gmail.com> bduvenhage <bernardt.duvenhage@gmail.com>
-Bertrand Lefebvre <bertrand.l3f@gmail.com> bertrand <bertrand.l3f@gmail.com>
-Bertrand Lefebvre <bertrand.l3f@gmail.com> Bertrand <bertrand.l3f@gmail.com>
-Bharat Raghunathan <bharatr@symphonyai.com> Bharat123Rox <bharatr@symphonyai.com>
-Bill Spotz <wfspotz@sandia.gov> William Spotz <wfspotz@sandia.gov@localhost>
-Bill Spotz <wfspotz@sandia.gov> wfspotz@sandia.gov <wfspotz@sandia.gov@localhost>
-Bob Eldering <eldering@jive.eu> bobeldering <eldering@jive.eu>
-Brett R Murphy <bmurphy@enthought.com> brettrmurphy <bmurphy@enthought.com>
+Bernardt Duvenhage <bernardt.duvenhage@gmail.com>
+Bernie Gray <bfgray3@users.noreply.github.com>
+Bertrand Lefebvre <bertrand.l3f@gmail.com>
+Bharat Raghunathan <bharatraghunthan9767@gmail.com>
+Bharat Raghunathan <bharatraghunthan9767@gmail.com> <bharatr@symphonyai.com>
+Bob Eldering <eldering@jive.eu>
+Brett R Murphy <bmurphy@enthought.com>
+Brigitta Sipocz <bsipocz@gmail.com> <b.sipocz@gmail.com>
+Brian Soto <iambriansoto@gmail.com>
+Brian Soto <iambriansoto@gmail.com> <theintrocode@gmail.com>
+Brian Soto <iambriansoto@gmail.com> <Iamsoto@users.noreply.github.com>
Bryan Van de Ven <bryanv@continuum.io> Bryan Van de Ven <bryan@Laptop-3.local>
Bryan Van de Ven <bryanv@continuum.io> Bryan Van de Ven <bryan@laptop.local>
-Bui Duc Minh <buiducminh287@gmail.com> Mibu287 <41239569+Mibu287@users.noreply.github.com>
-Carl Kleffner <cmkleffner@gmail.com> carlkl <cmkleffner@gmail.com>
-Carl Leake <leakec57@gmail.com> leakec <leakec57@gmail.com>
-Chris Burns <chris.burns@localhost> chris.burns <chris.burns@localhost>
-Chris Kerr <debdepba@dasganma.tk> Chris Kerr <cjk34@cam.ac.uk>
-Christian Clauss <cclauss@bluewin.ch> cclauss <cclauss@bluewin.ch>
-Christopher Hanley <chanley@gmail.com> chanley <chanley@gmail.com>
+Bui Duc Minh <buiducminh287@gmail.com> <41239569+Mibu287@users.noreply.github.com>
+Carl Kleffner <cmkleffner@gmail.com>
+Carl Leake <leakec57@gmail.com>
+Charles Stern <62192187+cisaacstern@users.noreply.github.com>
+Chris Barker <Chris.Barker@noaa.gov> <chris.barker@local>
+Chris Burns <chris.burns@localhost>
+Chris Holland <chrisholland3553@gmail.com> <41524756+ChrisAHolland@users.noreply.github.com>
+Chris Kerr <debdepba@dasganma.tk> <cjk34@cam.ac.uk>
+Chris Vavaliaris <cv1038@wildcats.unh.edu>
+Christian Clauss <cclauss@bluewin.ch>
+Christopher Dahlin <christopher@dahlin.tech> <christopher@tracsense.tech>
+Christopher Hanley <chanley@gmail.com>
+Christoph Gohlke <cgohlke@uci.edu>
+Christoph Gohlke <cgohlke@uci.edu> <cjgohlke@gmail.com>
Christoph Gohlke <cgohlke@uci.edu> cgholke <?@?>
-Christoph Gohlke <cgohlke@uci.edu> cgohlke <cgohlke@uci.edu>
-Christoph Gohlke <cgohlke@uci.edu> Christolph Gohlke <cgohlke@uci.edu>
-Chunlin Fang <fangchunlin@huawei.com> Qiyu8 <fangchunlin@huawei.com>
-Chunlin Fang <fangchunlin@huawei.com> qiyu8 <fangchunlin@huawei.com>
-Chunlin Fang <fangchunlin@huawei.com> Chunlin <fangchunlin@huawei.com>
-Colin Snyder <47012605+colinsnyder@users.noreply.github.com> colinsnyder <47012605+colinsnyder@users.noreply.github.com>
-Daniel B Allan <daniel.b.allan@gmail.com> danielballan <daniel.b.allan@gmail.com>
-Daniel da Silva <mail@danieldasilva.org> Daniel da Silva <daniel@meltingwax.net>
-Daniel da Silva <mail@danieldasilva.org> Daniel da Silva <var.mail.daniel@gmail.com>
-Daniel Hrisca <daniel.hrisca@gmail.com> danielhrisca <daniel.hrisca@gmail.com>
-Daniel J Farrell <danieljfarrel@me.com> danieljfarrell <danieljfarrel@me.com>
+Chunlin Fang <fangchunlin@huawei.com>
+Chunlin Fang <fangchunlin@huawei.com> <qiyu8@foxmail.com>
+Chunlin Fang <fangchunlin@huawei.com> <834352945@qq.com>
+Colin Snyder <8csnyder@gmail.com> <47012605+colinsnyder@users.noreply.github.com>
+Constanza Fierro <constanza.fierro94@gmail.com>
+Daniel B Allan <daniel.b.allan@gmail.com>
+Daniel da Silva <mail@danieldasilva.org> <daniel@meltingwax.net>
+Daniel da Silva <mail@danieldasilva.org> <var.mail.daniel@gmail.com>
+Daniel Hrisca <daniel.hrisca@gmail.com>
+Daniel J Farrell <danieljfarrel@me.com>
+Daniel Montes <53720019+Aerysv@users.noreply.github.com>
+Daniel Müllner <Daniel Müllner muellner@math.stanford.edu>
Daniel Müllner <Daniel Müllner muellner@math.stanford.edu> Daniel <muellner@localhost.localdomain>
-Daniel Müllner <Daniel Müllner muellner@math.stanford.edu> dmuellner <Daniel Müllner muellner@math.stanford.edu>
-Daniel Rasmussen <daniel.rasmussen@appliedbrainresearch.com> drasmuss <daniel.rasmussen@appliedbrainresearch.com>
+Daniel Rasmussen <daniel.rasmussen@appliedbrainresearch.com>
+Daniel G. A. Smith <dgasmith@icloud.com>
+Daniel G. A. Smith <dgasmith@icloud.com> <malorian@me.com>
+Dario Mory <daaawx@gmail.com>
David Huard <david.huard@gmail.com> dhuard <dhuard@localhost>
-David M Cooke <cookedm@localhost> cookedm <cookedm@localhost>
-David Nicholson <davidjn@google.com> davidjn <dnic12345@gmail.com>
-David Ochoa <ochoadavid@gmail.com> ochoadavid <ochoadavid@gmail.com>
-Davide Dal Bosco <davidemcwood@gmail.com> davidedalbosco <62077652+davidedalbosco@users.noreply.github.com>
-Dawid Zych <dawid.zych@yandex.com> silenc3r <dawid.zych@yandex.com>
-Dennis Zollo <dzollo@swift-nav.com> denniszollo <dzollo@swift-nav.com>
-Derek Homeier <derek@astro.physik.uni-goettingen.de> Derek Homeier <dhomeie@gwdg.de>
-Derek Homeier <derek@astro.physik.uni-goettingen.de> Derek Homeir <derek@astro.phsik.uni-goettingen.de>
-Derek Homeier <derek@astro.physik.uni-goettingen.de> Derek Homier <derek@astro.physik.uni-goettingen.de>
-Derrick Williams <myutat@gmail.com> derrick <myutat@gmail.com>
-Dmitriy Shalyga <zuko3d@gmail.com> zuko3d <zuko3d@gmail.com>
-Dustan Levenstein <dlevenstein@gmail.com> dustanlevenstein <43019642+dustanlevenstein@users.noreply.github.com>
-Ed Schofield <edschofield@localhost> edschofield <edschofield@localhost>
-Egor Zindy <ezindy@gmail.com> zindy <ezindy@gmail.com>
-Endolith <endolith@gmail.com>
-Erik M. Bray <erik.bray@lri.fr> E. M. Bray <erik.bray@lri.fr>
-Erik M. Bray <erik.bray@lri.fr> Erik Bray <erik.m.bray@gmail.com>
+David M Cooke <cookedm@localhost>
+David Nicholson <davidjn@google.com> <dnic12345@gmail.com>
+David Ochoa <ochoadavid@gmail.com>
+David Pitchford <david.t.pitchford@gmail.com> <david.t.pitchford@gmail.com>
+Davide Dal Bosco <davidemcwood@gmail.com> <62077652+davidedalbosco@users.noreply.github.com>
+Dawid Zych <dawid.zych@yandex.com>
+Dennis Zollo <dzollo@swift-nav.com>
+Derek Homeier <derek@astro.physik.uni-goettingen.de>
+Derek Homeier <derek@astro.physik.uni-goettingen.de> <dhomeie@gwdg.de>
+Derek Homeier <derek@astro.physik.uni-goettingen.de> <derek@astro.phsik.uni-goettingen.de>
+Derrick Williams <myutat@gmail.com>
+Dmitriy Shalyga <zuko3d@gmail.com>
+Dustan Levenstein <dlevenstein@gmail.com> <43019642+dustanlevenstein@users.noreply.github.com>
+Dylan Cutler <dylancutler@google.com>
+Ed Schofield <edschofield@localhost>
+Egor Zindy <ezindy@gmail.com>
+Elliott M. Forney <elliott.forney@gmail.com>
+Erik M. Bray <erik.m.bray@gmail.com>
+Erik M. Bray <erik.m.bray@gmail.com> <erik.bray@lri.fr>
+Erik M. Bray <erik.m.bray@gmail.com> <embray@stsci.edu>
Eric Fode <ericfode@gmail.com> Eric Fode <ericfode@linuxlaptop.(none)>
-Eric Quintero <eric.antonio.quintero@gmail.com> e-q <eric.antonio.quintero@gmail.com>
-Ernest N. Mamikonyan <ernest.mamikonyan@gmail.com> mamikony <ernest.mamikonyan@sig.com>
-Etienne Guesnet <etienne.guesnet.external@atos.net> EGuesnet <51407514+EGuesnet@users.noreply.github.com>
+Eric Quintero <eric.antonio.quintero@gmail.com>
+Ernest N. Mamikonyan <ernest.mamikonyan@gmail.com>
+Etienne Guesnet <etienne.guesnet.external@atos.net> <51407514+EGuesnet@users.noreply.github.com>
+Eva Jau <evaj@posteo.de>
Evgeni Burovski <evgeny.burovskiy@gmail.com> Evgeni Burovski <evgeni@burovski.me>
-Evgeny Toder <evgeny.toder@jpmorgan.com> eltjpm <evgeny.toder@jpmorgan.com>
-Fernando Perez <Fernando.Perez@berkeley.edu> Fernando Perez <fperez@fperez.org>
+Evgeny Toder <evgeny.toder@jpmorgan.com>
+Fernando Perez <Fernando.Perez@berkeley.edu> <fperez@fperez.org>
+Filip Trojan <f.trojan@centrum.cz> <Tarantula2018>
+François Le Lay <mfworx@gmail.com> <fly@spotify.com>
+Frank Breitling <frank.breitling@gmx.de>
Friedrich Dunne <dunneff@tcd.ie> dunneff <dunneff@tcd.ie>
Frederic Bastien <nouiz@nouiz.org> Frederic <nouiz@nouiz.org>
-Gael Varoquaux <gael.varoquaux@normalesup.org> GaelVaroquaux <gael.varoquaux@normalesup.org>
-Gerrit Holl <gerrit.holl@utoronto.ca> Gerrit Holl <g.holl@reading.ac.uk>
-Giuseppe Venturini <ggventurini@users.noreply.github.com> ggventurini <ggventurini@users.noreply.github.com>
-Golnaz Irannejad <golnazirannejad@gmail.com> golnazir <golnazirannejad@gmail.com>
-Gopal Singh Meena <gopalmeena94@gmail.com> gopalmeena <gopalmeena94@gmail.com>
-Greg Knoll <gregory@bccn-berlin.de> gkBCCN <gregory@bccn-berlin.de>
-Greg Yang <sorcererofdm@gmail.com> eulerreich <sorcererofdm@gmail.com>
-Greg Young <gfyoung17@gmail.com> gfyoung <gfyoung17@gmail.com>
-Greg Young <gfyoung17@gmail.com> gfyoung <gfyoung@mit.edu>
+FX Coudert <fxcoudert@gmail.com>
+Gael Varoquaux <gael.varoquaux@normalesup.org>
+Gerrit Holl <gerrit.holl@gmail.com> <gerrit.holl@utoronto.ca>
+Gerrit Holl <gerrit.holl@gmail.com> <g.holl@reading.ac.uk>
+Giuseppe Venturini <ggventurini@users.noreply.github.com>
+Golnaz Irannejad <golnazirannejad@gmail.com>
+Gopal Singh Meena <gopalmeena94@gmail.com>
+Greg Knoll <gregory@bccn-berlin.de>
+Greg Yang <sorcererofdm@gmail.com>
+Greg Young <gfyoung17@gmail.com>
+Greg Young <gfyoung17@gmail.com> <gfyoung@mit.edu>
+Gregory R. Lee <grlee77@gmail.com>
+Gregory R. Lee <grlee77@gmail.com> <gregory.lee@cchmc.org>
Guo Ci <zguoci@gmail.com> guoci <zguoci@gmail.com>
-Han Genuit <hangenuit@gmail.com> 87 <hangenuit@gmail.com>
-Han Genuit <hangenuit@gmail.com> hangenuit@gmail.com <hangenuit@gmail.com>
-Han Genuit <hangenuit@gmail.com> Han <hangenuit@gmail.com>
+Hameer Abbasi <einstein.edison@gmail.com> <hameerabbasi@yahoo.com>
+Han Genuit <hangenuit@gmail.com>
Hanno Klemm <hanno.klemm@maerskoil.com> hklemm <hanno.klemm@maerskoil.com>
-Hemil Desai <desai38@purdue.edu> hemildesai <desai38@purdue.edu>
-Hiroyuki V. Yamazaki <hiroyuki.vincent.yamazaki@gmail.com> hvy <hiroyuki.vincent.yamazaki@gmail.com>
-Hugo van Kemenade <hugovk@users.noreply.github.com> Hugo <hugovk@users.noreply.github.com>
-Irvin Probst <irvin.probst@ensta-bretagne.fr> I--P <irvin.probst@ensta-bretagne.fr>
-Isabela Presedo-Floyd <irpf.design@gmail.com> isabela-pf <ipresedo@calpoly.edu>
-Gerhard Hobler <gerhard.hobler@tuwien.ac.at> hobler <gerhard.hobler@tuwien.ac.at>
-Guillaume Peillex <guillaume.peillex@gmail.com> hippo91 <guillaume.peillex@gmail.com>
-Jaime Fernandez <jaime.frio@gmail.com> Jaime Fernandez <jaime.fernandez@hp.com>
-Jaime Fernandez <jaime.frio@gmail.com> jaimefrio <jaime.frio@gmail.com>
-Jaime Fernandez <jaime.frio@gmail.com> Jaime <jaime.frio@gmail.com>
-Jakob Jakobson <jakobjakobson13@posteo.de> Jakob <jakobjakobson13@posteo.de>
-Jakob Jacobson <jakobjakobson13@posteo.de> jakobjakobson13 <43045863+jakobjakobson13@users.noreply.github.com>
-James Webber <jamestwebber@gmail.com> jamestwebber <jamestwebber@gmail.com>
+Helder Oliveira <heldercro@gmail.com>
+Hemil Desai <desai38@purdue.edu>
+Hiroyuki V. Yamazaki <hiroyuki.vincent.yamazaki@gmail.com>
+Hugo van Kemenade <hugovk@users.noreply.github.com>
+I-Shen Leong <i-shenl@activestate.com>
+Inessa Pawson <albuscode@gmail.com>
+Irvin Probst <irvin.probst@ensta-bretagne.fr>
+Isabela Presedo-Floyd <irpf.design@gmail.com> <ipresedo@calpoly.edu>
+Gerhard Hobler <gerhard.hobler@tuwien.ac.at>
+Giannis Zapantis <sdi1900059@di.uoa.gr>
+Guillaume Peillex <guillaume.peillex@gmail.com>
+Jack J. Woehr <jwoehr@softwoehr.com>
+Jaime Fernandez <jaime.frio@gmail.com>
+Jaime Fernandez <jaime.frio@gmail.com> <jaime.fernandez@hp.com>
+Jaime Fernandez <jaime.frio@gmail.com> <jaimefrio@google.com>
+Jamie Macey <dodgerbarker@gmail.com>
+Jakob Jakobson <jakobjakobson13@posteo.de>
+Jakob Jakobson <jakobjakobson13@posteo.de> <43045863+jakobjakobson13@users.noreply.github.com>
+James Bourbeau <jrbourbeau@gmail.com> <jrbourbeau@users.noreply.github.com>
+James Webber <jamestwebber@gmail.com>
+Jan Schlüter <jan.schlueter@ofai.at> <github@jan-schlueter.de>
Jarrod Millman <millman@berkeley.edu> Jarrod Millman <jarrod.millman@gmail.com>
-Jason Grout <jason-github@creativetrax.com> Jason Grout <jason.grout@drake.edu>
-Jason King <pizza@netspace.net.au> jason king <pizza@netspace.net.au>
-Jay Bourque <jay.bourque@continuum.io> jayvius <jay.bourque@continuum.io>
-Jean Utke <jutke@allstate.com> jutke <jutke@allstate.com>
-Jeffrey Yancey <jeffrey@octane5.com> Jeff <3820914+jeffyancey@users.noreply.github.com>
-Jeremy Lay <jlay80@gmail.com> jeremycl01 <jlay80@gmail.com>
+Jason Grout <jason-github@creativetrax.com> <jason.grout@drake.edu>
+Jason King <pizza@netspace.net.au>
+Jay Bourque <jay.bourque@continuum.io>
+Jean Utke <jutke@allstate.com>
+Jeff VanOss <vanossj@gmail.com> <vanossj@users.noreply.github.com>
+Jeffrey Yancey <jeffrey@octane5.com> <3820914+jeffyancey@users.noreply.github.com>
+Jeremy Lay <jlay80@gmail.com>
Jérémie du Boisberranger <jeremie.du-boisberranger@inria.fr> jeremiedbb <34657725+jeremiedbb@users.noreply.github.com>
-Jerome Kelleher <jerome.kelleher@ed.ac.uk> jeromekelleher <jerome.kelleher@ed.ac.uk>
-Johannes Hampp <johannes.hampp@zeu.uni-giessen.de> euronion <42553970+euronion@users.noreply.github.com>
-Johannes Schönberger <hannesschoenberger@gmail.com> Johannes Schönberger <jschoenberger@demuc.de>
-Johann Faouzi <johann.faouzi@gmail.com> johann.faouzi <johann.faouzi@icm-institute.org>
-John Darbyshire <24256554+attack68@users.noreply.github.com> attack68 <24256554+attack68@users.noreply.github.com>
-John Hagen <johnthagen@gmail.com> johnthagen <johnthagen@users.noreply.github.com>
-John Kirkham <kirkhamj@janelia.hhmi.org> jakirkham <jakirkham@gmail.com>
-Joseph Fox-Rabinovitz <jfoxrabinovitz@gmail.com> Joseph Fox-Rabinovitz <joseph.r.fox-rabinovitz@nasa.gov>
-Joseph Fox-Rabinovitz <jfoxrabinovitz@gmail.com> Joseph Fox-Rabinovitz <madphysicist@users.noreply.github.com>
-Joseph Fox-Rabinovitz <jfoxrabinovitz@gmail.com> Mad Physicist <madphysicist@users.noreply.github.com>
-Joseph Martinot-Lagarde <contrebasse@gmail.com> Joseph Martinot-Lagarde <joseph.martinot-lagarde@onera.fr>
-Julian Taylor <juliantaylor108@gmail.com> Julian Taylor <jtaylor.debian@googlemail.com>
-Julian Taylor <juliantaylor108@gmail.com> Julian Taylor <juliantaylor108@googlemail.com>
+Jérome Eertmans <jeertmans@icloud.com>
+Jerome Kelleher <jerome.kelleher@ed.ac.uk>
+Johannes Hampp <johannes.hampp@zeu.uni-giessen.de> <42553970+euronion@users.noreply.github.com>
+Johannes Schönberger <hannesschoenberger@gmail.com> <jschoenberger@demuc.de>
+Johann Faouzi <johann.faouzi@gmail.com> <johann.faouzi@icm-institute.org>
+John Darbyshire <24256554+attack68@users.noreply.github.com> <24256554+attack68@users.noreply.github.com>
+John Hagen <johnthagen@gmail.com> <johnthagen@users.noreply.github.com>
+John Kirkham <jakirkham@gmail.com>
+John Kirkham <jakirkham@gmail.com> <kirkhamj@janelia.hhmi.org>
+Joseph Fox-Rabinovitz <jfoxrabinovitz@gmail.com>
+Joseph Fox-Rabinovitz <jfoxrabinovitz@gmail.com> <joseph.r.fox-rabinovitz@nasa.gov>
+Joseph Fox-Rabinovitz <jfoxrabinovitz@gmail.com> <madphysicist@users.noreply.github.com>
+Joseph Martinot-Lagarde <contrebasse@gmail.com> <joseph.martinot-lagarde@onera.fr>
+Julian Taylor <juliantaylor108@gmail.com>
+Julian Taylor <juliantaylor108@gmail.com> <jtaylor.debian@googlemail.com>
+Julian Taylor <juliantaylor108@gmail.com> <jtaylor108@googlemail.com>
Julien Lhermitte <jrmlhermitte@gmail.com> Julien Lhermitte <lhermitte@bnl.gov>
-Julien Schueller <julien.schueller@gmail.com> jschueller <julien.schueller@gmail.com>
-Justus Magin <keewis@posteo.de> keewis <keewis@users.noreply.github.com>
-Justus Magin <keewis@posteo.de> Keewis <keewis@posteo.de>
-Kai Striega <kaistriega@gmail.com> kai <kaistriega@gmail.com>
-Kai Striega <kaistriega@gmail.com> kai-striega <kaistriega@gmail.com>
-Kai Striega <kaistriega@gmail.com> kai-striega <kaistriega+github@gmail.com>
-Karan Dhir <karan.dhir@berkeley.edu> karan-dhir <kurrandhir@gmail.com>
-Khaled Ben Abdallah Okuda <khaled.ben.okuda@gmail.com> KhaledTo <khaled.ben.okuda@gmail.com>
+Julien Schueller <julien.schueller@gmail.com>
+Justus Magin <keewis@posteo.de>
+Justus Magin <keewis@posteo.de> <keewis@users.noreply.github.com>
+Kai Striega <kaistriega@gmail.com>
+Kai Striega <kaistriega@gmail.com> <kaistriega+github@gmail.com>
+Kasia Leszek <kati.leszek@gmail.com>
+Kasia Leszek <kati.leszek@gmail.com> <39829548+katleszek@users.noreply.github.com>
+Karan Dhir <karan.dhir@berkeley.edu> <kurrandhir@gmail.com>
+Keller Meier <max.kellermeier@hotmail.de>
+Kevin Sheppard <kevin.k.sheppard@gmail.com> <bashtage@users.noreply.github.com>
+Kevin Sheppard <kevin.k.sheppard@gmail.com> <kevin.sheppard@gmail.com>
+Kerem Hallaç <hallackerem@gmail.com>
+Khaled Ben Abdallah Okuda <khaled.ben.okuda@gmail.com>
Kiko Correoso <kachine@protonmail.com> kikocorreoso <kikocorreoso@gmail.com>
Kiko Correoso <kachine@protonmail.com> kikocorreoso <kikocorreoso@users.noreply.github.com>
-Konrad Kapp <k_kapp@yahoo.com> k_kapp@yahoo.com <k_kapp@yahoo.com>
-Kriti Singh <kritisingh1.ks@gmail.com> kritisingh1 <kritisingh1.ks@gmail.com>
-Kmol Yuan <pyslvs@gmail.com> Yuan <pyslvs@gmail.com>
+Konrad Kapp <k_kapp@yahoo.com>
+Kriti Singh <kritisingh1.ks@gmail.com>
+Kmol Yuan <pyslvs@gmail.com>
+Kumud Lakara <55556183+kumudlakara@users.noreply.github.com>
Lars Buitinck <larsmans@gmail.com> Lars Buitinck <l.buitinck@esciencecenter.nl>
Lars Buitinck <larsmans@gmail.com> Lars Buitinck <L.J.Buitinck@uva.nl>
-Lars Grüter <lagru@mailbox.org> Lars G <lagru@mailbox.org>
-Luis Pedro Coelho <luis@luispedro.org> Luis Pedro Coelho <lpc@cmu.edu>
-Luke Zoltan Kelley <lkelley@cfa.harvard.edu> lzkelley <lkelley@cfa.harvard.edu>
-Madhulika Jain Chambers <madhulikajain@gmail.com> madhulikajc <53166646+madhulikajc@users.noreply.github.com>
-Magdalena Proszewska <magdalena.proszewska@gmail.com> mpro <magdalena.proszewska@gmail.com>
-Magdalena Proszewska <magdalena.proszewska@gmail.com> mproszewska <38814059+mproszewska@users.noreply.github.com>
-Manoj Kumar <manojkumarsivaraj334@gmail.com> MechCoder <manojkumarsivaraj334@gmail.com>
-Marcin Podhajski <podhajskimarcin@gmail.com> m-podhajski <36967358+m-podhajski@users.noreply.github.com>
-Mark DePristo <mdepristo@synapdx.com> markdepristo <mdepristo@synapdx.com>
-Mark Weissman <mw9050@gmail.com> m-d-w <mw9050@gmail.com>
-Mark Wiebe <mwwiebe@gmail.com> Mark <mwwiebe@gmail.com>
-Mark Wiebe <mwwiebe@gmail.com> Mark Wiebe <mwiebe@continuum.io>
-Mark Wiebe <mwwiebe@gmail.com> Mark Wiebe <mwiebe@enthought.com>
-Mark Wiebe <mwwiebe@gmail.com> Mark Wiebe <mwiebe@georg.(none)>
-Martin Goodson <martingoodson@gmail.com> martingoodson <martingoodson@gmail.com>
-Martin Reinecke <martin@mpa-garching.mpg.de> mreineck <martin@mpa-garching.mpg.de>
-Martin Teichmann <martin.teichmann@xfel.eu> Martin Teichmann <lkb.teichmann@gmail.com>
-Matt Hancock <not.matt.hancock@gmail.com> matt <mhancock743@gmail.com>
-Martino Sorbaro <martino.sorbaro@ed.ac.uk> martinosorb <martino.sorbaro@ed.ac.uk>
-Mattheus Ueckermann <empeeu@yahoo.com> empeeu <empeeu@yahoo.com>
-Matthew Harrigan <harrigan.matthew@gmail.com> MattHarrigan <harrigan.matthew@gmail.com>
-Matti Picus <matti.picus@gmail.com> mattip <matti.picus@gmail.com>
-Maximilian Konrad <maximilianlukaskonrad@hotmail.de> MLK97 <maximilianlukaskonrad@hotmail.de>
-Melissa Weber Mendonça <melissawm@gmail.com> Melissa Weber Mendonca <melissawm@gmail.com>
-Melissa Weber Mendonça <melissawm@gmail.com> melissawm <melissawm@gmail.com>
+Lars Grüter <lagru@mailbox.org>
+Lars Grüter <lagru@mailbox.org> <lagru@users.noreply.github.com>
+Leonardus Chen <leonardus.chen@gmail.com>
+Licht Takeuchi <licht-t@outlook.jp> <licht-t@math.dis.titech.ac.jp>
+Luis Pedro Coelho <luis@luispedro.org> <lpc@cmu.edu>
+Luke Zoltan Kelley <lkelley@cfa.harvard.edu>
+Madhulika Jain Chambers <madhulikajain@gmail.com> <53166646+madhulikajc@users.noreply.github.com>
+Magdalena Proszewska <magdalena.proszewska@gmail.com>
+Magdalena Proszewska <magdalena.proszewska@gmail.com> <38814059+mproszewska@users.noreply.github.com>
+Manoj Kumar <manojkumarsivaraj334@gmail.com>
+Marcin Podhajski <podhajskimarcin@gmail.com> <36967358+m-podhajski@users.noreply.github.com>
+Mark DePristo <mdepristo@synapdx.com>
+Mark Weissman <mw9050@gmail.com>
+Mark Wiebe <mwwiebe@gmail.com>
+Mark Wiebe <mwwiebe@gmail.com> <mwiebe@continuum.io>
+Mark Wiebe <mwwiebe@gmail.com> <mwiebe@enthought.com>
+Mark Wiebe <mwwiebe@gmail.com> <mwiebe@georg.(none)>
+Martin Goodson <martingoodson@gmail.com>
+Martin Reinecke <martin@mpa-garching.mpg.de>
+Martin Teichmann <martin.teichmann@xfel.eu> <lkb.teichmann@gmail.com>
+Mary Conley <sleeplessinseattle.dev@gmail.com>
+Matheus Vieira Portela <matheus.v.portela@gmail.com>
+Mathieu Lamarre <mlamarre@ea.com> <mathieu@vlam3d.com>
+Matías Ríos <riosm@dickinson.edu>
+Matt Ord <Matthew.ord1@gmail.com>
+Matt Ord <Matthew.ord1@gmail.com> <55235095+Matt-Ord@users.noreply.github.com>
+Matt Hancock <not.matt.hancock@gmail.com> <mhancock743@gmail.com>
+Martino Sorbaro <martino.sorbaro@ed.ac.uk>
+Mattheus Ueckermann <empeeu@yahoo.com>
+Matthew Harrigan <harrigan.matthew@gmail.com>
+Matthias Bussonnier <bussonniermatthias@gmail.com> <mbussonnier@ucmerced.edu>
+Matti Picus <matti.picus@gmail.com>
+Maximilian Konrad <maximilianlukaskonrad@hotmail.de>
+Melissa Weber Mendonça <melissawm@gmail.com> <melissawm@gmail.com>
+Meltem Eren Copur <mecopur@outlook.com>
Michael Behrisch <oss@behrisch.de> behrisch <behrisch@users.sourceforge.net>
Michael Droettboom <mdboom@gmail.com> mdroe <mdroe@localhost>
-Michael K. Tran <trankmichael@gmail.com> mtran <trankmichael@gmail.com>
-Michael Martin <mmartin4242@gmail.com> mmartin <mmartin4242@gmail.com>
-Michael Schnaitter <schnaitterm@knights.ucf.edu> schnaitterm <schnaitterm@users.noreply.github.com>
-Muhammad Kasim <firman.kasim@gmail.com> mfkasim91 <firman.kasim@gmail.com>
-Masashi Kishimoto <drehbleistift@gmail.com> kishimoto-banana <drehbleistift@gmail.com>
-Nathaniel J. Smith <njs@pobox.com> njsmith <njs@pobox.com>
+Michael Dubravski <mdubravski@gmail.com>
+Michael Dubravski <mdubravski@gmail.com> <41096057+mdubravski@users.noreply.github.com>
+Michael Felt <aixtools@gmail.com> <aixtools@users.noreply.github.com>
+Michael Hirsch <scivision@users.noreply.github.com>
+Michael K. Tran <trankmichael@gmail.com>
+Michael Martin <mmartin4242@gmail.com>
+Michael Schnaitter <schnaitterm@knights.ucf.edu> <schnaitterm@users.noreply.github.com>
+Michael Seifert <michaelseifert04@yahoo.de>
+Michel Fruchart <michel.fruchart@ens-lyon.org> <fruchart@users.noreply.github.com>
+Mike Toews <mwtoews@gmail.com>
+Mircea Akos Bruma <bruma.mircea.a@gmail.com>
+Mircea Akos Bruma <bruma.mircea.a@gmail.com> <akos@debian-gnu-linux-vm.localdomain>
+Mitchell Faas <Faas.Mitchell@gmail.com> <35742861+Mitchell-Faas@users.noreply.github.com>
+Muhammad Kasim <firman.kasim@gmail.com>
+Masashi Kishimoto <drehbleistift@gmail.com>
+Mukulikaa Parhari <mukulikapahari@gmail.com> <60316606+Mukulikaa@users.noreply.github.com>
+Nathaniel J. Smith <njs@pobox.com>
Naveen Arunachalam <notatroll.troll@gmail.com> naveenarun <notatroll.troll@gmail.com>
+Neil Girdhar <mistersheik@gmail.com>
+Nick Papior <nickpapior@gmail.com>
+Nicola Soranzo <nicola.soranzo@gmail.com> <nicola.soranzo@earlham.ac.uk>
Nicolas Scheffer <nicolas.scheffer@sri.com> Nicolas Scheffer <scheffer@speech.sri.com>
Nicholas A. Del Grosso <delgrosso@bio.lmu.de> nickdg <delgrosso@bio.lmu.de>
+Nicholas McKibben <nicholas.bgp@gmail.com>
Nick Minkyu Lee <mknicklee@protonmail.com> fivemok <9394929+fivemok@users.noreply.github.com>
-Ondřej Čertík <ondrej.certik@gmail.com> Ondrej Certik <ondrej.certik@gmail.com>
-Óscar Villellas Guillén <oscar.villellas@continuum.io> ovillellas <oscar.villellas@continuum.io>
+Oliver Eberle <oliver_eberle@web.de>
+Ondřej Čertík <ondrej.certik@gmail.com>
+Óscar Villellas Guillén <oscar.villellas@continuum.io>
+Panos Mavrogiorgos <pmav99@users.noreply.github.com>
Pat Miller <patmiller@localhost> patmiller <patmiller@localhost>
-Paul Ivanov <pi@berkeley.edu> Paul Ivanov <paul.ivanov@local>
+Paul Ivanov <pivanov5@bloomberg.net> <pi@berkeley.edu>
+Paul Ivanov <pivanov5@bloomberg.net> <paul.ivanov@local>
Paul YS Lee <leeyspaul@gmail.com> Paul <leeyspaul@users.noreply.github.com>
-Paul Jacobson <hpj3@myuw.net> hpaulj <hpj3@myuw.net>
-Pearu Peterson <pearu.peterson@gmail.com> Pearu Peterson <pearu@pearu-laptop.(none)>
-Pete Peeradej Tanruangporn <pete.tanru@gmail.com> petetanru <pete.tanru@gmail.com>
-Peter Bell <peterbell10@live.co.uk> peterbell10 <peterbell10@live.co.uk>
-Peter J Cock <p.j.a.cock@googlemail.com> peterjc <p.j.a.cock@googlemail.com>
+Paul Jacobson <hpj3@myuw.net>
+Pearu Peterson <pearu.peterson@gmail.com> <pearu@pearu-laptop.(none)>
+Pete Peeradej Tanruangporn <pete.tanru@gmail.com>
+Peter Bell <peterbell10@live.co.uk>
+Peter J Cock <p.j.a.cock@googlemail.com>
Phil Elson <pelson.pub@gmail.com>
-Pierre GM <pierregmcode@gmail.com> pierregm <pierregmcode@gmail.com>
+Pierre GM <pierregmcode@gmail.com>
Pierre GM <pierregmcode@gmail.com> pierregm <pierregm@localhost>
-Piotr Gaiński <dociebieaniuszlem@gmail.com> panpiort8 <dociebieaniuszlem@gmail.com>
+Piotr Gaiński <dociebieaniuszlem@gmail.com>
Piotr Gaiński <dociebieaniuszlem@gmail.com> Pan Jan <rumcajsgajos@gmail.com>
Prabhu Ramachandran <prabhu@localhost> prabhu <prabhu@localhost>
-Przemyslaw Bartosik <sendthenote@gmail.com> przemb <sendthenote@gmail.com>
+Przemyslaw Bartosik <sendthenote@gmail.com>
+Raghuveer Devulapalli <me.raghuveer@gmail.com> <raghuveer.devulapalli@intel.com>
+Raghuveer Devulapalli <me.raghuveer@gmail.com> <44766858+r-devulap@users.noreply.github.com>
Rajas Rade <raderajas@gmail.com> lkdmttg7 <inprovertmer07@gmail.com>
-Ralf Gommers <ralf.gommers@gmail.com> Ralf Gommers <ralf.gommers@googlemail.com>
-Ralf Gommers <ralf.gommers@gmail.com> rgommers <ralf.gommers@googlemail.com>
-Rehas Sachdeva <aquannie@gmail.com> rehassachdeva <aquannie@gmail.com>
-Ritta Narita <narittan@gmail.com> RittaNarita <narittan@gmail.com>
-Riya Sharma <navneet.nmk@gmail.com> ayir <navneet.nmk@gmail.com>
-Robert Kern <rkern@enthought.com> Robert Kern <robert.kern@gmail.com>
-Robert LU <robberphex@gmail.com> RobberPhex <robberphex@gmail.com>
+Rakesh Vasudevan <rakesh.nvasudev@gmail.com>
+Ralf Gommers <ralf.gommers@gmail.com> <ralf.gommers@googlemail.com>
+Rehas Sachdeva <aquannie@gmail.com>
+Ritta Narita <narittan@gmail.com>
+Riya Sharma <navneet.nmk@gmail.com>
+Robert Kern <rkern@enthought.com> <robert.kern@gmail.com>
+Robert LU <robberphex@gmail.com>
+Robert T. McGibbon <rmcgibbo@gmail.com>
+Roland Kaufmann <rka081+numpy@uib.no> <roland.kaufmann@uni.no>
+Roman Yurchak <rth.yurchak@gmail.com> <rth.yurchak@pm.me>
Ronan Lamy <ronan.lamy@gmail.com> Ronan Lamy <Ronan.Lamy@normalesup.org>
-Russell Hewett <rhewett@mit.edu> rhewett <rhewett@mit.edu>
-Ryan Blakemore <rbtnet@gmail.com> ryanblak <rbtnet@gmail.com>
-Sam Preston <j.sam.preston@gmail.com> jspreston <j.sam.preston@gmail.com>
-Sam Radhakrishnan <sk09idm@gmail.com> = <=>
-Sam Radhakrishnan <sk09idm@gmail.com> sam09 <sk09idm@gmail.com>
-Sanchez Gonzalez Alvaro <as12513@imperial.ac.uk> alvarosg <as12513@imperial.ac.uk>
-Saullo Giovani <saullogiovani@gmail.com> saullogiovani <saullogiovani@gmail.com>
+Russell Hewett <rhewett@mit.edu>
+Ryan Blakemore <rbtnet@gmail.com>
+Ryan Polley <rypolley@gmail.com> <rypolley+github@gmail.com>
+Ryan Soklaski <rsoklaski@gmail.com> <ry26099@mit.edu>
+Ryan Soklaski <rsoklaski@gmail.com> <ryan.soklaski@gmail.com>
+Sabrina Simao <sabrina_simao@hotmail.com>
+Sabrina Simao <sabrina_simao@hotmail.com> SabrinaSimao <sabrinass@al.insper.edu.br>
+Sam Preston <j.sam.preston@gmail.com>
+Sam Radhakrishnan <sk09idm@gmail.com> = <=> # committed without an email address
+Samesh Lakhotia <samesh.lakhotia@gmail.com>
+Samesh Lakhotia <samesh.lakhotia@gmail.com> <43701530+sameshl@users.noreply.github.com>
+Sami Salonen <ssalonen@gmail.com> <sami.salonen@eniram.fi>
+Sanchez Gonzalez Alvaro <as12513@imperial.ac.uk>
+Saullo Giovani <saullogiovani@gmail.com>
Saurabh Mehta <e.samehta@gmail.com>
-Sebastian Berg <sebastian@sipsolutions.net> seberg <sebastian@sipsolutions.net>
-Sergei Vorfolomeev <svorfolomeev@vmssoftware.com> vorfol <39548292+vorfol@users.noreply.github.com>
-Shekhar Prasad Rajak <shekharrajak@live.com> shekharrajak <shekharrajak@live.com>
-Shota Kawabuchi <shota.kawabuchi+GitHub@gmail.com> skwbc <shota.kawabuchi+GitHub@gmail.com>
-Siavash Eliasi <siavashserver@gmail.com> siavashserver <siavashserver@gmail.com>
-Simon Gasse <simon.gasse@gmail.com> sgasse <sgasse@users.noreply.github.com>
-Søren Rasmussen <soren.rasmussen@alexandra.dk> sorenrasmussenai <47032123+sorenrasmussenai@users.noreply.github.com>
-Stefan Behnel <stefan_ml@behnel.de> scoder <stefan_ml@behnel.de>
-Stefan van der Walt <stefanv@berkeley.edu> Stefan van der Walt <sjvdwalt@gmail.com>
-Stefan van der Walt <stefanv@berkeley.edu> Stefan van der Walt <stefan@sun.ac.za>
-Stephan Hoyer <shoyer@gmail.com> Stephan Hoyer <shoyer@climate.com>
+Sebastian Berg <sebastian@sipsolutions.net>
+Sergei Vorfolomeev <svorfolomeev@vmssoftware.com> <39548292+vorfol@users.noreply.github.com>
+Shekhar Prasad Rajak <shekharrajak@live.com>
+Shen Zhou <shen_zhou@u.nus.edu>
+Shota Kawabuchi <shota.kawabuchi+GitHub@gmail.com>
+Siavash Eliasi <siavashserver@gmail.com>
+Simon Conseil <contact@saimon.org> <simon.conseil@univ-lyon1.fr>
+Simon Gasse <simon.gasse@gmail.com>
+Simon Gasse <simon.gasse@gmail.com> <sgasse@users.noreply.github.com>
+Søren Rasmussen <soren.rasmussen@alexandra.dk> <47032123+sorenrasmussenai@users.noreply.github.com>
+Spencer Hill <spencerahill@gmail.com> <shill@atmos.ucla.edu>
+Stefan Behnel <stefan_ml@behnel.de>
+Stefan van der Walt <stefanv@berkeley.edu> <sjvdwalt@gmail.com>
+Stefan van der Walt <stefanv@berkeley.edu> <stefan@sun.ac.za>
+Stephan Hoyer <shoyer@gmail.com> <shoyer@climate.com>
+Stephan Hoyer <shoyer@gmail.com> <shoyer@google.com>
+Steve Stagg <stestagg@gmail.com> <ste@sta.gg>
Steven J Kern <kern.steven0@gmail.com>
-Stuart Archibald <stuart.archibald@googlemail.com> stuartarchibald <stuartarchibald@users.noreply.github.com>
-SuryaChand P <psschand@gmail.com> Surya P <psschand@gmail.com>
-SuryaChand P <psschand@gmail.com> psschand <psschand@gmail.com>
-Takanori Hirano <takanori17h@gmail.com> takanori-pskq <takanori17h@gmail.com>
-Takanori H <takanori17h@gmail.com> takanori-pskq <takanori17h@gmail.com>
-Thomas A Caswell <tcaswell@gmail.com> Thomas A Caswell <tcaswell@bnl.gov>
-Tim Cera <tim@cerazone.net> tim cera <tcera@sjrwmd.com>
-Tim Teichmann <t.teichmann@dashdos.com> tteichmann <t.teichmann@dashdos.com>
-Tim Teichmann <t.teichmann@dashdos.com> tteichmann <44259103+tteichmann@users.noreply.github.com>
-Tirth Patel <tirthasheshpatel@gmail.com> tirthasheshpatel <tirthasheshpatel@gmail.com>
-Tom Boyd <pezcore@users.noreply.github.com> pezcore <pezcore@users.noreply.github.com>
-Tom Poole <t.b.poole@gmail.com> tpoole <t.b.poole@gmail.com>
-Tony LaTorre <tlatorre@uchicago.edu> tlatorre <tlatorre@uchicago.edu>
-Travis Oliphant <travis@continuum.io> Travis E. Oliphant <teoliphant@gmail.com>
-Travis Oliphant <travis@continuum.io> Travis Oliphant <oliphant@enthought.com>
-Valentin Haenel <valentin@haenel.co> Valentin Haenel <valentin.haenel@gmx.de>
-Rakesh Vasudevan <rakesh.nvasudev@gmail.com> vrakesh <rakesh.nvasudev@gmail.com>
-Vrinda Narayan <talk2vrinda@gmail.com> vrindaaa <48102157+vrindaaa@users.noreply.github.com>
-Wansoo Kim <rladhkstn8@gmail.com> marload <rladhkstn8@gmail.com>
-Warren Weckesser <warren.weckesser@enthought.com> Warren Weckesser <warren.weckesser@gmail.com>
-Weitang Li <liwt31@163.com> wtli@Dirac <liwt31@163.com>
-Weitang Li <liwt31@163.com> wtli <liwt31@163.com>
-Wendell Smith <wendellwsmith@gmail.com> Wendell Smith <wackywendell@gmail.com>
-Wim Glenn <wim.glenn@melbourneit.com.au> wim glenn <wim.glenn@melbourneit.com.au>
-Wojtek Ruszczewski <git@wr.waw.pl> wrwrwr <git@wr.waw.pl>
-Yogesh Raisinghani <vanshita12004@gmail.com> raisinghanii <46864533+raisinghanii@users.noreply.github.com>
-Yuji Kanagawa <yuji.kngw.80s.revive@gmail.com> kngwyu <yuji.kngw.80s.revive@gmail.com>
-Yury Kirienko <yury.kirienko@gmail.com> kirienko <yury.kirienko@gmail.com>
-Zac Hatfield-Dodds <zac.hatfield.dodds@gmail.com> Zac-HD <zac.hatfield.dodds@gmail.com>
-Zixu Zhao <zixu.zhao.tireless@gmail.com> ZZhaoTireless <zixu.zhao.tireless@gmail.com>
-Ziyan Zhou <ziyan.zhou@mujin.co.jp> Ziyan <ziyan.zhou@mujin.co.jp>
-Zieji Pohz <poh.ziji@gmail.com> jpoh <poh.zijie@gmail.com>
-Zieji Pohz <poh.ziji@gmail.com> zjpoh <poh.zijie@gmail.com>
-Zieji Pohz <poh.ziji@gmail.com> Zijie (ZJ) Poh <8103276+zjpoh@users.noreply.github.com>
-Zolisa Bleki <zolisa.bleki@gmail.com> zoj613 <44142765+zoj613@users.noreply.github.com>
-Zolisa Bleki <zolisa.bleki@gmail.com> RedRuM <44142765+zoj613@users.noreply.github.com>
-luzpaz <kunda@scribus.net> luz.paz <luzpaz@users.noreply.github.com>
-luzpaz <kunda@scribus.net> luzpaz <luzpaz@users.noreply.github.com>
-spacescientist <aspacescientist@protonmail.com> spacescientist <spacescientist@pm.me>
+Stuart Archibald <stuart.archibald@googlemail.com> <stuart@opengamma.com>
+Stuart Archibald <stuart.archibald@googlemail.com> <stuartarchibald@users.noreply.github.com>
+SuryaChand P <psschand@gmail.com>
+Takanori Hirano <takanori17h@gmail.com>
+Thomas A Caswell <tcaswell@gmail.com> <tcaswell@bnl.gov>
+Thomas Kluyver <takowl@gmail.com> <thomas@kluyver.me.uk>
+Thomas Orgis <thomas.orgis@uni-hamburg.de>
+Tim Cera <tim@cerazone.net> <tcera@sjrwmd.com>
+Tim Teichmann <t.teichmann@dashdos.com>
+Tim Teichmann <t.teichmann@dashdos.com> <44259103+tteichmann@users.noreply.github.com>
+Tirth Patel <tirthasheshpatel@gmail.com>
+Tobias Pitters <tobias.pitters@gmail.com> <tobias.pitters@gmx.de>
+Tobias Pitters <tobias.pitters@gmail.com> <31857876+CloseChoice@users.noreply.github.com>
+Tobias Uelwer <tobias.uelwer@googlemail.com> <tobias.uelwer@uni-duesseldorf.de>
+Tom Boyd <tboyd@scitec.com> <pezcore@users.noreply.github.com>
+Tom Poole <t.b.poole@gmail.com>
+Tong Zou <tongzou@uw.edu>
+Tony LaTorre <tlatorre@uchicago.edu>
+Toshiki Kataoka <kataoka@preferred.jp> <tos.lunar@gmail.com>
+Travis Oliphant <teoliphant@gmail.com>
+Travis Oliphant <teoliphant@gmail.com> <oliphant@enthought.com>
+Travis Oliphant <teoliphant@gmail.com> <travis@continuum.io>
+Valentin Haenel <valentin@haenel.co> <valentin.haenel@gmx.de>
+Valentin Haenel <valentin@haenel.co> <vhaenel@anaconda.com>
+Varun Nayyar <nayyarv@gmail.com> <nayyarv@users.noreply.github.com>
+Vrinda Narayan <talk2vrinda@gmail.com> <vrinda18120@iiitd.ac.in>
+Vrinda Narayan <talk2vrinda@gmail.com> <48102157+vrindaaa@users.noreply.github.com>
+Wansoo Kim <rladhkstn8@gmail.com>
+Warren Weckesser <warren.weckesser@gmail.com> <warren.weckesser@enthought.com>
+Weitang Li <liwt31@163.com>
+Wendell Smith <wendellwsmith@gmail.com> <wackywendell@gmail.com>
+William Spotz <wfspotz@sandia.gov> <wfspotz@sandia.gov@localhost>
+Wim Glenn <wim.glenn@melbourneit.com.au>
+Wojtek Ruszczewski <git@wr.waw.pl>
+Wojciech Rzadkowski <wojciech.rzadkowski@gmail.com> <33913808+wrzadkow@users.noreply.github.com>
+Yang Hau <yuanyanghau@gmail.com>
+Yang Hau <yuanyanghau@gmail.com> <vulxj0j8j8@gmail.com>
+Yogesh Raisinghani <vanshita12004@gmail.com> <46864533+raisinghanii@users.noreply.github.com>
+Yu Feng <rainwoodman@gmail.com> <feyu@google.com>
+Yuji Kanagawa <yuji.kngw.80s.revive@gmail.com>
+Yury Kirienko <yury.kirienko@gmail.com>
+Zac Hatfield-Dodds <zac.hatfield.dodds@gmail.com>
+Zé Vinícius <jvmirca@gmail.com>
+Zixu Zhao <zixu.zhao.tireless@gmail.com>
+Ziyan Zhou <ziyan.zhou@mujin.co.jp>
+Zieji Pohz <poh.ziji@gmail.com>
+Zieji Pohz <poh.ziji@gmail.com> <8103276+zjpoh@users.noreply.github.com>
+Zolboo Erdenebaatar <erdenebz@dickinson.edu>
+Zolisa Bleki <zolisa.bleki@gmail.com> <44142765+zoj613@users.noreply.github.com>
diff --git a/.travis.yml b/.travis.yml
index 6b7585a56..839f52ed1 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -3,7 +3,7 @@
language: python
group: travis_latest
os: linux
-dist: bionic
+dist: focal
# Travis allows these packages, additions can be requested
# https://github.com/travis-ci/apt-package-safelist
@@ -16,21 +16,26 @@ addons:
# Speedup builds, particularly when USE_CHROOT=1
- eatmydata
+# Disable clone depth
+git:
+ depth: false
+
cache:
directories:
- $HOME/.cache/pip
jobs:
include:
- - python: 3.7
+ - python: 3.8
os: linux
arch: ppc64le
env:
# use OpenBLAS build, not system ATLAS
- DOWNLOAD_OPENBLAS=1
+ - NPY_USE_BLAS_ILP64=1
- ATLAS=None
- - python: 3.7
+ - python: 3.8
os: linux
arch: s390x
env:
@@ -39,9 +44,10 @@ jobs:
- NPY_USE_BLAS_ILP64=1
- ATLAS=None
- - python: 3.7
+ - python: 3.8
os: linux
arch: arm64
+ virt: vm
env:
# use OpenBLAS build, not system ATLAS
- DOWNLOAD_OPENBLAS=1
diff --git a/INSTALL.rst.txt b/INSTALL.rst.txt
index 5ee97d790..1bc97c4b5 100644
--- a/INSTALL.rst.txt
+++ b/INSTALL.rst.txt
@@ -14,7 +14,7 @@ Prerequisites
Building NumPy requires the following installed software:
-1) Python__ 3.6.x or newer.
+1) Python__ 3.7.x or newer.
Please note that the Python development headers also need to be installed,
e.g., on Debian/Ubuntu one needs to install both `python3` and
diff --git a/LICENSE.txt b/LICENSE.txt
index 8ce645218..4723d4ea0 100644
--- a/LICENSE.txt
+++ b/LICENSE.txt
@@ -1,4 +1,4 @@
-Copyright (c) 2005-2020, NumPy Developers.
+Copyright (c) 2005-2021, NumPy Developers.
All rights reserved.
Redistribution and use in source and binary forms, with or without
diff --git a/LICENSES_bundled.txt b/LICENSES_bundled.txt
index 00b747377..26c7a7829 100644
--- a/LICENSES_bundled.txt
+++ b/LICENSES_bundled.txt
@@ -15,3 +15,8 @@ Name: dragon4
Files: numpy/core/src/multiarray/dragon4.c
License: MIT
For license text, see numpy/core/src/multiarray/dragon4.c
+
+Name: libdivide
+Files: numpy/core/include/numpy/libdivide/*
+License: Zlib
+ For license text, see numpy/core/include/numpy/libdivide/LICENSE.txt
diff --git a/MANIFEST.in b/MANIFEST.in
index 35eb05a61..8ec62123b 100644
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -4,16 +4,16 @@
# data, etc files to distribution (*for installation*).
# Avoid using MANIFEST.in for that.
#
-include MANIFEST.in
-include pyproject.toml
-include pytest.ini
-include *.txt
-include README.md
-include site.cfg.example
-include runtests.py
-include tox.ini
-include .coveragerc
-include test_requirements.txt
+# Files in top-level directory:
+include *.*
+# Exclude license file that we append to the main license when running
+# `python setup.py sdist`. And exclude generated files in repo root.
+exclude LICENSES_bundled.txt
+exclude .*
+exclude azure-*.yml
+
+# Sub-directories. Included are: numpy/, doc/, benchmarks/, tools/
+include numpy/_version.py
recursive-include numpy/random *.pyx *.pxd *.pyx.in *.pxd.in
include numpy/py.typed
include numpy/random/include/*
@@ -45,6 +45,3 @@ prune benchmarks/numpy
# Exclude generated files
prune */__pycache__
global-exclude *.pyc *.pyo *.pyd *.swp *.bak *~
-# Exclude license file that we append to the main license when running
-# `python setup.py sdist`
-exclude LICENSES_bundled.txt
diff --git a/README.md b/README.md
index 9271a5d28..4195ff917 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,4 @@
-# <img alt="NumPy" src="https://ghcdn.rawgit.org/numpy/numpy/master/branding/icons/primary/numpylogo.svg" height="60">
-
-[![Travis CI](https://img.shields.io/travis/com/numpy/numpy/master?label=Travis%20CI)](
- https://travis-ci.com/github/numpy/numpy)
-[![Azure](https://dev.azure.com/numpy/numpy/_apis/build/status/azure-pipeline%20numpy.numpy)](
- https://dev.azure.com/numpy/numpy/_build/latest?definitionId=5)
-[![codecov](https://codecov.io/gh/numpy/numpy/branch/master/graph/badge.svg)](
- https://codecov.io/gh/numpy/numpy)
+# <img alt="NumPy" src="/branding/logo/primary/numpylogo.svg" height="60">
NumPy is the fundamental package needed for scientific computing with Python.
@@ -26,10 +19,7 @@ It provides:
Testing:
-- NumPy versions &ge; 1.15 require `pytest`
-- NumPy versions &lt; 1.15 require `nose`
-
-Tests can then be run after installation with:
+NumPy requires `pytest`. Tests can then be run after installation with:
python -c 'import numpy; numpy.test()'
@@ -37,13 +27,40 @@ Tests can then be run after installation with:
Call for Contributions
----------------------
-NumPy appreciates help from a wide range of different backgrounds.
-Work such as high level documentation or website improvements are valuable
-and we would like to grow our team with people filling these roles.
-Small improvements or fixes are always appreciated and issues labeled as easy
-may be a good starting point.
-If you are considering larger contributions outside the traditional coding work,
-please contact us through the mailing list.
+The NumPy project welcomes your expertise and enthusiasm!
+
+Small improvements or fixes are always appreciated; issues labeled as ["good
+first issue"](https://github.com/numpy/numpy/labels/good%20first%20issue)
+may be a good starting point. If you are considering larger contributions
+to the source code, please contact us through the [mailing
+list](https://mail.python.org/mailman/listinfo/numpy-discussion) first.
+
+Writing code isn’t the only way to contribute to NumPy. You can also:
+- review pull requests
+- triage issues
+- develop tutorials, presentations, and other educational materials
+- maintain and improve [our website](https://github.com/numpy/numpy.org)
+- develop graphic design for our brand assets and promotional materials
+- translate website content
+- help with outreach and onboard new contributors
+- write grant proposals and help with other fundraising efforts
+
+If you’re unsure where to start or how your skills fit in, reach out! You can
+ask on the mailing list or here, on GitHub, by opening a new issue or leaving a
+comment on a relevant issue that is already open.
+
+Our preferred channels of communication are all public, but if you’d like to
+speak to us in private first, contact our community coordinators at
+numpy-team@googlegroups.com or on Slack (write numpy-team@googlegroups.com for
+an invitation).
+
+We also have a biweekly community call, details of which are announced on the
+mailing list. You are very welcome to join.
+
+If you are new to contributing to open source, [this
+guide](https://opensource.guide/how-to-contribute/) helps explain why, what,
+and how to successfully get involved.
+
[![Powered by NumFOCUS](https://img.shields.io/badge/powered%20by-NumFOCUS-orange.svg?style=flat&colorA=E1523D&colorB=007D8A)](https://numfocus.org)
diff --git a/azure-pipelines.yml b/azure-pipelines.yml
index f8773dc36..03571aed2 100644
--- a/azure-pipelines.yml
+++ b/azure-pipelines.yml
@@ -3,7 +3,7 @@ trigger:
batch: False
branches:
include:
- - master
+ - main
- maintenance/*
@@ -18,6 +18,54 @@ stages:
- stage: InitialTests
jobs:
+ # Native build is based on gcc flag `-march=native`
+ - job: Linux_baseline_native
+ pool:
+ vmImage: 'ubuntu-20.04'
+ steps:
+ - script: |
+ if ! `gcc 2>/dev/null`; then
+ sudo apt install gcc
+ fi
+ sudo apt install python3
+ sudo apt install python3-dev
+ # python3 has no setuptools, so install one to get us going
+ python3 -m pip install --user --upgrade pip 'setuptools<49.2.0'
+ python3 -m pip install --user -r test_requirements.txt
+ displayName: 'install python/requirements'
+ - script: |
+ python3 runtests.py --show-build-log --cpu-baseline=native --cpu-dispatch=none \
+ --debug-info --mode=full -- -rsx --junitxml=junit/test-results.xml
+ displayName: 'Run native baseline Build / Tests'
+ - task: PublishTestResults@2
+ condition: succeededOrFailed()
+ inputs:
+ testResultsFiles: '**/test-*.xml'
+ failTaskOnFailedTests: true
+ testRunTitle: 'Publish test results for baseline/native'
+
+- stage: ComprehensiveTests
+ jobs:
+
+ - job: Lint
+ condition: and(succeeded(), eq(variables['Build.Reason'], 'PullRequest'))
+ pool:
+ vmImage: 'ubuntu-18.04'
+ steps:
+ - task: UsePythonVersion@0
+ inputs:
+ versionSpec: '3.8'
+ addToPath: true
+ architecture: 'x64'
+ - script: >-
+ python -m pip install -r linter_requirements.txt
+ displayName: 'Install tools'
+ # pip 21.1 emits a pile of garbage messages to annoy users :)
+ # failOnStderr: true
+ - script: |
+ python tools/linter.py --branch origin/$(System.PullRequest.TargetBranch)
+ displayName: 'Run Lint Checks'
+ failOnStderr: true
- job: WindowsFast
pool:
@@ -25,26 +73,20 @@ stages:
strategy:
matrix:
Python37-32bit-fast:
- PYTHON_VERSION: '3.7'
+ PYTHON_VERSION: '3.8'
PYTHON_ARCH: 'x86'
TEST_MODE: fast
BITS: 32
steps:
- template: azure-steps-windows.yml
-
-- stage: ComprehensiveTests
- jobs:
-
-
- job: Linux_Python_38_32bit_full_with_asserts
pool:
- vmImage: 'ubuntu-18.04'
+ vmImage: 'ubuntu-20.04'
steps:
- script: |
- docker pull quay.io/pypa/manylinux2010_i686
docker run -v $(pwd):/numpy -e CFLAGS="-msse2 -std=c99 -UNDEBUG" \
- -e F77=gfortran-5 -e F90=gfortran-5 quay.io/pypa/manylinux2010_i686 \
+ -e F77=gfortran-5 -e F90=gfortran-5 quay.io/pypa/manylinux2014_i686 \
/bin/bash -xc "cd numpy && \
/opt/python/cp38-cp38/bin/python -mvenv venv &&\
source venv/bin/activate && \
@@ -78,11 +120,11 @@ stages:
strategy:
maxParallel: 3
matrix:
- Python37:
- PYTHON_VERSION: '3.7'
+ Python38:
+ PYTHON_VERSION: '3.8'
USE_OPENBLAS: '1'
- Python37-ILP64:
- PYTHON_VERSION: '3.7'
+ Python38-ILP64:
+ PYTHON_VERSION: '3.8'
NPY_USE_BLAS_ILP64: '1'
USE_OPENBLAS: '1'
steps:
@@ -155,7 +197,6 @@ stages:
- script: python setup.py build -j 4 build_ext --inplace install
displayName: 'Build NumPy without OpenBLAS and new casting'
env:
- NPY_USE_NEW_CASTINGIMPL: 1
BLAS: None
LAPACK: None
ATLAS: None
@@ -166,7 +207,7 @@ stages:
- script: python -m pip install matplotlib
displayName: 'Install matplotlib before refguide run'
- script: python runtests.py -g --refguide-check
- displayName: 'Run Refuide Check'
+ displayName: 'Run Refguide Check'
condition: eq(variables['USE_OPENBLAS'], '1')
- script: python runtests.py -n --mode=full -- -rsx --junitxml=junit/test-results.xml
displayName: 'Run Full NumPy Test Suite'
@@ -191,7 +232,7 @@ stages:
inputs:
testResultsFiles: '**/test-*.xml'
failTaskOnFailedTests: true
- testRunTitle: 'Publish test results for Python 3.7 64-bit full Mac OS'
+ testRunTitle: 'Publish test results for Python 3.8 64-bit full Mac OS'
- job: Windows
@@ -206,6 +247,11 @@ stages:
PYTHON_ARCH: 'x64'
TEST_MODE: full
BITS: 64
+ #PyPy37-64bit-full:
+ # PYTHON_VERSION: 'PyPy3.7'
+ # PYTHON_ARCH: 'x64'
+ # TEST_MODE: fast
+ # BITS: 64
Python38-32bit-fast:
PYTHON_VERSION: '3.8'
PYTHON_ARCH: 'x86'
@@ -227,7 +273,7 @@ stages:
TEST_MODE: full
BITS: 64
NPY_USE_BLAS_ILP64: '1'
- OPENBLAS_SUFFIX: '64_'
+
steps:
- template: azure-steps-windows.yml
@@ -238,6 +284,7 @@ stages:
vmImage: 'ubuntu-18.04'
steps:
- script: |
+ sudo apt update
sudo apt install python3.7
sudo apt install python3.7-dev
if ! `gcc-4.8 2>/dev/null`; then
@@ -258,3 +305,31 @@ stages:
failTaskOnFailedTests: true
testRunTitle: 'Publish test results for gcc 4.8'
+ - job: Linux_conda
+ pool:
+ vmImage: 'ubuntu-20.04'
+ steps:
+ - script: |
+ # create and activate conda environment
+ conda env create -f environment.yml
+ displayName: 'Create conda environment.'
+ - script: |
+ # >>> conda initialize >>>
+ # !! Contents within this block are 'conda init' !!
+ # see https://github.com/conda/conda/issues/7980
+ __conda_setup="$('conda' 'shell.bash' 'hook' 2> /dev/null)"
+ eval "$__conda_setup"
+ unset __conda_setup
+ # <<< conda initialize <<<
+ conda activate numpy-dev
+ # Run native baseline Build / Tests
+ python runtests.py --show-build-log --cpu-baseline=native --cpu-dispatch=none \
+ --debug-info --mode=full -- -rsx --junitxml=junit/test-results.xml
+ displayName: 'Run native baseline Build / Tests in conda.'
+ - task: PublishTestResults@2
+ condition: succeededOrFailed()
+ inputs:
+ testResultsFiles: '**/test-*.xml'
+ failTaskOnFailedTests: true
+ testRunTitle: 'Publish test results for conda installation'
+
diff --git a/azure-steps-windows.yml b/azure-steps-windows.yml
index 28762f5d9..9a5f9bb70 100644
--- a/azure-steps-windows.yml
+++ b/azure-steps-windows.yml
@@ -6,7 +6,7 @@ steps:
architecture: $(PYTHON_ARCH)
condition: not(contains(variables['PYTHON_VERSION'], 'PyPy'))
- powershell: |
- $url = "http://buildbot.pypy.org/nightly/py3.6/pypy-c-jit-latest-win32.zip"
+ $url = "http://buildbot.pypy.org/nightly/py3.7/pypy-c-jit-latest-win64.zip"
$output = "pypy.zip"
$wc = New-Object System.Net.WebClient
$wc.DownloadFile($url, $output)
@@ -30,6 +30,12 @@ steps:
displayName: 'Install dependencies; some are optional to avoid test skips'
- powershell: |
+ choco install -y mingw --forcex86 --force --version=7.3.0
+ refreshenv
+ displayName: 'Install 32-bit mingw for 32-bit builds'
+ condition: eq(variables['BITS'], 32)
+
+- powershell: |
$ErrorActionPreference = "Stop"
# Download and get the path to "openblas.a". We cannot copy it
# to $PYTHON_EXE's directory since that is on a different drive which
@@ -37,29 +43,25 @@ steps:
# since OPENBLAS will be picked up by the openblas discovery
$target = $(python tools/openblas_support.py)
mkdir openblas
- echo "Copying $target to openblas/openblas$env:OPENBLAS_SUFFIX.a"
- cp $target openblas/openblas$env:OPENBLAS_SUFFIX.a
- If ( Test-Path env:NPY_USE_BLAS_ILP64 ){
- echo "##vso[task.setvariable variable=OPENBLAS64_]$pwd\openblas"
- } else {
- echo "##vso[task.setvariable variable=OPENBLAS]$pwd\openblas"
- }
+ echo "Copying $target to openblas/"
+ cp $target openblas/
displayName: 'Download / Install OpenBLAS'
-- powershell: |
- choco install -y mingw --forcex86 --force --version=7.3.0
- refreshenv
- displayName: 'Install 32-bit mingw for 32-bit builds'
- condition: eq(variables['BITS'], 32)
# NOTE: for Windows builds it seems much more tractable to use runtests.py
# vs. manual setup.py and then runtests.py for testing only
- powershell: |
+ ls openblas
If ($(BITS) -eq 32) {
$env:CFLAGS = "-m32"
$env:LDFLAGS = "-m32"
$env:PATH = "C:\\ProgramData\\chocolatey\\lib\\mingw\\tools\\install\\mingw$(BITS)\\bin;" + $env:PATH
}
+ If ( Test-Path env:NPY_USE_BLAS_ILP64 ) {
+ $env:OPENBLAS64_ = "openblas"
+ } else {
+ $env:OPENBLAS = "openblas"
+ }
python -c "from tools import openblas_support; openblas_support.make_init('numpy')"
python -m pip wheel -v -v -v --no-build-isolation --no-use-pep517 --wheel-dir=dist .
diff --git a/benchmarks/README.rst b/benchmarks/README.rst
index f56c25339..2700e95e7 100644
--- a/benchmarks/README.rst
+++ b/benchmarks/README.rst
@@ -50,7 +50,7 @@ Compare change in benchmark results to another version/commit/branch::
python runtests.py --bench-compare v1.6.2 bench_core
python runtests.py --bench-compare 8bf4e9b bench_core
- python runtests.py --bench-compare master bench_core
+ python runtests.py --bench-compare main bench_core
All of the commands above display the results in plain text in
the console, and the results are not saved for comparison with
diff --git a/benchmarks/asv.conf.json b/benchmarks/asv.conf.json
index d9222d495..029adb589 100644
--- a/benchmarks/asv.conf.json
+++ b/benchmarks/asv.conf.json
@@ -35,7 +35,7 @@
// The Pythons you'd like to test against. If not provided, defaults
// to the current version of Python used to run `asv`.
- "pythons": ["3.7"],
+ // "pythons": ["3.9"],
// The matrix of dependencies to test. Each key is the name of a
// package (in PyPI) and the values are version numbers. An empty
diff --git a/benchmarks/asv_compare.conf.json.tpl b/benchmarks/asv_compare.conf.json.tpl
index 1f339077c..93d12d4a0 100644
--- a/benchmarks/asv_compare.conf.json.tpl
+++ b/benchmarks/asv_compare.conf.json.tpl
@@ -39,7 +39,7 @@
// The Pythons you'd like to test against. If not provided, defaults
// to the current version of Python used to run `asv`.
- "pythons": ["3.7"],
+ // "pythons": ["3.9"],
// The matrix of dependencies to test. Each key is the name of a
// package (in PyPI) and the values are version numbers. An empty
@@ -78,7 +78,9 @@
"build_command" : [
"python setup.py build {numpy_build_options}",
- "PIP_NO_BUILD_ISOLATION=false python -mpip wheel --no-deps --no-index -w {build_cache_dir} {build_dir}"
+ // pip ignores '--global-option' when pep517 is enabled, we also enabling pip verbose to
+ // be reached from asv `--verbose` so we can verify the build options.
+ "PIP_NO_BUILD_ISOLATION=false python {build_dir}/benchmarks/asv_pip_nopep517.py -v {numpy_global_options} --no-deps --no-index -w {build_cache_dir} {build_dir}"
],
// The commits after which the regression search in `asv publish`
// should start looking for regressions. Dictionary whose keys are
diff --git a/benchmarks/asv_pip_nopep517.py b/benchmarks/asv_pip_nopep517.py
new file mode 100644
index 000000000..9ba165493
--- /dev/null
+++ b/benchmarks/asv_pip_nopep517.py
@@ -0,0 +1,15 @@
+"""
+This file is used by asv_compare.conf.json.tpl.
+"""
+import subprocess, sys
+# pip ignores '--global-option' when pep517 is enabled therefore we disable it.
+cmd = [sys.executable, '-mpip', 'wheel', '--no-use-pep517']
+try:
+ output = subprocess.check_output(cmd, stderr=subprocess.STDOUT, universal_newlines=True)
+except Exception as e:
+ output = str(e.output)
+if "no such option" in output:
+ print("old version of pip, escape '--no-use-pep517'")
+ cmd.pop()
+
+subprocess.run(cmd + sys.argv[1:])
diff --git a/benchmarks/benchmarks/__init__.py b/benchmarks/benchmarks/__init__.py
index e4193cf05..7b9f1d3e6 100644
--- a/benchmarks/benchmarks/__init__.py
+++ b/benchmarks/benchmarks/__init__.py
@@ -1 +1,53 @@
from . import common
+import sys
+import os
+
+def show_cpu_features():
+ from numpy.lib.utils import _opt_info
+ info = _opt_info()
+ info = "NumPy CPU features: " + (info if info else 'nothing enabled')
+ # ASV wrapping stdout & stderr, so we assume having a tty here
+ if 'SHELL' in os.environ and sys.platform != 'win32':
+ # to avoid the red color that imposed by ASV
+ print(f"\033[33m{info}\033[0m")
+ else:
+ print(info)
+
+def dirty_lock(lock_name, lock_on_count=1):
+ # this lock occurred before each round to avoid duplicate printing
+ if not hasattr(os, "getppid"):
+ return False
+ ppid = os.getppid()
+ if not ppid or ppid == os.getpid():
+ # not sure if this gonna happen, but ASV run each round in
+ # a separate process so the lock should be based on the parent
+ # process id only
+ return False
+ lock_path = os.path.abspath(os.path.join(
+ os.path.dirname(__file__), "..", "env", lock_name)
+ )
+ # ASV load the 'benchmark_dir' to discovering the available benchmarks
+ # the issue here is ASV doesn't capture any strings from stdout or stderr
+ # during this stage so we escape it and lock on the second increment
+ try:
+ with open(lock_path, 'a+') as f:
+ f.seek(0)
+ count, _ppid = (f.read().split() + [0, 0])[:2]
+ count, _ppid = int(count), int(_ppid)
+ if _ppid == ppid:
+ if count >= lock_on_count:
+ return True
+ count += 1
+ else:
+ count = 0
+ f.seek(0)
+ f.truncate()
+ f.write(f"{str(count)} {str(ppid)}")
+ except IOError:
+ pass
+ return False
+
+
+# FIXME: there's no official way to provide extra information to the test log
+if not dirty_lock("print_cpu_features.lock"):
+ show_cpu_features()
diff --git a/benchmarks/benchmarks/bench_app.py b/benchmarks/benchmarks/bench_app.py
index bee95c201..d22aa2e09 100644
--- a/benchmarks/benchmarks/bench_app.py
+++ b/benchmarks/benchmarks/bench_app.py
@@ -70,8 +70,8 @@ class MaxesOfDots(Benchmark):
Arrays must agree only on the first dimension.
- For numpy it a join benchmark of dot products and max()
- on a set of arrays.
+ Numpy uses this as a simultaneous benchmark of 1) dot products
+ and 2) max(<array>, axis=<int>).
"""
feature_scores = ([0] * len(arrays))
for (i, sd) in enumerate(arrays):
diff --git a/benchmarks/benchmarks/bench_core.py b/benchmarks/benchmarks/bench_core.py
index 0c2a18c15..30647f4b8 100644
--- a/benchmarks/benchmarks/bench_core.py
+++ b/benchmarks/benchmarks/bench_core.py
@@ -93,6 +93,12 @@ class Core(Benchmark):
def time_tril_l10x10(self):
np.tril(self.l10x10)
+ def time_triu_indices_500(self):
+ np.triu_indices(500)
+
+ def time_tril_indices_500(self):
+ np.tril_indices(500)
+
class Temporaries(Benchmark):
def setup(self):
@@ -136,7 +142,7 @@ class CountNonzero(Benchmark):
params = [
[1, 2, 3],
[100, 10000, 1000000],
- [bool, int, str, object]
+ [bool, np.int8, np.int16, np.int32, np.int64, str, object]
]
def setup(self, numaxes, size, dtype):
@@ -165,6 +171,9 @@ class PackBits(Benchmark):
def time_packbits(self, dtype):
np.packbits(self.d)
+ def time_packbits_little(self, dtype):
+ np.packbits(self.d, bitorder="little")
+
def time_packbits_axis0(self, dtype):
np.packbits(self.d2, axis=0)
diff --git a/benchmarks/benchmarks/bench_function_base.py b/benchmarks/benchmarks/bench_function_base.py
index b1e592749..062843d10 100644
--- a/benchmarks/benchmarks/bench_function_base.py
+++ b/benchmarks/benchmarks/bench_function_base.py
@@ -47,6 +47,8 @@ class Median(Benchmark):
def setup(self):
self.e = np.arange(10000, dtype=np.float32)
self.o = np.arange(10001, dtype=np.float32)
+ self.tall = np.random.random((10000, 20))
+ self.wide = np.random.random((20, 10000))
def time_even(self):
np.median(self.e)
@@ -66,6 +68,12 @@ class Median(Benchmark):
def time_odd_small(self):
np.median(self.o[:500], overwrite_input=True)
+ def time_tall(self):
+ np.median(self.tall, axis=-1)
+
+ def time_wide(self):
+ np.median(self.wide, axis=0)
+
class Percentile(Benchmark):
def setup(self):
diff --git a/benchmarks/benchmarks/bench_lib.py b/benchmarks/benchmarks/bench_lib.py
index c22ceaa5e..f7884cd6c 100644
--- a/benchmarks/benchmarks/bench_lib.py
+++ b/benchmarks/benchmarks/bench_lib.py
@@ -53,6 +53,7 @@ class Pad(Benchmark):
def time_pad(self, shape, pad_width, mode):
np.pad(self.array, pad_width, mode)
+
class Nan(Benchmark):
"""Benchmarks for nan functions"""
@@ -113,3 +114,26 @@ class Nan(Benchmark):
def time_nanpercentile(self, array_size, percent_nans):
np.nanpercentile(self.arr, q=50)
+
+
+class Unique(Benchmark):
+ """Benchmark for np.unique with np.nan values."""
+
+ param_names = ["array_size", "percent_nans"]
+ params = [
+ # sizes of the 1D arrays
+ [200, int(2e5)],
+ # percent of np.nan in arrays
+ [0, 0.1, 2., 50., 90.],
+ ]
+
+ def setup(self, array_size, percent_nans):
+ np.random.seed(123)
+ # produce a randomly shuffled array with the
+ # approximate desired percentage np.nan content
+ base_array = np.random.uniform(size=array_size)
+ base_array[base_array < percent_nans / 100.] = np.nan
+ self.arr = base_array
+
+ def time_unique(self, array_size, percent_nans):
+ np.unique(self.arr)
diff --git a/benchmarks/benchmarks/bench_linalg.py b/benchmarks/benchmarks/bench_linalg.py
index a72cccb5f..5ed5b6eec 100644
--- a/benchmarks/benchmarks/bench_linalg.py
+++ b/benchmarks/benchmarks/bench_linalg.py
@@ -91,8 +91,8 @@ class Linalg(Benchmark):
# check that dtype is supported at all
try:
self.func(self.a[:2, :2])
- except TypeError:
- raise NotImplementedError()
+ except TypeError as e:
+ raise NotImplementedError() from e
def time_op(self, op, typename):
self.func(self.a)
diff --git a/benchmarks/benchmarks/bench_ufunc.py b/benchmarks/benchmarks/bench_ufunc.py
index 9f45a7257..b036581e1 100644
--- a/benchmarks/benchmarks/bench_ufunc.py
+++ b/benchmarks/benchmarks/bench_ufunc.py
@@ -134,6 +134,23 @@ class CustomScalar(Benchmark):
(self.d < 1)
+class CustomScalarFloorDivideInt(Benchmark):
+ params = (np.sctypes['int'] + np.sctypes['uint'], [8, -8, 43, -43])
+ param_names = ['dtype', 'divisors']
+
+ def setup(self, dtype, divisor):
+ if dtype in np.sctypes['uint'] and divisor < 0:
+ raise NotImplementedError(
+ "Skipping test for negative divisor with unsigned type")
+
+ iinfo = np.iinfo(dtype)
+ self.x = np.random.randint(
+ iinfo.min, iinfo.max, size=10000, dtype=dtype)
+
+ def time_floor_divide_int(self, dtype, divisor):
+ self.x // divisor
+
+
class Scalar(Benchmark):
def setup(self):
self.x = np.asarray(1.0)
diff --git a/benchmarks/benchmarks/bench_avx.py b/benchmarks/benchmarks/bench_ufunc_strides.py
index 82866c170..75aa510a6 100644
--- a/benchmarks/benchmarks/bench_avx.py
+++ b/benchmarks/benchmarks/bench_ufunc_strides.py
@@ -2,42 +2,34 @@ from .common import Benchmark
import numpy as np
-avx_ufuncs = ['sin',
- 'cos',
- 'exp',
- 'log',
- 'sqrt',
- 'absolute',
- 'reciprocal',
- 'square',
- 'rint',
- 'floor',
- 'ceil' ,
- 'trunc',
- 'frexp',
- 'isnan',
- 'isfinite',
- 'isinf',
- 'signbit']
+UNARY_UFUNCS = [obj for obj in np.core.umath.__dict__.values() if
+ isinstance(obj, np.ufunc)]
+UNARY_OBJECT_UFUNCS = [uf for uf in UNARY_UFUNCS if "O->O" in uf.types]
+UNARY_OBJECT_UFUNCS.remove(getattr(np, 'invert'))
+
stride = [1, 2, 4]
+stride_out = [1, 2, 4]
dtype = ['f', 'd']
-class AVX_UFunc(Benchmark):
- params = [avx_ufuncs, stride, dtype]
- param_names = ['avx_based_ufunc', 'stride', 'dtype']
+class Unary(Benchmark):
+ params = [UNARY_OBJECT_UFUNCS, stride, stride_out, dtype]
+ param_names = ['ufunc', 'stride_in', 'stride_out', 'dtype']
timeout = 10
- def setup(self, ufuncname, stride, dtype):
+ def setup(self, ufuncname, stride, stride_out, dtype):
np.seterr(all='ignore')
try:
- self.f = getattr(np, ufuncname)
+ self.f = ufuncname
except AttributeError:
- raise NotImplementedError()
- N = 10000
- self.arr = np.ones(stride*N, dtype)
+ raise NotImplementedError(f"No ufunc {ufuncname} found") from None
+ N = 100000
+ self.arr_out = np.empty(stride_out*N, dtype)
+ self.arr = np.random.rand(stride*N).astype(dtype)
+ if (ufuncname.__name__ == 'arccosh'):
+ self.arr = 1.0 + self.arr
- def time_ufunc(self, ufuncname, stride, dtype):
- self.f(self.arr[::stride])
+ def time_ufunc(self, ufuncname, stride, stride_out, dtype):
+ self.f(self.arr[::stride], self.arr_out[::stride_out])
class AVX_UFunc_log(Benchmark):
params = [stride, dtype]
@@ -66,7 +58,7 @@ class AVX_BFunc(Benchmark):
try:
self.f = getattr(np, ufuncname)
except AttributeError:
- raise NotImplementedError()
+ raise NotImplementedError(f"No ufunc {ufuncname} found") from None
N = 10000
self.arr1 = np.array(np.random.rand(stride*N), dtype=dtype)
self.arr2 = np.array(np.random.rand(stride*N), dtype=dtype)
@@ -107,7 +99,7 @@ class AVX_cmplx_arithmetic(Benchmark):
try:
self.f = getattr(np, bfuncname)
except AttributeError:
- raise NotImplementedError()
+ raise NotImplementedError(f"No bfunc {bfuncname} found") from None
N = 10000
self.arr1 = np.ones(stride*N, dtype)
self.arr2 = np.ones(stride*N, dtype)
@@ -130,7 +122,7 @@ class AVX_cmplx_funcs(Benchmark):
try:
self.f = getattr(np, bfuncname)
except AttributeError:
- raise NotImplementedError()
+ raise NotImplementedError(f"No bfunc {bfuncname} found") from None
N = 10000
self.arr1 = np.ones(stride*N, dtype)
diff --git a/benchmarks/benchmarks/common.py b/benchmarks/benchmarks/common.py
index b65cc5fd2..0c40e85b0 100644
--- a/benchmarks/benchmarks/common.py
+++ b/benchmarks/benchmarks/common.py
@@ -14,14 +14,14 @@ nx, ny = 1000, 1000
# time-consuming functions (ufunc, linalg, etc)
nxs, nys = 100, 100
-# a set of interesting types to test
+# a list of interesting types to test
TYPES1 = [
'int16', 'float16',
'int32', 'float32',
'int64', 'float64', 'complex64',
'longfloat', 'complex128',
]
-if 'complex256' in numpy.typeDict:
+if 'complex256' in numpy.sctypeDict:
TYPES1.append('complex256')
diff --git a/branding/logo/logoguidelines.md b/branding/logo/logoguidelines.md
index c674a9b37..0c37e3dd4 100644
--- a/branding/logo/logoguidelines.md
+++ b/branding/logo/logoguidelines.md
@@ -4,7 +4,7 @@ These guidelines are meant to help keep the NumPy logo consistent and recognizab
The primary logo is the horizontal option (logomark and text next to each other) and the secondary logo is the stacked version (logomark over text). I’ve also provided the logomark on its own (meaning it doesn’t have text). When in doubt, it’s preferable to use primary or secondary options over the logomark alone.
## Color
-The full color options are a combo of Maximum Blue (#4DABCF) and Han Blue (#4D77CF), while light options are white (#FFFFFF) and dark options Warm Black (#013243).
+The full color options are a combo of two shades of blue, rgb(77, 171, 207) and rgb(77, 119, 207), while light options are rgb(255, 255, 255) and dark options are rgb(1, 50, 67).
Whenever possible, use the full color logos. One color logos (light or dark) are to be used when full color will not have enough contrast, usually when logos must be on colored backgrounds.
@@ -15,4 +15,4 @@ Please do not make the primary logo smaller than 50px wide, secondary logo small
A few other notes to keep in mind when using the logo:
- Make sure to scale the logo proportionally.
- Maintain a good amount of space around the logo. Don’t let it overlap with text, images, or other elements.
-- Do not try and recreate or modify the logo. For example, do not use the logomark and then try to write NumPy in another font. \ No newline at end of file
+- Do not try and recreate or modify the logo. For example, do not use the logomark and then try to write NumPy in another font.
diff --git a/branding/logo/logomark/numpylogoicon.svg b/branding/logo/logomark/numpylogoicon.svg
index 4fef2a9c8..50810223b 100644
--- a/branding/logo/logomark/numpylogoicon.svg
+++ b/branding/logo/logomark/numpylogoicon.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"><defs><style>.cls-1{fill:#4dabcf;}.cls-2{fill:#4d77cf;}</style></defs><g id="Layer_1" data-name="Layer 1"><polygon class="cls-1" points="220.93 127.14 151.77 92.23 75.87 130.11 146.9 165.78 220.93 127.14"/><polygon class="cls-1" points="252.63 143.14 325.14 179.74 249.91 217.52 178.77 181.79 252.63 143.14"/><polygon class="cls-1" points="349.47 92.76 423.96 130.11 357.34 163.57 284.68 126.92 349.47 92.76"/><polygon class="cls-1" points="317.41 76.67 250.35 43.05 184.01 76.15 253.11 111 317.41 76.67"/><polygon class="cls-1" points="264.98 365.44 264.98 456.95 346.22 416.41 346.13 324.86 264.98 365.44"/><polygon class="cls-1" points="346.1 292.91 346.01 202.32 264.98 242.6 264.98 333.22 346.1 292.91"/><polygon class="cls-1" points="443.63 275.93 443.63 367.8 374.34 402.38 374.29 310.93 443.63 275.93"/><polygon class="cls-1" points="443.63 243.81 443.63 153.79 374.21 188.3 374.27 279.07 443.63 243.81"/><path class="cls-2" d="M236.3,242.6l-54.72-27.51V334s-66.92-142.39-73.12-155.18c-.8-1.65-4.09-3.46-4.93-3.9-12-6.3-47.16-24.11-47.16-24.11V360.89l48.64,26V277.08s66.21,127.23,66.88,128.62,7.32,14.8,14.42,19.51c9.46,6.26,50,30.64,50,30.64Z"/></g></svg> \ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"><defs><style>.cls-1{fill:rgb(77, 171, 207);}.cls-2{fill:rgb(77, 119, 207);}</style></defs><g id="Layer_1" data-name="Layer 1"><polygon class="cls-1" points="220.93 127.14 151.77 92.23 75.87 130.11 146.9 165.78 220.93 127.14"/><polygon class="cls-1" points="252.63 143.14 325.14 179.74 249.91 217.52 178.77 181.79 252.63 143.14"/><polygon class="cls-1" points="349.47 92.76 423.96 130.11 357.34 163.57 284.68 126.92 349.47 92.76"/><polygon class="cls-1" points="317.41 76.67 250.35 43.05 184.01 76.15 253.11 111 317.41 76.67"/><polygon class="cls-1" points="264.98 365.44 264.98 456.95 346.22 416.41 346.13 324.86 264.98 365.44"/><polygon class="cls-1" points="346.1 292.91 346.01 202.32 264.98 242.6 264.98 333.22 346.1 292.91"/><polygon class="cls-1" points="443.63 275.93 443.63 367.8 374.34 402.38 374.29 310.93 443.63 275.93"/><polygon class="cls-1" points="443.63 243.81 443.63 153.79 374.21 188.3 374.27 279.07 443.63 243.81"/><path class="cls-2" d="M236.3,242.6l-54.72-27.51V334s-66.92-142.39-73.12-155.18c-.8-1.65-4.09-3.46-4.93-3.9-12-6.3-47.16-24.11-47.16-24.11V360.89l48.64,26V277.08s66.21,127.23,66.88,128.62,7.32,14.8,14.42,19.51c9.46,6.26,50,30.64,50,30.64Z"/></g></svg> \ No newline at end of file
diff --git a/branding/logo/primary/numpylogo.svg b/branding/logo/primary/numpylogo.svg
index e5791dc3e..63d61c50f 100644
--- a/branding/logo/primary/numpylogo.svg
+++ b/branding/logo/primary/numpylogo.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 721.86 324.74"><defs><style>.cls-1{fill:#4d77cf;}.cls-2{fill:#4dabcf;}</style></defs><g id="Layer_1" data-name="Layer 1"><path class="cls-1" d="M299.23,125a5.76,5.76,0,0,1,1.62.45,5.58,5.58,0,0,1,1.38.93,17,17,0,0,1,1.49,1.62l41.51,52.47c-.17-1.67-.28-3.31-.36-4.88s-.12-3.07-.12-4.47V124.83h17.87v87.38H352.06a9.68,9.68,0,0,1-3.95-.72,8.47,8.47,0,0,1-3.12-2.64l-41.21-52c.13,1.51.22,3,.3,4.46s.13,2.83.13,4.11v46.84H286.33V124.83H297A17.21,17.21,0,0,1,299.23,125Z"/><path class="cls-1" d="M392,150v39.46q0,4.62,2.1,7.14a7.62,7.62,0,0,0,6.18,2.52,13.26,13.26,0,0,0,5.73-1.26,21.37,21.37,0,0,0,5.19-3.54V150h18.59v62.19H418.28a4.39,4.39,0,0,1-4.57-3.12l-1.13-3.6a37.32,37.32,0,0,1-3.72,3.16,23.32,23.32,0,0,1-4.11,2.39A24.55,24.55,0,0,1,400,212.6a25,25,0,0,1-5.51.57,21.75,21.75,0,0,1-9-1.77,18.67,18.67,0,0,1-6.63-4.94,21.68,21.68,0,0,1-4.08-7.5,31,31,0,0,1-1.38-9.48V150Z"/><path class="cls-1" d="M441.78,212.21V150H453.3a5.13,5.13,0,0,1,2.91.78,4.21,4.21,0,0,1,1.65,2.34l1,3.36a33.22,33.22,0,0,1,3.23-3,20.83,20.83,0,0,1,3.63-2.34,19.68,19.68,0,0,1,9.15-2.13,14.6,14.6,0,0,1,9.33,2.91,18.14,18.14,0,0,1,5.6,7.76,18.71,18.71,0,0,1,3.81-4.92,20.42,20.42,0,0,1,4.86-3.29,23.69,23.69,0,0,1,5.51-1.86,28.63,28.63,0,0,1,5.8-.6,26.3,26.3,0,0,1,9.47,1.59,18.05,18.05,0,0,1,6.93,4.62,20.15,20.15,0,0,1,4.23,7.44,32,32,0,0,1,1.44,10v39.52h-18.6V172.69q0-9.66-8.27-9.65a8.46,8.46,0,0,0-6.27,2.49q-2.49,2.47-2.49,7.16v39.52H477.65V172.69q0-5.34-2.1-7.5c-1.4-1.44-3.46-2.15-6.18-2.15a10.53,10.53,0,0,0-4.77,1.13,17.72,17.72,0,0,0-4.23,3.06v45Z"/><path class="cls-1" d="M562.93,183v29.21H542.66V124.83h30.82A50.86,50.86,0,0,1,589.35,127a30.49,30.49,0,0,1,10.91,6,23.36,23.36,0,0,1,6.33,9.06,30.63,30.63,0,0,1,2,11.27,33.11,33.11,0,0,1-2.1,12,24.08,24.08,0,0,1-6.42,9.36,30,30,0,0,1-10.94,6.08A49.9,49.9,0,0,1,573.48,183Zm0-15.29h10.55c5.28,0,9.08-1.25,11.4-3.78s3.48-6,3.48-10.55a15.79,15.79,0,0,0-.9-5.46,11.11,11.11,0,0,0-2.73-4.23,12.41,12.41,0,0,0-4.62-2.73,20.71,20.71,0,0,0-6.63-1H562.93Z"/><path class="cls-1" d="M644.61,228.35a6.69,6.69,0,0,1-2,2.72,6.62,6.62,0,0,1-3.84.87H624.82l12-25.18L612,150h16.43a5.25,5.25,0,0,1,3.36,1,5.15,5.15,0,0,1,1.68,2.28l10.19,26.81A59,59,0,0,1,646,187.5c.4-1.28.84-2.54,1.32-3.77s.94-2.5,1.38-3.78l9.24-26.69a4.5,4.5,0,0,1,1.89-2.31,5.4,5.4,0,0,1,3-.93h15Z"/><polygon class="cls-2" points="132.38 96.4 95.25 77.66 54.49 98 92.63 117.15 132.38 96.4"/><polygon class="cls-2" points="149.41 104.99 188.34 124.65 147.95 144.93 109.75 125.75 149.41 104.99"/><polygon class="cls-2" points="201.41 77.94 241.41 98 205.63 115.96 166.62 96.28 201.41 77.94"/><polygon class="cls-2" points="184.19 69.3 148.18 51.24 112.56 69.02 149.67 87.73 184.19 69.3"/><polygon class="cls-2" points="156.04 224.36 156.04 273.5 199.66 251.73 199.62 202.57 156.04 224.36"/><polygon class="cls-2" points="199.6 185.41 199.55 136.77 156.04 158.4 156.04 207.06 199.6 185.41"/><polygon class="cls-2" points="251.97 176.3 251.97 225.63 214.76 244.19 214.73 195.09 251.97 176.3"/><polygon class="cls-2" points="251.97 159.05 251.97 110.71 214.69 129.24 214.72 177.98 251.97 159.05"/><path class="cls-1" d="M140.64,158.4l-29.38-14.78v63.84S75.32,131,72,124.13c-.43-.89-2.19-1.86-2.64-2.1C62.88,118.65,44,109.09,44,109.09V221.92l26.12,14v-59s35.55,68.32,35.92,69.07,3.92,7.94,7.74,10.47c5.07,3.37,26.84,16.46,26.84,16.46Z"/></g></svg> \ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 721.86 324.74"><defs><style>.cls-1{fill:rgb(77, 119, 207);}.cls-2{fill:rgb(77, 171, 207);}</style></defs><g id="Layer_1" data-name="Layer 1"><path class="cls-1" d="M299.23,125a5.76,5.76,0,0,1,1.62.45,5.58,5.58,0,0,1,1.38.93,17,17,0,0,1,1.49,1.62l41.51,52.47c-.17-1.67-.28-3.31-.36-4.88s-.12-3.07-.12-4.47V124.83h17.87v87.38H352.06a9.68,9.68,0,0,1-3.95-.72,8.47,8.47,0,0,1-3.12-2.64l-41.21-52c.13,1.51.22,3,.3,4.46s.13,2.83.13,4.11v46.84H286.33V124.83H297A17.21,17.21,0,0,1,299.23,125Z"/><path class="cls-1" d="M392,150v39.46q0,4.62,2.1,7.14a7.62,7.62,0,0,0,6.18,2.52,13.26,13.26,0,0,0,5.73-1.26,21.37,21.37,0,0,0,5.19-3.54V150h18.59v62.19H418.28a4.39,4.39,0,0,1-4.57-3.12l-1.13-3.6a37.32,37.32,0,0,1-3.72,3.16,23.32,23.32,0,0,1-4.11,2.39A24.55,24.55,0,0,1,400,212.6a25,25,0,0,1-5.51.57,21.75,21.75,0,0,1-9-1.77,18.67,18.67,0,0,1-6.63-4.94,21.68,21.68,0,0,1-4.08-7.5,31,31,0,0,1-1.38-9.48V150Z"/><path class="cls-1" d="M441.78,212.21V150H453.3a5.13,5.13,0,0,1,2.91.78,4.21,4.21,0,0,1,1.65,2.34l1,3.36a33.22,33.22,0,0,1,3.23-3,20.83,20.83,0,0,1,3.63-2.34,19.68,19.68,0,0,1,9.15-2.13,14.6,14.6,0,0,1,9.33,2.91,18.14,18.14,0,0,1,5.6,7.76,18.71,18.71,0,0,1,3.81-4.92,20.42,20.42,0,0,1,4.86-3.29,23.69,23.69,0,0,1,5.51-1.86,28.63,28.63,0,0,1,5.8-.6,26.3,26.3,0,0,1,9.47,1.59,18.05,18.05,0,0,1,6.93,4.62,20.15,20.15,0,0,1,4.23,7.44,32,32,0,0,1,1.44,10v39.52h-18.6V172.69q0-9.66-8.27-9.65a8.46,8.46,0,0,0-6.27,2.49q-2.49,2.47-2.49,7.16v39.52H477.65V172.69q0-5.34-2.1-7.5c-1.4-1.44-3.46-2.15-6.18-2.15a10.53,10.53,0,0,0-4.77,1.13,17.72,17.72,0,0,0-4.23,3.06v45Z"/><path class="cls-1" d="M562.93,183v29.21H542.66V124.83h30.82A50.86,50.86,0,0,1,589.35,127a30.49,30.49,0,0,1,10.91,6,23.36,23.36,0,0,1,6.33,9.06,30.63,30.63,0,0,1,2,11.27,33.11,33.11,0,0,1-2.1,12,24.08,24.08,0,0,1-6.42,9.36,30,30,0,0,1-10.94,6.08A49.9,49.9,0,0,1,573.48,183Zm0-15.29h10.55c5.28,0,9.08-1.25,11.4-3.78s3.48-6,3.48-10.55a15.79,15.79,0,0,0-.9-5.46,11.11,11.11,0,0,0-2.73-4.23,12.41,12.41,0,0,0-4.62-2.73,20.71,20.71,0,0,0-6.63-1H562.93Z"/><path class="cls-1" d="M644.61,228.35a6.69,6.69,0,0,1-2,2.72,6.62,6.62,0,0,1-3.84.87H624.82l12-25.18L612,150h16.43a5.25,5.25,0,0,1,3.36,1,5.15,5.15,0,0,1,1.68,2.28l10.19,26.81A59,59,0,0,1,646,187.5c.4-1.28.84-2.54,1.32-3.77s.94-2.5,1.38-3.78l9.24-26.69a4.5,4.5,0,0,1,1.89-2.31,5.4,5.4,0,0,1,3-.93h15Z"/><polygon class="cls-2" points="132.38 96.4 95.25 77.66 54.49 98 92.63 117.15 132.38 96.4"/><polygon class="cls-2" points="149.41 104.99 188.34 124.65 147.95 144.93 109.75 125.75 149.41 104.99"/><polygon class="cls-2" points="201.41 77.94 241.41 98 205.63 115.96 166.62 96.28 201.41 77.94"/><polygon class="cls-2" points="184.19 69.3 148.18 51.24 112.56 69.02 149.67 87.73 184.19 69.3"/><polygon class="cls-2" points="156.04 224.36 156.04 273.5 199.66 251.73 199.62 202.57 156.04 224.36"/><polygon class="cls-2" points="199.6 185.41 199.55 136.77 156.04 158.4 156.04 207.06 199.6 185.41"/><polygon class="cls-2" points="251.97 176.3 251.97 225.63 214.76 244.19 214.73 195.09 251.97 176.3"/><polygon class="cls-2" points="251.97 159.05 251.97 110.71 214.69 129.24 214.72 177.98 251.97 159.05"/><path class="cls-1" d="M140.64,158.4l-29.38-14.78v63.84S75.32,131,72,124.13c-.43-.89-2.19-1.86-2.64-2.1C62.88,118.65,44,109.09,44,109.09V221.92l26.12,14v-59s35.55,68.32,35.92,69.07,3.92,7.94,7.74,10.47c5.07,3.37,26.84,16.46,26.84,16.46Z"/></g></svg> \ No newline at end of file
diff --git a/branding/logo/secondary/numpylogo2.svg b/branding/logo/secondary/numpylogo2.svg
index 76b076beb..20385487c 100644
--- a/branding/logo/secondary/numpylogo2.svg
+++ b/branding/logo/secondary/numpylogo2.svg
@@ -1 +1 @@
-<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"><defs><style>.cls-1{fill:#4d77cf;}.cls-2{fill:#4dabcf;}</style></defs><g id="Layer_1" data-name="Layer 1"><path class="cls-1" d="M69.36,351.63a5.46,5.46,0,0,1,1.59.44,5.58,5.58,0,0,1,1.37.92,17.85,17.85,0,0,1,1.48,1.6l41,51.84c-.16-1.66-.28-3.27-.36-4.82s-.12-3-.12-4.42V351.51H132v86.32H121.55a9.69,9.69,0,0,1-3.91-.71,8.35,8.35,0,0,1-3.08-2.61l-40.7-51.42q.18,2.25.3,4.41c.07,1.44.11,2.79.11,4.06v46.27H56.62V351.51H67.16A17,17,0,0,1,69.36,351.63Z"/><path class="cls-1" d="M161,376.39v39q0,4.56,2.07,7.05a7.54,7.54,0,0,0,6.11,2.49,13,13,0,0,0,5.65-1.25,21.12,21.12,0,0,0,5.13-3.49V376.39h18.37v61.44H187a4.31,4.31,0,0,1-4.5-3.08l-1.13-3.56a35.28,35.28,0,0,1-3.67,3.12,22.21,22.21,0,0,1-4.06,2.37,24.63,24.63,0,0,1-4.65,1.54,25.07,25.07,0,0,1-5.45.56,21.61,21.61,0,0,1-8.92-1.75,18.31,18.31,0,0,1-6.55-4.88,21.4,21.4,0,0,1-4-7.41,30.59,30.59,0,0,1-1.37-9.36v-39Z"/><path class="cls-1" d="M210.19,437.83V376.39h11.37a5.1,5.1,0,0,1,2.87.77,4.09,4.09,0,0,1,1.63,2.32l1,3.31a33.63,33.63,0,0,1,3.2-2.93A20,20,0,0,1,238,376a19.66,19.66,0,0,1,4.89-.56,14.39,14.39,0,0,1,9.21,2.87,17.82,17.82,0,0,1,5.54,7.67,18.28,18.28,0,0,1,3.77-4.86,20.07,20.07,0,0,1,4.79-3.25,22.73,22.73,0,0,1,5.45-1.84,28,28,0,0,1,5.72-.59,25.87,25.87,0,0,1,9.36,1.57,17.7,17.7,0,0,1,6.85,4.56,20,20,0,0,1,4.18,7.35,31.93,31.93,0,0,1,1.42,9.86v39H280.81v-39q0-9.54-8.18-9.54a8.4,8.4,0,0,0-6.19,2.46c-1.64,1.64-2.46,4-2.46,7.08v39H245.62v-39c0-3.52-.7-6-2.08-7.41s-3.42-2.13-6.1-2.13a10.4,10.4,0,0,0-4.71,1.12,17.42,17.42,0,0,0-4.18,3v44.43Z"/><path class="cls-1" d="M329.86,409v28.85h-20V351.51h30.45A50.26,50.26,0,0,1,356,353.67a30.21,30.21,0,0,1,10.79,6,23.05,23.05,0,0,1,6.24,8.95,30.12,30.12,0,0,1,2,11.13,32.77,32.77,0,0,1-2.07,11.85,23.87,23.87,0,0,1-6.34,9.24,29.85,29.85,0,0,1-10.82,6A49.24,49.24,0,0,1,340.29,409Zm0-15.11h10.43q7.81,0,11.26-3.73T355,379.71a15.67,15.67,0,0,0-.89-5.39,10.94,10.94,0,0,0-2.7-4.17,12,12,0,0,0-4.56-2.7,20.26,20.26,0,0,0-6.55-.95H329.86Z"/><path class="cls-1" d="M410.56,453.77a5.24,5.24,0,0,1-5.81,3.55H391l11.85-24.87-24.53-56.06h16.23a5.21,5.21,0,0,1,3.32.95,5.1,5.1,0,0,1,1.66,2.25l10.07,26.49a57.53,57.53,0,0,1,2.31,7.34c.4-1.26.83-2.51,1.3-3.73s.93-2.46,1.37-3.73l9.12-26.37a4.58,4.58,0,0,1,1.87-2.28,5.34,5.34,0,0,1,3-.92h14.81Z"/><polygon class="cls-2" points="229.82 96.34 181.83 72.11 129.15 98.4 178.44 123.16 229.82 96.34"/><polygon class="cls-2" points="251.82 107.45 302.15 132.85 249.94 159.07 200.56 134.27 251.82 107.45"/><polygon class="cls-2" points="319.04 72.48 370.73 98.4 324.5 121.63 274.07 96.19 319.04 72.48"/><polygon class="cls-2" points="296.78 61.32 250.24 37.98 204.2 60.95 252.16 85.14 296.78 61.32"/><polygon class="cls-2" points="260.39 261.73 260.39 325.25 316.78 297.11 316.72 233.57 260.39 261.73"/><polygon class="cls-2" points="316.7 211.39 316.63 148.52 260.39 176.47 260.39 239.37 316.7 211.39"/><polygon class="cls-2" points="384.39 199.61 384.39 263.37 336.3 287.37 336.26 223.9 384.39 199.61"/><polygon class="cls-2" points="384.39 177.31 384.39 114.84 336.21 138.79 336.25 201.78 384.39 177.31"/><path class="cls-1" d="M240.49,176.47l-38-19.09v82.5s-46.44-98.82-50.75-107.7c-.55-1.15-2.83-2.4-3.42-2.71-8.36-4.37-32.73-16.73-32.73-16.73V258.57l33.76,18.05V200.4s45.95,88.31,46.42,89.27,5.08,10.27,10,13.54c6.57,4.35,34.7,21.27,34.7,21.27Z"/></g></svg> \ No newline at end of file
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 500 500"><defs><style>.cls-1{fill:rgb(77, 119, 207);}.cls-2{fill:rgb(77, 171, 207);}</style></defs><g id="Layer_1" data-name="Layer 1"><path class="cls-1" d="M69.36,351.63a5.46,5.46,0,0,1,1.59.44,5.58,5.58,0,0,1,1.37.92,17.85,17.85,0,0,1,1.48,1.6l41,51.84c-.16-1.66-.28-3.27-.36-4.82s-.12-3-.12-4.42V351.51H132v86.32H121.55a9.69,9.69,0,0,1-3.91-.71,8.35,8.35,0,0,1-3.08-2.61l-40.7-51.42q.18,2.25.3,4.41c.07,1.44.11,2.79.11,4.06v46.27H56.62V351.51H67.16A17,17,0,0,1,69.36,351.63Z"/><path class="cls-1" d="M161,376.39v39q0,4.56,2.07,7.05a7.54,7.54,0,0,0,6.11,2.49,13,13,0,0,0,5.65-1.25,21.12,21.12,0,0,0,5.13-3.49V376.39h18.37v61.44H187a4.31,4.31,0,0,1-4.5-3.08l-1.13-3.56a35.28,35.28,0,0,1-3.67,3.12,22.21,22.21,0,0,1-4.06,2.37,24.63,24.63,0,0,1-4.65,1.54,25.07,25.07,0,0,1-5.45.56,21.61,21.61,0,0,1-8.92-1.75,18.31,18.31,0,0,1-6.55-4.88,21.4,21.4,0,0,1-4-7.41,30.59,30.59,0,0,1-1.37-9.36v-39Z"/><path class="cls-1" d="M210.19,437.83V376.39h11.37a5.1,5.1,0,0,1,2.87.77,4.09,4.09,0,0,1,1.63,2.32l1,3.31a33.63,33.63,0,0,1,3.2-2.93A20,20,0,0,1,238,376a19.66,19.66,0,0,1,4.89-.56,14.39,14.39,0,0,1,9.21,2.87,17.82,17.82,0,0,1,5.54,7.67,18.28,18.28,0,0,1,3.77-4.86,20.07,20.07,0,0,1,4.79-3.25,22.73,22.73,0,0,1,5.45-1.84,28,28,0,0,1,5.72-.59,25.87,25.87,0,0,1,9.36,1.57,17.7,17.7,0,0,1,6.85,4.56,20,20,0,0,1,4.18,7.35,31.93,31.93,0,0,1,1.42,9.86v39H280.81v-39q0-9.54-8.18-9.54a8.4,8.4,0,0,0-6.19,2.46c-1.64,1.64-2.46,4-2.46,7.08v39H245.62v-39c0-3.52-.7-6-2.08-7.41s-3.42-2.13-6.1-2.13a10.4,10.4,0,0,0-4.71,1.12,17.42,17.42,0,0,0-4.18,3v44.43Z"/><path class="cls-1" d="M329.86,409v28.85h-20V351.51h30.45A50.26,50.26,0,0,1,356,353.67a30.21,30.21,0,0,1,10.79,6,23.05,23.05,0,0,1,6.24,8.95,30.12,30.12,0,0,1,2,11.13,32.77,32.77,0,0,1-2.07,11.85,23.87,23.87,0,0,1-6.34,9.24,29.85,29.85,0,0,1-10.82,6A49.24,49.24,0,0,1,340.29,409Zm0-15.11h10.43q7.81,0,11.26-3.73T355,379.71a15.67,15.67,0,0,0-.89-5.39,10.94,10.94,0,0,0-2.7-4.17,12,12,0,0,0-4.56-2.7,20.26,20.26,0,0,0-6.55-.95H329.86Z"/><path class="cls-1" d="M410.56,453.77a5.24,5.24,0,0,1-5.81,3.55H391l11.85-24.87-24.53-56.06h16.23a5.21,5.21,0,0,1,3.32.95,5.1,5.1,0,0,1,1.66,2.25l10.07,26.49a57.53,57.53,0,0,1,2.31,7.34c.4-1.26.83-2.51,1.3-3.73s.93-2.46,1.37-3.73l9.12-26.37a4.58,4.58,0,0,1,1.87-2.28,5.34,5.34,0,0,1,3-.92h14.81Z"/><polygon class="cls-2" points="229.82 96.34 181.83 72.11 129.15 98.4 178.44 123.16 229.82 96.34"/><polygon class="cls-2" points="251.82 107.45 302.15 132.85 249.94 159.07 200.56 134.27 251.82 107.45"/><polygon class="cls-2" points="319.04 72.48 370.73 98.4 324.5 121.63 274.07 96.19 319.04 72.48"/><polygon class="cls-2" points="296.78 61.32 250.24 37.98 204.2 60.95 252.16 85.14 296.78 61.32"/><polygon class="cls-2" points="260.39 261.73 260.39 325.25 316.78 297.11 316.72 233.57 260.39 261.73"/><polygon class="cls-2" points="316.7 211.39 316.63 148.52 260.39 176.47 260.39 239.37 316.7 211.39"/><polygon class="cls-2" points="384.39 199.61 384.39 263.37 336.3 287.37 336.26 223.9 384.39 199.61"/><polygon class="cls-2" points="384.39 177.31 384.39 114.84 336.21 138.79 336.25 201.78 384.39 177.31"/><path class="cls-1" d="M240.49,176.47l-38-19.09v82.5s-46.44-98.82-50.75-107.7c-.55-1.15-2.83-2.4-3.42-2.71-8.36-4.37-32.73-16.73-32.73-16.73V258.57l33.76,18.05V200.4s45.95,88.31,46.42,89.27,5.08,10.27,10,13.54c6.57,4.35,34.7,21.27,34.7,21.27Z"/></g></svg> \ No newline at end of file
diff --git a/doc/DISTUTILS.rst.txt b/doc/DISTUTILS.rst.txt
index c58a423c0..539a3b9c1 100644
--- a/doc/DISTUTILS.rst.txt
+++ b/doc/DISTUTILS.rst.txt
@@ -472,7 +472,7 @@ by these modules during the build process are ready to be compiled. This
form of generic typing is also supported for C header files (preprocessed
to produce ``.h`` files).
-.. _conv_template.py: https://github.com/numpy/numpy/blob/master/numpy/distutils/conv_template.py
+.. _conv_template.py: https://github.com/numpy/numpy/blob/main/numpy/distutils/conv_template.py
Useful functions in ``numpy.distutils.misc_util``
-------------------------------------------------
diff --git a/doc/HOWTO_RELEASE.rst.txt b/doc/HOWTO_RELEASE.rst.txt
index 9dbee320c..37e047f9f 100644
--- a/doc/HOWTO_RELEASE.rst.txt
+++ b/doc/HOWTO_RELEASE.rst.txt
@@ -12,13 +12,12 @@ useful info can be found.
Source tree
-----------
- INSTALL.rst.txt
-- release.sh
- pavement.py
NumPy Docs
----------
-- https://github.com/numpy/numpy/blob/master/doc/HOWTO_RELEASE.rst.txt
+- https://github.com/numpy/numpy/blob/main/doc/HOWTO_RELEASE.rst.txt
SciPy.org wiki
@@ -35,7 +34,7 @@ Supported platforms and versions
================================
:ref:`NEP 29 <NEP29>` outlines which Python versions
are supported; For the first half of 2020, this will be Python >= 3.6. We test
-NumPy against all these versions every time we merge code to master. Binary
+NumPy against all these versions every time we merge code to main. Binary
installers may be available for a subset of these versions (see below).
OS X
@@ -69,8 +68,8 @@ reported.
Tool chain
==========
We build all our wheels on cloud infrastructure - so this list of compilers is
-for information and debugging builds locally. See the ``.travis.yml`` and
-``appveyor.yml`` scripts in the `numpy wheels`_ repo for the definitive source
+for information and debugging builds locally. See the ``.travis.yml`` script
+in the `numpy wheels`_ repo for the definitive source
of the build recipes. Packages that are available using pip are noted.
@@ -185,7 +184,7 @@ A typical release schedule is one beta, two release candidates and a final
release. It's best to discuss the timing on the mailing list first, in order
for people to get their commits in on time, get doc wiki edits merged, etc.
After a date is set, create a new maintenance/x.y.z branch, add new empty
-release notes for the next version in the master branch and update the Trac
+release notes for the next version in the main branch and update the Trac
Milestones.
@@ -194,11 +193,10 @@ Make sure current branch builds a package correctly
::
git clean -fxd
- python setup.py bdist
+ python setup.py bdist_wheel
python setup.py sdist
-To actually build the binaries after everything is set up correctly, the
-release.sh script can be used. For details of the build process itself, it is
+For details of the build process itself, it is
best to read the pavement.py script.
.. note:: The following steps are repeated for the beta(s), release
@@ -258,10 +256,8 @@ Check the release notes
Use `towncrier`_ to build the release note and
commit the changes. This will remove all the fragments from
``doc/release/upcoming_changes`` and add ``doc/release/<version>-note.rst``.
-Note that currently towncrier must be installed from its master branch as the
-last release (19.2.0) is outdated.
- towncrier --version "<version>"
+ towncrier build --version "<version>"
git commit -m"Create release note"
Check that the release notes are up-to-date.
@@ -275,14 +271,13 @@ following:
- for SciPy, supported NumPy version(s)
- outlook for the near future
-.. _towncrier: https://github.com/hawkowl/towncrier
+.. _towncrier: https://pypi.org/project/towncrier/
Update the release status and create a release "tag"
----------------------------------------------------
-Identify the commit hash of the release, e.g. 1b2e1d63ff.
+Identify the commit hash of the release, e.g. 1b2e1d63ff::
-::
git co 1b2e1d63ff # gives warning about detached head
First, change/check the following variables in ``pavement.py`` depending on the
@@ -336,8 +331,8 @@ to public keyservers, with a command such as::
gpg --send-keys <yourkeyid>
-Update the version of the master branch
----------------------------------------
+Update the version of the main branch
+-------------------------------------
Increment the release number in setup.py. Release candidates should have "rc1"
(or "rc2", "rcN") appended to the X.Y.Z format.
@@ -347,7 +342,7 @@ define NPY_x_y_API_VERSION in numpyconfig.h
Trigger the wheel builds
------------------------
-See the `MacPython/numpy wheels` repository.
+See the `numpy wheels`_ repository.
In that repository edit the files:
@@ -492,5 +487,5 @@ After the final release is announced, a few administrative tasks are left to be
done:
- Forward port changes in the release branch to release notes and release
- scripts, if any, to master branch.
+ scripts, if any, to main branch.
- Update the Milestones in Trac.
diff --git a/doc/Makefile b/doc/Makefile
index dd63702de..68d496389 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -49,7 +49,7 @@ help:
@echo " show to show the html output in a browser"
clean:
- -rm -rf build/*
+ -rm -rf build/*
find . -name generated -type d -prune -exec rm -rf "{}" ";"
gitwash-update:
@@ -66,7 +66,7 @@ gitwash-update:
# Build the current numpy version, and extract docs from it.
# We have to be careful of some issues:
-#
+#
# - Everything must be done using the same Python version
# - We must use eggs (otherwise they might override PYTHONPATH on import).
# - Different versions of easy_install install to different directories (!)
@@ -80,8 +80,7 @@ UPLOAD_DIR=/srv/docs_scipy_org/doc/numpy-$(RELEASE)
DIST_VARS=SPHINXBUILD="LANG=C PYTHONPATH=$(INSTALL_PPH) python$(PYVER) `which sphinx-build`" PYTHON="PYTHONPATH=$(INSTALL_PPH) python$(PYVER)"
NUMPYVER:=$(shell $(PYTHON) -c "import numpy; print(numpy.version.git_revision[:10])" 2>/dev/null)
-GITVER ?= $(shell cd ..; $(PYTHON) -c "from setup import git_version; \
- print(git_version()[:10])")
+GITVER ?= $(shell cd ..; $(PYTHON) -c "import versioneer as v; print(v.get_versions()['full-revisionid'][:10])")
version-check:
ifeq "$(GITVER)" "Unknown"
@@ -163,7 +162,7 @@ endif
@echo " <!-- insert here -->"
@echo in build/merge/index.html,
@echo then \"git commit\", \"git push\"
-
+
#------------------------------------------------------------------------------
# Basic Sphinx generation rules for different formats
diff --git a/doc/RELEASE_WALKTHROUGH.rst.txt b/doc/RELEASE_WALKTHROUGH.rst.txt
index 733f681af..6febd554f 100644
--- a/doc/RELEASE_WALKTHROUGH.rst.txt
+++ b/doc/RELEASE_WALKTHROUGH.rst.txt
@@ -29,7 +29,7 @@ appended to ``doc/release/1.19.0-notes.rst`` for patch release, though not for
new releases like ``1.19.0``, as the changelogs for ``*.0`` releases tend to be
excessively long. The ``doc/source/release.rst`` file should also be updated
with a link to the new release notes. These changes should be committed to the
-maintenance branch, and later will be forward ported to master. The changelog
+maintenance branch, and later will be forward ported to main. The changelog
should be reviewed for name duplicates or short names and the ``.mailmap`` file
updated if needed.
@@ -102,8 +102,8 @@ someone else, then create a new branch for the series. If the branch already
exists skip this::
$ cd ../numpy-wheels
- $ git co master
- $ git pull upstream master
+ $ git checkout main
+ $ git pull upstream main
$ git branch v1.19.x
Checkout the new branch and edit the ``azure-pipelines.yml`` and
@@ -252,6 +252,10 @@ work::
$ firefox doc/build/merge/index.html
+Update the stable link::
+
+ $ ln -sfn 1.19 stable
+
Once everything seems satisfactory, commit and upload the changes::
$ pushd doc/build/merge
@@ -288,7 +292,7 @@ python-announce-list is BCC so that replies will not be sent to that list.
Post-Release Tasks
------------------
-Checkout master and forward port the documentation changes::
+Checkout main and forward port the documentation changes::
$ git checkout -b post-1.19.0-release-update
$ git checkout maintenance/1.19.x doc/source/release/1.19.0-notes.rst
@@ -297,7 +301,7 @@ Checkout master and forward port the documentation changes::
$ gvim doc/source/release.rst # Add link to new notes
$ git add doc/changelog/1.19.0-changelog.rst doc/source/release/1.19.0-notes.rst
$ git status # check status before commit
- $ git commit -a -m"REL: Update master after 1.19.0 release."
+ $ git commit -a -m"REL: Update main after 1.19.0 release."
$ git push origin HEAD
Go to github and make a PR.
diff --git a/doc/TESTS.rst.txt b/doc/TESTS.rst.txt
index d1af7017b..ba09aa800 100644
--- a/doc/TESTS.rst.txt
+++ b/doc/TESTS.rst.txt
@@ -59,7 +59,7 @@ that are run; but if it is greater than 1, then the tests will also provide
warnings on missing tests. So if you want to run every test and get
messages about which modules don't have tests::
- >>> numpy.test(label='full', verbose=2) # or numpy.test('full', 2)
+ >>> numpy.test(label='full', verbose=2) # or numpy.test('full', 2)
Finally, if you are only interested in testing a subset of NumPy, for
example, the ``core`` module, use the following::
@@ -101,27 +101,39 @@ module called ``test_yyy.py``. If you only need to test one aspect of
``zzz``, you can simply add a test function::
def test_zzz():
- assert_(zzz() == 'Hello from zzz')
+ assert zzz() == 'Hello from zzz'
More often, we need to group a number of tests together, so we create
a test class::
- from numpy.testing import assert_, assert_raises
+ import pytest
# import xxx symbols
from numpy.xxx.yyy import zzz
+ import pytest
class TestZzz:
def test_simple(self):
- assert_(zzz() == 'Hello from zzz')
+ assert zzz() == 'Hello from zzz'
def test_invalid_parameter(self):
- assert_raises(...)
+ with pytest.raises(ValueError, match='.*some matching regex.*'):
+ ...
-Within these test methods, ``assert_()`` and related functions are used to test
+Within these test methods, ``assert`` and related functions are used to test
whether a certain assumption is valid. If the assertion fails, the test fails.
-Note that the Python builtin ``assert`` should not be used, because it is
-stripped during compilation with ``-O``.
+``pytest`` internally rewrites the ``assert`` statement to give informative
+output when it fails, so should be preferred over the legacy variant
+``numpy.testing.assert_``. Whereas plain ``assert`` statements are ignored
+when running Python in optimized mode with ``-O``, this is not an issue when
+running tests with pytest.
+
+Similarly, the pytest functions :func:`pytest.raises` and :func:`pytest.warns`
+should be preferred over their legacy counterparts
+:func:`numpy.testing.assert_raises` and :func:`numpy.testing.assert_warns`,
+since the pytest variants are more broadly used and allow more explicit
+targeting of warnings and errors when used with the ``match`` regex.
+
Note that ``test_`` functions or methods should not have a docstring, because
that makes it hard to identify the test from the output of running the test
@@ -145,7 +157,7 @@ can label it with ``pytest.mark.slow``::
@pytest.mark.slow
def test_big(self):
- print 'Big, slow test'
+ print('Big, slow test')
Similarly for methods::
@@ -162,21 +174,21 @@ name; thus::
def setup():
"""Module-level setup"""
- print 'doing setup'
+ print('doing setup')
def teardown():
"""Module-level teardown"""
- print 'doing teardown'
+ print('doing teardown')
class TestMe:
def setup():
"""Class-level setup"""
- print 'doing setup'
+ print('doing setup')
def teardown():
"""Class-level teardown"""
- print 'doing teardown'
+ print('doing teardown')
Setup and teardown functions to functions and methods are known as "fixtures",
@@ -187,7 +199,7 @@ Parametric tests
One very nice feature of testing is allowing easy testing across a range
of parameters - a nasty problem for standard unit tests. Use the
-``dec.paramaterize`` decorator.
+``pytest.mark.parametrize`` decorator.
Doctests
--------
@@ -278,16 +290,16 @@ minor variations, it can be helpful to create a base class containing
all the common tests, and then create a subclass for each variation.
Several examples of this technique exist in NumPy; below are excerpts
from one in `numpy/linalg/tests/test_linalg.py
-<https://github.com/numpy/numpy/blob/master/numpy/linalg/tests/test_linalg.py>`__::
+<https://github.com/numpy/numpy/blob/main/numpy/linalg/tests/test_linalg.py>`__::
class LinalgTestCase:
def test_single(self):
- a = array([[1.,2.], [3.,4.]], dtype=single)
+ a = array([[1., 2.], [3., 4.]], dtype=single)
b = array([2., 1.], dtype=single)
self.do(a, b)
def test_double(self):
- a = array([[1.,2.], [3.,4.]], dtype=double)
+ a = array([[1., 2.], [3., 4.]], dtype=double)
b = array([2., 1.], dtype=double)
self.do(a, b)
@@ -296,14 +308,14 @@ from one in `numpy/linalg/tests/test_linalg.py
class TestSolve(LinalgTestCase):
def do(self, a, b):
x = linalg.solve(a, b)
- assert_almost_equal(b, dot(a, x))
- assert_(imply(isinstance(b, matrix), isinstance(x, matrix)))
+ assert_allclose(b, dot(a, x))
+ assert imply(isinstance(b, matrix), isinstance(x, matrix))
class TestInv(LinalgTestCase):
def do(self, a, b):
a_inv = linalg.inv(a)
- assert_almost_equal(dot(a, a_inv), identity(asarray(a).shape[0]))
- assert_(imply(isinstance(a, matrix), isinstance(a_inv, matrix)))
+ assert_allclose(dot(a, a_inv), identity(asarray(a).shape[0]))
+ assert imply(isinstance(a, matrix), isinstance(a_inv, matrix))
In this case, we wanted to test solving a linear algebra problem using
matrices of several data types, using ``linalg.solve`` and
diff --git a/doc/changelog/1.17.0-changelog.rst b/doc/changelog/1.17.0-changelog.rst
index 4177c848f..8179c180b 100644
--- a/doc/changelog/1.17.0-changelog.rst
+++ b/doc/changelog/1.17.0-changelog.rst
@@ -159,7 +159,7 @@ names contributed a patch for the first time.
Pull requests merged
====================
-A total of 531 pull requests were merged for this release.
+A total of 532 pull requests were merged for this release.
* `#4808 <https://github.com/numpy/numpy/pull/4808>`__: ENH: Make the `mode` parameter of np.pad default to 'constant'
* `#8131 <https://github.com/numpy/numpy/pull/8131>`__: BUG: Fix help() formatting for deprecated functions.
@@ -174,6 +174,7 @@ A total of 531 pull requests were merged for this release.
* `#10855 <https://github.com/numpy/numpy/pull/10855>`__: ENH: Adding a count parameter to np.unpackbits
* `#11230 <https://github.com/numpy/numpy/pull/11230>`__: MAINT: More cleanup of einsum
* `#11233 <https://github.com/numpy/numpy/pull/11233>`__: BUG: ensure i0 does not change the shape.
+* `#11358 <https://github.com/numpy/numpy/pull/11358>`__: MAINT: Rewrite numpy.pad without concatenate
* `#11684 <https://github.com/numpy/numpy/pull/11684>`__: BUG: Raise when unravel_index, ravel_multi_index are given empty...
* `#11689 <https://github.com/numpy/numpy/pull/11689>`__: DOC: Add ref docs for C generic types.
* `#11721 <https://github.com/numpy/numpy/pull/11721>`__: BUG: Make `arr.ctypes.data` hold onto a reference to the underlying...
diff --git a/doc/changelog/1.18.0-changelog.rst b/doc/changelog/1.18.0-changelog.rst
index b86b3614a..266ff0807 100644
--- a/doc/changelog/1.18.0-changelog.rst
+++ b/doc/changelog/1.18.0-changelog.rst
@@ -123,20 +123,20 @@ names contributed a patch for the first time.
Pull requests merged
====================
-A total of 406 pull requests were merged for this release.
+A total of 413 pull requests were merged for this release.
* `#9301 <https://github.com/numpy/numpy/pull/9301>`__: DOC: added note to docstring of numpy.savez
* `#10151 <https://github.com/numpy/numpy/pull/10151>`__: BUG: Numpy scalar types sometimes have the same name
* `#12129 <https://github.com/numpy/numpy/pull/12129>`__: DOC: Improve axes shift description and example in np.tensordot
-* `#12205 <https://github.com/numpy/numpy/pull/12205>`__: MAINT: avoid relying on `np.generic.__name__` in `np.dtype.name`
+* `#12205 <https://github.com/numpy/numpy/pull/12205>`__: MAINT: avoid relying on ``np.generic.__name__`` in ``np.dtype.name``
* `#12284 <https://github.com/numpy/numpy/pull/12284>`__: ENH: supply our version of numpy.pxd, requires cython>=0.29
* `#12633 <https://github.com/numpy/numpy/pull/12633>`__: BUG: General fixes to f2py reference counts (dereferencing)
* `#12658 <https://github.com/numpy/numpy/pull/12658>`__: BUG: NaT now sorts to ends of arrays
* `#12828 <https://github.com/numpy/numpy/pull/12828>`__: DOC: Updates to nditer usage instructions
-* `#13003 <https://github.com/numpy/numpy/pull/13003>`__: BUG: Do not crash on recursive `.dtype` attribute lookup.
+* `#13003 <https://github.com/numpy/numpy/pull/13003>`__: BUG: Do not crash on recursive ``.dtype`` attribute lookup.
* `#13368 <https://github.com/numpy/numpy/pull/13368>`__: ENH: Use AVX for float32 implementation of np.sin & np.cos
* `#13605 <https://github.com/numpy/numpy/pull/13605>`__: DEP: Deprecate silent ignoring of bad data in fromfile/fromstring
-* `#13610 <https://github.com/numpy/numpy/pull/13610>`__: ENH: Always produce a consistent shape in the result of `argwhere`
+* `#13610 <https://github.com/numpy/numpy/pull/13610>`__: ENH: Always produce a consistent shape in the result of ``argwhere``
* `#13673 <https://github.com/numpy/numpy/pull/13673>`__: DOC: array(obj, dtype=dt) can downcast
* `#13698 <https://github.com/numpy/numpy/pull/13698>`__: DOC: Document ma.filled behavior with non-scalar fill_value
* `#13710 <https://github.com/numpy/numpy/pull/13710>`__: DOC: Add note to irfft-like functions about the default sizes
@@ -144,6 +144,7 @@ A total of 406 pull requests were merged for this release.
* `#13766 <https://github.com/numpy/numpy/pull/13766>`__: MAINT: Update NEP template.
* `#13794 <https://github.com/numpy/numpy/pull/13794>`__: ENH: random: Add the multivariate hypergeometric distribution.
* `#13799 <https://github.com/numpy/numpy/pull/13799>`__: DOC: Fix unrendered links
+* `#13802 <https://github.com/numpy/numpy/pull/13802>`__: BUG: Fixed maximum relative error reporting in assert_allclose
* `#13812 <https://github.com/numpy/numpy/pull/13812>`__: MAINT: Rewrite Floyd algorithm
* `#13825 <https://github.com/numpy/numpy/pull/13825>`__: DOC: Add missing macros to C-API documentation
* `#13829 <https://github.com/numpy/numpy/pull/13829>`__: ENH: Add axis argument to random.permutation and random.shuffle
@@ -162,6 +163,7 @@ A total of 406 pull requests were merged for this release.
* `#13892 <https://github.com/numpy/numpy/pull/13892>`__: DOC : Refactor Array API documentation -- Array Structure and...
* `#13895 <https://github.com/numpy/numpy/pull/13895>`__: DOC: Fix typo in "make_mask" documentation
* `#13896 <https://github.com/numpy/numpy/pull/13896>`__: MAINT: Delete unused _aliased_types.py
+* `#13899 <https://github.com/numpy/numpy/pull/13899>`__: MAINT: Change the type of error raised in set_printoptions
* `#13901 <https://github.com/numpy/numpy/pull/13901>`__: BLD: Remove Trusty dist in Travis CI build
* `#13907 <https://github.com/numpy/numpy/pull/13907>`__: BUG: Handle weird bytestrings in dtype()
* `#13908 <https://github.com/numpy/numpy/pull/13908>`__: ENH: use towncrier to build the release note
@@ -174,7 +176,7 @@ A total of 406 pull requests were merged for this release.
* `#13926 <https://github.com/numpy/numpy/pull/13926>`__: DOC: Remove explicit .next method calls with built-in next function...
* `#13928 <https://github.com/numpy/numpy/pull/13928>`__: DOC: Don't override MaskedArray.view documentation with the one...
* `#13930 <https://github.com/numpy/numpy/pull/13930>`__: BUG: Fix incorrect GIL release in array.nonzero
-* `#13935 <https://github.com/numpy/numpy/pull/13935>`__: MAINT: Warn if `_add_newdocs.py` is used to add docstrings to...
+* `#13935 <https://github.com/numpy/numpy/pull/13935>`__: MAINT: Warn if ``_add_newdocs.py`` is used to add docstrings to...
* `#13943 <https://github.com/numpy/numpy/pull/13943>`__: MAINT: Revert #13876, "MAINT,BUG,DOC: Fix errors in _add_newdocs"
* `#13944 <https://github.com/numpy/numpy/pull/13944>`__: MAINT,BUG,DOC: Fix errors in _add_newdocs
* `#13945 <https://github.com/numpy/numpy/pull/13945>`__: DOC, MAINT: emphasize random API changes, remove Generator.randint
@@ -184,7 +186,7 @@ A total of 406 pull requests were merged for this release.
* `#13950 <https://github.com/numpy/numpy/pull/13950>`__: Fixing failure on Python 2.7 on Windows 7
* `#13952 <https://github.com/numpy/numpy/pull/13952>`__: Fix a typo related to the range of indices
* `#13959 <https://github.com/numpy/numpy/pull/13959>`__: DOC: add space between words across lines
-* `#13964 <https://github.com/numpy/numpy/pull/13964>`__: BUG, DOC: add new recfunctions to `__all__`
+* `#13964 <https://github.com/numpy/numpy/pull/13964>`__: BUG, DOC: add new recfunctions to ``__all__``
* `#13967 <https://github.com/numpy/numpy/pull/13967>`__: DOC: Change (old) range() to np.arange()
* `#13968 <https://github.com/numpy/numpy/pull/13968>`__: DOC: improve np.sort docstring
* `#13970 <https://github.com/numpy/numpy/pull/13970>`__: DOC: spellcheck numpy/doc/broadcasting.py
@@ -226,7 +228,7 @@ A total of 406 pull requests were merged for this release.
* `#14076 <https://github.com/numpy/numpy/pull/14076>`__: TST: Add 3.8-dev to travisCI testing.
* `#14085 <https://github.com/numpy/numpy/pull/14085>`__: DOC: Add blank line above doctest for intersect1d
* `#14086 <https://github.com/numpy/numpy/pull/14086>`__: ENH: Propose standard policy for dropping support of old Python...
-* `#14089 <https://github.com/numpy/numpy/pull/14089>`__: DOC: Use `pip install .` where possible instead of calling setup.py
+* `#14089 <https://github.com/numpy/numpy/pull/14089>`__: DOC: Use ``pip install .`` where possible instead of calling setup.py
* `#14091 <https://github.com/numpy/numpy/pull/14091>`__: MAINT: adjustments to test_ufunc_noncontigous
* `#14092 <https://github.com/numpy/numpy/pull/14092>`__: MAINT: Improve NEP template
* `#14096 <https://github.com/numpy/numpy/pull/14096>`__: DOC: fix documentation of i and j for tri.
@@ -236,6 +238,7 @@ A total of 406 pull requests were merged for this release.
* `#14106 <https://github.com/numpy/numpy/pull/14106>`__: MAINT: remove duplicate variable assignments
* `#14108 <https://github.com/numpy/numpy/pull/14108>`__: BUG: initialize variable that is passed by pointer
* `#14110 <https://github.com/numpy/numpy/pull/14110>`__: DOC: fix typo in c-api/array.rst doc
+* `#14115 <https://github.com/numpy/numpy/pull/14115>`__: DOC: fix markup of news fragment readme
* `#14121 <https://github.com/numpy/numpy/pull/14121>`__: BUG: Add gcd/lcm definitions to npy_math.h
* `#14122 <https://github.com/numpy/numpy/pull/14122>`__: MAINT: Mark umath accuracy test xfail.
* `#14124 <https://github.com/numpy/numpy/pull/14124>`__: MAINT: Use equality instead of identity check with literal
@@ -249,36 +252,39 @@ A total of 406 pull requests were merged for this release.
* `#14153 <https://github.com/numpy/numpy/pull/14153>`__: TST: Allow fuss in testing strided/non-strided exp/log loops
* `#14170 <https://github.com/numpy/numpy/pull/14170>`__: NEP: Proposal for __duckarray__ protocol
* `#14171 <https://github.com/numpy/numpy/pull/14171>`__: BUG: Make advanced indexing result on read-only subclass writeable
+* `#14174 <https://github.com/numpy/numpy/pull/14174>`__: BUG: Check for existence of ``fromstr`` which used in ``fromstr_next_element``
* `#14178 <https://github.com/numpy/numpy/pull/14178>`__: TST: Clean up of test_pocketfft.py
* `#14181 <https://github.com/numpy/numpy/pull/14181>`__: DEP: Deprecate np.alen
+* `#14183 <https://github.com/numpy/numpy/pull/14183>`__: DOC: Fix misleading ``allclose`` docstring for ``equal_nan``
* `#14185 <https://github.com/numpy/numpy/pull/14185>`__: MAINT: Workaround for Intel compiler bug leading to failing test
-* `#14190 <https://github.com/numpy/numpy/pull/14190>`__: DOC: Fix hermitian argument docs in `svd`
+* `#14190 <https://github.com/numpy/numpy/pull/14190>`__: DOC: Fix hermitian argument docs in ``svd``
* `#14195 <https://github.com/numpy/numpy/pull/14195>`__: MAINT: Fix a docstring typo.
-* `#14196 <https://github.com/numpy/numpy/pull/14196>`__: DOC: Fix links in `/.github/CONTRIBUTING.md`.
+* `#14196 <https://github.com/numpy/numpy/pull/14196>`__: DOC: Fix links in ``/.github/CONTRIBUTING.md``.
* `#14197 <https://github.com/numpy/numpy/pull/14197>`__: ENH: Multivariate normal speedups
* `#14203 <https://github.com/numpy/numpy/pull/14203>`__: MAINT: Improve mismatch message of np.testing.assert_array_equal
* `#14204 <https://github.com/numpy/numpy/pull/14204>`__: DOC,MAINT: Move towncrier files and fixup categories
* `#14207 <https://github.com/numpy/numpy/pull/14207>`__: BUG: Fixed default BitGenerator name
* `#14209 <https://github.com/numpy/numpy/pull/14209>`__: BUG: Fix uint-overflow if padding with linear_ramp and negative...
* `#14216 <https://github.com/numpy/numpy/pull/14216>`__: ENH: Enable huge pages in all Linux builds
-* `#14217 <https://github.com/numpy/numpy/pull/14217>`__: BUG: Fix leak in the f2py-generated module init and `PyMem_Del`...
+* `#14217 <https://github.com/numpy/numpy/pull/14217>`__: BUG: Fix leak in the f2py-generated module init and ``PyMem_Del``...
* `#14219 <https://github.com/numpy/numpy/pull/14219>`__: DOC: new nan_to_num keywords are from 1.17 onwards
* `#14223 <https://github.com/numpy/numpy/pull/14223>`__: TST: Add tests for deprecated C functions (PyArray_As1D, PyArray_As1D)
-* `#14224 <https://github.com/numpy/numpy/pull/14224>`__: DOC: mention `take_along_axis` in `choose`
+* `#14224 <https://github.com/numpy/numpy/pull/14224>`__: DOC: mention ``take_along_axis`` in ``choose``
* `#14227 <https://github.com/numpy/numpy/pull/14227>`__: ENH: Parse complex number from string
* `#14231 <https://github.com/numpy/numpy/pull/14231>`__: DOC: update or remove outdated sourceforge links
* `#14234 <https://github.com/numpy/numpy/pull/14234>`__: MAINT: Better error message for norm
* `#14235 <https://github.com/numpy/numpy/pull/14235>`__: DOC: add backlinks to numpy.org
* `#14240 <https://github.com/numpy/numpy/pull/14240>`__: BUG: Don't fail when lexsorting some empty arrays.
-* `#14241 <https://github.com/numpy/numpy/pull/14241>`__: BUG: Fix segfault in `random.permutation(x)` when x is a string.
+* `#14241 <https://github.com/numpy/numpy/pull/14241>`__: BUG: Fix segfault in ``random.permutation(x)`` when x is a string.
* `#14245 <https://github.com/numpy/numpy/pull/14245>`__: Doc: fix a typo in NEP21
* `#14249 <https://github.com/numpy/numpy/pull/14249>`__: DOC: set status of NEP 28 (website redesign) to Accepted
* `#14250 <https://github.com/numpy/numpy/pull/14250>`__: BLD: MAINT: change default behavior of build flag appending.
* `#14252 <https://github.com/numpy/numpy/pull/14252>`__: BUG: Fixes StopIteration error from 'np.genfromtext' for empty...
-* `#14255 <https://github.com/numpy/numpy/pull/14255>`__: BUG: fix inconsistent axes ordering for axis in function `unique`
+* `#14255 <https://github.com/numpy/numpy/pull/14255>`__: BUG: fix inconsistent axes ordering for axis in function ``unique``
* `#14256 <https://github.com/numpy/numpy/pull/14256>`__: DEP: Deprecate load/dump functions in favour of pickle methods
* `#14257 <https://github.com/numpy/numpy/pull/14257>`__: MAINT: Update NEP-30
* `#14259 <https://github.com/numpy/numpy/pull/14259>`__: DEP: Deprecate arrayprint formatting functions
+* `#14263 <https://github.com/numpy/numpy/pull/14263>`__: DOC: Make Py3K docs C code snippets RST literal blocks
* `#14266 <https://github.com/numpy/numpy/pull/14266>`__: DOC: remove scipy.org from the breadcrumb formattiong
* `#14270 <https://github.com/numpy/numpy/pull/14270>`__: BUG: Fix formatting error in exception message
* `#14272 <https://github.com/numpy/numpy/pull/14272>`__: DOC: Address typos in dispatch docs
@@ -293,9 +299,9 @@ A total of 406 pull requests were merged for this release.
* `#14313 <https://github.com/numpy/numpy/pull/14313>`__: DOC: Clarify rules about broadcasting when empty arrays are involved.
* `#14321 <https://github.com/numpy/numpy/pull/14321>`__: TST, MAINT: bump to OpenBLAS 0.3.7 stable
* `#14325 <https://github.com/numpy/numpy/pull/14325>`__: DEP: numpy.testing.rand
-* `#14335 <https://github.com/numpy/numpy/pull/14335>`__: DEP: Deprecate class `SafeEval`
+* `#14335 <https://github.com/numpy/numpy/pull/14335>`__: DEP: Deprecate class ``SafeEval``
* `#14341 <https://github.com/numpy/numpy/pull/14341>`__: BUG: revert detecting and raising error on ragged arrays
-* `#14342 <https://github.com/numpy/numpy/pull/14342>`__: DOC: Improve documentation of `isscalar`.
+* `#14342 <https://github.com/numpy/numpy/pull/14342>`__: DOC: Improve documentation of ``isscalar``.
* `#14349 <https://github.com/numpy/numpy/pull/14349>`__: MAINT: Fix bloated mismatch error percentage in array comparisons.
* `#14351 <https://github.com/numpy/numpy/pull/14351>`__: DOC: Fix a minor typo in dispatch documentation.
* `#14352 <https://github.com/numpy/numpy/pull/14352>`__: MAINT: Remove redundant deprecation checks
@@ -344,7 +350,7 @@ A total of 406 pull requests were merged for this release.
* `#14475 <https://github.com/numpy/numpy/pull/14475>`__: DOC: add timedelta64 signature
* `#14477 <https://github.com/numpy/numpy/pull/14477>`__: MAINT: Extract raising of MemoryError to a helper function
* `#14483 <https://github.com/numpy/numpy/pull/14483>`__: BUG,MAINT: Some fixes and minor cleanup based on clang analysis
-* `#14484 <https://github.com/numpy/numpy/pull/14484>`__: MAINT: Add `NPY_UNUSED` and `const` qualified suggested by clang
+* `#14484 <https://github.com/numpy/numpy/pull/14484>`__: MAINT: Add ``NPY_UNUSED`` and ``const`` qualified suggested by clang
* `#14485 <https://github.com/numpy/numpy/pull/14485>`__: MAINT: Silence integer comparison build warnings in assert statements
* `#14486 <https://github.com/numpy/numpy/pull/14486>`__: MAINT: distutils: Add newline at the end of printed warnings.
* `#14490 <https://github.com/numpy/numpy/pull/14490>`__: BUG: random: Revert gh-14458 and refix gh-14557.
@@ -383,7 +389,7 @@ A total of 406 pull requests were merged for this release.
* `#14567 <https://github.com/numpy/numpy/pull/14567>`__: DEP: remove deprecated (and private) numpy.testing submodules.
* `#14568 <https://github.com/numpy/numpy/pull/14568>`__: BLD, DOC: fix gh-14518, add release note
* `#14570 <https://github.com/numpy/numpy/pull/14570>`__: BUG: importing build_src breaks setuptools monkeypatch for msvc14
-* `#14572 <https://github.com/numpy/numpy/pull/14572>`__: DOC: Note runtests.py `-- -s` method to use pytests `-s`
+* `#14572 <https://github.com/numpy/numpy/pull/14572>`__: DOC: Note runtests.py ``-- -s`` method to use pytests ``-s``
* `#14573 <https://github.com/numpy/numpy/pull/14573>`__: DOC: update submodule docstrings, remove info.py files
* `#14576 <https://github.com/numpy/numpy/pull/14576>`__: DOC: Document the NPY_SCALARKIND values as C variables.
* `#14582 <https://github.com/numpy/numpy/pull/14582>`__: MAINT: Bump pytest from 5.1.2 to 5.1.3
@@ -405,30 +411,31 @@ A total of 406 pull requests were merged for this release.
* `#14614 <https://github.com/numpy/numpy/pull/14614>`__: MAINT: Bump pytest from 5.1.3 to 5.2.0
* `#14615 <https://github.com/numpy/numpy/pull/14615>`__: MAINT: Add "MAINT" tag to dependabot commit msg
* `#14616 <https://github.com/numpy/numpy/pull/14616>`__: DOC: Updated sphinx directive formatting
-* `#14620 <https://github.com/numpy/numpy/pull/14620>`__: DEP: Finish deprecation of non-integer `num` in linspace
+* `#14620 <https://github.com/numpy/numpy/pull/14620>`__: DEP: Finish deprecation of non-integer ``num`` in linspace
* `#14621 <https://github.com/numpy/numpy/pull/14621>`__: DOC: s/OR/AND/ in np.logical_and docstring
* `#14623 <https://github.com/numpy/numpy/pull/14623>`__: DOC: misleading np.sinc() documentation
* `#14629 <https://github.com/numpy/numpy/pull/14629>`__: DOC: clarify residual in np.polyfit
* `#14630 <https://github.com/numpy/numpy/pull/14630>`__: BUILD: change to build_src --verbose-cfg, runtests.py --debug-info
* `#14631 <https://github.com/numpy/numpy/pull/14631>`__: BUG: always free clean_sep
-* `#14634 <https://github.com/numpy/numpy/pull/14634>`__: DOC: Create `class Extension` docstring and add it to documentation.
-* `#14636 <https://github.com/numpy/numpy/pull/14636>`__: DOC: add `printoptions` as a context manager to `set_printoptions`
+* `#14634 <https://github.com/numpy/numpy/pull/14634>`__: DOC: Create ``class Extension`` docstring and add it to documentation.
+* `#14636 <https://github.com/numpy/numpy/pull/14636>`__: DOC: add ``printoptions`` as a context manager to ``set_printoptions``
* `#14639 <https://github.com/numpy/numpy/pull/14639>`__: DOC: Fix typo in NEP 29
* `#14643 <https://github.com/numpy/numpy/pull/14643>`__: MAINT: Use scalar math power function directly
* `#14649 <https://github.com/numpy/numpy/pull/14649>`__: DOC: Add IPython to dependencies needed to build docs.
* `#14652 <https://github.com/numpy/numpy/pull/14652>`__: MAINT: Bump pytest-cov from 2.7.1 to 2.8.1
* `#14653 <https://github.com/numpy/numpy/pull/14653>`__: MAINT: Bump pytest from 5.2.0 to 5.2.1
* `#14654 <https://github.com/numpy/numpy/pull/14654>`__: MAINT: Bump pytz from 2019.2 to 2019.3
-* `#14656 <https://github.com/numpy/numpy/pull/14656>`__: MAINT: Use `extract_unit` throughout datetime
+* `#14656 <https://github.com/numpy/numpy/pull/14656>`__: MAINT: Use ``extract_unit`` throughout datetime
* `#14657 <https://github.com/numpy/numpy/pull/14657>`__: BUG: fix fromfile behavior when reading sub-array dtypes
* `#14662 <https://github.com/numpy/numpy/pull/14662>`__: BUG: random: Use correct length when axis is given to shuffle.
* `#14669 <https://github.com/numpy/numpy/pull/14669>`__: BUG: Do not rely on undefined behaviour to cast from float to...
* `#14674 <https://github.com/numpy/numpy/pull/14674>`__: NEP: add default-dtype-object-deprecation nep 34
* `#14681 <https://github.com/numpy/numpy/pull/14681>`__: MAINT: Remove unused boolean negative/subtract loops
-* `#14682 <https://github.com/numpy/numpy/pull/14682>`__: DEP: ufunc `out` argument must be a tuple for multiple outputs
-* `#14693 <https://github.com/numpy/numpy/pull/14693>`__: BUG: Fix `np.einsum` errors on Power9 Linux and z/Linux
+* `#14682 <https://github.com/numpy/numpy/pull/14682>`__: DEP: ufunc ``out`` argument must be a tuple for multiple outputs
+* `#14693 <https://github.com/numpy/numpy/pull/14693>`__: BUG: Fix ``np.einsum`` errors on Power9 Linux and z/Linux
* `#14696 <https://github.com/numpy/numpy/pull/14696>`__: DOC: Note release notes process changes on devdocs start page
* `#14699 <https://github.com/numpy/numpy/pull/14699>`__: Doc warnings
+* `#14703 <https://github.com/numpy/numpy/pull/14703>`__: TST: Adding CI stages, with one initial job to the Travis CI
* `#14705 <https://github.com/numpy/numpy/pull/14705>`__: DOC: Switch Markdown link to RST in NEP 29
* `#14709 <https://github.com/numpy/numpy/pull/14709>`__: TST: Divide Azure CI Pipelines into stages.
* `#14710 <https://github.com/numpy/numpy/pull/14710>`__: DEP: Finish the out kwarg deprecation for ufunc calls
@@ -526,7 +533,7 @@ A total of 406 pull requests were merged for this release.
* `#15058 <https://github.com/numpy/numpy/pull/15058>`__: API, DOC: change names to multivariate_hypergeometric, improve docs
* `#15059 <https://github.com/numpy/numpy/pull/15059>`__: REL: Prepare for NumPy 1.18.0 release.
* `#15109 <https://github.com/numpy/numpy/pull/15109>`__: TST: Check requires_memory immediately before the test
-* `#15111 <https://github.com/numpy/numpy/pull/15111>`__: ENH: Add support to sort timedelta64 `NaT` to end of the array
+* `#15111 <https://github.com/numpy/numpy/pull/15111>`__: ENH: Add support to sort timedelta64 ``NaT`` to end of the array
* `#15112 <https://github.com/numpy/numpy/pull/15112>`__: MAINT: follow-up cleanup for blas64 PR
* `#15113 <https://github.com/numpy/numpy/pull/15113>`__: ENH: f2py: add --f2cmap option for specifying the name of .f2py_f2cmap
* `#15114 <https://github.com/numpy/numpy/pull/15114>`__: ENH: add support for ILP64 OpenBLAS (without symbol suffix)
diff --git a/doc/changelog/1.18.5-changelog.rst b/doc/changelog/1.18.5-changelog.rst
new file mode 100644
index 000000000..f0bc51e6f
--- /dev/null
+++ b/doc/changelog/1.18.5-changelog.rst
@@ -0,0 +1,18 @@
+
+Contributors
+============
+
+A total of 3 people contributed to this release. People with a "+" by their
+names contributed a patch for the first time.
+
+* Charles Harris
+* Matti Picus
+* Siyuan +
+
+Pull requests merged
+====================
+
+A total of 2 pull requests were merged for this release.
+
+* `#16439 <https://github.com/numpy/numpy/pull/16439>`__: ENH: enable pickle protocol 5 support for python3.5
+* `#16441 <https://github.com/numpy/numpy/pull/16441>`__: BUG: relpath fails for different drives on windows
diff --git a/doc/changelog/1.19.0-changelog.rst b/doc/changelog/1.19.0-changelog.rst
index bd743832a..bde002499 100644
--- a/doc/changelog/1.19.0-changelog.rst
+++ b/doc/changelog/1.19.0-changelog.rst
@@ -136,25 +136,28 @@ names contributed a patch for the first time.
Pull requests merged
====================
-A total of 452 pull requests were merged for this release.
+A total of 488 pull requests were merged for this release.
* `#8255 <https://github.com/numpy/numpy/pull/8255>`__: ENH: add identity kwarg to frompyfunc
+* `#10600 <https://github.com/numpy/numpy/pull/10600>`__: DOC: Do not complain about contiguity when mutating ``ndarray.shape``
* `#12646 <https://github.com/numpy/numpy/pull/12646>`__: TST: check exception details in refguide_check.py
* `#13421 <https://github.com/numpy/numpy/pull/13421>`__: ENH: improve runtime detection of CPU features
* `#14326 <https://github.com/numpy/numpy/pull/14326>`__: TST: Add assert_array_equal test for big integer arrays.
* `#14376 <https://github.com/numpy/numpy/pull/14376>`__: MAINT: Remove unnecessary 'from __future__ import ...' statements
* `#14530 <https://github.com/numpy/numpy/pull/14530>`__: MAINT: Fix typos and copy edit NEP-0030.
* `#14546 <https://github.com/numpy/numpy/pull/14546>`__: DOC: NumPy for absolute beginners tutorial
-* `#14715 <https://github.com/numpy/numpy/pull/14715>`__: NEP: Proposal for array creation dispatching with `__array_function__`
+* `#14715 <https://github.com/numpy/numpy/pull/14715>`__: NEP: Proposal for array creation dispatching with ``__array_function__``
* `#14867 <https://github.com/numpy/numpy/pull/14867>`__: ENH: Use AVX-512F for np.maximum and np.minimum
* `#14924 <https://github.com/numpy/numpy/pull/14924>`__: BUG: Fix numpy.random.dirichlet returns NaN for small 'alpha'...
-* `#14933 <https://github.com/numpy/numpy/pull/14933>`__: API: Use `ResultType` in `PyArray_ConvertToCommonType`
+* `#14933 <https://github.com/numpy/numpy/pull/14933>`__: API: Use ``ResultType`` in ``PyArray_ConvertToCommonType``
+* `#14940 <https://github.com/numpy/numpy/pull/14940>`__: BUG: pickle the content of a scalar containing objects, not the...
* `#14942 <https://github.com/numpy/numpy/pull/14942>`__: MAINT,API: ignore and NULL fasttake/fastputmask ArrFuncs slots
* `#14981 <https://github.com/numpy/numpy/pull/14981>`__: BUG: Make ``ediff1d`` kwarg casting consistent
* `#14988 <https://github.com/numpy/numpy/pull/14988>`__: DOC: linalg: Include information about scipy.linalg.
* `#14995 <https://github.com/numpy/numpy/pull/14995>`__: BUG: Use ``__array__`` during dimension discovery
* `#15011 <https://github.com/numpy/numpy/pull/15011>`__: MAINT: cleanup compat.py3k.py
* `#15022 <https://github.com/numpy/numpy/pull/15022>`__: ENH: f2py: improve error messages
+* `#15024 <https://github.com/numpy/numpy/pull/15024>`__: DOC: clarify documentation for transpose()
* `#15028 <https://github.com/numpy/numpy/pull/15028>`__: [DOC] LaTeX: fix preamble (closes #15026)
* `#15035 <https://github.com/numpy/numpy/pull/15035>`__: BUG: add endfunction, endsubroutine to valid fortran end words
* `#15040 <https://github.com/numpy/numpy/pull/15040>`__: TST: Add test for object method (and general unary) loops
@@ -165,6 +168,7 @@ A total of 452 pull requests were merged for this release.
* `#15052 <https://github.com/numpy/numpy/pull/15052>`__: MAINT: follow-up cleanup for blas64 PR
* `#15054 <https://github.com/numpy/numpy/pull/15054>`__: DOC: add docstrings to refguide-check
* `#15066 <https://github.com/numpy/numpy/pull/15066>`__: Revert "DEP: issue deprecation warning when creating ragged array...
+* `#15068 <https://github.com/numpy/numpy/pull/15068>`__: ENH: Add support to sort timedelta64 ``NaT`` to end of the array
* `#15069 <https://github.com/numpy/numpy/pull/15069>`__: ENH: add support for ILP64 OpenBLAS (without symbol suffix)
* `#15070 <https://github.com/numpy/numpy/pull/15070>`__: DOC: correct version for NaT sort
* `#15072 <https://github.com/numpy/numpy/pull/15072>`__: TST: Check requires_memory immediately before the test
@@ -201,6 +205,7 @@ A total of 452 pull requests were merged for this release.
* `#15187 <https://github.com/numpy/numpy/pull/15187>`__: MAINT: unskip test on win32
* `#15189 <https://github.com/numpy/numpy/pull/15189>`__: ENH: Add property-based tests using Hypothesis
* `#15194 <https://github.com/numpy/numpy/pull/15194>`__: BUG: test, fix for c++ compilation
+* `#15195 <https://github.com/numpy/numpy/pull/15195>`__: MAINT: refactoring in np.core.records
* `#15196 <https://github.com/numpy/numpy/pull/15196>`__: DOC: Adding instructions for building documentation to developer...
* `#15197 <https://github.com/numpy/numpy/pull/15197>`__: DOC: NEP 37: A dispatch protocol for NumPy-like modules
* `#15203 <https://github.com/numpy/numpy/pull/15203>`__: MAINT: Do not use private Python function in testing
@@ -215,6 +220,8 @@ A total of 452 pull requests were merged for this release.
* `#15227 <https://github.com/numpy/numpy/pull/15227>`__: DOC: typo in release.rst
* `#15228 <https://github.com/numpy/numpy/pull/15228>`__: NEP: universal SIMD NEP 38
* `#15229 <https://github.com/numpy/numpy/pull/15229>`__: MAINT: Remove unused int_asbuffer
+* `#15230 <https://github.com/numpy/numpy/pull/15230>`__: BUG: do not emit warnings for np.sign, np.equal when using nan
+* `#15231 <https://github.com/numpy/numpy/pull/15231>`__: MAINT: Remove Python2 specific C module setup [part2]
* `#15232 <https://github.com/numpy/numpy/pull/15232>`__: MAINT: Cleaning up PY_MAJOR_VERSION/PY_VERSION_HEX
* `#15233 <https://github.com/numpy/numpy/pull/15233>`__: MAINT: Clean up more PY_VERSION_HEX
* `#15236 <https://github.com/numpy/numpy/pull/15236>`__: MAINT: Remove implicit inheritance from object class
@@ -224,14 +231,14 @@ A total of 452 pull requests were merged for this release.
* `#15241 <https://github.com/numpy/numpy/pull/15241>`__: MAINT: Remove references to non-existent sys.exc_clear()
* `#15242 <https://github.com/numpy/numpy/pull/15242>`__: DOC: Update HOWTO_RELEASE.rst
* `#15248 <https://github.com/numpy/numpy/pull/15248>`__: MAINT: cleanup use of sys.exc_info
-* `#15249 <https://github.com/numpy/numpy/pull/15249>`__: MAINT: Eliminate some calls to `eval`
+* `#15249 <https://github.com/numpy/numpy/pull/15249>`__: MAINT: Eliminate some calls to ``eval``
* `#15251 <https://github.com/numpy/numpy/pull/15251>`__: MAINT: Improve const-correctness of shapes and strides
* `#15253 <https://github.com/numpy/numpy/pull/15253>`__: DOC: clarify the effect of None parameters passed to ndarray.view
* `#15254 <https://github.com/numpy/numpy/pull/15254>`__: MAINT: Improve const-correctness of string arguments
* `#15255 <https://github.com/numpy/numpy/pull/15255>`__: MAINT: Delete numpy.distutils.compat
* `#15256 <https://github.com/numpy/numpy/pull/15256>`__: MAINT: Implement keyword-only arguments as syntax
* `#15260 <https://github.com/numpy/numpy/pull/15260>`__: MAINT: Remove FIXME comments introduced in the previous commit
-* `#15261 <https://github.com/numpy/numpy/pull/15261>`__: MAINT: Work with unicode strings in `dtype('i8,i8')`
+* `#15261 <https://github.com/numpy/numpy/pull/15261>`__: MAINT: Work with unicode strings in ``dtype('i8,i8')``
* `#15262 <https://github.com/numpy/numpy/pull/15262>`__: BUG: Use PyDict_GetItemWithError() instead of PyDict_GetItem()
* `#15263 <https://github.com/numpy/numpy/pull/15263>`__: MAINT: Remove python2 array_{get,set}slice
* `#15264 <https://github.com/numpy/numpy/pull/15264>`__: DOC: Add some missing functions in the list of available ufuncs.
@@ -248,8 +255,9 @@ A total of 452 pull requests were merged for this release.
* `#15280 <https://github.com/numpy/numpy/pull/15280>`__: BENCH: Add basic benchmarks for take and putmask
* `#15281 <https://github.com/numpy/numpy/pull/15281>`__: MAINT: Cleanup most PY3K #ifdef guards
* `#15282 <https://github.com/numpy/numpy/pull/15282>`__: DOC: BLD: add empty release notes for 1.19.0 to fix doc build...
+* `#15283 <https://github.com/numpy/numpy/pull/15283>`__: MAINT: Cleanup more NPY_PY3K
* `#15284 <https://github.com/numpy/numpy/pull/15284>`__: MAINT: Use a simpler return convention for internal functions
-* `#15285 <https://github.com/numpy/numpy/pull/15285>`__: MAINT: Simplify np.int_ inheritance
+* `#15285 <https://github.com/numpy/numpy/pull/15285>`__: MAINT: Simplify ``np.int_`` inheritance
* `#15286 <https://github.com/numpy/numpy/pull/15286>`__: DOC" Update np.full docstring.
* `#15287 <https://github.com/numpy/numpy/pull/15287>`__: MAINT: Express PyArray_DescrAlignConverter in terms of _convert_from_any
* `#15288 <https://github.com/numpy/numpy/pull/15288>`__: MAINT: Push down declarations in _convert_from_*
@@ -261,7 +269,7 @@ A total of 452 pull requests were merged for this release.
* `#15304 <https://github.com/numpy/numpy/pull/15304>`__: MAINT: Remove NPY_PY3K constant
* `#15305 <https://github.com/numpy/numpy/pull/15305>`__: MAINT: Remove sys.version checks in tests
* `#15307 <https://github.com/numpy/numpy/pull/15307>`__: MAINT: cleanup sys.version dependant code
-* `#15310 <https://github.com/numpy/numpy/pull/15310>`__: MAINT: Ensure `_convert_from_*` functions set errors
+* `#15310 <https://github.com/numpy/numpy/pull/15310>`__: MAINT: Ensure ``_convert_from_*`` functions set errors
* `#15312 <https://github.com/numpy/numpy/pull/15312>`__: MAINT: Avoid escaping unicode in error messages
* `#15315 <https://github.com/numpy/numpy/pull/15315>`__: MAINT: Change file extension of ma README to rst.
* `#15319 <https://github.com/numpy/numpy/pull/15319>`__: BUG: fix NameError in clip nan propagation tests
@@ -271,22 +279,25 @@ A total of 452 pull requests were merged for this release.
* `#15329 <https://github.com/numpy/numpy/pull/15329>`__: TST: move _no_tracing to testing._private, remove testing.support
* `#15333 <https://github.com/numpy/numpy/pull/15333>`__: BUG: Add some missing C error handling
* `#15335 <https://github.com/numpy/numpy/pull/15335>`__: MAINT: Remove sys.version checks
-* `#15336 <https://github.com/numpy/numpy/pull/15336>`__: DEP: Deprecate `->f->fastclip` at registration time
+* `#15336 <https://github.com/numpy/numpy/pull/15336>`__: DEP: Deprecate ``->f->fastclip`` at registration time
* `#15338 <https://github.com/numpy/numpy/pull/15338>`__: DOC: document site.cfg.example
* `#15350 <https://github.com/numpy/numpy/pull/15350>`__: MAINT: Fix mistype in histogramdd docstring
* `#15351 <https://github.com/numpy/numpy/pull/15351>`__: DOC, BLD: reword release note, upgrade sphinx version
* `#15353 <https://github.com/numpy/numpy/pull/15353>`__: MAINT: Remove unnecessary calls to PyArray_DATA from binomial...
* `#15354 <https://github.com/numpy/numpy/pull/15354>`__: MAINT: Bump pytest from 5.3.2 to 5.3.3
+* `#15355 <https://github.com/numpy/numpy/pull/15355>`__: MAINT: Const qualify UFunc inner loops
* `#15358 <https://github.com/numpy/numpy/pull/15358>`__: MAINT: Remove six
* `#15361 <https://github.com/numpy/numpy/pull/15361>`__: MAINT: Revise imports from collections.abc module
* `#15362 <https://github.com/numpy/numpy/pull/15362>`__: MAINT: remove internal functions required to handle Python2/3...
* `#15364 <https://github.com/numpy/numpy/pull/15364>`__: MAINT: Remove other uses of six module
* `#15366 <https://github.com/numpy/numpy/pull/15366>`__: MAINT: resolve pyflake F403 'from module import *' used
+* `#15367 <https://github.com/numpy/numpy/pull/15367>`__: DOC: Fix Multithreaded Generation example docs
* `#15368 <https://github.com/numpy/numpy/pull/15368>`__: MAINT: Update tox for supported Python versions
* `#15369 <https://github.com/numpy/numpy/pull/15369>`__: MAINT: simd: Avoid signed comparison warning
-* `#15370 <https://github.com/numpy/numpy/pull/15370>`__: DOC: Updating Chararry Buffer datatypes #15360
+* `#15370 <https://github.com/numpy/numpy/pull/15370>`__: DOC: Updating Chararry Buffer datatypes
+* `#15373 <https://github.com/numpy/numpy/pull/15373>`__: MAINT: Remove sys.version checks
* `#15374 <https://github.com/numpy/numpy/pull/15374>`__: TST: Simplify unicode test
-* `#15375 <https://github.com/numpy/numpy/pull/15375>`__: MAINT: Use `with open` when possible
+* `#15375 <https://github.com/numpy/numpy/pull/15375>`__: MAINT: Use ``with open`` when possible
* `#15377 <https://github.com/numpy/numpy/pull/15377>`__: MAINT: Cleanup python2 references
* `#15379 <https://github.com/numpy/numpy/pull/15379>`__: MAINT: Python2 Cleanups
* `#15381 <https://github.com/numpy/numpy/pull/15381>`__: DEP: add PendingDeprecation to matlib.py funky namespace
@@ -303,11 +314,14 @@ A total of 452 pull requests were merged for this release.
* `#15407 <https://github.com/numpy/numpy/pull/15407>`__: MAINT: Replace basestring with str.
* `#15408 <https://github.com/numpy/numpy/pull/15408>`__: ENH: Use AVX-512F for complex number arithmetic, absolute, square...
* `#15414 <https://github.com/numpy/numpy/pull/15414>`__: MAINT: Remove Python2 workarounds
+* `#15415 <https://github.com/numpy/numpy/pull/15415>`__: MAINT: Revert f2py Python 2.6 workaround
* `#15417 <https://github.com/numpy/numpy/pull/15417>`__: MAINT: Cleanup references to python2
* `#15418 <https://github.com/numpy/numpy/pull/15418>`__: MAINT, DOC: Remove use of old Python __builtin__, now known as...
* `#15421 <https://github.com/numpy/numpy/pull/15421>`__: ENH: Make use of ExitStack in npyio.py
* `#15422 <https://github.com/numpy/numpy/pull/15422>`__: MAINT: Inline gentype_getreadbuf
* `#15423 <https://github.com/numpy/numpy/pull/15423>`__: MAINT: Use f-strings for clarity.
+* `#15425 <https://github.com/numpy/numpy/pull/15425>`__: MAINT: dir(numpy) returns duplicate "testing"
+* `#15426 <https://github.com/numpy/numpy/pull/15426>`__: MAINT: Use the PyArrayScalar_VAL macro where possible
* `#15427 <https://github.com/numpy/numpy/pull/15427>`__: DEP: Schedule unused C-API functions for removal/disabling
* `#15428 <https://github.com/numpy/numpy/pull/15428>`__: DOC: Improve ndarray.ctypes example
* `#15429 <https://github.com/numpy/numpy/pull/15429>`__: DOC: distutils: Add a docstring to show_config().
@@ -315,14 +329,15 @@ A total of 452 pull requests were merged for this release.
* `#15434 <https://github.com/numpy/numpy/pull/15434>`__: MAINT: Updated polynomial to use fstrings
* `#15435 <https://github.com/numpy/numpy/pull/15435>`__: DOC: Fix Incorrect document in Beginner Docs
* `#15436 <https://github.com/numpy/numpy/pull/15436>`__: MAINT: Update core.py with fstrings (issue #15420)
-* `#15439 <https://github.com/numpy/numpy/pull/15439>`__: DOC: fix docstrings so `python tools/refguide-check --rst <file>...
+* `#15439 <https://github.com/numpy/numpy/pull/15439>`__: DOC: fix docstrings so ``python tools/refguide-check --rst <file>``...
* `#15441 <https://github.com/numpy/numpy/pull/15441>`__: MAINT: Tidy macros in scalar_new
* `#15444 <https://github.com/numpy/numpy/pull/15444>`__: MAINT: use 'yield from <expr>' for simple cases
* `#15445 <https://github.com/numpy/numpy/pull/15445>`__: MAINT: Bump pytest from 5.3.3 to 5.3.4
* `#15446 <https://github.com/numpy/numpy/pull/15446>`__: BUG: Reject nonsense arguments to scalar constructors
* `#15449 <https://github.com/numpy/numpy/pull/15449>`__: DOC: Update refguide_check note on how to skip code
-* `#15451 <https://github.com/numpy/numpy/pull/15451>`__: MAINT: Simplify `np.object_.__new__`
+* `#15451 <https://github.com/numpy/numpy/pull/15451>`__: MAINT: Simplify ``np.object_.__new__``
* `#15452 <https://github.com/numpy/numpy/pull/15452>`__: STY,MAINT: avoid 'multiple imports on one line'
+* `#15463 <https://github.com/numpy/numpy/pull/15463>`__: ENH: expose ``bit_generator`` and random C-API to cython
* `#15464 <https://github.com/numpy/numpy/pull/15464>`__: MAINT: Cleanup duplicate line in refguide_check
* `#15465 <https://github.com/numpy/numpy/pull/15465>`__: MAINT: cleanup unused imports; avoid redefinition of imports
* `#15468 <https://github.com/numpy/numpy/pull/15468>`__: BUG: Fix for SVD not always sorted with hermitian=True
@@ -330,21 +345,22 @@ A total of 452 pull requests were merged for this release.
* `#15474 <https://github.com/numpy/numpy/pull/15474>`__: MAINT: Eliminate messy _WORK macro
* `#15476 <https://github.com/numpy/numpy/pull/15476>`__: update result of rng.random(3) to current rng output
* `#15480 <https://github.com/numpy/numpy/pull/15480>`__: DOC: Correct get_state doc
-* `#15482 <https://github.com/numpy/numpy/pull/15482>`__: MAINT: Use `.identifier = val` to fill type structs
+* `#15482 <https://github.com/numpy/numpy/pull/15482>`__: MAINT: Use ``.identifier = val`` to fill type structs
* `#15483 <https://github.com/numpy/numpy/pull/15483>`__: [DOC] Mention behaviour of np.squeeze with one element
* `#15484 <https://github.com/numpy/numpy/pull/15484>`__: ENH: fixing generic error messages to be more specific in multiarray/descriptor.c
* `#15487 <https://github.com/numpy/numpy/pull/15487>`__: BUG: Fixing result of np quantile edge case
* `#15491 <https://github.com/numpy/numpy/pull/15491>`__: TST: mark the top 3 slowest tests to save ~10 seconds
* `#15493 <https://github.com/numpy/numpy/pull/15493>`__: MAINT: Bump pytest from 5.3.4 to 5.3.5
* `#15500 <https://github.com/numpy/numpy/pull/15500>`__: MAINT: Use True/False instead of 1/0 in np.dtype.__reduce__
-* `#15503 <https://github.com/numpy/numpy/pull/15503>`__: MAINT: Do not allow `copyswap` and friends to fail silently
+* `#15503 <https://github.com/numpy/numpy/pull/15503>`__: MAINT: Do not allow ``copyswap`` and friends to fail silently
* `#15504 <https://github.com/numpy/numpy/pull/15504>`__: DOC: Remove duplicated code in true_divide docstring
* `#15505 <https://github.com/numpy/numpy/pull/15505>`__: NEP 40: Informational NEP about current DTypes
+* `#15506 <https://github.com/numpy/numpy/pull/15506>`__: NEP 41: First steps towards improved Datatype Support
* `#15510 <https://github.com/numpy/numpy/pull/15510>`__: DOC: Update unique docstring example
* `#15511 <https://github.com/numpy/numpy/pull/15511>`__: MAINT: Large overhead in some random functions
* `#15516 <https://github.com/numpy/numpy/pull/15516>`__: TST: Fix missing output in refguide-check
* `#15521 <https://github.com/numpy/numpy/pull/15521>`__: MAINT: Simplify arraydescr_richcompare
-* `#15522 <https://github.com/numpy/numpy/pull/15522>`__: MAINT: Fix internal misuses of `NPY_TITLE_KEY`
+* `#15522 <https://github.com/numpy/numpy/pull/15522>`__: MAINT: Fix internal misuses of ``NPY_TITLE_KEY``
* `#15524 <https://github.com/numpy/numpy/pull/15524>`__: DOC: Update instructions for building/archiving docs.
* `#15526 <https://github.com/numpy/numpy/pull/15526>`__: BUG: Fix inline assembly that detects cpu features on x86(32bit)
* `#15532 <https://github.com/numpy/numpy/pull/15532>`__: update doctests, small bugs and changes of repr
@@ -354,13 +370,15 @@ A total of 452 pull requests were merged for this release.
* `#15543 <https://github.com/numpy/numpy/pull/15543>`__: NEP: edit and move NEP 38 to accepted status
* `#15547 <https://github.com/numpy/numpy/pull/15547>`__: MAINT: Refresh Doxyfile and modernize numpyfilter.py
* `#15549 <https://github.com/numpy/numpy/pull/15549>`__: TST: Accuracy test float32 sin/cos/exp/log for AVX platforms
-* `#15550 <https://github.com/numpy/numpy/pull/15550>`__: DOC: Improve the `numpy.linalg.eig` docstring.
+* `#15550 <https://github.com/numpy/numpy/pull/15550>`__: DOC: Improve the ``numpy.linalg.eig`` docstring.
+* `#15553 <https://github.com/numpy/numpy/pull/15553>`__: BUG: Added missing error check in ``ndarray.__contains__``
* `#15554 <https://github.com/numpy/numpy/pull/15554>`__: NEP 44 - Restructuring the NumPy Documentation
* `#15556 <https://github.com/numpy/numpy/pull/15556>`__: TST: (Travis CI) Use full python3-dbg path for virtual env creation
* `#15560 <https://github.com/numpy/numpy/pull/15560>`__: BUG, DOC: restore missing import
* `#15566 <https://github.com/numpy/numpy/pull/15566>`__: DOC: Removing bad practices from quick start + some PEP8
* `#15574 <https://github.com/numpy/numpy/pull/15574>`__: TST: Do not create symbolic link named gfortran.
* `#15575 <https://github.com/numpy/numpy/pull/15575>`__: DOC: Document caveat in random.uniform
+* `#15577 <https://github.com/numpy/numpy/pull/15577>`__: TST: Test division by zero both with scalar and with array
* `#15579 <https://github.com/numpy/numpy/pull/15579>`__: DOC: numpy.clip is equivalent to minimum(..., maximum(...))
* `#15582 <https://github.com/numpy/numpy/pull/15582>`__: MAINT: Bump cython from 0.29.14 to 0.29.15
* `#15583 <https://github.com/numpy/numpy/pull/15583>`__: MAINT: Bump hypothesis from 5.3.0 to 5.5.4
@@ -369,6 +387,7 @@ A total of 452 pull requests were merged for this release.
* `#15600 <https://github.com/numpy/numpy/pull/15600>`__: TST: use manylinux2010 docker instead of ubuntu
* `#15610 <https://github.com/numpy/numpy/pull/15610>`__: TST: mask DeprecationWarning in xfailed test
* `#15612 <https://github.com/numpy/numpy/pull/15612>`__: BUG: Fix bug in AVX-512F np.maximum and np.minimum
+* `#15614 <https://github.com/numpy/numpy/pull/15614>`__: DOC: Reword docstring for assert_equal
* `#15615 <https://github.com/numpy/numpy/pull/15615>`__: BUG: Remove check requiring natural alignment of float/double...
* `#15616 <https://github.com/numpy/numpy/pull/15616>`__: DOC: Add missing imports, definitions and dummy file
* `#15619 <https://github.com/numpy/numpy/pull/15619>`__: DOC: Fix documentation for apply_along_axis
@@ -376,9 +395,10 @@ A total of 452 pull requests were merged for this release.
* `#15631 <https://github.com/numpy/numpy/pull/15631>`__: MAINT: Pull identical line out of conditional.
* `#15633 <https://github.com/numpy/numpy/pull/15633>`__: DOC: remove broken link in f2py tutorial
* `#15639 <https://github.com/numpy/numpy/pull/15639>`__: BLD: update openblas download to new location, use manylinux2010-base
+* `#15644 <https://github.com/numpy/numpy/pull/15644>`__: DOC: Update to clarify actual behavior real_if_(all elements)_close
* `#15648 <https://github.com/numpy/numpy/pull/15648>`__: MAINT: AVX512 implementation with intrinsic for float64 input...
* `#15653 <https://github.com/numpy/numpy/pull/15653>`__: BLD: update OpenBLAS to pre-0.3.9 version
-* `#15662 <https://github.com/numpy/numpy/pull/15662>`__: DOC: Refactor `np.polynomial` docs using `automodule`
+* `#15662 <https://github.com/numpy/numpy/pull/15662>`__: DOC: Refactor ``np.polynomial`` docs using ``automodule``
* `#15665 <https://github.com/numpy/numpy/pull/15665>`__: BUG: fix doctest exception messages
* `#15672 <https://github.com/numpy/numpy/pull/15672>`__: MAINT: Added comment pointing FIXME to relevant PR.
* `#15673 <https://github.com/numpy/numpy/pull/15673>`__: DOC: Make extension module wording more clear
@@ -386,16 +406,18 @@ A total of 452 pull requests were merged for this release.
* `#15680 <https://github.com/numpy/numpy/pull/15680>`__: DOC: Improve Benchmark README with environment setup and more...
* `#15682 <https://github.com/numpy/numpy/pull/15682>`__: MAINT: Bump hypothesis from 5.5.4 to 5.6.0
* `#15683 <https://github.com/numpy/numpy/pull/15683>`__: NEP: move NEP 44 to accepted status
+* `#15685 <https://github.com/numpy/numpy/pull/15685>`__: ENH: Add ``subok`` parameter to np.copy function (cf. #6509)
* `#15694 <https://github.com/numpy/numpy/pull/15694>`__: DOC: Fix indexing docs to pass refguide
* `#15695 <https://github.com/numpy/numpy/pull/15695>`__: MAINT: Test during import to detect bugs with Accelerate(MacOS)...
* `#15696 <https://github.com/numpy/numpy/pull/15696>`__: MAINT: Add a fast path to var for complex input
* `#15701 <https://github.com/numpy/numpy/pull/15701>`__: MAINT: Convert shebang from python to python3 (#15687)
* `#15702 <https://github.com/numpy/numpy/pull/15702>`__: MAINT: replace optparse with argparse for 'doc' and 'tools' scripts
* `#15703 <https://github.com/numpy/numpy/pull/15703>`__: DOC: Fix quickstart doc to pass refguide
+* `#15705 <https://github.com/numpy/numpy/pull/15705>`__: DOC: Change list to tuple in example description.
* `#15706 <https://github.com/numpy/numpy/pull/15706>`__: MAINT: Fixing typos in f2py comments and code.
* `#15710 <https://github.com/numpy/numpy/pull/15710>`__: DOC: fix SVD tutorial to pass refguide
* `#15714 <https://github.com/numpy/numpy/pull/15714>`__: MAINT: use list-based APIs to call subprocesses
-* `#15715 <https://github.com/numpy/numpy/pull/15715>`__: ENH: update numpy.linalg.multi_dot to accept an `out` argument
+* `#15715 <https://github.com/numpy/numpy/pull/15715>`__: ENH: update numpy.linalg.multi_dot to accept an ``out`` argument
* `#15716 <https://github.com/numpy/numpy/pull/15716>`__: TST: always use 'python -mpip' not 'pip'
* `#15717 <https://github.com/numpy/numpy/pull/15717>`__: DOC: update datetime reference to pass refguide
* `#15718 <https://github.com/numpy/numpy/pull/15718>`__: DOC: Fix coremath.rst to fix refguide_check
@@ -403,6 +425,7 @@ A total of 452 pull requests were merged for this release.
* `#15723 <https://github.com/numpy/numpy/pull/15723>`__: BUG: fix logic error when nm fails on 32-bit
* `#15724 <https://github.com/numpy/numpy/pull/15724>`__: TST: Remove nose from the test_requirements.txt file.
* `#15733 <https://github.com/numpy/numpy/pull/15733>`__: DOC: Allow NEPs to link to python, numpy, scipy, and matplotlib...
+* `#15735 <https://github.com/numpy/numpy/pull/15735>`__: DOC: LICENSE 2019 -> 2020
* `#15736 <https://github.com/numpy/numpy/pull/15736>`__: BUG: Guarantee array is in valid state after memory error occurs...
* `#15738 <https://github.com/numpy/numpy/pull/15738>`__: MAINT: Remove non-native byte order from _var check.
* `#15740 <https://github.com/numpy/numpy/pull/15740>`__: MAINT: Add better error handling in linalg.norm for vectors and...
@@ -418,28 +441,30 @@ A total of 452 pull requests were merged for this release.
* `#15769 <https://github.com/numpy/numpy/pull/15769>`__: ENH: Allow toggling madvise hugepage and fix default
* `#15771 <https://github.com/numpy/numpy/pull/15771>`__: DOC: Fix runtests example in developer docs
* `#15773 <https://github.com/numpy/numpy/pull/15773>`__: DEP: Make issubdtype consistent for types and dtypes
-* `#15774 <https://github.com/numpy/numpy/pull/15774>`__: MAINT: remove useless `global` statements
+* `#15774 <https://github.com/numpy/numpy/pull/15774>`__: MAINT: remove useless ``global`` statements
* `#15778 <https://github.com/numpy/numpy/pull/15778>`__: BLD: Add requirements.txt file for building docs
* `#15781 <https://github.com/numpy/numpy/pull/15781>`__: BUG: don't add 'public' or 'private' if the other one exists
-* `#15784 <https://github.com/numpy/numpy/pull/15784>`__: ENH: Use TypeError in `np.array` for python consistency
+* `#15784 <https://github.com/numpy/numpy/pull/15784>`__: ENH: Use TypeError in ``np.array`` for python consistency
* `#15794 <https://github.com/numpy/numpy/pull/15794>`__: BUG: Add basic __format__ for masked element to fix incorrect...
* `#15797 <https://github.com/numpy/numpy/pull/15797>`__: TST: Add unit test for out=None of np.einsum
* `#15799 <https://github.com/numpy/numpy/pull/15799>`__: MAINT: Cleanups to np.insert and np.delete
* `#15800 <https://github.com/numpy/numpy/pull/15800>`__: BUG: Add error-checking versions of strided casts.
-* `#15802 <https://github.com/numpy/numpy/pull/15802>`__: DEP: Make `np.insert` and `np.delete` on 0d arrays with an axis...
-* `#15803 <https://github.com/numpy/numpy/pull/15803>`__: DOC: correct possible list lengths for `extobj` in ufunc calls
+* `#15802 <https://github.com/numpy/numpy/pull/15802>`__: DEP: Make ``np.insert`` and ``np.delete`` on 0d arrays with an axis...
+* `#15803 <https://github.com/numpy/numpy/pull/15803>`__: DOC: correct possible list lengths for ``extobj`` in ufunc calls
* `#15804 <https://github.com/numpy/numpy/pull/15804>`__: DEP: Make np.delete on out-of-bounds indices an error
-* `#15805 <https://github.com/numpy/numpy/pull/15805>`__: DEP: Forbid passing non-integral index arrays to `insert` and...
+* `#15805 <https://github.com/numpy/numpy/pull/15805>`__: DEP: Forbid passing non-integral index arrays to ``insert`` and...
* `#15806 <https://github.com/numpy/numpy/pull/15806>`__: TST: Parametrize sort test
* `#15809 <https://github.com/numpy/numpy/pull/15809>`__: TST: switch PyPy job with CPython
* `#15812 <https://github.com/numpy/numpy/pull/15812>`__: TST: Remove code that is not supposed to warn out of warning...
* `#15815 <https://github.com/numpy/numpy/pull/15815>`__: DEP: Do not cast boolean indices to integers in np.delete
* `#15816 <https://github.com/numpy/numpy/pull/15816>`__: MAINT: simplify code that assumes str/unicode and int/long are...
+* `#15827 <https://github.com/numpy/numpy/pull/15827>`__: BUG: Break on all errors when performing strided casts.
* `#15830 <https://github.com/numpy/numpy/pull/15830>`__: MAINT: pathlib and hashlib are in stdlib in Python 3.5+
-* `#15832 <https://github.com/numpy/numpy/pull/15832>`__: ENH: improved error message `IndexError: too many indices for...
+* `#15832 <https://github.com/numpy/numpy/pull/15832>`__: ENH: improved error message ``IndexError: too many indices for``...
+* `#15834 <https://github.com/numpy/numpy/pull/15834>`__: NEP: Add paragraph to NEP 41 about no array-object use and fix...
* `#15836 <https://github.com/numpy/numpy/pull/15836>`__: BUG: Fix IndexError for illegal axis in np.mean
* `#15839 <https://github.com/numpy/numpy/pull/15839>`__: DOC: Minor fix to _hist_bin_fd documentation
-* `#15840 <https://github.com/numpy/numpy/pull/15840>`__: BUG,DEP: Make `scalar.__round__()` behave like pythons round
+* `#15840 <https://github.com/numpy/numpy/pull/15840>`__: BUG,DEP: Make ``scalar.__round__()`` behave like pythons round
* `#15843 <https://github.com/numpy/numpy/pull/15843>`__: DOC: First steps towards docs restructuring (NEP 44)
* `#15848 <https://github.com/numpy/numpy/pull/15848>`__: DOC, TST: enable refguide_check in circleci
* `#15850 <https://github.com/numpy/numpy/pull/15850>`__: DOC: fix typo in C-API reference
@@ -447,8 +472,9 @@ A total of 452 pull requests were merged for this release.
* `#15866 <https://github.com/numpy/numpy/pull/15866>`__: MAINT: Bump cython from 0.29.15 to 0.29.16
* `#15867 <https://github.com/numpy/numpy/pull/15867>`__: DEP: Deprecate ndarray.tostring()
* `#15868 <https://github.com/numpy/numpy/pull/15868>`__: TST: use draft OpenBLAS build
+* `#15870 <https://github.com/numpy/numpy/pull/15870>`__: ENH: Add keepdims argument to count_nonzero
* `#15872 <https://github.com/numpy/numpy/pull/15872>`__: BUG: Fix eigh and cholesky methods of numpy.random.multivariate_normal
-* `#15876 <https://github.com/numpy/numpy/pull/15876>`__: BUG: Check that `pvals` is 1D in `_generator.multinomial`.
+* `#15876 <https://github.com/numpy/numpy/pull/15876>`__: BUG: Check that ``pvals`` is 1D in ``_generator.multinomial``.
* `#15877 <https://github.com/numpy/numpy/pull/15877>`__: DOC: Add missing signature from nditer docstring
* `#15881 <https://github.com/numpy/numpy/pull/15881>`__: BUG: Fix empty_like to respect shape=()
* `#15882 <https://github.com/numpy/numpy/pull/15882>`__: BUG: Do not ignore empty tuple of strides in ndarray.__new__
@@ -456,29 +482,34 @@ A total of 452 pull requests were merged for this release.
* `#15884 <https://github.com/numpy/numpy/pull/15884>`__: BUG: Setting a 0d array's strides to themselves should be legal
* `#15885 <https://github.com/numpy/numpy/pull/15885>`__: BUG: Respect itershape=() in nditer
* `#15887 <https://github.com/numpy/numpy/pull/15887>`__: MAINT: Clean-up 'next = __next__' used for Python 2 compatibility
+* `#15891 <https://github.com/numpy/numpy/pull/15891>`__: DOC: Clarify docs on mixed advanced indexing and slicing
* `#15893 <https://github.com/numpy/numpy/pull/15893>`__: TST: Run test_large_zip in a child process
* `#15894 <https://github.com/numpy/numpy/pull/15894>`__: DOC: Add missing doc of numpy.ma.apply_over_axes in API list.
* `#15899 <https://github.com/numpy/numpy/pull/15899>`__: DOC: Improve record module documentation
* `#15901 <https://github.com/numpy/numpy/pull/15901>`__: DOC: Fixed order of items and link to mailing list in dev docs...
* `#15903 <https://github.com/numpy/numpy/pull/15903>`__: BLD: report clang version on macOS
-* `#15904 <https://github.com/numpy/numpy/pull/15904>`__: MAINT: records: Remove private `format_parser._descr` attribute
+* `#15904 <https://github.com/numpy/numpy/pull/15904>`__: MAINT: records: Remove private ``format_parser._descr`` attribute
+* `#15907 <https://github.com/numpy/numpy/pull/15907>`__: DOC: Update documentation w.r.t. NPY_RELAXED_STRIDES_CHECKING
* `#15914 <https://github.com/numpy/numpy/pull/15914>`__: BUG: random: Disallow p=0 in negative_binomial
+* `#15920 <https://github.com/numpy/numpy/pull/15920>`__: DOC: Improve docstring for numpy.linalg.lstsq
* `#15921 <https://github.com/numpy/numpy/pull/15921>`__: ENH: Use sysconfig instead of probing Makefile
* `#15928 <https://github.com/numpy/numpy/pull/15928>`__: DOC: Update np.copy docstring to include ragged case
* `#15931 <https://github.com/numpy/numpy/pull/15931>`__: DOC: Correct private function name to PyArray_AdaptFlexibleDType
-* `#15936 <https://github.com/numpy/numpy/pull/15936>`__: MAINT: Fix capitalization in error message in `mtrand.pyx`
+* `#15936 <https://github.com/numpy/numpy/pull/15936>`__: MAINT: Fix capitalization in error message in ``mtrand.pyx``
+* `#15938 <https://github.com/numpy/numpy/pull/15938>`__: BUG: Add _LARGE_FILES to def_macros[] when platform is AIX.
* `#15939 <https://github.com/numpy/numpy/pull/15939>`__: DOC: Update np.rollaxis docstring
* `#15949 <https://github.com/numpy/numpy/pull/15949>`__: BUG: fix AttributeError on accessing object in nested MaskedArray.
-* `#15951 <https://github.com/numpy/numpy/pull/15951>`__: BUG: Alpha parameter must be 1D in `generator.dirichlet`
+* `#15951 <https://github.com/numpy/numpy/pull/15951>`__: BUG: Alpha parameter must be 1D in ``generator.dirichlet``
* `#15953 <https://github.com/numpy/numpy/pull/15953>`__: NEP: minor maintenance, update filename and fix a cross-reference
* `#15964 <https://github.com/numpy/numpy/pull/15964>`__: MAINT: Bump hypothesis from 5.8.0 to 5.8.3
* `#15967 <https://github.com/numpy/numpy/pull/15967>`__: TST: Add slow_pypy support
* `#15968 <https://github.com/numpy/numpy/pull/15968>`__: DOC: Added note to angle function docstring about angle(0) being...
* `#15982 <https://github.com/numpy/numpy/pull/15982>`__: MAINT/BUG: Cleanup and minor fixes to conform_reduce_result
-* `#15985 <https://github.com/numpy/numpy/pull/15985>`__: BUG: Avoid duplication in stack trace of `linspace(a, b, num=1.5)`
-* `#15988 <https://github.com/numpy/numpy/pull/15988>`__: BUG: Fix inf and NaN-warnings in half float `nextafter`
+* `#15985 <https://github.com/numpy/numpy/pull/15985>`__: BUG: Avoid duplication in stack trace of ``linspace(a, b, num=1.5)``
+* `#15988 <https://github.com/numpy/numpy/pull/15988>`__: BUG: Fix inf and NaN-warnings in half float ``nextafter``
* `#15989 <https://github.com/numpy/numpy/pull/15989>`__: MAINT: Remove 0d check for PyArray_ISONESEGMENT
* `#15990 <https://github.com/numpy/numpy/pull/15990>`__: DEV: Pass additional runtests.py args to ASV
+* `#15991 <https://github.com/numpy/numpy/pull/15991>`__: BUG: max/min of a masked array dtype fix
* `#15993 <https://github.com/numpy/numpy/pull/15993>`__: DOC: Fix method documentation of function sort in MaskedArray
* `#16000 <https://github.com/numpy/numpy/pull/16000>`__: NEP: Improve Value Based Casting paragraph in NEP 40
* `#16001 <https://github.com/numpy/numpy/pull/16001>`__: DOC: add note on flatten ordering in matlab page
@@ -496,6 +527,8 @@ A total of 452 pull requests were merged for this release.
* `#16038 <https://github.com/numpy/numpy/pull/16038>`__: MAINT,TST: Move _repr_latex tests to test_printing.
* `#16041 <https://github.com/numpy/numpy/pull/16041>`__: BUG: missing 'f' prefix for fstring
* `#16042 <https://github.com/numpy/numpy/pull/16042>`__: ENH: Fix exception causes in build_ext.py
+* `#16043 <https://github.com/numpy/numpy/pull/16043>`__: DOC: Add converters example to the loadtxt docstring
+* `#16051 <https://github.com/numpy/numpy/pull/16051>`__: DOC: Add missing bracket
* `#16053 <https://github.com/numpy/numpy/pull/16053>`__: DOC: Small typo fixes to NEP 40.
* `#16054 <https://github.com/numpy/numpy/pull/16054>`__: DOC, BLD: update release howto and walkthrough for ananconda.org...
* `#16061 <https://github.com/numpy/numpy/pull/16061>`__: ENH: Chained exceptions in linalg.py and polyutils.py
@@ -508,6 +541,7 @@ A total of 452 pull requests were merged for this release.
* `#16077 <https://github.com/numpy/numpy/pull/16077>`__: BLD: fix path to libgfortran on macOS
* `#16078 <https://github.com/numpy/numpy/pull/16078>`__: DOC: Add axis to random module "new or different" docs
* `#16079 <https://github.com/numpy/numpy/pull/16079>`__: DOC,BLD: Limit timeit iterations in random docs.
+* `#16080 <https://github.com/numpy/numpy/pull/16080>`__: BUG: numpy.einsum indexing arrays now accept numpy int type
* `#16081 <https://github.com/numpy/numpy/pull/16081>`__: DOC: add note on type casting to numpy.left_shift().
* `#16083 <https://github.com/numpy/numpy/pull/16083>`__: DOC: improve development debugging doc
* `#16084 <https://github.com/numpy/numpy/pull/16084>`__: DOC: tweak neps/scope.rst
@@ -517,10 +551,12 @@ A total of 452 pull requests were merged for this release.
* `#16097 <https://github.com/numpy/numpy/pull/16097>`__: MAINT, DOC: Improve grammar on a comment in the quickstart
* `#16100 <https://github.com/numpy/numpy/pull/16100>`__: NEP 41: Accept NEP 41 and add DType<->scalar duplication paragraph
* `#16101 <https://github.com/numpy/numpy/pull/16101>`__: BLD: put openblas library in local directory on windows
+* `#16102 <https://github.com/numpy/numpy/pull/16102>`__: ENH: correct identity for logaddexp2 ufunc: -inf
* `#16113 <https://github.com/numpy/numpy/pull/16113>`__: MAINT: Fix random.PCG64 signature
* `#16119 <https://github.com/numpy/numpy/pull/16119>`__: DOC: Move misplaced news fragment for gh-13421
* `#16122 <https://github.com/numpy/numpy/pull/16122>`__: DOC: Fix links for NEP 40 in NEP 41
* `#16125 <https://github.com/numpy/numpy/pull/16125>`__: BUG: lib: Fix a problem with vectorize with default parameters.
+* `#16128 <https://github.com/numpy/numpy/pull/16128>`__: ENH: Add equal_nan keyword argument to array_equal
* `#16129 <https://github.com/numpy/numpy/pull/16129>`__: ENH: Better error message when ``bins`` has float value in ``histogramdd``.
* `#16133 <https://github.com/numpy/numpy/pull/16133>`__: MAINT: Unify casting error creation (outside the iterator)
* `#16141 <https://github.com/numpy/numpy/pull/16141>`__: BENCH: Default to building HEAD instead of master
@@ -571,7 +607,7 @@ A total of 452 pull requests were merged for this release.
* `#16344 <https://github.com/numpy/numpy/pull/16344>`__: BUG: Allow attaching documentation twice in add_docstring
* `#16355 <https://github.com/numpy/numpy/pull/16355>`__: MAINT: Remove f-strings in setup.py. (gh-16346)
* `#16356 <https://github.com/numpy/numpy/pull/16356>`__: BUG: Indentation for docstrings
-* `#16358 <https://github.com/numpy/numpy/pull/16358>`__: BUG: Fix dtype leak in `PyArray_FromAny` error path
+* `#16358 <https://github.com/numpy/numpy/pull/16358>`__: BUG: Fix dtype leak in ``PyArray_FromAny`` error path
* `#16383 <https://github.com/numpy/numpy/pull/16383>`__: ENH: Optimize Cpu feature detect in X86, fix for GCC on macOS...
* `#16398 <https://github.com/numpy/numpy/pull/16398>`__: MAINT: core: Use a raw string for the fromstring docstring.
* `#16399 <https://github.com/numpy/numpy/pull/16399>`__: MAINT: Make ctypes optional on Windows
diff --git a/doc/changelog/1.19.5-changelog.rst b/doc/changelog/1.19.5-changelog.rst
new file mode 100644
index 000000000..f7cbd5377
--- /dev/null
+++ b/doc/changelog/1.19.5-changelog.rst
@@ -0,0 +1,32 @@
+
+Contributors
+============
+
+A total of 8 people contributed to this release. People with a "+" by their
+names contributed a patch for the first time.
+
+* Charles Harris
+* Christoph Gohlke
+* Matti Picus
+* Raghuveer Devulapalli
+* Sebastian Berg
+* Simon Graham +
+* Veniamin Petrenko +
+* Bernie Gray +
+
+Pull requests merged
+====================
+
+A total of 11 pull requests were merged for this release.
+
+* `#17756 <https://github.com/numpy/numpy/pull/17756>`__: BUG: Fix segfault due to out of bound pointer in floatstatus...
+* `#17774 <https://github.com/numpy/numpy/pull/17774>`__: BUG: fix np.timedelta64('nat').__format__ throwing an exception
+* `#17775 <https://github.com/numpy/numpy/pull/17775>`__: BUG: Fixed file handle leak in array_tofile.
+* `#17786 <https://github.com/numpy/numpy/pull/17786>`__: BUG: Raise recursion error during dimension discovery
+* `#17917 <https://github.com/numpy/numpy/pull/17917>`__: BUG: Fix subarray dtype used with too large count in fromfile
+* `#17918 <https://github.com/numpy/numpy/pull/17918>`__: BUG: 'bool' object has no attribute 'ndim'
+* `#17919 <https://github.com/numpy/numpy/pull/17919>`__: BUG: ensure _UFuncNoLoopError can be pickled
+* `#17924 <https://github.com/numpy/numpy/pull/17924>`__: BLD: use BUFFERSIZE=20 in OpenBLAS
+* `#18026 <https://github.com/numpy/numpy/pull/18026>`__: BLD: update to OpenBLAS 0.3.13
+* `#18036 <https://github.com/numpy/numpy/pull/18036>`__: BUG: make a variable volatile to work around clang compiler bug
+* `#18114 <https://github.com/numpy/numpy/pull/18114>`__: REL: Prepare for the NumPy 1.19.5 release.
diff --git a/doc/changelog/1.20.0-changelog.rst b/doc/changelog/1.20.0-changelog.rst
index 5db423c41..f06bd8a8d 100644
--- a/doc/changelog/1.20.0-changelog.rst
+++ b/doc/changelog/1.20.0-changelog.rst
@@ -2,7 +2,7 @@
Contributors
============
-A total of 182 people contributed to this release. People with a "+" by their
+A total of 184 people contributed to this release. People with a "+" by their
names contributed a patch for the first time.
* Aaron Meurer +
@@ -18,7 +18,7 @@ names contributed a patch for the first time.
* Alexander Kuhn-Regnier +
* Allen Downey +
* Andras Deak
-* Andrea Olivo andryandrew@gmail.com andryandrew +
+* Andrea Olivo +
* Andrew Eckart +
* Anirudh Subramanian
* Anthony Byuraev +
@@ -29,6 +29,7 @@ names contributed a patch for the first time.
* Ben Derrett +
* Ben Elliston +
* Ben Nathanson +
+* Bernie Gray +
* Bharat Medasani +
* Bharat Raghunathan
* Bijesh Mohan +
@@ -42,6 +43,7 @@ names contributed a patch for the first time.
* Charles Harris
* Chris Brown +
* Chris Vavaliaris +
+* Christoph Gohlke
* Chunlin Fang
* CloseChoice +
* Daniel G. A. Smith +
@@ -49,13 +51,14 @@ names contributed a patch for the first time.
* Daniel Vanzo +
* David Pitchford +
* Davide Dal Bosco +
+* Derek Homeier
* Dima Kogan +
* Dmitry Kutlenkov +
* Douglas Fenstermacher +
* Dustin Spicuzza +
* E. Madison Bray +
* Elia Franzella +
-* Enrique Matías Sánchez (Quique) +
+* Enrique Matías Sánchez +
* Erfan Nariman | Veneficus +
* Eric Larson
* Eric Moore
@@ -63,6 +66,7 @@ names contributed a patch for the first time.
* Erik M. Bray
* EthanCJ-git +
* Etienne Guesnet +
+* FX Coudert +
* Felix Divo
* Frankie Robertson +
* Ganesh Kathiresan
@@ -76,7 +80,6 @@ names contributed a patch for the first time.
* InessaPawson +
* Isabela Presedo-Floyd +
* Isuru Fernando
-* Jakob Jacobson +
* Jakob Jakobson +
* Jakub Wilk
* James Myatt +
@@ -155,6 +158,7 @@ names contributed a patch for the first time.
* Tina Oberoi
* Tirth Patel
* Tobias Pitters +
+* Tomoki, Karatsu +
* Tyler Reddy
* Veniamin Petrenko +
* Wansoo Kim +
@@ -168,7 +172,6 @@ names contributed a patch for the first time.
* Zac Hatfield-Dodds
* Zuhair Ali-Khan +
* @abhilash42 +
-* @bernie gray +
* @danbeibei +
* @dojafrat
* @dpitch40 +
@@ -178,7 +181,6 @@ names contributed a patch for the first time.
* @leeyspaul +
* @mitch +
* @prateek arora +
-* @qiyu8 +
* @serge-sans-paille +
* @skywalker +
* @stphnlyd +
@@ -191,7 +193,7 @@ names contributed a patch for the first time.
Pull requests merged
====================
-A total of 650 pull requests were merged for this release.
+A total of 716 pull requests were merged for this release.
* `#13516 <https://github.com/numpy/numpy/pull/13516>`__: ENH: enable multi-platform SIMD compiler optimizations
* `#14779 <https://github.com/numpy/numpy/pull/14779>`__: NEP 36 (fair play)
@@ -202,6 +204,7 @@ A total of 650 pull requests were merged for this release.
* `#15471 <https://github.com/numpy/numpy/pull/15471>`__: BUG: Ensure PyArray_FromScalar always returns the requested dtype
* `#15507 <https://github.com/numpy/numpy/pull/15507>`__: NEP 42: Technical decisions for new DTypes
* `#15508 <https://github.com/numpy/numpy/pull/15508>`__: API: Create Preliminary DTypeMeta class and np.dtype subclasses
+* `#15551 <https://github.com/numpy/numpy/pull/15551>`__: DOC: Simd optimization documentation
* `#15604 <https://github.com/numpy/numpy/pull/15604>`__: MAINT: Avoid exception in NpzFile destructor if constructor raises...
* `#15666 <https://github.com/numpy/numpy/pull/15666>`__: ENH: Improved ``__str__`` for polynomials
* `#15759 <https://github.com/numpy/numpy/pull/15759>`__: BUILD: Remove Accelerate support
@@ -210,6 +213,7 @@ A total of 650 pull requests were merged for this release.
* `#15886 <https://github.com/numpy/numpy/pull/15886>`__: DEP: Deprecate passing shape=None to mean shape=()
* `#15900 <https://github.com/numpy/numpy/pull/15900>`__: DEP: Ensure indexing errors will be raised even on empty results
* `#15997 <https://github.com/numpy/numpy/pull/15997>`__: ENH: improve printing of arrays with multi-line reprs
+* `#16056 <https://github.com/numpy/numpy/pull/16056>`__: DEP: Deprecate inexact matches for mode, searchside
* `#16130 <https://github.com/numpy/numpy/pull/16130>`__: DOC: Correct documentation of ``__array__`` when used as output...
* `#16134 <https://github.com/numpy/numpy/pull/16134>`__: ENH: Implement concatenate dtype and casting keyword arguments
* `#16156 <https://github.com/numpy/numpy/pull/16156>`__: DEP: Deprecate ``numpy.dual``.
@@ -218,14 +222,18 @@ A total of 650 pull requests were merged for this release.
* `#16174 <https://github.com/numpy/numpy/pull/16174>`__: DOC: Add transition note to all lib/poly functions
* `#16200 <https://github.com/numpy/numpy/pull/16200>`__: ENH: Rewrite of array-coercion to support new dtypes
* `#16205 <https://github.com/numpy/numpy/pull/16205>`__: ENH: Add ``full_output`` argument to ``f2py.compile``.
+* `#16207 <https://github.com/numpy/numpy/pull/16207>`__: DOC: Add PyArray_ContiguousFromObject C docs
* `#16232 <https://github.com/numpy/numpy/pull/16232>`__: DEP: Deprecate ufunc.outer with matrix inputs
+* `#16237 <https://github.com/numpy/numpy/pull/16237>`__: MAINT: precompute ``log(2.0 * M_PI)`` in ``random_loggam``
* `#16238 <https://github.com/numpy/numpy/pull/16238>`__: MAINT: Unify cached (C-level static) imports
* `#16239 <https://github.com/numpy/numpy/pull/16239>`__: BUG,DOC: Allow attach docs twice but error if wrong
* `#16242 <https://github.com/numpy/numpy/pull/16242>`__: BUG: Fix default fallback in genfromtxt
* `#16247 <https://github.com/numpy/numpy/pull/16247>`__: ENH:Umath Replace raw SIMD of unary float point(32-64) with NPYV...
* `#16248 <https://github.com/numpy/numpy/pull/16248>`__: MRG, ENH: added edge keyword argument to digitize
+* `#16253 <https://github.com/numpy/numpy/pull/16253>`__: DOC: Clarify tiny/xmin in finfo and machar
+* `#16254 <https://github.com/numpy/numpy/pull/16254>`__: MAINT: Chain exceptions in generate_umath.py
* `#16257 <https://github.com/numpy/numpy/pull/16257>`__: DOC: Update the f2py section of the "Using Python as Glue" page.
-* `#16260 <https://github.com/numpy/numpy/pull/16260>`__: DOC: Improve ``rec.array`` function documentation (#15853)
+* `#16260 <https://github.com/numpy/numpy/pull/16260>`__: DOC: Improve ``rec.array`` function documentation
* `#16266 <https://github.com/numpy/numpy/pull/16266>`__: ENH: include dt64/td64 isinstance checks in ``__init__.pxd``
* `#16267 <https://github.com/numpy/numpy/pull/16267>`__: DOC: Clarifications for np.std
* `#16273 <https://github.com/numpy/numpy/pull/16273>`__: BUG: Order percentile monotonically
@@ -236,6 +244,7 @@ A total of 650 pull requests were merged for this release.
* `#16283 <https://github.com/numpy/numpy/pull/16283>`__: DOC: Add a note about performance of isclose compared to math.isclose
* `#16284 <https://github.com/numpy/numpy/pull/16284>`__: MAINT: Clean up the implementation of quantile
* `#16285 <https://github.com/numpy/numpy/pull/16285>`__: MAINT: Bump hypothesis from 5.12.0 to 5.14.0
+* `#16288 <https://github.com/numpy/numpy/pull/16288>`__: BLD: Avoid "visibility attribute not supported" warning
* `#16291 <https://github.com/numpy/numpy/pull/16291>`__: DOC: Improve "tobytes" docstring.
* `#16292 <https://github.com/numpy/numpy/pull/16292>`__: BUG: Fix tools/download-wheels.py.
* `#16295 <https://github.com/numpy/numpy/pull/16295>`__: BUG: Require Python >= 3.6 in setup.py
@@ -252,14 +261,17 @@ A total of 650 pull requests were merged for this release.
* `#16318 <https://github.com/numpy/numpy/pull/16318>`__: MAINT: Stop Using PyEval_Call* and simplify some uses
* `#16321 <https://github.com/numpy/numpy/pull/16321>`__: ENH: Improve the ARM cpu feature detection by parsing /proc/cpuinfo
* `#16323 <https://github.com/numpy/numpy/pull/16323>`__: DOC: Reconstruct Testing Guideline.
+* `#16327 <https://github.com/numpy/numpy/pull/16327>`__: BUG: Don't segfault on bad __len__ when assigning.
* `#16329 <https://github.com/numpy/numpy/pull/16329>`__: MAINT: Cleanup 'tools/download-wheels.py'
* `#16332 <https://github.com/numpy/numpy/pull/16332>`__: DOC: link np.interp to SciPy's interpolation functions (closes...
* `#16333 <https://github.com/numpy/numpy/pull/16333>`__: DOC: Fix spelling typo - homogenous to homogeneous. (#16324)
* `#16334 <https://github.com/numpy/numpy/pull/16334>`__: ENH: Use AVX-512 for np.isnan, np.infinite, np.isinf and np.signbit
* `#16336 <https://github.com/numpy/numpy/pull/16336>`__: BUG: Fix refcounting in add_newdoc
* `#16337 <https://github.com/numpy/numpy/pull/16337>`__: CI: Create a link for the circleCI artifact
+* `#16346 <https://github.com/numpy/numpy/pull/16346>`__: MAINT: Remove f-strings in setup.py.
* `#16348 <https://github.com/numpy/numpy/pull/16348>`__: BUG: Fix dtype leak in ``PyArray_FromAny`` error path
* `#16349 <https://github.com/numpy/numpy/pull/16349>`__: BUG: Indentation for docstrings
+* `#16350 <https://github.com/numpy/numpy/pull/16350>`__: BUG: Set readonly flag in array interface
* `#16351 <https://github.com/numpy/numpy/pull/16351>`__: BUG: Fix small leaks in error path and ``empty_like`` with shape
* `#16362 <https://github.com/numpy/numpy/pull/16362>`__: MAINT: Streamline download-wheels.
* `#16365 <https://github.com/numpy/numpy/pull/16365>`__: DOC: Fix an obvious mistake in a message printed in doc/Makefile.
@@ -299,6 +311,7 @@ A total of 650 pull requests were merged for this release.
* `#16447 <https://github.com/numpy/numpy/pull/16447>`__: DOC: add a "make show" command to doc/Makefile
* `#16450 <https://github.com/numpy/numpy/pull/16450>`__: DOC: Add a NEP link to all neps.
* `#16452 <https://github.com/numpy/numpy/pull/16452>`__: DOC,ENH: extend error message when Accelerate is detected
+* `#16454 <https://github.com/numpy/numpy/pull/16454>`__: TST: Add tests for PyArray_IntpConverter
* `#16463 <https://github.com/numpy/numpy/pull/16463>`__: DOC: Improve assert_warns docstring with example
* `#16464 <https://github.com/numpy/numpy/pull/16464>`__: MAINT: Bump hypothesis from 5.15.1 to 5.16.0
* `#16465 <https://github.com/numpy/numpy/pull/16465>`__: DOC: Fix development_workflow links
@@ -337,7 +350,8 @@ A total of 650 pull requests were merged for this release.
* `#16572 <https://github.com/numpy/numpy/pull/16572>`__: BUG: fix sin/cos bug when input is strided array
* `#16574 <https://github.com/numpy/numpy/pull/16574>`__: MAINT: fix name of first parameter to dtype constructor in type...
* `#16581 <https://github.com/numpy/numpy/pull/16581>`__: DOC: Added an example for np.transpose(4d_array)
-* `#16583 <https://github.com/numpy/numpy/pull/16583>`__: MAINT: changed ``np.generic`` arguments to positional-only
+* `#16583 <https://github.com/numpy/numpy/pull/16583>`__: MAINT: changed np.generic arguments to positional-only
+* `#16589 <https://github.com/numpy/numpy/pull/16589>`__: MAINT: Remove nickname from polynomial classes.
* `#16590 <https://github.com/numpy/numpy/pull/16590>`__: DOC: Clarify dtype default for logspace and geomspace
* `#16591 <https://github.com/numpy/numpy/pull/16591>`__: DOC: Disallow complex args in arange
* `#16592 <https://github.com/numpy/numpy/pull/16592>`__: BUG: Raise TypeError for float->timedelta promotion
@@ -364,6 +378,7 @@ A total of 650 pull requests were merged for this release.
* `#16639 <https://github.com/numpy/numpy/pull/16639>`__: BUG: Fix uint->timedelta promotion to raise TypeError
* `#16642 <https://github.com/numpy/numpy/pull/16642>`__: MAINT: Replace ``PyUString_GET_SIZE`` with ``PyUnicode_GetLength``.
* `#16643 <https://github.com/numpy/numpy/pull/16643>`__: REL: Fix outdated docs link
+* `#16644 <https://github.com/numpy/numpy/pull/16644>`__: MAINT: Improve performance of np.full
* `#16646 <https://github.com/numpy/numpy/pull/16646>`__: TST: add a static typing test for memoryviews as ArrayLikes
* `#16647 <https://github.com/numpy/numpy/pull/16647>`__: ENH: Added annotations to 8 functions from np.core.fromnumeric
* `#16648 <https://github.com/numpy/numpy/pull/16648>`__: REL: Update master after 1.19.0 release.
@@ -375,10 +390,11 @@ A total of 650 pull requests were merged for this release.
* `#16664 <https://github.com/numpy/numpy/pull/16664>`__: DOC: Add lib.format.open_memmap to autosummary.
* `#16666 <https://github.com/numpy/numpy/pull/16666>`__: BUG: Fix bug in AVX complex absolute while processing array of...
* `#16669 <https://github.com/numpy/numpy/pull/16669>`__: MAINT: remove blacklist/whitelist terms
+* `#16671 <https://github.com/numpy/numpy/pull/16671>`__: DOC: Simplify and update git setup page
* `#16674 <https://github.com/numpy/numpy/pull/16674>`__: TST: Add extra debugging information to CPU features detection
* `#16675 <https://github.com/numpy/numpy/pull/16675>`__: ENH: Add support for file like objects to np.core.records.fromfile
* `#16683 <https://github.com/numpy/numpy/pull/16683>`__: DOC: updated gcc minimum recommend version to build from source
-* `#16684 <https://github.com/numpy/numpy/pull/16684>`__: MAINT: Allow ``None`` to be passed to certain ``generic`` subclasses
+* `#16684 <https://github.com/numpy/numpy/pull/16684>`__: MAINT: Allow None to be passed to certain generic subclasses
* `#16690 <https://github.com/numpy/numpy/pull/16690>`__: DOC: fixed docstring for descr_to_dtype
* `#16691 <https://github.com/numpy/numpy/pull/16691>`__: DOC: Remove "matrix" from ``triu`` docstring.
* `#16696 <https://github.com/numpy/numpy/pull/16696>`__: MAINT: add py.typed sentinel to package manifest
@@ -391,6 +407,7 @@ A total of 650 pull requests were merged for this release.
* `#16710 <https://github.com/numpy/numpy/pull/16710>`__: ENH, BLD: Add RPATH support for AIX
* `#16718 <https://github.com/numpy/numpy/pull/16718>`__: DOC: fix typo
* `#16720 <https://github.com/numpy/numpy/pull/16720>`__: BUG: Fix PyArray_SearchSorted signature.
+* `#16723 <https://github.com/numpy/numpy/pull/16723>`__: NEP: Initial draft for NEP 43 for extensible ufuncs
* `#16729 <https://github.com/numpy/numpy/pull/16729>`__: ENH: Add annotations to the last 8 functions in numpy.core.fromnumeric
* `#16730 <https://github.com/numpy/numpy/pull/16730>`__: ENH: Use f90 compiler specified in f2py command line args for...
* `#16731 <https://github.com/numpy/numpy/pull/16731>`__: DOC: reword random c-api introduction, cython is documented in...
@@ -412,6 +429,8 @@ A total of 650 pull requests were merged for this release.
* `#16770 <https://github.com/numpy/numpy/pull/16770>`__: MAINT: Remove unneeded call to PyUnicode_READY
* `#16771 <https://github.com/numpy/numpy/pull/16771>`__: MAINT: Fix deprecated functions in scalarapi.c
* `#16775 <https://github.com/numpy/numpy/pull/16775>`__: DOC: switch to logo with text
+* `#16777 <https://github.com/numpy/numpy/pull/16777>`__: BUG: Added missing return after raising error in methods.c
+* `#16778 <https://github.com/numpy/numpy/pull/16778>`__: NEP: Update NEP 42 to note the issue of circular references
* `#16782 <https://github.com/numpy/numpy/pull/16782>`__: ENH, TST: Bring the NumPy C SIMD vectorization interface "NPYV"...
* `#16786 <https://github.com/numpy/numpy/pull/16786>`__: BENCH: Add basic benchmarks for scalar indexing and assignment
* `#16789 <https://github.com/numpy/numpy/pull/16789>`__: BUG: fix decode error when building and get rid of warn
@@ -465,6 +484,7 @@ A total of 650 pull requests were merged for this release.
* `#16886 <https://github.com/numpy/numpy/pull/16886>`__: DOC: Fix types including curly braces
* `#16887 <https://github.com/numpy/numpy/pull/16887>`__: DOC: Remove the links for ``True`` and ``False``
* `#16888 <https://github.com/numpy/numpy/pull/16888>`__: ENH: Integrate the new CPU dispatcher with umath generator
+* `#16890 <https://github.com/numpy/numpy/pull/16890>`__: TST, BUG: Re-raise MemoryError exception in test_large_zip's...
* `#16894 <https://github.com/numpy/numpy/pull/16894>`__: DOC: Fix wrong markups in ``arrays.dtypes``
* `#16896 <https://github.com/numpy/numpy/pull/16896>`__: DOC: Remove links for C codes
* `#16897 <https://github.com/numpy/numpy/pull/16897>`__: DOC: Fix the declarations of C fuctions
@@ -478,6 +498,7 @@ A total of 650 pull requests were merged for this release.
* `#16919 <https://github.com/numpy/numpy/pull/16919>`__: DOC: Add ufunc docstring to generated docs.
* `#16925 <https://github.com/numpy/numpy/pull/16925>`__: REL: Update master after 1.19.1 release.
* `#16931 <https://github.com/numpy/numpy/pull/16931>`__: Revert "Merge pull request #16248 from alexrockhill/edge"
+* `#16935 <https://github.com/numpy/numpy/pull/16935>`__: ENH: implement NEP-35's ``like=`` argument
* `#16936 <https://github.com/numpy/numpy/pull/16936>`__: BUG: Fix memory leak of buffer-info cache due to relaxed strides
* `#16938 <https://github.com/numpy/numpy/pull/16938>`__: ENH,API: Store exported buffer info on the array
* `#16940 <https://github.com/numpy/numpy/pull/16940>`__: BLD: update OpenBLAS build
@@ -503,8 +524,10 @@ A total of 650 pull requests were merged for this release.
* `#16996 <https://github.com/numpy/numpy/pull/16996>`__: DOC: Revise glossary page
* `#17002 <https://github.com/numpy/numpy/pull/17002>`__: DOC: clip() allows arguments.
* `#17009 <https://github.com/numpy/numpy/pull/17009>`__: NEP: Updated NEP-35 with keyword-only instruction
+* `#17010 <https://github.com/numpy/numpy/pull/17010>`__: BUG: Raise correct errors in boolean indexing fast path
* `#17013 <https://github.com/numpy/numpy/pull/17013>`__: MAINT: Simplify scalar power
* `#17014 <https://github.com/numpy/numpy/pull/17014>`__: MAINT: Improve error handling in umathmodule setup
+* `#17022 <https://github.com/numpy/numpy/pull/17022>`__: DOC: Fix non-matching pronoun.
* `#17028 <https://github.com/numpy/numpy/pull/17028>`__: DOC: Disclaimer for FFT library
* `#17029 <https://github.com/numpy/numpy/pull/17029>`__: MAINT: Add error return to all casting functionality and NpyIter
* `#17033 <https://github.com/numpy/numpy/pull/17033>`__: BUG: fix a compile and a test warning
@@ -513,8 +536,12 @@ A total of 650 pull requests were merged for this release.
* `#17041 <https://github.com/numpy/numpy/pull/17041>`__: MAINT: Bump hypothesis from 5.23.9 to 5.23.12
* `#17048 <https://github.com/numpy/numpy/pull/17048>`__: STY: core._internal style fixups
* `#17050 <https://github.com/numpy/numpy/pull/17050>`__: MAINT: Remove _EXTRAFLAGS variable
+* `#17050 <https://github.com/numpy/numpy/pull/17051>`__: MAINT: change ``for line in open()`` to ``with open() as f``
+* `#17052 <https://github.com/numpy/numpy/pull/17052>`__: MAINT: Delete obsolete conversion to list
* `#17053 <https://github.com/numpy/numpy/pull/17053>`__: BUG: fix typo in polydiv that prevented promotion to poly1d
+* `#17055 <https://github.com/numpy/numpy/pull/17055>`__: MAINT: Replace lambda function by list comprehension
* `#17058 <https://github.com/numpy/numpy/pull/17058>`__: MAINT: Revert boolean casting back to elementwise comparisons...
+* `#17059 <https://github.com/numpy/numpy/pull/17059>`__: BUG: fix pickling of arrays larger than 2GiB
* `#17062 <https://github.com/numpy/numpy/pull/17062>`__: API, BUG: Raise error on complex input to i0
* `#17063 <https://github.com/numpy/numpy/pull/17063>`__: MAINT: Remove obsolete conversion to set
* `#17067 <https://github.com/numpy/numpy/pull/17067>`__: DEP: lib: Remove the deprecated financial functions.
@@ -552,7 +579,7 @@ A total of 650 pull requests were merged for this release.
* `#17160 <https://github.com/numpy/numpy/pull/17160>`__: Clean up some more bytes vs unicode handling
* `#17161 <https://github.com/numpy/numpy/pull/17161>`__: BUG: Remove Void special case for "safe casting"
* `#17163 <https://github.com/numpy/numpy/pull/17163>`__: MAINT: Remove redundant headers
-* `#17164 <https://github.com/numpy/numpy/pull/17164>`__: MAINT: Remove ``NPY_COPY_PYOBJECT_PTR``
+* `#17164 <https://github.com/numpy/numpy/pull/17164>`__: MAINT: Remove NPY_COPY_PYOBJECT_PTR
* `#17167 <https://github.com/numpy/numpy/pull/17167>`__: BLD: Merge the npysort library into multiarray
* `#17168 <https://github.com/numpy/numpy/pull/17168>`__: TST: Add tests mapping out the rules for metadata in promotion
* `#17171 <https://github.com/numpy/numpy/pull/17171>`__: BUG: revert trim_zeros changes from gh-16911
@@ -572,7 +599,8 @@ A total of 650 pull requests were merged for this release.
* `#17204 <https://github.com/numpy/numpy/pull/17204>`__: DOC: Fixed headings for tutorials so they appear at new theme...
* `#17210 <https://github.com/numpy/numpy/pull/17210>`__: DOC: Canonical_urls
* `#17214 <https://github.com/numpy/numpy/pull/17214>`__: MAINT: Fix various issues with the ``np.generic`` annotations
-* `#17219 <https://github.com/numpy/numpy/pull/17219>`__: BLD: enabled negation of library choices in ``NPY_*_ORDER``
+* `#17215 <https://github.com/numpy/numpy/pull/17215>`__: DOC: Use official MATLAB spelling in numpy-for-matlab-users.rst
+* `#17219 <https://github.com/numpy/numpy/pull/17219>`__: BLD: enabled negation of library choices in NPY_*_ORDER
* `#17220 <https://github.com/numpy/numpy/pull/17220>`__: BUG, DOC: comment out metadata added via javascript
* `#17222 <https://github.com/numpy/numpy/pull/17222>`__: MAINT, DOC: move informational files from numpy.doc.*.py to their...
* `#17223 <https://github.com/numpy/numpy/pull/17223>`__: MAINT: use sysconfig not distutils.sysconfig where possible
@@ -581,7 +609,9 @@ A total of 650 pull requests were merged for this release.
* `#17233 <https://github.com/numpy/numpy/pull/17233>`__: DEP: Deprecated ndindex.ndincr
* `#17235 <https://github.com/numpy/numpy/pull/17235>`__: MAINT: Remove old PY_VERSION_HEX and sys.version_info code
* `#17237 <https://github.com/numpy/numpy/pull/17237>`__: BUG: Avoid using ``np.random`` in typing tests.
+* `#17238 <https://github.com/numpy/numpy/pull/17238>`__: DOC: Use SPDX license expressions with correct license
* `#17239 <https://github.com/numpy/numpy/pull/17239>`__: DOC: Fix link quick-start in old random API functions
+* `#17240 <https://github.com/numpy/numpy/pull/17240>`__: MAINT: added exception chaining in shape_base.py
* `#17241 <https://github.com/numpy/numpy/pull/17241>`__: MAINT: ``__array_interface__`` data address cannot be bytes
* `#17242 <https://github.com/numpy/numpy/pull/17242>`__: MAINT: Run slow CI jobs earlier so builds finishes sooner
* `#17247 <https://github.com/numpy/numpy/pull/17247>`__: ENH: Add tool to help speed up Travis CI
@@ -652,6 +682,7 @@ A total of 650 pull requests were merged for this release.
* `#17391 <https://github.com/numpy/numpy/pull/17391>`__: DOC: Replace "About NumPy" with "Document conventions"
* `#17392 <https://github.com/numpy/numpy/pull/17392>`__: DOC: Update info on doc style rules
* `#17393 <https://github.com/numpy/numpy/pull/17393>`__: BUG: Fix default void, datetime, and timedelta in array coercion
+* `#17394 <https://github.com/numpy/numpy/pull/17394>`__: ENH: Implement sliding window
* `#17396 <https://github.com/numpy/numpy/pull/17396>`__: MAINT: Replace append_metastr_to_string function.
* `#17399 <https://github.com/numpy/numpy/pull/17399>`__: BLD: Fixed ARGOUTVIEWM memory deallocation. Closes #17398.
* `#17400 <https://github.com/numpy/numpy/pull/17400>`__: DOC: rm incorrect alias from recarray user article.
@@ -703,6 +734,7 @@ A total of 650 pull requests were merged for this release.
* `#17483 <https://github.com/numpy/numpy/pull/17483>`__: DOC: Fix the references for ``random.*``
* `#17485 <https://github.com/numpy/numpy/pull/17485>`__: BLD: circleCI- merge before build, add -n to sphinx
* `#17487 <https://github.com/numpy/numpy/pull/17487>`__: MAINT: Remove duplicate placeholder annotations
+* `#17493 <https://github.com/numpy/numpy/pull/17493>`__: DOC: New round of NEP 42 edits
* `#17497 <https://github.com/numpy/numpy/pull/17497>`__: DOC: Use consistent lowercase on docs landing page
* `#17498 <https://github.com/numpy/numpy/pull/17498>`__: MAINT: fix incompatible type comparison in numpy.lib.utils.info
* `#17501 <https://github.com/numpy/numpy/pull/17501>`__: BUG: Fix failures in master related to userdtype registeration
@@ -797,7 +829,9 @@ A total of 650 pull requests were merged for this release.
* `#17700 <https://github.com/numpy/numpy/pull/17700>`__: Fix small typos.
* `#17701 <https://github.com/numpy/numpy/pull/17701>`__: BUG: Fixed an issue where ``.pyi`` files were ignored by numpy...
* `#17703 <https://github.com/numpy/numpy/pull/17703>`__: Fix Doc Typos & Added Example
+* `#17706 <https://github.com/numpy/numpy/pull/17706>`__: BUG: Raise promotion error if a DType was provided in array coercion
* `#17708 <https://github.com/numpy/numpy/pull/17708>`__: Improve the einsum bench by adding new bench cases and variable...
+* `#17711 <https://github.com/numpy/numpy/pull/17711>`__: ENH: adds type hints to numpy.version
* `#17715 <https://github.com/numpy/numpy/pull/17715>`__: REV: Revert gh-17654 - f2py incorrectly translates dimension...
* `#17717 <https://github.com/numpy/numpy/pull/17717>`__: MAINT: Add more files to ``.gitgnore``
* `#17720 <https://github.com/numpy/numpy/pull/17720>`__: API: Do not import sliding_window_view to main namespace
@@ -833,7 +867,7 @@ A total of 650 pull requests were merged for this release.
* `#17829 <https://github.com/numpy/numpy/pull/17829>`__: MAINT: Bump hypothesis from 5.41.2 to 5.41.3
* `#17830 <https://github.com/numpy/numpy/pull/17830>`__: TST: Add back durations flag for DEBUG builds.
* `#17832 <https://github.com/numpy/numpy/pull/17832>`__: BUG: Fix subarray dtype used with too large count in fromfile
-* `#17833 <https://github.com/numpy/numpy/pull/17833>`__: BUG: Fix pickling of scalars with ``NPY_LISTPICKLE``
+* `#17833 <https://github.com/numpy/numpy/pull/17833>`__: BUG: Fix pickling of scalars with NPY_LISTPICKLE
* `#17838 <https://github.com/numpy/numpy/pull/17838>`__: DOC: Update the ``numpy.typing`` documentation
* `#17841 <https://github.com/numpy/numpy/pull/17841>`__: DOC: Fixing boilerplate code example
* `#17844 <https://github.com/numpy/numpy/pull/17844>`__: MAINT: Add ``__all__`` to ``numpy.typing``
@@ -841,5 +875,39 @@ A total of 650 pull requests were merged for this release.
* `#17855 <https://github.com/numpy/numpy/pull/17855>`__: BUG: Fix incorrect C function prototypes/declarations.
* `#17857 <https://github.com/numpy/numpy/pull/17857>`__: MAINT: Prepare for the NumPy 1.20.x branch.
* `#17869 <https://github.com/numpy/numpy/pull/17869>`__: BUG, TST: use python-version not PYTHON_VERSION
-* `#17875 <https://github.com/numpy/numpy/pull/17875>`__: DOC: Prepare for 1.20.0 release
* `#17879 <https://github.com/numpy/numpy/pull/17879>`__: BUG: Fix buffer readflag errors and small leaks
+* `#17893 <https://github.com/numpy/numpy/pull/17893>`__: DOC: Prepare for 1.20.0 release
+* `#17898 <https://github.com/numpy/numpy/pull/17898>`__: MAINT: Remove remaining uses of Python 3.6.
+* `#17899 <https://github.com/numpy/numpy/pull/17899>`__: TST: use latest pypy37 not pypy36
+* `#17901 <https://github.com/numpy/numpy/pull/17901>`__: MAINT: clean up a spurious warning in numpy/typing/setup.py
+* `#17904 <https://github.com/numpy/numpy/pull/17904>`__: ENH: Speed up default ``where`` in the reduce-like method
+* `#17915 <https://github.com/numpy/numpy/pull/17915>`__: TST: remove stray '+' from f-string upgrade
+* `#17916 <https://github.com/numpy/numpy/pull/17916>`__: ENH: add support for fujitsu compiler to numpy.
+* `#17922 <https://github.com/numpy/numpy/pull/17922>`__: BUG: 'bool' object has no attribute 'ndim'
+* `#17931 <https://github.com/numpy/numpy/pull/17931>`__: DOC: Update release notes to mention ``type(dtype) is not np.dtype``
+* `#17990 <https://github.com/numpy/numpy/pull/17990>`__: BUG: Replace f-string in setup.py
+* `#18015 <https://github.com/numpy/numpy/pull/18015>`__: BUG: Ignore fewer errors during array-coercion
+* `#18016 <https://github.com/numpy/numpy/pull/18016>`__: BUG: Fix a MacOS build failure
+* `#18017 <https://github.com/numpy/numpy/pull/18017>`__: TST: Fix crosstalk issues with polynomial str tests.
+* `#18018 <https://github.com/numpy/numpy/pull/18018>`__: TST: Ensure tests are not sensitive to execution order
+* `#18019 <https://github.com/numpy/numpy/pull/18019>`__: BLD: update to OpenBLAS 0.3.13
+* `#18024 <https://github.com/numpy/numpy/pull/18024>`__: DEP: Futurewarn on requiring __len__ on array-likes
+* `#18035 <https://github.com/numpy/numpy/pull/18035>`__: BUG: make a variable volatile to work around clang compiler bug
+* `#18049 <https://github.com/numpy/numpy/pull/18049>`__: TST: add back sdist test run
+* `#18063 <https://github.com/numpy/numpy/pull/18063>`__: BUG: Fix concatenation when the output is "S" or "U"
+* `#18064 <https://github.com/numpy/numpy/pull/18064>`__: BLD, BUG: Fix detecting aarch64 on macOS
+* `#18068 <https://github.com/numpy/numpy/pull/18068>`__: REL: Prepare for 1.20.0rc2 release.
+* `#18108 <https://github.com/numpy/numpy/pull/18108>`__: BUG, BLD: Generate the main dispatcher config header into the...
+* `#18120 <https://github.com/numpy/numpy/pull/18120>`__: BUG, SIMD: Fix _simd module build for 64bit ARM/NEON clang
+* `#18127 <https://github.com/numpy/numpy/pull/18127>`__: REL: Update 1.20.x after 1.19.5 release.
+* `#18130 <https://github.com/numpy/numpy/pull/18130>`__: BUG: Fix promotion of half and string
+* `#18146 <https://github.com/numpy/numpy/pull/18146>`__: BUG, MAINT: improve avx512 mask logical operations
+* `#18154 <https://github.com/numpy/numpy/pull/18154>`__: BUG: Promotion between strings and objects was assymetric
+* `#18192 <https://github.com/numpy/numpy/pull/18192>`__: MAINT: Use explicit reexports for numpy.typing objects
+* `#18201 <https://github.com/numpy/numpy/pull/18201>`__: BUG: Keep ignoring most errors during array-protocol lookup
+* `#18219 <https://github.com/numpy/numpy/pull/18219>`__: MAINT: random shuffle: warn on unrecognized objects, fix empty...
+* `#18231 <https://github.com/numpy/numpy/pull/18231>`__: BLD: update OpenBLAS to af2b0d02
+* `#18237 <https://github.com/numpy/numpy/pull/18237>`__: DOC: Clarify the type alias deprecation message
+* `#18257 <https://github.com/numpy/numpy/pull/18257>`__: BUG: Ensure too many advanced indices raises an exception
+* `#18258 <https://github.com/numpy/numpy/pull/18258>`__: MAINT: add an 'apt update'
+* `#18259 <https://github.com/numpy/numpy/pull/18259>`__: DOC: Prepare for the NumPy 1.20.0 release.
diff --git a/doc/changelog/1.20.1-changelog.rst b/doc/changelog/1.20.1-changelog.rst
new file mode 100644
index 000000000..215cdca3c
--- /dev/null
+++ b/doc/changelog/1.20.1-changelog.rst
@@ -0,0 +1,36 @@
+
+Contributors
+============
+
+A total of 8 people contributed to this release. People with a "+" by their
+names contributed a patch for the first time.
+
+* Bas van Beek
+* Charles Harris
+* Nicholas McKibben +
+* Pearu Peterson
+* Ralf Gommers
+* Sebastian Berg
+* Tyler Reddy
+* @Aerysv +
+
+Pull requests merged
+====================
+
+A total of 15 pull requests were merged for this release.
+
+* `#18306 <https://github.com/numpy/numpy/pull/18306>`__: MAINT: Add missing placeholder annotations
+* `#18310 <https://github.com/numpy/numpy/pull/18310>`__: BUG: Fix typo in ``numpy.__init__.py``
+* `#18326 <https://github.com/numpy/numpy/pull/18326>`__: BUG: don't mutate list of fake libraries while iterating over...
+* `#18327 <https://github.com/numpy/numpy/pull/18327>`__: MAINT: gracefully shuffle memoryviews
+* `#18328 <https://github.com/numpy/numpy/pull/18328>`__: BUG: Use C linkage for random distributions
+* `#18336 <https://github.com/numpy/numpy/pull/18336>`__: CI: fix when GitHub Actions builds trigger, and allow ci skips
+* `#18337 <https://github.com/numpy/numpy/pull/18337>`__: BUG: Allow unmodified use of isclose, allclose, etc. with timedelta
+* `#18345 <https://github.com/numpy/numpy/pull/18345>`__: BUG: Allow pickling all relevant DType types/classes
+* `#18351 <https://github.com/numpy/numpy/pull/18351>`__: BUG: Fix missing signed_char dependency. Closes #18335.
+* `#18352 <https://github.com/numpy/numpy/pull/18352>`__: DOC: Change license date 2020 -> 2021
+* `#18353 <https://github.com/numpy/numpy/pull/18353>`__: CI: CircleCI seems to occasionally time out, increase the limit
+* `#18354 <https://github.com/numpy/numpy/pull/18354>`__: BUG: Fix f2py bugs when wrapping F90 subroutines.
+* `#18356 <https://github.com/numpy/numpy/pull/18356>`__: MAINT: crackfortran regex simplify
+* `#18357 <https://github.com/numpy/numpy/pull/18357>`__: BUG: threads.h existence test requires GLIBC > 2.12.
+* `#18359 <https://github.com/numpy/numpy/pull/18359>`__: REL: Prepare for the NumPy 1.20.1 release.
diff --git a/doc/changelog/1.20.2-changelog.rst b/doc/changelog/1.20.2-changelog.rst
new file mode 100644
index 000000000..831cf0332
--- /dev/null
+++ b/doc/changelog/1.20.2-changelog.rst
@@ -0,0 +1,40 @@
+
+Contributors
+============
+
+A total of 7 people contributed to this release. People with a "+" by their
+names contributed a patch for the first time.
+
+* Allan Haldane
+* Bas van Beek
+* Charles Harris
+* Christoph Gohlke
+* Mateusz Sokół +
+* Michael Lamparski
+* Sebastian Berg
+
+Pull requests merged
+====================
+
+A total of 20 pull requests were merged for this release.
+
+* `#18382 <https://github.com/numpy/numpy/pull/18382>`__: MAINT: Update f2py from master.
+* `#18459 <https://github.com/numpy/numpy/pull/18459>`__: BUG: ``diagflat`` could overflow on windows or 32-bit platforms
+* `#18460 <https://github.com/numpy/numpy/pull/18460>`__: BUG: Fix refcount leak in f2py ``complex_double_from_pyobj``.
+* `#18461 <https://github.com/numpy/numpy/pull/18461>`__: BUG: Fix tiny memory leaks when ``like=`` overrides are used
+* `#18462 <https://github.com/numpy/numpy/pull/18462>`__: BUG: Remove temporary change of descr/flags in VOID functions
+* `#18469 <https://github.com/numpy/numpy/pull/18469>`__: BUG: Segfault in nditer buffer dealloc for Object arrays
+* `#18485 <https://github.com/numpy/numpy/pull/18485>`__: BUG: Remove suspicious type casting
+* `#18486 <https://github.com/numpy/numpy/pull/18486>`__: BUG: remove nonsensical comparison of pointer < 0
+* `#18487 <https://github.com/numpy/numpy/pull/18487>`__: BUG: verify pointer against NULL before using it
+* `#18488 <https://github.com/numpy/numpy/pull/18488>`__: BUG: check if PyArray_malloc succeeded
+* `#18546 <https://github.com/numpy/numpy/pull/18546>`__: BUG: incorrect error fallthrough in nditer
+* `#18559 <https://github.com/numpy/numpy/pull/18559>`__: CI: Backport CI fixes from main.
+* `#18599 <https://github.com/numpy/numpy/pull/18599>`__: MAINT: Add annotations for ``dtype.__getitem__``, ``__mul__`` and...
+* `#18611 <https://github.com/numpy/numpy/pull/18611>`__: BUG: NameError in numpy.distutils.fcompiler.compaq
+* `#18612 <https://github.com/numpy/numpy/pull/18612>`__: BUG: Fixed ``where`` keyword for ``np.mean`` & ``np.var`` methods
+* `#18617 <https://github.com/numpy/numpy/pull/18617>`__: CI: Update apt package list before Python install
+* `#18636 <https://github.com/numpy/numpy/pull/18636>`__: MAINT: Ensure that re-exported sub-modules are properly annotated
+* `#18638 <https://github.com/numpy/numpy/pull/18638>`__: BUG: Fix ma coercion list-of-ma-arrays if they do not cast to...
+* `#18661 <https://github.com/numpy/numpy/pull/18661>`__: BUG: Fix small valgrind-found issues
+* `#18671 <https://github.com/numpy/numpy/pull/18671>`__: BUG: Fix small issues found with pytest-leaks
diff --git a/doc/changelog/1.20.3-changelog.rst b/doc/changelog/1.20.3-changelog.rst
new file mode 100644
index 000000000..df7f10565
--- /dev/null
+++ b/doc/changelog/1.20.3-changelog.rst
@@ -0,0 +1,35 @@
+
+Contributors
+============
+
+A total of 7 people contributed to this release. People with a "+" by their
+names contributed a patch for the first time.
+
+* Anne Archibald
+* Bas van Beek
+* Charles Harris
+* Dong Keun Oh +
+* Kamil Choudhury +
+* Sayed Adel
+* Sebastian Berg
+
+Pull requests merged
+====================
+
+A total of 15 pull requests were merged for this release.
+
+* `#18763 <https://github.com/numpy/numpy/pull/18763>`__: BUG: Correct ``datetime64`` missing type overload for ``datetime.date``...
+* `#18764 <https://github.com/numpy/numpy/pull/18764>`__: MAINT: Remove ``__all__`` in favor of explicit re-exports
+* `#18768 <https://github.com/numpy/numpy/pull/18768>`__: BLD: Strip extra newline when dumping gfortran version on MacOS
+* `#18769 <https://github.com/numpy/numpy/pull/18769>`__: BUG: fix segfault in object/longdouble operations
+* `#18794 <https://github.com/numpy/numpy/pull/18794>`__: MAINT: Use towncrier build explicitly
+* `#18887 <https://github.com/numpy/numpy/pull/18887>`__: MAINT: Relax certain integer-type constraints
+* `#18915 <https://github.com/numpy/numpy/pull/18915>`__: MAINT: Remove unsafe unions and ABCs from return-annotations
+* `#18921 <https://github.com/numpy/numpy/pull/18921>`__: MAINT: Allow more recursion depth for scalar tests.
+* `#18922 <https://github.com/numpy/numpy/pull/18922>`__: BUG: Initialize the full nditer buffer in case of error
+* `#18923 <https://github.com/numpy/numpy/pull/18923>`__: BLD: remove unnecessary flag ``-faltivec`` on macOS
+* `#18924 <https://github.com/numpy/numpy/pull/18924>`__: MAINT, CI: treats _SIMD module build warnings as errors through...
+* `#18925 <https://github.com/numpy/numpy/pull/18925>`__: BUG: for MINGW, threads.h existence test requires GLIBC > 2.12
+* `#18941 <https://github.com/numpy/numpy/pull/18941>`__: BUG: Make changelog recognize gh- as a PR number prefix.
+* `#18948 <https://github.com/numpy/numpy/pull/18948>`__: REL, DOC: Prepare for the NumPy 1.20.3 release.
+* `#18953 <https://github.com/numpy/numpy/pull/18953>`__: BUG: Fix failing mypy test in 1.20.x.
diff --git a/doc/changelog/1.21.0-changelog.rst b/doc/changelog/1.21.0-changelog.rst
new file mode 100644
index 000000000..947da4da7
--- /dev/null
+++ b/doc/changelog/1.21.0-changelog.rst
@@ -0,0 +1,769 @@
+
+Contributors
+============
+
+A total of 175 people contributed to this release. People with a "+" by their
+names contributed a patch for the first time.
+
+* @8bitmp3 +
+* @DWesl +
+* @Endolith
+* @Illviljan +
+* @Lbogula +
+* @Lisa +
+* @Patrick +
+* @Scian +
+* @h-vetinari +
+* @h6197627 +
+* @jbCodeHub +
+* @legoffant +
+* @sfolje0 +
+* @tautaus +
+* @yetanothercheer +
+* Abhay Raghuvanshi +
+* Adrian Price-Whelan +
+* Aerik Pawson +
+* Agbonze Osazuwa +
+* Aitik Gupta +
+* Al-Baraa El-Hag
+* Alex Henrie
+* Alexander Hunt +
+* Alizé Papp +
+* Allan Haldane
+* Amarnath1904 +
+* Amrit Krishnan +
+* Andras Deak
+* AngelGris +
+* Anne Archibald
+* Anthony Vo +
+* Antony Lee
+* Atharva-Vidwans +
+* Ayush Verma +
+* Bas van Beek
+* Bharat Raghunathan
+* Bhargav V +
+* Brian Soto
+* Carl Michal +
+* Charles Harris
+* Charles Stern +
+* Chiara Marmo +
+* Chris Barnes +
+* Chris Vavaliaris
+* Christina Hedges +
+* Christoph Gohlke
+* Christopher Dahlin +
+* Christos Efstathiou +
+* Chunlin Fang
+* Constanza Fierro +
+* Daniel Evans +
+* Daniel Montes +
+* Dario Mory +
+* David Carlier +
+* David Stansby
+* Deepyaman Datta +
+* Derek Homeier
+* Dong Keun Oh +
+* Dylan Cutler +
+* Eric Larson
+* Eric Wieser
+* Eva Jau +
+* Evgeni Burovski
+* FX Coudert +
+* Faris A Chugthai +
+* Filip Ter +
+* Filip Trojan +
+* François Le Lay +
+* Ganesh Kathiresan
+* Giannis Zapantis +
+* Giulio Procopio +
+* Greg Lucas +
+* Hollow Man +
+* Holly Corbett +
+* I-Shen Leong +
+* Inessa Pawson
+* Isabela Presedo-Floyd
+* Ismael Jimenez +
+* Isuru Fernando
+* Jakob Jakobson
+* James Gerity +
+* Jamie Macey +
+* Jasmin Classen +
+* Jody Klymak +
+* Joseph Fox-Rabinovitz
+* Jérome Eertmans +
+* Jérôme Kieffer +
+* Kamil Choudhury +
+* Kasia Leszek +
+* Keller Meier +
+* Kenichi Maehashi
+* Kevin Sheppard
+* Kulin Seth +
+* Kumud Lakara +
+* Laura Kopf +
+* Laura Martens +
+* Leo Singer +
+* Leonardus Chen +
+* Lima Tango +
+* Lumir Balhar +
+* Maia Kaplan +
+* Mainak Debnath +
+* Marco Aurélio da Costa +
+* Marta Lemanczyk +
+* Marten van Kerkwijk
+* Mary Conley +
+* Marysia Winkels +
+* Mateusz Sokół +
+* Matt Haberland
+* Matt Hall +
+* Matt Ord +
+* Matthew Badin +
+* Matthias Bussonnier
+* Matthias Geier
+* Matti Picus
+* Matías Ríos +
+* Maxim Belkin +
+* Melissa Weber Mendonça
+* Meltem Eren Copur +
+* Michael Dubravski +
+* Michael Lamparski
+* Michal W. Tarnowski +
+* Michał Górny +
+* Mike Boyle +
+* Mike Toews
+* Misal Raj +
+* Mitchell Faas +
+* Mukulikaa Parhari +
+* Neil Girdhar +
+* Nicholas McKibben +
+* Nico Schlömer
+* Nicolas Hug +
+* Nilo Kruchelski +
+* Nirjas Jakilim +
+* Ohad Ravid +
+* Olivier Grisel
+* Pamphile ROY +
+* Panos Mavrogiorgos +
+* Patrick T. Komiske III +
+* Pearu Peterson
+* Peter Hawkins +
+* Raghuveer Devulapalli
+* Ralf Gommers
+* Raúl Montón Pinillos +
+* Rin Arakaki +
+* Robert Kern
+* Rohit Sanjay
+* Roman Yurchak
+* Ronan Lamy
+* Ross Barnowski
+* Ryan C Cooper
+* Ryan Polley +
+* Ryan Soklaski
+* Sabrina Simao +
+* Sayed Adel
+* Sebastian Berg
+* Shen Zhou +
+* Stefan van der Walt
+* Sylwester Arabas +
+* Takanori Hirano
+* Tania Allard +
+* Thomas J. Fan +
+* Thomas Orgis +
+* Tim Hoffmann
+* Tomoki, Karatsu +
+* Tong Zou +
+* Touqir Sajed +
+* Tyler Reddy
+* Wansoo Kim
+* Warren Weckesser
+* Weh Andreas +
+* Yang Hau
+* Yashasvi Misra +
+* Zolboo Erdenebaatar +
+* Zolisa Bleki
+
+Pull requests merged
+====================
+
+A total of 581 pull requests were merged for this release.
+
+* `#13578 <https://github.com/numpy/numpy/pull/13578>`__: DEP: Deprecate `data_type.dtype` if attribute is not already...
+* `#15269 <https://github.com/numpy/numpy/pull/15269>`__: ENH: Implement faster keyword argument parsing capable of ``METH_FASTCALL``
+* `#15271 <https://github.com/numpy/numpy/pull/15271>`__: ENH: Optimize and cleanup ufunc calls and ufunc CheckOverrides
+* `#15392 <https://github.com/numpy/numpy/pull/15392>`__: BUG: Remove temporary change of descr/flags in VOID functions
+* `#16164 <https://github.com/numpy/numpy/pull/16164>`__: DOC: Add more information about poly1d -> polynomial to reference...
+* `#16241 <https://github.com/numpy/numpy/pull/16241>`__: ENH: Warn when reloading numpy or using numpy in sub-interpreter
+* `#16370 <https://github.com/numpy/numpy/pull/16370>`__: DOC: Fix for building with sphinx 3
+* `#16588 <https://github.com/numpy/numpy/pull/16588>`__: DOC: unify the docs for np.transpose and ndarray.transpose
+* `#16818 <https://github.com/numpy/numpy/pull/16818>`__: DOC: added examples section for rfft2 and irfft2 docstring
+* `#16855 <https://github.com/numpy/numpy/pull/16855>`__: DOC: Fix Typo (Wrong argument name)
+* `#16987 <https://github.com/numpy/numpy/pull/16987>`__: ENH: Phase unwrapping generalized to arbitrary interval size
+* `#17102 <https://github.com/numpy/numpy/pull/17102>`__: SIMD: Optimize the performance of np.packbits in AVX2/AVX512F/VSX.
+* `#17122 <https://github.com/numpy/numpy/pull/17122>`__: MAINT: Use numpy version for f2py version.
+* `#17492 <https://github.com/numpy/numpy/pull/17492>`__: DEP: Shift correlate mode parsing to C and deprecate inexact...
+* `#17586 <https://github.com/numpy/numpy/pull/17586>`__: DEP: Formally deprecate `np.typeDict`
+* `#17587 <https://github.com/numpy/numpy/pull/17587>`__: SIMD: Replace raw SIMD of sin/cos with NPYV(universal intrinsics)
+* `#17636 <https://github.com/numpy/numpy/pull/17636>`__: MAINT: Bump pydata-sphinx-theme and set logo link to index
+* `#17637 <https://github.com/numpy/numpy/pull/17637>`__: DOC: Add module template
+* `#17719 <https://github.com/numpy/numpy/pull/17719>`__: ENH: Make `ndarray` generic w.r.t. its shape and dtype
+* `#17727 <https://github.com/numpy/numpy/pull/17727>`__: ENH: Added libdivide for floor divide
+* `#17736 <https://github.com/numpy/numpy/pull/17736>`__: BUG, Benchmark: fix passing optimization build options to asv
+* `#17737 <https://github.com/numpy/numpy/pull/17737>`__: MAINT, Benchmark: print the supported CPU features during the...
+* `#17778 <https://github.com/numpy/numpy/pull/17778>`__: ENH: Add annotations for comparison operations
+* `#17782 <https://github.com/numpy/numpy/pull/17782>`__: SIMD: Optimize the performance of einsum's submodule multiply...
+* `#17789 <https://github.com/numpy/numpy/pull/17789>`__: ENH, SIMD: Add new NPYV intrinsics pack(0)
+* `#17790 <https://github.com/numpy/numpy/pull/17790>`__: ENH, SIMD: Add new NPYV intrinsics pack(1)
+* `#17791 <https://github.com/numpy/numpy/pull/17791>`__: BLD: Enable Werror=undef in travis
+* `#17792 <https://github.com/numpy/numpy/pull/17792>`__: ENH: add support for fujitsu compiler to numpy.
+* `#17795 <https://github.com/numpy/numpy/pull/17795>`__: ENH: Add two new `_<X>Like` unions
+* `#17817 <https://github.com/numpy/numpy/pull/17817>`__: BUG: Ignore fewer errors during array-coercion
+* `#17836 <https://github.com/numpy/numpy/pull/17836>`__: MAINT: Add git rules to ignore all SIMD generated files
+* `#17843 <https://github.com/numpy/numpy/pull/17843>`__: ENH: Add a mypy plugin for inferring platform-specific `np.number`...
+* `#17847 <https://github.com/numpy/numpy/pull/17847>`__: TST: use latest pypy37 not pypy36
+* `#17852 <https://github.com/numpy/numpy/pull/17852>`__: DOC: Doc for deprecate_with_doc
+* `#17853 <https://github.com/numpy/numpy/pull/17853>`__: DOC: Clarify docs of np.resize().
+* `#17861 <https://github.com/numpy/numpy/pull/17861>`__: MAINT: Update master after 1.20.x branch.
+* `#17862 <https://github.com/numpy/numpy/pull/17862>`__: Make it clearer that np.interp input must be monotonically increasing
+* `#17863 <https://github.com/numpy/numpy/pull/17863>`__: MAINT: Implement new casting loops based on NEP 42 and 43
+* `#17866 <https://github.com/numpy/numpy/pull/17866>`__: DOC: fix typo in glossary.rst
+* `#17868 <https://github.com/numpy/numpy/pull/17868>`__: BUG, TST: use python-version not PYTHON_VERSION
+* `#17872 <https://github.com/numpy/numpy/pull/17872>`__: DOC: update the release howto for oldest-supported-numpy
+* `#17874 <https://github.com/numpy/numpy/pull/17874>`__: MAINT: clean up a spurious warning in numpy/typing/setup.py
+* `#17875 <https://github.com/numpy/numpy/pull/17875>`__: DOC: Prepare for 1.20.0 release
+* `#17876 <https://github.com/numpy/numpy/pull/17876>`__: DOC: fixed typo in np-indexing.png explaining [-2:] slice in...
+* `#17877 <https://github.com/numpy/numpy/pull/17877>`__: BUG: Fix buffer readflag errors and small leaks
+* `#17878 <https://github.com/numpy/numpy/pull/17878>`__: BUG: np.arange: Allow `stop` not `start` as sole kwargs.
+* `#17881 <https://github.com/numpy/numpy/pull/17881>`__: MAINT: Bump hypothesis from 5.41.3 to 5.41.4
+* `#17883 <https://github.com/numpy/numpy/pull/17883>`__: MAINT: Remove duplicate dictionary entry
+* `#17884 <https://github.com/numpy/numpy/pull/17884>`__: BUG: numpy.putmask not respecting writeable flag
+* `#17886 <https://github.com/numpy/numpy/pull/17886>`__: ENH: Timestamp development versions.
+* `#17887 <https://github.com/numpy/numpy/pull/17887>`__: DOC: Update arraycreation
+* `#17888 <https://github.com/numpy/numpy/pull/17888>`__: DOC: Correct sentence/statement composition
+* `#17889 <https://github.com/numpy/numpy/pull/17889>`__: DOC: Rename basics to fundamentals + added description
+* `#17895 <https://github.com/numpy/numpy/pull/17895>`__: MAINT: Remove remaining uses of Python 3.6.
+* `#17896 <https://github.com/numpy/numpy/pull/17896>`__: ENH: Speed up default `where` in the reduce-like method
+* `#17897 <https://github.com/numpy/numpy/pull/17897>`__: BUG: merging PR to use -Werror=undef broke another PR
+* `#17900 <https://github.com/numpy/numpy/pull/17900>`__: DEP: Finalize unravel_index `dims` alias for `shape` keyword
+* `#17906 <https://github.com/numpy/numpy/pull/17906>`__: BUG: Fix a MacOS build failure
+* `#17907 <https://github.com/numpy/numpy/pull/17907>`__: BUG: 'bool' object has no attribute 'ndim'
+* `#17912 <https://github.com/numpy/numpy/pull/17912>`__: BUG: remove stray '+' from f-string upgrade in numba/extending.py
+* `#17914 <https://github.com/numpy/numpy/pull/17914>`__: DOC: Update release notes to mention `type(dtype) is not np.dtype`
+* `#17920 <https://github.com/numpy/numpy/pull/17920>`__: NEP: Update NEP 42 and 43 according to the current implementation
+* `#17921 <https://github.com/numpy/numpy/pull/17921>`__: BUG: Enforce high >= low on uniform number generators
+* `#17929 <https://github.com/numpy/numpy/pull/17929>`__: MAINT: Replace `contextlib_nullcontext` with `contextlib.nullcontext`
+* `#17934 <https://github.com/numpy/numpy/pull/17934>`__: DOC: Add information about leak checking and valgrind
+* `#17936 <https://github.com/numpy/numpy/pull/17936>`__: TST: Fixed an issue where the typing tests would fail for comparison...
+* `#17942 <https://github.com/numpy/numpy/pull/17942>`__: DOC: Clarify savez documentation of naming arrays in output file
+* `#17943 <https://github.com/numpy/numpy/pull/17943>`__: [DOC]: Wrong length for underline in docstring.
+* `#17945 <https://github.com/numpy/numpy/pull/17945>`__: MAINT: Bump hypothesis from 5.41.4 to 5.41.5
+* `#17950 <https://github.com/numpy/numpy/pull/17950>`__: BUG: Removed empty String from Nag Compiler's Flags
+* `#17953 <https://github.com/numpy/numpy/pull/17953>`__: NEP: Accept NEP 42 -- New and extensible DTypes
+* `#17955 <https://github.com/numpy/numpy/pull/17955>`__: DOC: Replace {var} in docstrings type annotation with `scalar...
+* `#17956 <https://github.com/numpy/numpy/pull/17956>`__: ENH: Use versioneer to manage numpy versions.
+* `#17957 <https://github.com/numpy/numpy/pull/17957>`__: TST: Fix crosstalk issues with polynomial str tests.
+* `#17958 <https://github.com/numpy/numpy/pull/17958>`__: MAINT: Optimize the performance of count_nonzero by using universal...
+* `#17960 <https://github.com/numpy/numpy/pull/17960>`__: TST, BUILD: Add a native x86 baseline build running on ubuntu-20.04
+* `#17962 <https://github.com/numpy/numpy/pull/17962>`__: TST: Ensure tests are not sensitive to execution order
+* `#17966 <https://github.com/numpy/numpy/pull/17966>`__: BUG: Add missing decref to arange
+* `#17968 <https://github.com/numpy/numpy/pull/17968>`__: ENH: Use more typevars in `np.dtype`
+* `#17971 <https://github.com/numpy/numpy/pull/17971>`__: BUG, SIMD: Fix direactive check for AVX512BW of intrinsics npyv_tobits_*
+* `#17973 <https://github.com/numpy/numpy/pull/17973>`__: DEP: Futurewarn on requiring __len__ on array-likes
+* `#17974 <https://github.com/numpy/numpy/pull/17974>`__: BLD: Fixes for versioneer and setup.py sdist.
+* `#17976 <https://github.com/numpy/numpy/pull/17976>`__: DOC: Add/remove spaces in snippets and re-format here and there
+* `#17978 <https://github.com/numpy/numpy/pull/17978>`__: MAINT: Update test_requirements and release_requirements.
+* `#17981 <https://github.com/numpy/numpy/pull/17981>`__: ENH: Add proper dtype-support to `np.flatiter`
+* `#17985 <https://github.com/numpy/numpy/pull/17985>`__: ENH, SIMD: Ditching the old CPU dispatcher(Arithmetic)
+* `#17992 <https://github.com/numpy/numpy/pull/17992>`__: DOC: Replace verbatim with reference to local parameter
+* `#17993 <https://github.com/numpy/numpy/pull/17993>`__: [DOC] np.kron use double backticks for non-references
+* `#17994 <https://github.com/numpy/numpy/pull/17994>`__: SIMD: Optimize the performance of einsum's submodule dot .
+* `#17995 <https://github.com/numpy/numpy/pull/17995>`__: MAINT: Bump pytest from 6.0.2 to 6.2.0
+* `#17996 <https://github.com/numpy/numpy/pull/17996>`__: MAINT: Update wheel requirement from <=0.35.1 to <0.36.3
+* `#17997 <https://github.com/numpy/numpy/pull/17997>`__: MAINT: Bump hypothesis from 5.41.5 to 5.43.3
+* `#17998 <https://github.com/numpy/numpy/pull/17998>`__: TST: ignore pytest warning
+* `#17999 <https://github.com/numpy/numpy/pull/17999>`__: Replace Numpy with NumPy
+* `#18001 <https://github.com/numpy/numpy/pull/18001>`__: BLD, BUG: Fix detecting aarch64 on macOS
+* `#18002 <https://github.com/numpy/numpy/pull/18002>`__: DOC: Fix and extend the docstring for np.inner
+* `#18007 <https://github.com/numpy/numpy/pull/18007>`__: DOC: Add a brief explanation of float printing
+* `#18008 <https://github.com/numpy/numpy/pull/18008>`__: DOC: fix for doctests
+* `#18011 <https://github.com/numpy/numpy/pull/18011>`__: BLD: update to OpenBLAS 0.3.13
+* `#18012 <https://github.com/numpy/numpy/pull/18012>`__: SIMD: Optimize the performance of einsum's submodule sum.
+* `#18014 <https://github.com/numpy/numpy/pull/18014>`__: DOC: random: add some examples for SeedSequence
+* `#18027 <https://github.com/numpy/numpy/pull/18027>`__: DOC, MAINT: Minor fixes to refguide_check.py documentation.
+* `#18030 <https://github.com/numpy/numpy/pull/18030>`__: BUG: make a variable volatile to work around clang compiler bug
+* `#18031 <https://github.com/numpy/numpy/pull/18031>`__: DOC: Parameter name typo axes -> axis in numpy.fft._pocketfft.
+* `#18032 <https://github.com/numpy/numpy/pull/18032>`__: ENH: Add annotations for `np.core.arrayprint`
+* `#18034 <https://github.com/numpy/numpy/pull/18034>`__: DOC: Fix a couple of reference to verbatim and vice versa
+* `#18042 <https://github.com/numpy/numpy/pull/18042>`__: MAINT: Add dist_info to "other" setup.py commands.
+* `#18045 <https://github.com/numpy/numpy/pull/18045>`__: MAINT: Bump pytest from 6.2.0 to 6.2.1
+* `#18046 <https://github.com/numpy/numpy/pull/18046>`__: TST: add back sdist test run
+* `#18047 <https://github.com/numpy/numpy/pull/18047>`__: BLD,DOC: pin sphinx to 3.3.1
+* `#18048 <https://github.com/numpy/numpy/pull/18048>`__: DOC: Update TESTS.rst.txt
+* `#18050 <https://github.com/numpy/numpy/pull/18050>`__: MAINT: Add aliases for commonly used `ArrayLike` objects
+* `#18051 <https://github.com/numpy/numpy/pull/18051>`__: DEP: deprecate np.testing.dec
+* `#18052 <https://github.com/numpy/numpy/pull/18052>`__: BUG: Fix concatenation when the output is "S" or "U"
+* `#18054 <https://github.com/numpy/numpy/pull/18054>`__: DOC: Update stack docstrings
+* `#18057 <https://github.com/numpy/numpy/pull/18057>`__: BLD: ensure we give the right error message for old Python versions
+* `#18062 <https://github.com/numpy/numpy/pull/18062>`__: DOC: add missing details to linalg.lstsq docstring
+* `#18065 <https://github.com/numpy/numpy/pull/18065>`__: MAINT: CPUs that support unaligned access.
+* `#18066 <https://github.com/numpy/numpy/pull/18066>`__: TST: Allow mypy output types to be specified via aliases
+* `#18067 <https://github.com/numpy/numpy/pull/18067>`__: MAINT: Remove obsolete workaround to set ndarray.__hash__ = None
+* `#18070 <https://github.com/numpy/numpy/pull/18070>`__: BUG: Fix unique handling of nan entries.
+* `#18072 <https://github.com/numpy/numpy/pull/18072>`__: MAINT: crackfortran regex simplify
+* `#18074 <https://github.com/numpy/numpy/pull/18074>`__: MAINT: exprtype regex simplify
+* `#18075 <https://github.com/numpy/numpy/pull/18075>`__: ENH, SIMD: Dispatch for unsigned floor division
+* `#18077 <https://github.com/numpy/numpy/pull/18077>`__: NEP: mark NEP 28 on website redesign as final
+* `#18078 <https://github.com/numpy/numpy/pull/18078>`__: Fix build warnings in NEPs
+* `#18079 <https://github.com/numpy/numpy/pull/18079>`__: MAINT: Bump sphinx from 3.3.1 to 3.4.1
+* `#18080 <https://github.com/numpy/numpy/pull/18080>`__: MAINT: Bump pytz from 2020.4 to 2020.5
+* `#18081 <https://github.com/numpy/numpy/pull/18081>`__: MAINT: Bump hypothesis from 5.43.3 to 5.43.4
+* `#18082 <https://github.com/numpy/numpy/pull/18082>`__: DOC: roadmap update
+* `#18083 <https://github.com/numpy/numpy/pull/18083>`__: MAINT: regex char class improve
+* `#18084 <https://github.com/numpy/numpy/pull/18084>`__: NEP: NumPy sponsorship guidelines (NEP 46)
+* `#18085 <https://github.com/numpy/numpy/pull/18085>`__: DOC: replace 'this platform' with the actual platform in the...
+* `#18086 <https://github.com/numpy/numpy/pull/18086>`__: BUG, SIMD: Fix _simd module build for 64bit Arm/neon clang
+* `#18088 <https://github.com/numpy/numpy/pull/18088>`__: DOC: Update reference to verbatim in a few location.
+* `#18090 <https://github.com/numpy/numpy/pull/18090>`__: MAINT: multiline regex class simplify
+* `#18091 <https://github.com/numpy/numpy/pull/18091>`__: DOC: Avoid using "set of" when talking about an ordered list.
+* `#18097 <https://github.com/numpy/numpy/pull/18097>`__: NEP: update backwards compatibility and deprecation policy NEP
+* `#18100 <https://github.com/numpy/numpy/pull/18100>`__: BUG, BLD: Generate the main dispatcher config header into the...
+* `#18101 <https://github.com/numpy/numpy/pull/18101>`__: ENH: move exp, log, frexp, ldexp to SIMD dispatching
+* `#18103 <https://github.com/numpy/numpy/pull/18103>`__: TST: Avoid changing odd tempfile names in tests' site.cfg
+* `#18104 <https://github.com/numpy/numpy/pull/18104>`__: TST: Turn some tests with loops into parametrized tests.
+* `#18109 <https://github.com/numpy/numpy/pull/18109>`__: MAINT: Fix exception cause in mingw32ccompiler.py
+* `#18110 <https://github.com/numpy/numpy/pull/18110>`__: API: make piecewise subclass safe using use zeros_like.
+* `#18111 <https://github.com/numpy/numpy/pull/18111>`__: MAINT: Bump hypothesis from 5.43.4 to 5.46.0
+* `#18115 <https://github.com/numpy/numpy/pull/18115>`__: BUG: Fix promotion of half and string
+* `#18116 <https://github.com/numpy/numpy/pull/18116>`__: DEP: Deprecate promotion of numbers and bool to string
+* `#18118 <https://github.com/numpy/numpy/pull/18118>`__: BUG, MAINT: improve avx512 mask logical operations
+* `#18126 <https://github.com/numpy/numpy/pull/18126>`__: REL: Update master after 1.19.5 release.
+* `#18128 <https://github.com/numpy/numpy/pull/18128>`__: ENH: Add dtype support to the array comparison ops
+* `#18136 <https://github.com/numpy/numpy/pull/18136>`__: ENH: Adding keyboard interrupt support for array creation
+* `#18144 <https://github.com/numpy/numpy/pull/18144>`__: BLD: add found Cython version to check in cythonize.py
+* `#18148 <https://github.com/numpy/numpy/pull/18148>`__: MAINT: Bump sphinx from 3.4.1 to 3.4.3
+* `#18149 <https://github.com/numpy/numpy/pull/18149>`__: MAINT: Bump hypothesis from 5.46.0 to 6.0.0
+* `#18150 <https://github.com/numpy/numpy/pull/18150>`__: BUG: Ensure too many advanced indices raises an exception
+* `#18152 <https://github.com/numpy/numpy/pull/18152>`__: BUG: Promotion between strings and objects was assymetric
+* `#18156 <https://github.com/numpy/numpy/pull/18156>`__: MAINT: Remove redundant null check before free
+* `#18157 <https://github.com/numpy/numpy/pull/18157>`__: BUG: Initialize value of no_castable_output used in ufunc_loop_matches
+* `#18161 <https://github.com/numpy/numpy/pull/18161>`__: MAINT: Make keyword arrays static
+* `#18164 <https://github.com/numpy/numpy/pull/18164>`__: TST: add a pypy37 windows 64-bit build
+* `#18166 <https://github.com/numpy/numpy/pull/18166>`__: Use sinus based formula for ``chebpts1``
+* `#18169 <https://github.com/numpy/numpy/pull/18169>`__: ENH: cpu features detection implementation on FreeBSD ARM
+* `#18173 <https://github.com/numpy/numpy/pull/18173>`__: TST: Clear the mypy cache before running any typing tests
+* `#18174 <https://github.com/numpy/numpy/pull/18174>`__: MAINT: Changed the `NBitBase` variancy in `number` from co- to...
+* `#18176 <https://github.com/numpy/numpy/pull/18176>`__: ENH: Improve performance of tril_indices and triu_indices
+* `#18178 <https://github.com/numpy/numpy/pull/18178>`__: SIMD: add fast integer division intrinsics for all supported...
+* `#18180 <https://github.com/numpy/numpy/pull/18180>`__: BUG: threads.h existence test requires GLIBC > 2.12.
+* `#18181 <https://github.com/numpy/numpy/pull/18181>`__: ENH: [f2py] Add external attribute support.
+* `#18182 <https://github.com/numpy/numpy/pull/18182>`__: MAINT: Bump hypothesis from 6.0.0 to 6.0.2
+* `#18183 <https://github.com/numpy/numpy/pull/18183>`__: MAINT: Optimize numpy.count_nonzero for int types using SIMD...
+* `#18184 <https://github.com/numpy/numpy/pull/18184>`__: BUG: Fix f2py bugs when wrapping F90 subroutines.
+* `#18185 <https://github.com/numpy/numpy/pull/18185>`__: MAINT: Give the `_<X>Like` and `_ArrayLike<X>` type aliases a...
+* `#18187 <https://github.com/numpy/numpy/pull/18187>`__: STY: unify imports in __init__.py
+* `#18191 <https://github.com/numpy/numpy/pull/18191>`__: STY: Use explicit reexports for numpy.typing objects
+* `#18193 <https://github.com/numpy/numpy/pull/18193>`__: MAINT: Fix typo in docstring example
+* `#18194 <https://github.com/numpy/numpy/pull/18194>`__: MAINT: einsum: Optimize the sub function two-operands by using...
+* `#18196 <https://github.com/numpy/numpy/pull/18196>`__: BLD: update OpenBLAS to af2b0d02
+* `#18197 <https://github.com/numpy/numpy/pull/18197>`__: BUG: Keep ignoring most errors during array-protocol lookup
+* `#18200 <https://github.com/numpy/numpy/pull/18200>`__: ENH: Add new intrinsics sum_u8/u16/u64.
+* `#18204 <https://github.com/numpy/numpy/pull/18204>`__: TST: Speed up the typing tests
+* `#18205 <https://github.com/numpy/numpy/pull/18205>`__: MAINT: Update pavement.py to work with versioneer.
+* `#18208 <https://github.com/numpy/numpy/pull/18208>`__: TST: raise memory limit for test
+* `#18210 <https://github.com/numpy/numpy/pull/18210>`__: DOC: typo in post-loop return
+* `#18211 <https://github.com/numpy/numpy/pull/18211>`__: MAINT: random shuffle: warn on unrecognized objects, fix empty...
+* `#18213 <https://github.com/numpy/numpy/pull/18213>`__: DOC: Formatting consistency.
+* `#18214 <https://github.com/numpy/numpy/pull/18214>`__: DOC: Double backticks for inline code example.
+* `#18217 <https://github.com/numpy/numpy/pull/18217>`__: MAINT: Ignore ComplexWarning in ``test_iter_copy_casts``.
+* `#18221 <https://github.com/numpy/numpy/pull/18221>`__: DOC: Misc single to double backticks fixes.
+* `#18223 <https://github.com/numpy/numpy/pull/18223>`__: DOC: Improve doc for numpy.random.Generator.choice
+* `#18224 <https://github.com/numpy/numpy/pull/18224>`__: MAINT: Bump pydata-sphinx-theme from 0.4.1 to 0.4.2
+* `#18225 <https://github.com/numpy/numpy/pull/18225>`__: MAINT: Bump mypy from 0.790 to 0.800
+* `#18226 <https://github.com/numpy/numpy/pull/18226>`__: MAINT: Bump hypothesis from 6.0.2 to 6.0.3
+* `#18227 <https://github.com/numpy/numpy/pull/18227>`__: MAINT: Bump pytest-cov from 2.10.1 to 2.11.1
+* `#18228 <https://github.com/numpy/numpy/pull/18228>`__: ENH: Add dtype-support to the ufunc-based `ndarray` magic methods...
+* `#18229 <https://github.com/numpy/numpy/pull/18229>`__: MAINT: Clean up all module-level dunders
+* `#18230 <https://github.com/numpy/numpy/pull/18230>`__: DOC: Clarify the type alias deprecation message
+* `#18232 <https://github.com/numpy/numpy/pull/18232>`__: DOC: lib/shape_base numpydoc formatting.
+* `#18233 <https://github.com/numpy/numpy/pull/18233>`__: NEP: accept NEP 23 (backwards compatibility policy)
+* `#18234 <https://github.com/numpy/numpy/pull/18234>`__: NEP: accept NEP 46 (sponsorship guidelines)
+* `#18235 <https://github.com/numpy/numpy/pull/18235>`__: DOC: Fix command in "Writing custom array containers" guide
+* `#18236 <https://github.com/numpy/numpy/pull/18236>`__: ENH: Add aliases for commonly used dtype-like objects
+* `#18238 <https://github.com/numpy/numpy/pull/18238>`__: DOC: __array__ accepts a dtype argument
+* `#18245 <https://github.com/numpy/numpy/pull/18245>`__: BLD: fix issue with `bdist_egg`, which made `make dist` in doc/...
+* `#18247 <https://github.com/numpy/numpy/pull/18247>`__: DOC: Misc numpydoc format fixes
+* `#18248 <https://github.com/numpy/numpy/pull/18248>`__: DOC: See also -> See Also (casing)
+* `#18251 <https://github.com/numpy/numpy/pull/18251>`__: DOC: more misc fixes of syntax
+* `#18252 <https://github.com/numpy/numpy/pull/18252>`__: DOC: cleanup of numpy/polynomial.
+* `#18253 <https://github.com/numpy/numpy/pull/18253>`__: DOC: improve description of `_NoValue`
+* `#18255 <https://github.com/numpy/numpy/pull/18255>`__: MAINT: add an 'apt update'
+* `#18262 <https://github.com/numpy/numpy/pull/18262>`__: REL: Update master after 1.20.0 release.
+* `#18263 <https://github.com/numpy/numpy/pull/18263>`__: ENH: Added sanity check to printoptions
+* `#18264 <https://github.com/numpy/numpy/pull/18264>`__: BUG: Use C linkage for random distributions
+* `#18269 <https://github.com/numpy/numpy/pull/18269>`__: DOC: Numpydoc format space before `:` in Parameters
+* `#18272 <https://github.com/numpy/numpy/pull/18272>`__: DOC: Numpydoc warning incorrect underline length.
+* `#18274 <https://github.com/numpy/numpy/pull/18274>`__: MAINT: Chain exceptions in linalg
+* `#18275 <https://github.com/numpy/numpy/pull/18275>`__: MAINT: Bump hypothesis from 6.0.3 to 6.1.1
+* `#18276 <https://github.com/numpy/numpy/pull/18276>`__: MAINT: Bump pytest from 6.2.1 to 6.2.2
+* `#18277 <https://github.com/numpy/numpy/pull/18277>`__: MAINT: Bump pydata-sphinx-theme from 0.4.2 to 0.4.3
+* `#18278 <https://github.com/numpy/numpy/pull/18278>`__: MAINT: defer the import of shutil
+* `#18282 <https://github.com/numpy/numpy/pull/18282>`__: MAINT: gracefully shuffle memoryviews
+* `#18284 <https://github.com/numpy/numpy/pull/18284>`__: ENH: Add annotations for the remaining `np.generic` aliases
+* `#18285 <https://github.com/numpy/numpy/pull/18285>`__: TST: Pin `typing_extensions` to the latest version
+* `#18289 <https://github.com/numpy/numpy/pull/18289>`__: MAINT: Move transferdata into buffer-wise struct
+* `#18293 <https://github.com/numpy/numpy/pull/18293>`__: BUG: Fix typo in ``numpy.__init__.py``
+* `#18295 <https://github.com/numpy/numpy/pull/18295>`__: BUG: don't mutate list of fake libraries while iterating over...
+* `#18301 <https://github.com/numpy/numpy/pull/18301>`__: MAINT: avoid chaining exceptions in conv_template.py
+* `#18302 <https://github.com/numpy/numpy/pull/18302>`__: MAINT: Add missing placeholder annotations
+* `#18303 <https://github.com/numpy/numpy/pull/18303>`__: MAINT: Fix typo in PyArray_RegisterDataType error
+* `#18307 <https://github.com/numpy/numpy/pull/18307>`__: DOC: Corrected numpy.power example.
+* `#18313 <https://github.com/numpy/numpy/pull/18313>`__: Numpy logo fix on README
+* `#18315 <https://github.com/numpy/numpy/pull/18315>`__: CI: rearrange Azure build jobs
+* `#18317 <https://github.com/numpy/numpy/pull/18317>`__: MAINT: Fixed chain exception for array_split func
+* `#18320 <https://github.com/numpy/numpy/pull/18320>`__: DOC: add links to polynomial function/class listing
+* `#18322 <https://github.com/numpy/numpy/pull/18322>`__: ENH: Add a mypy plugin for exposing platform-specific extended-precision...
+* `#18323 <https://github.com/numpy/numpy/pull/18323>`__: ENH: Add dtype-support to the ufunc-based `ndarray` magic methods...
+* `#18324 <https://github.com/numpy/numpy/pull/18324>`__: MAINT: Avoid moveaxis overhead in median.
+* `#18329 <https://github.com/numpy/numpy/pull/18329>`__: BUG: Allow unmodified use of isclose, allclose, etc. with timedelta
+* `#18331 <https://github.com/numpy/numpy/pull/18331>`__: MAINT: Update openblas_support for macosx-arm64
+* `#18332 <https://github.com/numpy/numpy/pull/18332>`__: BUG: Allow pickling all relevant DType types/classes
+* `#18333 <https://github.com/numpy/numpy/pull/18333>`__: CI: fix when GitHub Actions builds trigger, and allow ci skips
+* `#18334 <https://github.com/numpy/numpy/pull/18334>`__: TST: use setup-python action for pypy, disable win64 pypy
+* `#18338 <https://github.com/numpy/numpy/pull/18338>`__: DOC: Fix whitespace before "last updated" on overview page
+* `#18339 <https://github.com/numpy/numpy/pull/18339>`__: DOC: Discussion on the @ operator and the matrix class
+* `#18340 <https://github.com/numpy/numpy/pull/18340>`__: DOC: remove pygments_style from conf.py
+* `#18342 <https://github.com/numpy/numpy/pull/18342>`__: DOC: Specified all possible return types for trapz function #18140
+* `#18344 <https://github.com/numpy/numpy/pull/18344>`__: DOC: Added sentence to docstring of histogram_bin_edges to explain...
+* `#18346 <https://github.com/numpy/numpy/pull/18346>`__: DOC: Change license date 2020 -> 2021
+* `#18347 <https://github.com/numpy/numpy/pull/18347>`__: MAINT: Delete unused "dst" clearing functions
+* `#18348 <https://github.com/numpy/numpy/pull/18348>`__: DEP: doc-deprecate BLAS_SRC/LAPACK_SRC
+* `#18349 <https://github.com/numpy/numpy/pull/18349>`__: CI: CircleCI seems to occasionally time out, increase the limit
+* `#18350 <https://github.com/numpy/numpy/pull/18350>`__: BUG: Fix missing signed_char dependency.
+* `#18361 <https://github.com/numpy/numpy/pull/18361>`__: ENH: Share memory of read-only intent(in) arrays.
+* `#18362 <https://github.com/numpy/numpy/pull/18362>`__: REL: Update master after 1.20.1 release.
+* `#18364 <https://github.com/numpy/numpy/pull/18364>`__: DOC: Update landing page to match table of contents
+* `#18366 <https://github.com/numpy/numpy/pull/18366>`__: MAINT: Disable TravisCI git clone depth.
+* `#18367 <https://github.com/numpy/numpy/pull/18367>`__: MAINT: Bump pytz from 2020.5 to 2021.1
+* `#18369 <https://github.com/numpy/numpy/pull/18369>`__: BUG: np.in1d bug on the object array (issue 17923)
+* `#18372 <https://github.com/numpy/numpy/pull/18372>`__: DOC: improve standard_t example in numpy.random.
+* `#18374 <https://github.com/numpy/numpy/pull/18374>`__: TST: Add a test for nditer write masked with references
+* `#18375 <https://github.com/numpy/numpy/pull/18375>`__: BUG: fix regression in a hidden callback use case in f2py.
+* `#18377 <https://github.com/numpy/numpy/pull/18377>`__: ENH: Add annotations for `np.lib.ufunclike`
+* `#18379 <https://github.com/numpy/numpy/pull/18379>`__: DOC: Fix docstring of _median_nancheck.
+* `#18384 <https://github.com/numpy/numpy/pull/18384>`__: BUG: improve the interface of `tofile` method
+* `#18389 <https://github.com/numpy/numpy/pull/18389>`__: MAINT: Fix version of wheel to support Python 3.10
+* `#18390 <https://github.com/numpy/numpy/pull/18390>`__: ENH: Add annotations for `np.core.einsumfunc`
+* `#18392 <https://github.com/numpy/numpy/pull/18392>`__: BUG: Remove check in shuffle for non-ndarrays
+* `#18394 <https://github.com/numpy/numpy/pull/18394>`__: MAINT: Added Chain exceptions where appropriate
+* `#18395 <https://github.com/numpy/numpy/pull/18395>`__: ENH: Initial typing of random
+* `#18396 <https://github.com/numpy/numpy/pull/18396>`__: MAINT: Threading and Unicode strings
+* `#18397 <https://github.com/numpy/numpy/pull/18397>`__: ENH: Add annotations for `np.lib.index_tricks`
+* `#18398 <https://github.com/numpy/numpy/pull/18398>`__: MAINT: Fix casting signatures to align with NEP 43 signature
+* `#18400 <https://github.com/numpy/numpy/pull/18400>`__: MAINT: Added Chain exceptions where appropriate
+* `#18402 <https://github.com/numpy/numpy/pull/18402>`__: BUG: Fix typo in char_codes
+* `#18404 <https://github.com/numpy/numpy/pull/18404>`__: BUG: Fix iterator shape in advanced index assignment broadcast...
+* `#18405 <https://github.com/numpy/numpy/pull/18405>`__: DOC: Mention `scipy.signal.correlate` and FFT method in `np.correlate`closes...
+* `#18413 <https://github.com/numpy/numpy/pull/18413>`__: MAINT: Bump sphinx from 3.4.3 to 3.5.0
+* `#18414 <https://github.com/numpy/numpy/pull/18414>`__: MAINT: Bump hypothesis from 6.1.1 to 6.2.0
+* `#18415 <https://github.com/numpy/numpy/pull/18415>`__: MAINT: Update END statements parsing for recent Fortran standards.
+* `#18416 <https://github.com/numpy/numpy/pull/18416>`__: BUG: Fix f2py parsing continued lines that follow comment lines.
+* `#18417 <https://github.com/numpy/numpy/pull/18417>`__: ENH: Add dtype-support to the ufunc-based `ndarray` magic methods...
+* `#18418 <https://github.com/numpy/numpy/pull/18418>`__: DOC: remove layout overrides for headers
+* `#18420 <https://github.com/numpy/numpy/pull/18420>`__: BUG: Fix tiny memory leaks when ``like=`` overrides are used
+* `#18423 <https://github.com/numpy/numpy/pull/18423>`__: ENH: Lint checks for PR diffs
+* `#18428 <https://github.com/numpy/numpy/pull/18428>`__: DOC: remove explanations.rst
+* `#18429 <https://github.com/numpy/numpy/pull/18429>`__: DOC: point intersphinx to matplotlib/stable...
+* `#18432 <https://github.com/numpy/numpy/pull/18432>`__: MAINT: Correct code producing warnings
+* `#18433 <https://github.com/numpy/numpy/pull/18433>`__: ENH: Add typing for RandomState
+* `#18436 <https://github.com/numpy/numpy/pull/18436>`__: BUG: Fix refcount leak in f2py `complex_double_from_pyobj`
+* `#18437 <https://github.com/numpy/numpy/pull/18437>`__: TST: Fix some uninitialized memory in the tests
+* `#18438 <https://github.com/numpy/numpy/pull/18438>`__: BUG: Correct shuffling of objects in 1-d array likes
+* `#18439 <https://github.com/numpy/numpy/pull/18439>`__: MAINT: random: Use 'from exc' when raising a ValueError in choice.
+* `#18443 <https://github.com/numpy/numpy/pull/18443>`__: BUG: fix stacklevel in warning within random.shuffle
+* `#18448 <https://github.com/numpy/numpy/pull/18448>`__: DOC: Remove unfinished Linear Algebra section from Quickstart...
+* `#18450 <https://github.com/numpy/numpy/pull/18450>`__: BUG: Segfault in nditer buffer dealloc for Object arrays
+* `#18454 <https://github.com/numpy/numpy/pull/18454>`__: NEP: add Spending NumPy Project Funds (NEP 48)
+* `#18455 <https://github.com/numpy/numpy/pull/18455>`__: BUG: ``diagflat`` could overflow on windows or 32-bit platforms
+* `#18456 <https://github.com/numpy/numpy/pull/18456>`__: NEP: array API standard adoption (NEP 47)
+* `#18458 <https://github.com/numpy/numpy/pull/18458>`__: DOC: update NEP status for accepted/finished NEPs
+* `#18463 <https://github.com/numpy/numpy/pull/18463>`__: MAINT: Bump mypy from 0.800 to 0.812
+* `#18464 <https://github.com/numpy/numpy/pull/18464>`__: MAINT: Bump sphinx from 3.5.0 to 3.5.1
+* `#18465 <https://github.com/numpy/numpy/pull/18465>`__: MAINT: Bump cython from 0.29.21 to 0.29.22
+* `#18466 <https://github.com/numpy/numpy/pull/18466>`__: MAINT: Bump hypothesis from 6.2.0 to 6.3.0
+* `#18475 <https://github.com/numpy/numpy/pull/18475>`__: ENH: Added type annotations to eye() function
+* `#18476 <https://github.com/numpy/numpy/pull/18476>`__: BUG: Remove suspicious type casting
+* `#18477 <https://github.com/numpy/numpy/pull/18477>`__: BUG: remove nonsensical comparison of pointer < 0
+* `#18478 <https://github.com/numpy/numpy/pull/18478>`__: BUG: verify pointer against NULL before using it
+* `#18479 <https://github.com/numpy/numpy/pull/18479>`__: BUG: check if PyArray_malloc succeeded
+* `#18481 <https://github.com/numpy/numpy/pull/18481>`__: DOC: Generator and RandomState doc improvements
+* `#18482 <https://github.com/numpy/numpy/pull/18482>`__: ENH: Improve error message in multinomial
+* `#18489 <https://github.com/numpy/numpy/pull/18489>`__: DOC: Rename "Ones and zeros" section in array-creation documentation.
+* `#18493 <https://github.com/numpy/numpy/pull/18493>`__: BUG: Fix non-versioneer uses of numpy.distutils
+* `#18497 <https://github.com/numpy/numpy/pull/18497>`__: TST: Remove the `einsum` typing tests reliance on issuing a `ComplexWarning`
+* `#18498 <https://github.com/numpy/numpy/pull/18498>`__: BUG: Fixed Von Mises distribution for big values of kappa
+* `#18499 <https://github.com/numpy/numpy/pull/18499>`__: TST: Branch coverage improvement for `np.polynomial`
+* `#18502 <https://github.com/numpy/numpy/pull/18502>`__: DOC: Fix links to landing page
+* `#18505 <https://github.com/numpy/numpy/pull/18505>`__: DOC: add guide for downstream package authors
+* `#18509 <https://github.com/numpy/numpy/pull/18509>`__: DOC: trunc, floor, ceil, rint, fix should all link to each other
+* `#18513 <https://github.com/numpy/numpy/pull/18513>`__: BLD: add _2_24 to valid manylinux names
+* `#18515 <https://github.com/numpy/numpy/pull/18515>`__: MAINT: Improve error message when common type not found.
+* `#18517 <https://github.com/numpy/numpy/pull/18517>`__: MAINT: Bump hypothesis from 6.3.0 to 6.3.4
+* `#18518 <https://github.com/numpy/numpy/pull/18518>`__: DOC Improve formatting in the depending_on_numpy documentation
+* `#18522 <https://github.com/numpy/numpy/pull/18522>`__: BUG: remove extraneous ARGOUTVIEWM dim. 4 typemaps
+* `#18526 <https://github.com/numpy/numpy/pull/18526>`__: MAINT: Specify color in RGB in the docs about the new NumPy logo
+* `#18530 <https://github.com/numpy/numpy/pull/18530>`__: BUG: incorrect error fallthrough in nditer
+* `#18531 <https://github.com/numpy/numpy/pull/18531>`__: CI: Use Ubuntu 18.04 to run "full" test.
+* `#18537 <https://github.com/numpy/numpy/pull/18537>`__: [BLD] use the new openblas lib
+* `#18538 <https://github.com/numpy/numpy/pull/18538>`__: Fix the numpy Apple M1 build
+* `#18539 <https://github.com/numpy/numpy/pull/18539>`__: BUG: NameError in numpy.distutils.fcompiler.compaq
+* `#18544 <https://github.com/numpy/numpy/pull/18544>`__: MAINT: Update master to main after branch rename
+* `#18545 <https://github.com/numpy/numpy/pull/18545>`__: ENH: Add annotations for `np.lib.arrayterator`
+* `#18554 <https://github.com/numpy/numpy/pull/18554>`__: CI: Pin docker image for Linux_Python_38_32bit_full_with_asserts...
+* `#18560 <https://github.com/numpy/numpy/pull/18560>`__: BUG: Fixed ``where`` keyword for ``np.mean`` & ``np.var`` methods
+* `#18566 <https://github.com/numpy/numpy/pull/18566>`__: CI: another master -> main fix
+* `#18567 <https://github.com/numpy/numpy/pull/18567>`__: CI: skip lint check on merges with main
+* `#18569 <https://github.com/numpy/numpy/pull/18569>`__: CI: Ensure that doc-build uses "main" as branch name
+* `#18570 <https://github.com/numpy/numpy/pull/18570>`__: CI: Use `git branch -m` instead of `--initial-branch=main`
+* `#18571 <https://github.com/numpy/numpy/pull/18571>`__: BUG: Fix overflow warning on apple silicon
+* `#18572 <https://github.com/numpy/numpy/pull/18572>`__: CI: Set git default branch to "main" in CircleCI.
+* `#18574 <https://github.com/numpy/numpy/pull/18574>`__: MAINT: Update the Call for Contributions section
+* `#18575 <https://github.com/numpy/numpy/pull/18575>`__: MAINT: Bump sphinx from 3.5.1 to 3.5.2
+* `#18576 <https://github.com/numpy/numpy/pull/18576>`__: MAINT: Bump hypothesis from 6.3.4 to 6.6.0
+* `#18578 <https://github.com/numpy/numpy/pull/18578>`__: MAINT: Bump pycodestyle from 2.5.0 to 2.6.0
+* `#18579 <https://github.com/numpy/numpy/pull/18579>`__: MAINT: OrderedDict is no longer necessary from Python 3.7
+* `#18582 <https://github.com/numpy/numpy/pull/18582>`__: BLD, TST: use pypy nightly to work around bug
+* `#18583 <https://github.com/numpy/numpy/pull/18583>`__: DOC: Clarify docs for fliplr() / flipud()
+* `#18584 <https://github.com/numpy/numpy/pull/18584>`__: DOC: Added documentation for linter (#18423)
+* `#18593 <https://github.com/numpy/numpy/pull/18593>`__: MAINT: Do not claim input to binops is `self` (array object)
+* `#18594 <https://github.com/numpy/numpy/pull/18594>`__: MAINT: Remove strange `op == NULL` check
+* `#18596 <https://github.com/numpy/numpy/pull/18596>`__: MAINT: Chain exceptions in index_tricks.py and mrecords.py
+* `#18598 <https://github.com/numpy/numpy/pull/18598>`__: MAINT: Add annotations for `dtype.__getitem__`, `__mul__` and...
+* `#18602 <https://github.com/numpy/numpy/pull/18602>`__: CI: Do not fail CI on lint error
+* `#18605 <https://github.com/numpy/numpy/pull/18605>`__: BUG: Fix ma coercion list-of-ma-arrays if they do not cast to...
+* `#18614 <https://github.com/numpy/numpy/pull/18614>`__: MAINT: Bump pycodestyle from 2.6.0 to 2.7.0
+* `#18615 <https://github.com/numpy/numpy/pull/18615>`__: MAINT: Bump hypothesis from 6.6.0 to 6.8.1
+* `#18616 <https://github.com/numpy/numpy/pull/18616>`__: CI: Update apt package list before Python install
+* `#18618 <https://github.com/numpy/numpy/pull/18618>`__: MAINT: Ensure that re-exported sub-modules are properly annotated
+* `#18622 <https://github.com/numpy/numpy/pull/18622>`__: DOC: Consistently use rng as variable name for random generators
+* `#18629 <https://github.com/numpy/numpy/pull/18629>`__: BUG, ENH: fix array2string rounding bug by adding min_digits...
+* `#18630 <https://github.com/numpy/numpy/pull/18630>`__: DOC: add note to numpy.rint() docstrings
+* `#18634 <https://github.com/numpy/numpy/pull/18634>`__: BUG: Use npy_log1p where appropriate in random generation
+* `#18635 <https://github.com/numpy/numpy/pull/18635>`__: ENH: Improve the exception for default low in Generator.integers
+* `#18641 <https://github.com/numpy/numpy/pull/18641>`__: MAINT: Remove useless declarations in `bad_commands`
+* `#18642 <https://github.com/numpy/numpy/pull/18642>`__: ENH: Use new argument parsing for array creation functions
+* `#18643 <https://github.com/numpy/numpy/pull/18643>`__: DOC: Remove mention of nose from README
+* `#18645 <https://github.com/numpy/numpy/pull/18645>`__: DOC: Minor fix in inline code example of ufunc reference
+* `#18648 <https://github.com/numpy/numpy/pull/18648>`__: MAINT: use super() as described by PEP 3135
+* `#18649 <https://github.com/numpy/numpy/pull/18649>`__: MAINT: Add missing type to cdef statement
+* `#18651 <https://github.com/numpy/numpy/pull/18651>`__: BUG: Fix small valgrind-found issues
+* `#18652 <https://github.com/numpy/numpy/pull/18652>`__: DOC: Update some plotting code to current Matplotlib idioms
+* `#18657 <https://github.com/numpy/numpy/pull/18657>`__: ENH: Improve performance of `np.save` for small arrays
+* `#18658 <https://github.com/numpy/numpy/pull/18658>`__: BLD: remove /usr/include from default include dirs
+* `#18659 <https://github.com/numpy/numpy/pull/18659>`__: DEV: add a conda environment.yml with all development dependencies
+* `#18660 <https://github.com/numpy/numpy/pull/18660>`__: DOC: add release note for removal of /usr/include from include...
+* `#18664 <https://github.com/numpy/numpy/pull/18664>`__: MAINT: Bump sphinx from 3.5.2 to 3.5.3
+* `#18666 <https://github.com/numpy/numpy/pull/18666>`__: ENH: Use exponentials in place of inversion in Rayleigh and geometric
+* `#18670 <https://github.com/numpy/numpy/pull/18670>`__: BUG: Fix small issues found with pytest-leaks
+* `#18676 <https://github.com/numpy/numpy/pull/18676>`__: MAINT: Implement new style promotion for `np.result_type`, etc.
+* `#18679 <https://github.com/numpy/numpy/pull/18679>`__: BUG: Changed METH_VARARGS to METH_NOARGS
+* `#18680 <https://github.com/numpy/numpy/pull/18680>`__: Docs: simd-optimizations.rst: fix typo (basline ~> baseline)
+* `#18685 <https://github.com/numpy/numpy/pull/18685>`__: REL: Update main after 1.20.2 release.
+* `#18686 <https://github.com/numpy/numpy/pull/18686>`__: BUG: Fix test_ccompiler_opt when path contains dots
+* `#18689 <https://github.com/numpy/numpy/pull/18689>`__: DOC: Change matrix size in absolute beginners doc.
+* `#18690 <https://github.com/numpy/numpy/pull/18690>`__: BUG: Correct datetime64 missing type overload for datetime.date...
+* `#18691 <https://github.com/numpy/numpy/pull/18691>`__: BUG: fix segfault in object/longdouble operations
+* `#18692 <https://github.com/numpy/numpy/pull/18692>`__: MAINT: Bump pydata-sphinx-theme from 0.5.0 to 0.5.2
+* `#18693 <https://github.com/numpy/numpy/pull/18693>`__: MAINT: Bump hypothesis from 6.8.1 to 6.8.3
+* `#18694 <https://github.com/numpy/numpy/pull/18694>`__: TST: pin pypy version to 7.3.4rc1
+* `#18695 <https://github.com/numpy/numpy/pull/18695>`__: ENH: Support parsing Fortran abstract interface blocks.
+* `#18697 <https://github.com/numpy/numpy/pull/18697>`__: DEP: Disable PyUFunc_GenericFunction and PyUFunc_SetUsesArraysAsData
+* `#18698 <https://github.com/numpy/numpy/pull/18698>`__: MAINT: Specify the color space in all new NumPy logo files
+* `#18701 <https://github.com/numpy/numpy/pull/18701>`__: BLD: Strip extra newline when dumping gfortran version on MacOS
+* `#18705 <https://github.com/numpy/numpy/pull/18705>`__: DOC: update Steering Council membership and people on governance...
+* `#18706 <https://github.com/numpy/numpy/pull/18706>`__: DOC: Add release notes to upcoming_changes
+* `#18708 <https://github.com/numpy/numpy/pull/18708>`__: TST: add tests for using np.meshgrid for higher dimensional grids.
+* `#18712 <https://github.com/numpy/numpy/pull/18712>`__: DOC: Simplifies Mandelbrot set plot in Quickstart guide
+* `#18718 <https://github.com/numpy/numpy/pull/18718>`__: API, DEP: Move ufunc signature parsing to the start
+* `#18722 <https://github.com/numpy/numpy/pull/18722>`__: DOC: deduplicate dtype basic types (2)
+* `#18725 <https://github.com/numpy/numpy/pull/18725>`__: MAINT: Bump pytest from 6.2.2 to 6.2.3
+* `#18726 <https://github.com/numpy/numpy/pull/18726>`__: MAINT: Bump hypothesis from 6.8.3 to 6.8.4
+* `#18728 <https://github.com/numpy/numpy/pull/18728>`__: MAINT: Add exception chaining where appropriate
+* `#18731 <https://github.com/numpy/numpy/pull/18731>`__: BUG: Check out requirements and raise when not satisfied
+* `#18733 <https://github.com/numpy/numpy/pull/18733>`__: DEV: Adds gitpod to numpy
+* `#18737 <https://github.com/numpy/numpy/pull/18737>`__: BLD: introduce use of BLAS_LIBS and LAPACK_LIBS in distutils/system_info
+* `#18739 <https://github.com/numpy/numpy/pull/18739>`__: MAINT: Add exception chaining where appropriate
+* `#18741 <https://github.com/numpy/numpy/pull/18741>`__: DOC: Emphasize distinctions between np.copy and ndarray.copy
+* `#18745 <https://github.com/numpy/numpy/pull/18745>`__: CI: remove shippable CI
+* `#18750 <https://github.com/numpy/numpy/pull/18750>`__: MAINT: Allow more recursion depth for scalar tests.
+* `#18751 <https://github.com/numpy/numpy/pull/18751>`__: BUG: Regression #18075 | Fixing Ufunc TD generation order
+* `#18753 <https://github.com/numpy/numpy/pull/18753>`__: BLD: Negative zero handling with ifort
+* `#18755 <https://github.com/numpy/numpy/pull/18755>`__: MAINT: Bump sphinx from 3.5.3 to 3.5.4
+* `#18757 <https://github.com/numpy/numpy/pull/18757>`__: MAINT: Bump hypothesis from 6.8.4 to 6.9.1
+* `#18758 <https://github.com/numpy/numpy/pull/18758>`__: DOC: Update howto-docs with link to NumPy tutorials.
+* `#18761 <https://github.com/numpy/numpy/pull/18761>`__: DOC: Small fixes (including formatting) for NEP 43
+* `#18765 <https://github.com/numpy/numpy/pull/18765>`__: ENH: Improve the placeholder annotations for the main numpy namespace
+* `#18766 <https://github.com/numpy/numpy/pull/18766>`__: ENH, SIMD: Replace libdivide functions of signed integer division...
+* `#18770 <https://github.com/numpy/numpy/pull/18770>`__: DOC: More concise "How to import NumPy" description
+* `#18771 <https://github.com/numpy/numpy/pull/18771>`__: DOC: Use: from numpy.testing import ...
+* `#18772 <https://github.com/numpy/numpy/pull/18772>`__: CI: Use informational mode for codecov
+* `#18773 <https://github.com/numpy/numpy/pull/18773>`__: CI: Fixing typo in Azure job run
+* `#18777 <https://github.com/numpy/numpy/pull/18777>`__: DOC: update random and asserts in test guidelines
+* `#18778 <https://github.com/numpy/numpy/pull/18778>`__: MAINT: Relax the integer-type-constraint of `npt._ShapeLike`
+* `#18779 <https://github.com/numpy/numpy/pull/18779>`__: DOC: fix spelling of "reccomended" ("recommended")
+* `#18780 <https://github.com/numpy/numpy/pull/18780>`__: ENH: Improve the placeholder annotations for the main numpy namespace...
+* `#18781 <https://github.com/numpy/numpy/pull/18781>`__: ENH: Add `__all__` to a number of public modules
+* `#18785 <https://github.com/numpy/numpy/pull/18785>`__: DOC: change `dec.parametrize` to `pytest.mark.parametrize`
+* `#18786 <https://github.com/numpy/numpy/pull/18786>`__: DOC: add note for clip() special case a_min > a_max See #18782
+* `#18787 <https://github.com/numpy/numpy/pull/18787>`__: DOC: Document newer pytest conventions
+* `#18789 <https://github.com/numpy/numpy/pull/18789>`__: DEV: Pin pydata-sphinx-theme to 0.5.2.
+* `#18790 <https://github.com/numpy/numpy/pull/18790>`__: CI: Use `towncrier build` explicitly
+* `#18791 <https://github.com/numpy/numpy/pull/18791>`__: DOC: Fixes small things in the genfromtext docstring
+* `#18792 <https://github.com/numpy/numpy/pull/18792>`__: MAINT: Use recent towncrier releases on PyPI.
+* `#18795 <https://github.com/numpy/numpy/pull/18795>`__: SIMD, TEST: Workaround for misaligned stack GCC BUG ABI on WIN64
+* `#18796 <https://github.com/numpy/numpy/pull/18796>`__: DOC: Misc Numpydoc and formatting for proper parsing.
+* `#18797 <https://github.com/numpy/numpy/pull/18797>`__: DOC: Update random c-api documentation
+* `#18799 <https://github.com/numpy/numpy/pull/18799>`__: MAINT: Improve the placeholder annotations for the main numpy...
+* `#18800 <https://github.com/numpy/numpy/pull/18800>`__: MAINT: Relax miscellaneous integer-type constraints
+* `#18801 <https://github.com/numpy/numpy/pull/18801>`__: DOC: fix typo in frexp docstring
+* `#18802 <https://github.com/numpy/numpy/pull/18802>`__: DOC: Improve random.choice() documentation
+* `#18805 <https://github.com/numpy/numpy/pull/18805>`__: NEP: propose new nep for allocator policies
+* `#18806 <https://github.com/numpy/numpy/pull/18806>`__: MAINT: Bump hypothesis from 6.9.1 to 6.10.0
+* `#18807 <https://github.com/numpy/numpy/pull/18807>`__: MAINT: Bump cython from 0.29.22 to 0.29.23
+* `#18809 <https://github.com/numpy/numpy/pull/18809>`__: MAINT: runtests help text cleanup
+* `#18812 <https://github.com/numpy/numpy/pull/18812>`__: DOC: Document howto build documentation in a virtual environment
+* `#18813 <https://github.com/numpy/numpy/pull/18813>`__: BUG: Initialize the full nditer buffer in case of error
+* `#18818 <https://github.com/numpy/numpy/pull/18818>`__: ENH: Add annotations for 4 objects in `np.core.numerictypes`
+* `#18820 <https://github.com/numpy/numpy/pull/18820>`__: MAINT: Remove incorrect inline
+* `#18822 <https://github.com/numpy/numpy/pull/18822>`__: DEV: general Gitpod enhancements
+* `#18823 <https://github.com/numpy/numpy/pull/18823>`__: MAINT: Minor fix to add reference link to numpy.fill_diagonal...
+* `#18825 <https://github.com/numpy/numpy/pull/18825>`__: MAINT: Update README.md
+* `#18831 <https://github.com/numpy/numpy/pull/18831>`__: BUG: Prevent nan being used in percentile
+* `#18834 <https://github.com/numpy/numpy/pull/18834>`__: DOC: Fix typo in random docs
+* `#18836 <https://github.com/numpy/numpy/pull/18836>`__: MAINT: Generalize and shorten the ufunc "trivially iterable"...
+* `#18837 <https://github.com/numpy/numpy/pull/18837>`__: ENH, SIMD: Add support for dispatching C++ sources
+* `#18839 <https://github.com/numpy/numpy/pull/18839>`__: DOC: Add Gitpod development documentation
+* `#18841 <https://github.com/numpy/numpy/pull/18841>`__: DOC: Add favicon
+* `#18842 <https://github.com/numpy/numpy/pull/18842>`__: ENH: Improve the placeholder annotations within sub-modules
+* `#18843 <https://github.com/numpy/numpy/pull/18843>`__: DOC: Clarify isreal docstring
+* `#18845 <https://github.com/numpy/numpy/pull/18845>`__: DOC: Move Sphinx numpy target in reference index.
+* `#18851 <https://github.com/numpy/numpy/pull/18851>`__: MAINT: Disable pip version check for azure lint check.
+* `#18853 <https://github.com/numpy/numpy/pull/18853>`__: ENH: Improve the placeholder annotations within sub-modules (part...
+* `#18855 <https://github.com/numpy/numpy/pull/18855>`__: STY: change CRLF line terminators to Unix
+* `#18856 <https://github.com/numpy/numpy/pull/18856>`__: MAINT: Fix the typo "implment"
+* `#18862 <https://github.com/numpy/numpy/pull/18862>`__: TST: Skip f2py TestSharedMemory for LONGDOUBLE on macos/arm64
+* `#18863 <https://github.com/numpy/numpy/pull/18863>`__: ENH: Add max values comparison for floating point
+* `#18864 <https://github.com/numpy/numpy/pull/18864>`__: MAINT: Remove dead codepath in generalized ufuncs
+* `#18868 <https://github.com/numpy/numpy/pull/18868>`__: Upgrade to GitHub-native Dependabot
+* `#18869 <https://github.com/numpy/numpy/pull/18869>`__: MAINT: Fix azure linter problems with pip 21.1
+* `#18871 <https://github.com/numpy/numpy/pull/18871>`__: MAINT: Bump hypothesis from 6.10.0 to 6.10.1
+* `#18874 <https://github.com/numpy/numpy/pull/18874>`__: BLD, ENH: Enable Accelerate Framework
+* `#18877 <https://github.com/numpy/numpy/pull/18877>`__: MAINT: Update PyPy version used by CI
+* `#18880 <https://github.com/numpy/numpy/pull/18880>`__: API: Ensure that casting does not affect ufunc loop
+* `#18882 <https://github.com/numpy/numpy/pull/18882>`__: ENH: Add min values comparison for floating point
+* `#18885 <https://github.com/numpy/numpy/pull/18885>`__: MAINT: Remove unsafe unions and ABCs from return-annotations
+* `#18889 <https://github.com/numpy/numpy/pull/18889>`__: ENH: Add SIMD operations for min and max value comparision
+* `#18890 <https://github.com/numpy/numpy/pull/18890>`__: MAINT: ssize_t -> Py_ssize_t and other fixes for Python v3.10.0
+* `#18891 <https://github.com/numpy/numpy/pull/18891>`__: MAINT: Bump typing-extensions from 3.7.4.3 to 3.10.0.0
+* `#18893 <https://github.com/numpy/numpy/pull/18893>`__: DOC: Add a set of standard replies.
+* `#18895 <https://github.com/numpy/numpy/pull/18895>`__: DOC: Improve cumsum documentation
+* `#18896 <https://github.com/numpy/numpy/pull/18896>`__: MAINT: Explicitly mark text files in .gitattributes.
+* `#18897 <https://github.com/numpy/numpy/pull/18897>`__: MAINT: Add ".csv" some data file names.
+* `#18899 <https://github.com/numpy/numpy/pull/18899>`__: BLD, BUG: Fix compiler optimization log AttributeError
+* `#18900 <https://github.com/numpy/numpy/pull/18900>`__: BLD: remove unnecessary flag `-faltivec` on macOS
+* `#18903 <https://github.com/numpy/numpy/pull/18903>`__: MAINT, CI: treats _SIMD module build warnings as errors through...
+* `#18906 <https://github.com/numpy/numpy/pull/18906>`__: ENH: Add PCG64DXSM BitGenerator
+* `#18908 <https://github.com/numpy/numpy/pull/18908>`__: MAINT: Adjust NumPy float hashing to Python's slightly changed...
+* `#18909 <https://github.com/numpy/numpy/pull/18909>`__: ENH: Improve the placeholder annotations within sub-modules (part...
+* `#18910 <https://github.com/numpy/numpy/pull/18910>`__: BUG : for MINGW, threads.h existence test requires GLIBC > 2.12
+* `#18911 <https://github.com/numpy/numpy/pull/18911>`__: BLD, BUG: Fix bdist_wheel duplicate building
+* `#18912 <https://github.com/numpy/numpy/pull/18912>`__: CI: fix the GitHub Actions trigger in docker.yml
+* `#18918 <https://github.com/numpy/numpy/pull/18918>`__: DOC: fix documentation of cloning over ssh
+* `#18919 <https://github.com/numpy/numpy/pull/18919>`__: ENH: Add placeholder annotations for two missing `np.testing`...
+* `#18920 <https://github.com/numpy/numpy/pull/18920>`__: BUG: Report underflow condition in AVX implementation of np.exp
+* `#18927 <https://github.com/numpy/numpy/pull/18927>`__: NEP: add mailing list thread, fixes from review
+* `#18930 <https://github.com/numpy/numpy/pull/18930>`__: BUG: Make changelog recognize ``gh-`` as a PR number prefix.
+* `#18931 <https://github.com/numpy/numpy/pull/18931>`__: BUG: Fix refcounting in string-promotion deprecation code path
+* `#18933 <https://github.com/numpy/numpy/pull/18933>`__: BUG: Fix underflow error in AVX512 implementation of ufunc exp/f64
+* `#18934 <https://github.com/numpy/numpy/pull/18934>`__: DOC: Add a release note for the improved placeholder annotations
+* `#18935 <https://github.com/numpy/numpy/pull/18935>`__: API: Add `npt.NDArray`, a runtime-subscriptable alias for `np.ndarray`
+* `#18936 <https://github.com/numpy/numpy/pull/18936>`__: DOC: Update performance for new PRNG
+* `#18940 <https://github.com/numpy/numpy/pull/18940>`__: ENH: manually inline PCG64DXSM code for performance.
+* `#18943 <https://github.com/numpy/numpy/pull/18943>`__: TST: xfail `TestCond.test_nan` unconditionally
+* `#18944 <https://github.com/numpy/numpy/pull/18944>`__: ENH: Add annotations for `np.lib.utils`
+* `#18954 <https://github.com/numpy/numpy/pull/18954>`__: DOC: Update beginners docu for sum function with axis
+* `#18955 <https://github.com/numpy/numpy/pull/18955>`__: DOC: add an extra example in runtests.py help test
+* `#18956 <https://github.com/numpy/numpy/pull/18956>`__: DOC: change copyright SciPy to NumPy
+* `#18957 <https://github.com/numpy/numpy/pull/18957>`__: DOC: Improve datetime64 docs.
+* `#18958 <https://github.com/numpy/numpy/pull/18958>`__: MAINT: Do not use deprecated ``mktemp()``
+* `#18959 <https://github.com/numpy/numpy/pull/18959>`__: DOC: improve numpy.histogram2d() documentation
+* `#18960 <https://github.com/numpy/numpy/pull/18960>`__: BUG: fixed ma.average ignoring masked weights
+* `#18961 <https://github.com/numpy/numpy/pull/18961>`__: DOC: add note and examples to `isrealobj` docstring
+* `#18962 <https://github.com/numpy/numpy/pull/18962>`__: DOC: Update a page title with proper case
+* `#18963 <https://github.com/numpy/numpy/pull/18963>`__: DEP: remove PolyBase from np.polynomial.polyutils
+* `#18965 <https://github.com/numpy/numpy/pull/18965>`__: DOC: Improve description of array scalar in glossary
+* `#18967 <https://github.com/numpy/numpy/pull/18967>`__: BUG: fix np.ma.masked_where(copy=False) when input has no mask
+* `#18970 <https://github.com/numpy/numpy/pull/18970>`__: MAINT, SIMD: Hardened the AVX compile-time tests
+* `#18972 <https://github.com/numpy/numpy/pull/18972>`__: ENH: Include co-authors in changelog.
+* `#18973 <https://github.com/numpy/numpy/pull/18973>`__: MAINT: Bump sphinx from 3.5.4 to 4.0.0
+* `#18974 <https://github.com/numpy/numpy/pull/18974>`__: MAINT: Bump hypothesis from 6.10.1 to 6.12.0
+* `#18976 <https://github.com/numpy/numpy/pull/18976>`__: MAINT: Bump pytest from 6.2.3 to 6.2.4
+* `#18980 <https://github.com/numpy/numpy/pull/18980>`__: DOC: Gitpod documentation enhancements
+* `#18982 <https://github.com/numpy/numpy/pull/18982>`__: MAINT: Cleanup tools/changelog.py
+* `#18983 <https://github.com/numpy/numpy/pull/18983>`__: REL: Update main after 1.20.3 release.
+* `#18985 <https://github.com/numpy/numpy/pull/18985>`__: MAINT: Remove usage of the PEP 604 pipe operator
+* `#18987 <https://github.com/numpy/numpy/pull/18987>`__: BUG: Update coordinates in PyArray_ITER_GOTO1D
+* `#18989 <https://github.com/numpy/numpy/pull/18989>`__: BUG: fix potential buffer overflow(#18939)
+* `#18990 <https://github.com/numpy/numpy/pull/18990>`__: ENH: Add annotations for `np.lib.NumpyVersion`
+* `#18996 <https://github.com/numpy/numpy/pull/18996>`__: MAINT: Remove warning when checking AVX512f on MSVC
+* `#18998 <https://github.com/numpy/numpy/pull/18998>`__: ENH: Improve annotations of the `item`, `tolist`, `take` and...
+* `#18999 <https://github.com/numpy/numpy/pull/18999>`__: DEP: Ensure the string promotion FutureWarning is raised
+* `#19001 <https://github.com/numpy/numpy/pull/19001>`__: DEP: Deprecate error clearing for special method in array-coercion
+* `#19002 <https://github.com/numpy/numpy/pull/19002>`__: ENH: Add annotations for `np.broadcast` and `np.DataSource`
+* `#19005 <https://github.com/numpy/numpy/pull/19005>`__: ENH: Add dtype-support to 11 `ndarray` / `generic` methods
+* `#19007 <https://github.com/numpy/numpy/pull/19007>`__: BUG: fix potential use of null pointer in nditer buffers
+* `#19008 <https://github.com/numpy/numpy/pull/19008>`__: BUG: fix variable misprint in multiarray test code
+* `#19009 <https://github.com/numpy/numpy/pull/19009>`__: BUG: fix variable misprint checking wrong variable in umath tests
+* `#19011 <https://github.com/numpy/numpy/pull/19011>`__: BUG: fix ValueError in PyArray_Std on win_amd64
+* `#19012 <https://github.com/numpy/numpy/pull/19012>`__: MAINT: Small cleanups in `PyArray_NewFromDescr_int`
+* `#19014 <https://github.com/numpy/numpy/pull/19014>`__: Revert "BUG: Update coordinates in PyArray_ITER_GOTO1D"
+* `#19018 <https://github.com/numpy/numpy/pull/19018>`__: DOC: "NumPy" <- "numpy" in NumPy Fundamentals - Indexing
+* `#19021 <https://github.com/numpy/numpy/pull/19021>`__: DOC: Add comment for ifdef macro guard
+* `#19024 <https://github.com/numpy/numpy/pull/19024>`__: MAINT: Bump pytest-cov from 2.11.1 to 2.12.0
+* `#19025 <https://github.com/numpy/numpy/pull/19025>`__: MAINT: Bump sphinx from 4.0.0 to 4.0.1
+* `#19026 <https://github.com/numpy/numpy/pull/19026>`__: DOC: Clarify minimum numpy version needed to use random c-api
+* `#19029 <https://github.com/numpy/numpy/pull/19029>`__: ENH: Improve the annotations of `np.core._internal`
+* `#19031 <https://github.com/numpy/numpy/pull/19031>`__: DEP: Deprecate 4 `ndarray.ctypes` methods
+* `#19035 <https://github.com/numpy/numpy/pull/19035>`__: MAINT: Python3 classes do not need to inherit from object
+* `#19037 <https://github.com/numpy/numpy/pull/19037>`__: BUG: do not use PyLong_FromLong for intp
+* `#19041 <https://github.com/numpy/numpy/pull/19041>`__: DOC: Improve trapz docstring
+* `#19043 <https://github.com/numpy/numpy/pull/19043>`__: DOC: Fix typo in release notes for v1.21
+* `#19046 <https://github.com/numpy/numpy/pull/19046>`__: BUG, SIMD: Fix unexpected result of uint8 division on X86
+* `#19047 <https://github.com/numpy/numpy/pull/19047>`__: BUG, SIMD: Fix NumPy build on ppc64le(IBM/Power) for old versions...
+* `#19048 <https://github.com/numpy/numpy/pull/19048>`__: BUG: Fix duplicate variable names in compiler check for AVX512_SKX
+* `#19049 <https://github.com/numpy/numpy/pull/19049>`__: BLD,API: (distutils) Force strict floating point error model...
+* `#19052 <https://github.com/numpy/numpy/pull/19052>`__: ENH: Improve the `np.ufunc` annotations
+* `#19055 <https://github.com/numpy/numpy/pull/19055>`__: DOC: Forward port missing 1.18.5 release note.
+* `#19063 <https://github.com/numpy/numpy/pull/19063>`__: ENH: Stubs for array_equal appear out of date.
+* `#19066 <https://github.com/numpy/numpy/pull/19066>`__: BUG: Fixed an issue wherein `nanmedian` could return an array...
+* `#19068 <https://github.com/numpy/numpy/pull/19068>`__: MAINT: Update mailmap
+* `#19073 <https://github.com/numpy/numpy/pull/19073>`__: REL: Prepare 1.21.0 release
+* `#19074 <https://github.com/numpy/numpy/pull/19074>`__: BUG: Fix compile-time test of POPCNT
+* `#19075 <https://github.com/numpy/numpy/pull/19075>`__: BUG: Fix test_numpy_version.
+* `#19094 <https://github.com/numpy/numpy/pull/19094>`__: BUG: Fixed an issue wherein `_GenericAlias.__getitem__` would...
+* `#19100 <https://github.com/numpy/numpy/pull/19100>`__: BUG: Linter should only run on pull requests.
+* `#19120 <https://github.com/numpy/numpy/pull/19120>`__: BUG: Fix setup.py to work in maintenance branches.
+* `#19144 <https://github.com/numpy/numpy/pull/19144>`__: BUG: expose short_version as previously in version.py
+* `#19175 <https://github.com/numpy/numpy/pull/19175>`__: API: Delay string and number promotion deprecation/future warning
+* `#19178 <https://github.com/numpy/numpy/pull/19178>`__: BUG, SIMD: Fix detect host/native CPU features on ICC at compile-time
+* `#19180 <https://github.com/numpy/numpy/pull/19180>`__: BUG: Add -std=c99 to intel icc compiler flags on linux
+* `#19193 <https://github.com/numpy/numpy/pull/19193>`__: NEP: Accept NEP 35 as final
+* `#19194 <https://github.com/numpy/numpy/pull/19194>`__: MAINT, BUG: Adapt `castingimpl.casting` to denote a minimal level
+* `#19197 <https://github.com/numpy/numpy/pull/19197>`__: REL: Prepare for NumPy 1.20.0rc2 release.
+* `#19213 <https://github.com/numpy/numpy/pull/19213>`__: MAINT: Add annotations for the missing `period` parameter to...
+* `#19219 <https://github.com/numpy/numpy/pull/19219>`__: MAINT: Add `complex` as allowed type for the `np.complexfloating`...
+* `#19233 <https://github.com/numpy/numpy/pull/19233>`__: TST: Ignore exp FP exceptions test for glibc ver < 2.17
+* `#19238 <https://github.com/numpy/numpy/pull/19238>`__: MAINT: replace imgmath with mathjax for docs
+* `#19239 <https://github.com/numpy/numpy/pull/19239>`__: BUG: Fix out-of-bounds access in convert_datetime_divisor_to_multiple
+* `#19240 <https://github.com/numpy/numpy/pull/19240>`__: ENH: Support major version larger than 9 in NumpyVersion
+* `#19268 <https://github.com/numpy/numpy/pull/19268>`__: DOC: fix duplicate navbar in development documentation index
+* `#19269 <https://github.com/numpy/numpy/pull/19269>`__: BUG: Invalid dtypes comparison should not raise TypeError
+* `#19280 <https://github.com/numpy/numpy/pull/19280>`__: BUG: Add missing DECREF in new path
+* `#19283 <https://github.com/numpy/numpy/pull/19283>`__: REL: Prepare for 1.21.0 release
diff --git a/doc/changelog/1.21.1-changelog.rst b/doc/changelog/1.21.1-changelog.rst
new file mode 100644
index 000000000..f219c5012
--- /dev/null
+++ b/doc/changelog/1.21.1-changelog.rst
@@ -0,0 +1,51 @@
+
+Contributors
+============
+
+A total of 11 people contributed to this release. People with a "+" by their
+names contributed a patch for the first time.
+
+* Bas van Beek
+* Charles Harris
+* Ganesh Kathiresan
+* Gregory R. Lee
+* Hugo Defois +
+* Kevin Sheppard
+* Matti Picus
+* Ralf Gommers
+* Sayed Adel
+* Sebastian Berg
+* Thomas J. Fan
+
+Pull requests merged
+====================
+
+A total of 26 pull requests were merged for this release.
+
+* `#19311 <https://github.com/numpy/numpy/pull/19311>`__: REV,BUG: Replace ``NotImplemented`` with ``typing.Any``
+* `#19324 <https://github.com/numpy/numpy/pull/19324>`__: MAINT: Fixed the return-dtype of ``ndarray.real`` and ``imag``
+* `#19330 <https://github.com/numpy/numpy/pull/19330>`__: MAINT: Replace ``"dtype[Any]"`` with ``dtype`` in the definiton of...
+* `#19342 <https://github.com/numpy/numpy/pull/19342>`__: DOC: Fix some docstrings that crash pdf generation.
+* `#19343 <https://github.com/numpy/numpy/pull/19343>`__: MAINT: bump scipy-mathjax
+* `#19347 <https://github.com/numpy/numpy/pull/19347>`__: BUG: Fix arr.flat.index for large arrays and big-endian machines
+* `#19348 <https://github.com/numpy/numpy/pull/19348>`__: ENH: add ``numpy.f2py.get_include`` function
+* `#19349 <https://github.com/numpy/numpy/pull/19349>`__: BUG: Fix reference count leak in ufunc dtype handling
+* `#19350 <https://github.com/numpy/numpy/pull/19350>`__: MAINT: Annotate missing attributes of ``np.number`` subclasses
+* `#19351 <https://github.com/numpy/numpy/pull/19351>`__: BUG: Fix cast safety and comparisons for zero sized voids
+* `#19352 <https://github.com/numpy/numpy/pull/19352>`__: BUG: Correct Cython declaration in random
+* `#19353 <https://github.com/numpy/numpy/pull/19353>`__: BUG: protect against accessing base attribute of a NULL subarray
+* `#19365 <https://github.com/numpy/numpy/pull/19365>`__: BUG, SIMD: Fix detecting AVX512 features on Darwin
+* `#19366 <https://github.com/numpy/numpy/pull/19366>`__: MAINT: remove ``print()``'s in distutils template handling
+* `#19390 <https://github.com/numpy/numpy/pull/19390>`__: ENH: SIMD architectures to show_config
+* `#19391 <https://github.com/numpy/numpy/pull/19391>`__: BUG: Do not raise deprecation warning for all nans in unique...
+* `#19392 <https://github.com/numpy/numpy/pull/19392>`__: BUG: Fix NULL special case in object-to-any cast code
+* `#19430 <https://github.com/numpy/numpy/pull/19430>`__: MAINT: Use arm64-graviton2 for testing on travis
+* `#19495 <https://github.com/numpy/numpy/pull/19495>`__: BUILD: update OpenBLAS to v0.3.17
+* `#19496 <https://github.com/numpy/numpy/pull/19496>`__: MAINT: Avoid unicode characters in division SIMD code comments
+* `#19499 <https://github.com/numpy/numpy/pull/19499>`__: BUG, SIMD: Fix infinite loop during count non-zero on GCC-11
+* `#19500 <https://github.com/numpy/numpy/pull/19500>`__: BUG: fix a numpy.npiter leak in npyiter_multi_index_set
+* `#19501 <https://github.com/numpy/numpy/pull/19501>`__: TST: Fix a ``GenericAlias`` test failure for python 3.9.0
+* `#19502 <https://github.com/numpy/numpy/pull/19502>`__: MAINT: Start testing with Python 3.10.0b3.
+* `#19503 <https://github.com/numpy/numpy/pull/19503>`__: MAINT: Add missing dtype overloads for object- and ctypes-based...
+* `#19510 <https://github.com/numpy/numpy/pull/19510>`__: REL: Prepare for NumPy 1.21.1 release.
+
diff --git a/doc/neps/_static/nep-0047-casting-rules-lattice.png b/doc/neps/_static/nep-0047-casting-rules-lattice.png
new file mode 100644
index 000000000..669d30476
--- /dev/null
+++ b/doc/neps/_static/nep-0047-casting-rules-lattice.png
Binary files differ
diff --git a/doc/neps/_static/nep-0047-library-dependencies.png b/doc/neps/_static/nep-0047-library-dependencies.png
new file mode 100644
index 000000000..4eab600a5
--- /dev/null
+++ b/doc/neps/_static/nep-0047-library-dependencies.png
Binary files differ
diff --git a/doc/neps/_static/nep-0047-scope-of-array-API.png b/doc/neps/_static/nep-0047-scope-of-array-API.png
new file mode 100644
index 000000000..55253288c
--- /dev/null
+++ b/doc/neps/_static/nep-0047-scope-of-array-API.png
Binary files differ
diff --git a/doc/neps/nep-0000.rst b/doc/neps/nep-0000.rst
index 590976081..7f841b7e2 100644
--- a/doc/neps/nep-0000.rst
+++ b/doc/neps/nep-0000.rst
@@ -278,7 +278,7 @@ References and Footnotes
.. [1] This historical record is available by the normal git commands
for retrieving older revisions, and can also be browsed on
- `GitHub <https://github.com/numpy/numpy/tree/master/doc/neps>`_.
+ `GitHub <https://github.com/numpy/numpy/tree/main/doc/neps>`_.
.. [2] The URL for viewing NEPs on the web is
https://www.numpy.org/neps/.
diff --git a/doc/neps/nep-0001-npy-format.rst b/doc/neps/nep-0001-npy-format.rst
index 3a28247ab..fdf4ae47a 100644
--- a/doc/neps/nep-0001-npy-format.rst
+++ b/doc/neps/nep-0001-npy-format.rst
@@ -292,7 +292,7 @@ included in the 1.9.0 release of numpy.
Specifically, the file format.py in this directory implements the
format as described here.
- https://github.com/numpy/numpy/blob/master/numpy/lib/format.py
+ https://github.com/numpy/numpy/blob/main/numpy/lib/format.py
References
diff --git a/doc/neps/nep-0010-new-iterator-ufunc.rst b/doc/neps/nep-0010-new-iterator-ufunc.rst
index 358018c46..4e7fdfdf5 100644
--- a/doc/neps/nep-0010-new-iterator-ufunc.rst
+++ b/doc/neps/nep-0010-new-iterator-ufunc.rst
@@ -575,12 +575,16 @@ ndim, and niter will produce slightly different layouts.
intp shape;
/* The current coordinate along this axis */
intp coord;
- /* The operand and index strides for this axis
+ /* The operand and index strides for this axis */
intp stride[niter];
- {intp indexstride;} #if (flags&FLAGS_HASINDEX);
+ #if (flags&FLAGS_HASINDEX)
+ intp indexstride;
+ #endif
/* The operand pointers and index values for this axis */
char* ptr[niter];
- {intp index;} #if (flags&FLAGS_HASINDEX);
+ #if (flags&FLAGS_HASINDEX)
+ intp index;
+ #endif
}[ndim];
};
diff --git a/doc/neps/nep-0013-ufunc-overrides.rst b/doc/neps/nep-0013-ufunc-overrides.rst
index 698e45738..ceb8b23e9 100644
--- a/doc/neps/nep-0013-ufunc-overrides.rst
+++ b/doc/neps/nep-0013-ufunc-overrides.rst
@@ -46,8 +46,8 @@ right behaviour, hence the change in name.)
The ``__array_ufunc__`` as described below requires that any
corresponding Python binary operations (``__mul__`` et al.) should be
-implemented in a specific way and be compatible with Numpy's ndarray
-semantics. Objects that do not satisfy this cannot override any Numpy
+implemented in a specific way and be compatible with NumPy's ndarray
+semantics. Objects that do not satisfy this cannot override any NumPy
ufuncs. We do not specify a future-compatible path by which this
requirement can be relaxed --- any changes here require corresponding
changes in 3rd party code.
@@ -132,7 +132,7 @@ However, this behavior is more confusing than useful, and having a
:exc:`TypeError` would be preferable.
This proposal will *not* resolve the issue with scipy.sparse matrices,
-which have multiplication semantics incompatible with numpy arrays.
+which have multiplication semantics incompatible with NumPy arrays.
However, the aim is to enable writing other custom array types that have
strictly ndarray compatible semantics.
@@ -246,7 +246,7 @@ three groups:
- *Incompatible*: neither above nor below A; types for which no
(indirect) upcasting is possible.
-Note that the legacy behaviour of numpy ufuncs is to try to convert
+Note that the legacy behaviour of NumPy ufuncs is to try to convert
unknown objects to :class:`ndarray` via :func:`np.asarray`. This is
equivalent to placing :class:`ndarray` above these objects in the graph.
Since we above defined :class:`ndarray` to return `NotImplemented` for
@@ -454,7 +454,7 @@ implements the following behavior:
A class wishing to modify the interaction with :class:`ndarray` in
binary operations therefore has two options:
-1. Implement ``__array_ufunc__`` and follow Numpy semantics for Python
+1. Implement ``__array_ufunc__`` and follow NumPy semantics for Python
binary operations (see below).
2. Set ``__array_ufunc__ = None``, and implement Python binary
@@ -478,7 +478,7 @@ are not compatible, i.e., implementations should be something like::
except AttributeError:
return False
- class ArrayLike(object):
+ class ArrayLike:
...
def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
...
@@ -516,7 +516,7 @@ does not know how to deal with arrays and ufuncs, and thus has set
``__array_ufunc__`` to :obj:`None`, but does know how to do
multiplication::
- class MyObject(object):
+ class MyObject:
__array_ufunc__ = None
def __init__(self, value):
self.value = value
@@ -678,7 +678,7 @@ NA ``abs`` :func:`absolute`
Future extensions to other functions
------------------------------------
-Some numpy functions could be implemented as (generalized) Ufunc, in
+Some NumPy functions could be implemented as (generalized) Ufunc, in
which case it would be possible for them to be overridden by the
``__array_ufunc__`` method. A prime candidate is :func:`~numpy.matmul`,
which currently is not a Ufunc, but could be relatively easily be
diff --git a/doc/neps/nep-0014-dropping-python2.7-proposal.rst b/doc/neps/nep-0014-dropping-python2.7-proposal.rst
index dfc09d254..e14a173e2 100644
--- a/doc/neps/nep-0014-dropping-python2.7-proposal.rst
+++ b/doc/neps/nep-0014-dropping-python2.7-proposal.rst
@@ -4,7 +4,7 @@
NEP 14 — Plan for dropping Python 2.7 support
=============================================
-:Status: Accepted
+:Status: Final
:Resolution: https://mail.python.org/pipermail/numpy-discussion/2017-November/077419.html
The Python core team plans to stop supporting Python 2 in 2020. The NumPy
diff --git a/doc/neps/nep-0016-abstract-array.rst b/doc/neps/nep-0016-abstract-array.rst
index 63ad600e9..9d21abe6f 100644
--- a/doc/neps/nep-0016-abstract-array.rst
+++ b/doc/neps/nep-0016-abstract-array.rst
@@ -141,7 +141,7 @@ Notes:
In practice, either way we'd only do the full test after first
checking for well-known types like ``ndarray``, ``list``, etc. `This
is how NumPy currently checks for other double-underscore attributes
-<https://github.com/numpy/numpy/blob/master/numpy/core/src/private/get_attr_string.h>`__
+<https://github.com/numpy/numpy/blob/main/numpy/core/src/private/get_attr_string.h>`__
and the same idea applies here to either approach. So these numbers
won't affect the common case, just the case where we actually have an
``AbstractArray``, or else another third-party object that will end up
diff --git a/doc/neps/nep-0023-backwards-compatibility.rst b/doc/neps/nep-0023-backwards-compatibility.rst
index 158f46273..8b6f4cd11 100644
--- a/doc/neps/nep-0023-backwards-compatibility.rst
+++ b/doc/neps/nep-0023-backwards-compatibility.rst
@@ -5,10 +5,11 @@ NEP 23 — Backwards compatibility and deprecation policy
=======================================================
:Author: Ralf Gommers <ralf.gommers@gmail.com>
-:Status: Draft
+:Status: Final
:Type: Process
:Created: 2018-07-14
-:Resolution: <url> (required for Accepted | Rejected | Withdrawn)
+:Resolution: https://mail.python.org/pipermail/numpy-discussion/2021-January/081423.html
+
Abstract
--------
@@ -19,46 +20,222 @@ processes for individual cases where breaking backwards compatibility
is considered.
-Detailed description
+Motivation and Scope
--------------------
NumPy has a very large user base. Those users rely on NumPy being stable
and the code they write that uses NumPy functionality to keep working.
NumPy is also actively maintained and improved -- and sometimes improvements
-require, or are made much easier, by breaking backwards compatibility.
+require, or are made easier, by breaking backwards compatibility.
Finally, there are trade-offs in stability for existing users vs. avoiding
errors or having a better user experience for new users. These competing
-needs often give rise to heated debates and delays in accepting or rejecting
+needs often give rise to long debates and delay accepting or rejecting
contributions. This NEP tries to address that by providing a policy as well
as examples and rationales for when it is or isn't a good idea to break
backwards compatibility.
-General principles:
-
-- Aim not to break users' code unnecessarily.
-- Aim never to change code in ways that can result in users silently getting
- incorrect results from their previously working code.
-- Backwards incompatible changes can be made, provided the benefits outweigh
- the costs.
-- When assessing the costs, keep in mind that most users do not read the mailing
- list, do not look at deprecation warnings, and sometimes wait more than one or
- two years before upgrading from their old version. And that NumPy has
- many hundreds of thousands or even a couple of million users, so "no one will
- do or use this" is very likely incorrect.
-- Benefits include improved functionality, usability and performance (in order
- of importance), as well as lower maintenance cost and improved future
- extensibility.
-- Bug fixes are exempt from the backwards compatibility policy. However in case
- of serious impact on users (e.g. a downstream library doesn't build anymore),
- even bug fixes may have to be delayed for one or more releases.
-- The Python API and the C API will be treated in the same way.
-
-
-Examples
-^^^^^^^^
-
-We now discuss a number of concrete examples to illustrate typical issues
-and trade-offs.
+In addition, this NEP can serve as documentation for users about how the NumPy
+project treats backwards compatibility, and the speed at which they can expect
+changes to be made.
+
+In scope for this NEP are:
+
+- Principles of NumPy's approach to backwards compatibility.
+- How to deprecate functionality, and when to remove already deprecated
+ functionality.
+- Decision making process for deprecations and removals.
+- How to ensure that users are well informed about any change.
+
+Out of scope are:
+
+- Making concrete decisions about deprecations of particular functionality.
+- NumPy's versioning scheme.
+
+
+General principles
+------------------
+
+When considering proposed changes that are backwards incompatible, the
+main principles the NumPy developers use when making a decision are:
+
+1. Changes need to benefit more than they harm users.
+2. NumPy is widely used, so breaking changes should be assumed by default to be
+ harmful.
+3. Decisions should be based on how they affect users and downstream packages
+ and should be based on usage data where possible. It does not matter whether
+ this use contradicts the documentation or best practices.
+4. The possibility of an incorrect result is worse than an error or even crash.
+
+When assessing the costs of proposed changes, keep in mind that most users do
+not read the mailing list, do not notice deprecation warnings, and sometimes
+wait more than one or two years before upgrading from their old version. And
+that NumPy has millions of users, so "no one will do or use this" is likely
+incorrect.
+
+Benefits of proposed changes can include improved functionality, usability and
+performance, as well as lower maintenance cost and improved future
+extensibility.
+
+Fixes for clear bugs are exempt from this backwards compatibility policy.
+However, in case of serious impact on users even bug fixes may have to be
+delayed for one or more releases. For example, if a downstream library would no
+longer build or would give incorrect results.
+
+
+Strategies related to deprecations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Impact assessment
+`````````````````
+
+Getting hard data on the impact of a deprecation of often difficult. Strategies
+that can be used to assess such impact include:
+
+- Use a code search engine ([1]_, [2]_) or static ([3]_) or dynamic ([4]_) code
+ analysis tools to determine where and how the functionality is used.
+- Test prominent downstream libraries against a development build of NumPy
+ containing the proposed change to get real-world data on its impact.
+- Make a change on the main branch and revert it before release if it
+ causes problems. We encourage other packages to test against
+ NumPy's main branch and if that's too burdensome, then at least to
+ test pre-releases. This often turns up issues quickly.
+
+Alternatives to deprecations
+````````````````````````````
+
+If the impact is unclear or significant, it is often good to consider
+alternatives to deprecations. For example, discouraging use in documentation
+only, or moving the documentation for the functionality to a less prominent
+place or even removing it completely. Commenting on open issues related to it
+that they are low-prio or labeling them as "wontfix" will also be a signal to
+users, and reduce the maintenance effort needing to be spent.
+
+
+Implementing deprecations and removals
+--------------------------------------
+
+Deprecation warnings are necessary in all cases where functionality
+will eventually be removed. If there is no intent to remove functionality,
+then it should not be deprecated. A "please don't use this for new code"
+in the documentation or other type of warning should be used instead, and the
+documentation can be organized such that the preferred alternative is more
+prominently shown.
+
+Deprecations:
+
+- shall include the version number of the release in which the functionality
+ was deprecated.
+- shall include information on alternatives to the deprecated functionality, or a
+ reason for the deprecation if no clear alternative is available. Note that
+ release notes can include longer messages if needed.
+- shall use ``DeprecationWarning`` by default, and ``VisibleDeprecation``
+ for changes that need attention again after already having been deprecated or
+ needing extra attention for some reason.
+- shall be listed in the release notes of the release where the deprecation is
+ first present.
+- shall not be introduced in micro (bug fix) releases.
+- shall set a ``stacklevel``, so the warning appears to come from the correct
+ place.
+- shall be mentioned in the documentation for the functionality. A
+ ``.. deprecated::`` directive can be used for this.
+
+Examples of good deprecation warnings (also note standard form of the comments
+above the warning, helps when grepping):
+
+.. code-block:: python
+
+ # NumPy 1.15.0, 2018-09-02
+ warnings.warn('np.asscalar(a) is deprecated since NumPy 1.16.0, use '
+ 'a.item() instead', DeprecationWarning, stacklevel=3)
+
+ # NumPy 1.15.0, 2018-02-10
+ warnings.warn("Importing from numpy.testing.utils is deprecated "
+ "since 1.15.0, import from numpy.testing instead.",
+ DeprecationWarning, stacklevel=2)
+
+ # NumPy 1.14.0, 2017-07-14
+ warnings.warn(
+ "Reading unicode strings without specifying the encoding "
+ "argument is deprecated since NumPy 1.14.0. Set the encoding, "
+ "use None for the system default.",
+ np.VisibleDeprecationWarning, stacklevel=2)
+
+.. code-block:: C
+
+ /* DEPRECATED 2020-05-13, NumPy 1.20 */
+ if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
+ matrix_deprecation_msg, ufunc->name, "first") < 0) {
+ return NULL;
+ }
+
+Removal of deprecated functionality:
+
+- shall be done after at least 2 releases assuming the current 6-monthly
+ release cycle; if that changes, there shall be at least 1 year between
+ deprecation and removal.
+- shall be listed in the release notes of the release where the removal happened.
+- can be done in any minor, but not bugfix, release.
+
+For backwards incompatible changes that aren't "deprecate and remove" but for
+which code will start behaving differently, a ``FutureWarning`` should be
+used. Release notes, mentioning version number and using ``stacklevel`` should
+be done in the same way as for deprecation warnings. A ``.. versionchanged::``
+directive shall be used in the documentation after the behaviour change was
+made to indicate when the behavior changed:
+
+.. code-block:: python
+
+ def argsort(self, axis=np._NoValue, ...):
+ """
+ Parameters
+ ----------
+ axis : int, optional
+ Axis along which to sort. If None, the default, the flattened array
+ is used.
+
+ .. versionchanged:: 1.13.0
+ Previously, the default was documented to be -1, but that was
+ in error. At some future date, the default will change to -1, as
+ originally intended.
+ Until then, the axis should be given explicitly when
+ ``arr.ndim > 1``, to avoid a FutureWarning.
+ """
+ ...
+ warnings.warn(
+ "In the future the default for argsort will be axis=-1, not the "
+ "current None, to match its documentation and np.argsort. "
+ "Explicitly pass -1 or None to silence this warning.",
+ MaskedArrayFutureWarning, stacklevel=3)
+
+
+Decision making
+---------------
+
+In concrete cases where this policy needs to be applied, decisions are made according
+to the `NumPy governance model
+<https://docs.scipy.org/doc/numpy/dev/governance/index.html>`_.
+
+All deprecations must be proposed on the mailing list in order to give everyone
+with an interest in NumPy development a chance to comment. Removal of
+deprecated functionality does not need discussion on the mailing list.
+
+
+Functionality with more strict deprecation policies
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+- ``numpy.random`` has its own backwards compatibility policy with additional
+ requirements on top of the ones in this NEP, see
+ `NEP 19 <http://www.numpy.org/neps/nep-0019-rng-policy.html>`_.
+- The file format of ``.npy`` and ``.npz`` files is strictly versioned
+ independent of the NumPy version; existing format versions must remain
+ backwards compatible even if a newer format version is introduced.
+
+
+Example cases
+-------------
+
+We now discuss a few concrete examples from NumPy's history to illustrate
+typical issues and trade-offs.
**Changing the behavior of a function**
@@ -89,21 +266,6 @@ forces users to change their code more than once, which is almost never the
right thing to do. Instead, a better approach here would have been to
deprecate ``histogram`` and introduce a new function ``hist`` in its place.
-**Returning a view rather than a copy**
-
-The ``ndarray.diag`` method used to return a copy. A view would be better for
-both performance and design consistency. This change was warned about
-(``FutureWarning``) in v.8.0, and in v1.9.0 ``diag`` was changed to return
-a *read-only* view. The planned change to a writeable view in v1.10.0 was
-postponed due to backwards compatibility concerns, and is still an open issue
-(gh-7661).
-
-What should have happened instead: nothing. This change resulted in a lot of
-discussions and wasted effort, did not achieve its final goal, and was not that
-important in the first place. Finishing the change to a *writeable* view in
-the future is not desired, because it will result in users silently getting
-different results if they upgraded multiple versions or simply missed the
-warnings.
**Disallowing indexing with floats**
@@ -117,131 +279,33 @@ introduced for v1.11.0 and turned into a hard error for v1.12.0.
This change was disruptive, however it did catch real bugs in, e.g., SciPy and
scikit-learn. Overall the change was worth the cost, and introducing it in
-master first to allow testing, then removing it again before a release, is a
-useful strategy.
+the main branch first to allow testing, then removing it again before
+a release, is a useful strategy.
-Similar recent deprecations also look like good examples of
+Similar deprecations that also look like good examples of
cleanups/improvements:
-- removing deprecated boolean indexing (gh-8312)
-- deprecating truth testing on empty arrays (gh-9718)
-- deprecating ``np.sum(generator)`` (gh-10670, one issue with this one is that
- its warning message is wrong - this should error in the future).
+- removing deprecated boolean indexing (in 2016, see `gh-8312 <https://github.com/numpy/numpy/pull/8312>`__)
+- deprecating truth testing on empty arrays (in 2017, see `gh-9718 <https://github.com/numpy/numpy/pull/9718>`__)
+
**Removing the financial functions**
-The financial functions (e.g. ``np.pmt``) are badly named, are present in the
-main NumPy namespace, and don't really fit well within NumPy's scope.
-They were added in 2008 after
+The financial functions (e.g. ``np.pmt``) had short non-descriptive names, were
+present in the main NumPy namespace, and didn't really fit well within NumPy's
+scope. They were added in 2008 after
`a discussion <https://mail.python.org/pipermail/numpy-discussion/2008-April/032353.html>`_
on the mailing list where opinion was divided (but a majority in favor).
-At the moment these functions don't cause a lot of overhead, however there are
-multiple issues and PRs a year for them which cost maintainer time to deal
-with. And they clutter up the ``numpy`` namespace. Discussion in 2013 happened
-on removing them again (gh-2880).
-
-This case is borderline, but given that they're clearly out of scope,
-deprecation and removal out of at least the main ``numpy`` namespace can be
-proposed. Alternatively, document clearly that new features for financial
-functions are unwanted, to keep the maintenance costs to a minimum.
-
-**Examples of features not added because of backwards compatibility**
-
-TODO: do we have good examples here? Possibly subclassing related?
-
-
-Removing complete submodules
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-This year there have been suggestions to consider removing some or all of
-``numpy.distutils``, ``numpy.f2py``, ``numpy.linalg``, and ``numpy.random``.
-The motivation was that all these cost maintenance effort, and that they slow
-down work on the core of Numpy (ndarrays, dtypes and ufuncs).
-
-The impact on downstream libraries and users would be very large, and
-maintenance of these modules would still have to happen. Therefore this is
-simply not a good idea; removing these submodules should not happen even for
-a new major version of NumPy.
-
-
-Subclassing of ndarray
-^^^^^^^^^^^^^^^^^^^^^^
-
-Subclassing of ``ndarray`` is a pain point. ``ndarray`` was not (or at least
-not well) designed to be subclassed. Despite that, a lot of subclasses have
-been created even within the NumPy code base itself, and some of those (e.g.
-``MaskedArray``, ``astropy.units.Quantity``) are quite popular. The main
-problems with subclasses are:
-
-- They make it hard to change ``ndarray`` in ways that would otherwise be
- backwards compatible.
-- Some of them change the behavior of ndarray methods, making it difficult to
- write code that accepts array duck-types.
-
-Subclassing ``ndarray`` has been officially discouraged for a long time. Of
-the most important subclasses, ``np.matrix`` will be deprecated (see gh-10142)
-and ``MaskedArray`` will be kept in NumPy (`NEP 17
-<http://www.numpy.org/neps/nep-0017-split-out-maskedarray.html>`_).
-``MaskedArray`` will ideally be rewritten in a way such that it uses only
-public NumPy APIs. For subclasses outside of NumPy, more work is needed to
-provide alternatives (e.g. mixins, see gh-9016 and gh-10446) or better support
-for custom dtypes (see gh-2899). Until that is done, subclasses need to be
-taken into account when making change to the NumPy code base. A future change
-in NumPy to not support subclassing will certainly need a major version
-increase.
-
-
-Policy
-------
-
-1. Code changes that have the potential to silently change the results of a users'
- code must never be made (except in the case of clear bugs).
-2. Code changes that break users' code (i.e. the user will see a clear exception)
- can be made, *provided the benefit is worth the cost* and suitable deprecation
- warnings have been raised first.
-3. Deprecation warnings are in all cases warnings that functionality will be removed.
- If there is no intent to remove functionality, then deprecation in documentation
- only or other types of warnings shall be used.
-4. Deprecations for stylistic reasons (e.g. consistency between functions) are
- strongly discouraged.
-
-Deprecations:
-
-- shall include the version numbers of both when the functionality was deprecated
- and when it will be removed (either two releases after the warning is
- introduced, or in the next major version).
-- shall include information on alternatives to the deprecated functionality, or a
- reason for the deprecation if no clear alternative is available.
-- shall use ``VisibleDeprecationWarning`` rather than ``DeprecationWarning``
- for cases of relevance to end users (as opposed to cases only relevant to
- libraries building on top of NumPy).
-- shall be listed in the release notes of the release where the deprecation happened.
-
-Removal of deprecated functionality:
+The financial functions didn't cause a lot of overhead, however there were
+still multiple issues and PRs a year for them which cost maintainer time to
+deal with. And they cluttered up the ``numpy`` namespace. Discussion on
+removing them was discussed in 2013 (gh-2880, rejected) and in 2019
+(:ref:`NEP32`, accepted without significant complaints).
-- shall be done after 2 releases (assuming a 6-monthly release cycle; if that changes,
- there shall be at least 1 year between deprecation and removal), unless the
- impact of the removal is such that a major version number increase is
- warranted.
-- shall be listed in the release notes of the release where the removal happened.
-
-Versioning:
-
-- removal of deprecated code can be done in any minor (but not bugfix) release.
-- for heavily used functionality (e.g. removal of ``np.matrix``, of a whole submodule,
- or significant changes to behavior for subclasses) the major version number shall
- be increased.
-
-In concrete cases where this policy needs to be applied, decisions are made according
-to the `NumPy governance model
-<https://docs.scipy.org/doc/numpy/dev/governance/index.html>`_.
-
-Functionality with more strict policies:
-
-- ``numpy.random`` has its own backwards compatibility policy,
- see `NEP 19 <http://www.numpy.org/neps/nep-0019-rng-policy.html>`_.
-- The file format for ``.npy`` and ``.npz`` files must not be changed in a backwards
- incompatible way.
+Given that they were clearly outside of NumPy's scope, moving them to a
+separate ``numpy-financial`` package and removing them from NumPy after a
+deprecation period made sense. That also gave users an easy way to update
+their code by doing `pip install numpy-financial`.
Alternatives
@@ -257,34 +321,31 @@ ecosystem - being fairly conservative is required in order to not increase the
extra maintenance for downstream libraries and end users to an unacceptable
level.
-**Semantic versioning.**
-
-This would change the versioning scheme for code removals; those could then
-only be done when the major version number is increased. Rationale for
-rejection: semantic versioning is relatively common in software engineering,
-however it is not at all common in the Python world. Also, it would mean that
-NumPy's version number simply starts to increase faster, which would be more
-confusing than helpful. gh-10156 contains more discussion on this alternative.
-
Discussion
----------
-TODO
-
-This section may just be a bullet list including links to any discussions
-regarding the NEP:
-
-- This includes links to mailing list threads or relevant GitHub issues.
+- `Mailing list discussion on the first version of this NEP in 2018 <https://mail.python.org/pipermail/numpy-discussion/2018-July/078432.html>`__
+- `Mailing list discussion on the Dec 2020 update of this NEP <https://mail.python.org/pipermail/numpy-discussion/2020-December/081358.html>`__
+- `PR with review comments on the the Dec 2020 update of this NEP <https://github.com/numpy/numpy/pull/18097>`__
References and Footnotes
------------------------
-.. [1] TODO
+- `Issue requesting semantic versioning <https://github.com/numpy/numpy/issues/10156>`__
+
+- `PEP 387 - Backwards Compatibility Policy <https://www.python.org/dev/peps/pep-0387/>`__
+
+.. [1] https://searchcode.com/
+
+.. [2] https://sourcegraph.com/search
+
+.. [3] https://github.com/Quansight-Labs/python-api-inspect
+.. [4] https://github.com/data-apis/python-record-api
Copyright
---------
-This document has been placed in the public domain. [1]_
+This document has been placed in the public domain.
diff --git a/doc/neps/nep-0024-missing-data-2.rst b/doc/neps/nep-0024-missing-data-2.rst
index 8e63629f3..903ece1ba 100644
--- a/doc/neps/nep-0024-missing-data-2.rst
+++ b/doc/neps/nep-0024-missing-data-2.rst
@@ -14,7 +14,7 @@ Abstract
--------
*Context: this NEP was written as an alternative to NEP 12, which at the time of writing
-had an implementation that was merged into the NumPy master branch.*
+had an implementation that was merged into the NumPy main branch.*
The principle of this NEP is to separate the APIs for masking and for missing values, according to
diff --git a/doc/neps/nep-0025-missing-data-3.rst b/doc/neps/nep-0025-missing-data-3.rst
index ffe208c98..1756ce491 100644
--- a/doc/neps/nep-0025-missing-data-3.rst
+++ b/doc/neps/nep-0025-missing-data-3.rst
@@ -14,7 +14,7 @@ Abstract
*Context: this NEP was written as an additional alternative to NEP 12 (NEP 24
is another alternative), which at the time of writing had an implementation
-that was merged into the NumPy master branch.*
+that was merged into the NumPy main branch.*
To try and make more progress on the whole missing values/masked arrays/...
debate, it seems useful to have a more technical discussion of the pieces
@@ -62,7 +62,7 @@ values, (4) it is compatible with the common practice of using NaN to indicate
missingness when working with floating point numbers, (5) the dtype is already
a place where "weird things can happen" -- there are a wide variety of dtypes
that don't act like ordinary numbers (including structs, Python objects,
-fixed-length strings, ...), so code that accepts arbitrary numpy arrays already
+fixed-length strings, ...), so code that accepts arbitrary NumPy arrays already
has to be prepared to handle these (even if only by checking for them and
raising an error). Therefore adding yet more new dtypes has less impact on
extension authors than if we change the ndarray object itself.
@@ -96,7 +96,7 @@ for consistency.
General strategy
================
-Numpy already has a general mechanism for defining new dtypes and slotting them
+NumPy already has a general mechanism for defining new dtypes and slotting them
in so that they're supported by ndarrays, by the casting machinery, by ufuncs,
and so on. In principle, we could implement NA-dtypes just using these existing
interfaces. But we don't want to do that, because defining all those new ufunc
@@ -271,7 +271,7 @@ below.
Casting
-------
-FIXME: this really needs attention from an expert on numpy's casting rules. But
+FIXME: this really needs attention from an expert on NumPy's casting rules. But
I can't seem to find the docs that explain how casting loops are looked up and
decided between (e.g., if you're casting from dtype A to dtype B, which dtype's
loops are used?), so I can't go into details. But those details are tricky and
@@ -338,7 +338,7 @@ Printing
--------
FIXME: There should be some sort of mechanism by which values which are NA are
-automatically repr'ed as NA, but I don't really understand how numpy printing
+automatically repr'ed as NA, but I don't really understand how NumPy printing
works, so I'll let someone else fill in this section.
Indexing
@@ -364,10 +364,10 @@ own global singleton.) So for now we stick to scalar indexing just returning
Python API for generic NA support
=================================
-NumPy will gain a global singleton called numpy.NA, similar to None, but with
+NumPy will gain a global singleton called ``numpy.NA``, similar to None, but with
semantics reflecting its status as a missing value. In particular, trying to
treat it as a boolean will raise an exception, and comparisons with it will
-produce numpy.NA instead of True or False. These basics are adopted from the
+produce ``numpy.NA`` instead of True or False. These basics are adopted from the
behavior of the NA value in the R project. To dig deeper into the ideas,
http://en.wikipedia.org/wiki/Ternary_logic#Kleene_logic provides a starting
point.
@@ -453,8 +453,8 @@ The NEP also contains a proposal for a somewhat elaborate
domain-specific-language for describing NA dtypes. I'm not sure how great an
idea that is. (I have a bias against using strings as data structures, and find
the already existing strings confusing enough as it is -- also, apparently the
-NEP version of numpy uses strings like 'f8' when printing dtypes, while my
-numpy uses object names like 'float64', so I'm not sure what's going on there.
+NEP version of NumPy uses strings like 'f8' when printing dtypes, while my
+NumPy uses object names like 'float64', so I'm not sure what's going on there.
``withNA(float64, arg1=value1)`` seems like a more pleasant way to print a
dtype than "NA[f8,value1]", at least to me.) But if people want it, then cool.
diff --git a/doc/neps/nep-0026-missing-data-summary.rst b/doc/neps/nep-0026-missing-data-summary.rst
index f25ce9b91..49d89d828 100644
--- a/doc/neps/nep-0026-missing-data-summary.rst
+++ b/doc/neps/nep-0026-missing-data-summary.rst
@@ -17,7 +17,7 @@ The debate about how NumPy should handle missing data, a subject with
many preexisting approaches, requirements, and conventions, has been long and
contentious. There has been more than one proposal for how to implement
support into NumPy, and there is a testable implementation which is
-merged into NumPy's current master. The vast number of emails and differing
+merged into NumPy's current main. The vast number of emails and differing
points of view has made it difficult for interested parties to understand
the issues and be comfortable with the direction NumPy is going.
@@ -565,7 +565,7 @@ Recommendations for Moving Forward
we're going to have to figure out how to experiment with such
changes out-of-core if NumPy is to continue to evolve without
forking -- might as well do it now. The existing code can live in
- master, disabled, or it can live in a branch -- it'll still be there
+ the main branch, be disabled, or live its own branch -- it'll still be there
once we know what we're doing.
**Mark** thinks we should:
@@ -576,8 +576,8 @@ Recommendations for Moving Forward
A more detailed rationale for this recommendation is:
* A solid preliminary NA-mask implementation is currently in NumPy
- master. This implementation has been extensively tested
- against scipy and other third-party packages, and has been in master
+ main. This implementation has been extensively tested
+ against scipy and other third-party packages, and has been in main
in a stable state for a significant amount of time.
* This implementation integrates deeply with the core, providing an
interface which is usable in the same way R's NA support is. It
diff --git a/doc/neps/nep-0027-zero-rank-arrarys.rst b/doc/neps/nep-0027-zero-rank-arrarys.rst
index 2d152234c..cb3972675 100644
--- a/doc/neps/nep-0027-zero-rank-arrarys.rst
+++ b/doc/neps/nep-0027-zero-rank-arrarys.rst
@@ -57,7 +57,7 @@ However there are some important differences:
Motivation for Array Scalars
----------------------------
-Numpy's design decision to provide 0-d arrays and array scalars in addition to
+NumPy's design decision to provide 0-d arrays and array scalars in addition to
native python types goes against one of the fundamental python design
principles that there should be only one obvious way to do it. In this section
we will try to explain why it is necessary to have three different ways to
@@ -109,7 +109,7 @@ arrays to scalars were summarized as follows:
are something like Python lists (which except for
Object arrays they are not).
-Numpy implements a solution that is designed to have all the pros and none of the cons above.
+NumPy implements a solution that is designed to have all the pros and none of the cons above.
Create Python scalar types for all of the 21 types and also
inherit from the three that already exist. Define equivalent
diff --git a/doc/neps/nep-0028-website-redesign.rst b/doc/neps/nep-0028-website-redesign.rst
index e27da91c6..592209a5f 100644
--- a/doc/neps/nep-0028-website-redesign.rst
+++ b/doc/neps/nep-0028-website-redesign.rst
@@ -7,7 +7,7 @@ NEP 28 — numpy.org website redesign
:Author: Ralf Gommers <ralf.gommers@gmail.com>
:Author: Joe LaChance <joe@boldmetrics.com>
:Author: Shekhar Rajak <shekharrajak.1994@gmail.com>
-:Status: Accepted
+:Status: Final
:Type: Informational
:Created: 2019-07-16
:Resolution: https://mail.python.org/pipermail/numpy-discussion/2019-August/079889.html
@@ -323,7 +323,9 @@ Alternatives we considered for the overall design of the website:
Discussion
----------
-Mailing list thread discussing this NEP: TODO
+- Pull request for this NEP (with a good amount of discussion): https://github.com/numpy/numpy/pull/14032
+- Email about NEP for review: https://mail.python.org/pipermail/numpy-discussion/2019-July/079856.html
+- Proposal to accept this NEP: https://mail.python.org/pipermail/numpy-discussion/2019-August/079889.html
References and Footnotes
diff --git a/doc/neps/nep-0029-deprecation_policy.rst b/doc/neps/nep-0029-deprecation_policy.rst
index 957674ee6..a50afcb98 100644
--- a/doc/neps/nep-0029-deprecation_policy.rst
+++ b/doc/neps/nep-0029-deprecation_policy.rst
@@ -1,7 +1,7 @@
.. _NEP29:
==================================================================================
-NEP 29 — Recommend Python and Numpy version support as a community policy standard
+NEP 29 — Recommend Python and NumPy version support as a community policy standard
==================================================================================
@@ -124,14 +124,14 @@ Drop Schedule
::
On next release, drop support for Python 3.5 (initially released on Sep 13, 2015)
- On Jan 07, 2020 drop support for Numpy 1.14 (initially released on Jan 06, 2018)
+ On Jan 07, 2020 drop support for NumPy 1.14 (initially released on Jan 06, 2018)
On Jun 23, 2020 drop support for Python 3.6 (initially released on Dec 23, 2016)
- On Jul 23, 2020 drop support for Numpy 1.15 (initially released on Jul 23, 2018)
- On Jan 13, 2021 drop support for Numpy 1.16 (initially released on Jan 13, 2019)
- On Jul 26, 2021 drop support for Numpy 1.17 (initially released on Jul 26, 2019)
- On Dec 22, 2021 drop support for Numpy 1.18 (initially released on Dec 22, 2019)
+ On Jul 23, 2020 drop support for NumPy 1.15 (initially released on Jul 23, 2018)
+ On Jan 13, 2021 drop support for NumPy 1.16 (initially released on Jan 13, 2019)
+ On Jul 26, 2021 drop support for NumPy 1.17 (initially released on Jul 26, 2019)
+ On Dec 22, 2021 drop support for NumPy 1.18 (initially released on Dec 22, 2019)
On Dec 26, 2021 drop support for Python 3.7 (initially released on Jun 27, 2018)
- On Jun 21, 2022 drop support for Numpy 1.19 (initially released on Jun 20, 2020)
+ On Jun 21, 2022 drop support for NumPy 1.19 (initially released on Jun 20, 2020)
On Apr 14, 2023 drop support for Python 3.8 (initially released on Oct 14, 2019)
@@ -249,18 +249,18 @@ Code to generate support and drop schedule tables ::
from datetime import datetime, timedelta
- data = """Jan 15, 2017: Numpy 1.12
+ data = """Jan 15, 2017: NumPy 1.12
Sep 13, 2015: Python 3.5
Dec 23, 2016: Python 3.6
Jun 27, 2018: Python 3.7
- Jun 07, 2017: Numpy 1.13
- Jan 06, 2018: Numpy 1.14
- Jul 23, 2018: Numpy 1.15
- Jan 13, 2019: Numpy 1.16
- Jul 26, 2019: Numpy 1.17
+ Jun 07, 2017: NumPy 1.13
+ Jan 06, 2018: NumPy 1.14
+ Jul 23, 2018: NumPy 1.15
+ Jan 13, 2019: NumPy 1.16
+ Jul 26, 2019: NumPy 1.17
Oct 14, 2019: Python 3.8
- Dec 22, 2019: Numpy 1.18
- Jun 20, 2020: Numpy 1.19
+ Dec 22, 2019: NumPy 1.18
+ Jun 20, 2020: NumPy 1.19
"""
releases = []
@@ -284,7 +284,7 @@ Code to generate support and drop schedule tables ::
py_major,py_minor = sorted([int(x) for x in r[2].split('.')] for r in releases if r[1] == 'Python')[-1]
minpy = f"{py_major}.{py_minor+1}+"
- num_major,num_minor = sorted([int(x) for x in r[2].split('.')] for r in releases if r[1] == 'Numpy')[-1]
+ num_major,num_minor = sorted([int(x) for x in r[2].split('.')] for r in releases if r[1] == 'NumPy')[-1]
minnum = f"{num_major}.{num_minor+1}+"
toprint_drop_dates = ['']
diff --git a/doc/neps/nep-0032-remove-financial-functions.rst b/doc/neps/nep-0032-remove-financial-functions.rst
index 1c3722f46..b57ae943f 100644
--- a/doc/neps/nep-0032-remove-financial-functions.rst
+++ b/doc/neps/nep-0032-remove-financial-functions.rst
@@ -5,7 +5,7 @@ NEP 32 — Remove the financial functions from NumPy
==================================================
:Author: Warren Weckesser <warren.weckesser@gmail.com>
-:Status: Accepted
+:Status: Final
:Type: Standards Track
:Created: 2019-08-30
:Resolution: https://mail.python.org/pipermail/numpy-discussion/2019-September/080074.html
@@ -174,19 +174,19 @@ References and footnotes
.. [1] Financial functions,
https://numpy.org/doc/1.17/reference/routines.financial.html
-.. [2] Numpy-discussion mailing list, "Simple financial functions for NumPy",
+.. [2] NumPy-Discussion mailing list, "Simple financial functions for NumPy",
https://mail.python.org/pipermail/numpy-discussion/2008-April/032353.html
-.. [3] Numpy-discussion mailing list, "add xirr to numpy financial functions?",
+.. [3] NumPy-Discussion mailing list, "add xirr to numpy financial functions?",
https://mail.python.org/pipermail/numpy-discussion/2009-May/042645.html
-.. [4] Numpy-discussion mailing list, "Definitions of pv, fv, nper, pmt, and rate",
+.. [4] NumPy-Discussion mailing list, "Definitions of pv, fv, nper, pmt, and rate",
https://mail.python.org/pipermail/numpy-discussion/2009-June/043188.html
.. [5] Get financial functions out of main namespace,
https://github.com/numpy/numpy/issues/2880
-.. [6] Numpy-discussion mailing list, "Deprecation of financial routines",
+.. [6] NumPy-Discussion mailing list, "Deprecation of financial routines",
https://mail.python.org/pipermail/numpy-discussion/2013-August/067409.html
.. [7] ``component: numpy.lib.financial`` issues,
@@ -198,7 +198,7 @@ References and footnotes
.. [9] Quansight-Labs/python-api-inspect,
https://github.com/Quansight-Labs/python-api-inspect/
-.. [10] Numpy-discussion mailing list, "NEP 32: Remove the financial functions
+.. [10] NumPy-Discussion mailing list, "NEP 32: Remove the financial functions
from NumPy"
https://mail.python.org/pipermail/numpy-discussion/2019-September/079965.html
@@ -206,7 +206,7 @@ References and footnotes
remove the financial functions.
https://mail.google.com/mail/u/0/h/1w0mjgixc4rpe/?&th=16d5c38be45f77c4&q=nep+32&v=c&s=q
-.. [12] Numpy-discussion mailing list, "Proposal to accept NEP 32: Remove the
+.. [12] NumPy-Discussion mailing list, "Proposal to accept NEP 32: Remove the
financial functions from NumPy"
https://mail.python.org/pipermail/numpy-discussion/2019-September/080074.html
diff --git a/doc/neps/nep-0035-array-creation-dispatch-with-array-function.rst b/doc/neps/nep-0035-array-creation-dispatch-with-array-function.rst
index 5ec01081a..3a689a4dc 100644
--- a/doc/neps/nep-0035-array-creation-dispatch-with-array-function.rst
+++ b/doc/neps/nep-0035-array-creation-dispatch-with-array-function.rst
@@ -5,11 +5,11 @@ NEP 35 — Array Creation Dispatching With __array_function__
===========================================================
:Author: Peter Andreas Entschev <pentschev@nvidia.com>
-:Status: Draft
+:Status: Final
:Type: Standards Track
:Created: 2019-10-15
:Updated: 2020-11-06
-:Resolution:
+:Resolution: https://mail.python.org/pipermail/numpy-discussion/2021-May/081761.html
Abstract
--------
@@ -327,7 +327,7 @@ The first version of this proposal suggested the implementation above as one
viable solution for NumPy functions implemented in C. However, due to the
downsides pointed out above we have decided to discard any changes on the Python
side and resolve those issues with a pure-C implementation. Please refer to
-[implementation]_ for details.
+[7]_ for details.
Reading the Reference Array Downstream
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -344,6 +344,7 @@ An example of such use is to create a new Dask array while preserving its
backend type:
.. code:: python
+
# Returns dask.array<array, shape=(3,), dtype=int64, chunksize=(3,), chunktype=cupy.ndarray>
np.asarray([1, 2, 3], like=da.array(cp.array(())))
@@ -357,6 +358,7 @@ not use the ``like=`` argument via the ``self`` attribute from
instead:
.. code:: python
+
# Returns dask.array<array, shape=(3,), dtype=int64, chunksize=(3,), chunktype=numpy.ndarray>
np.asarray([1, 2, 3], like=da.array(cp.array(())))
@@ -379,6 +381,7 @@ implemented in Dask. The current relevant part of ``__array_function__``
definition in Dask is seen below:
.. code:: python
+
def __array_function__(self, func, types, args, kwargs):
# Code not relevant for this example here
@@ -388,6 +391,7 @@ definition in Dask is seen below:
And this is how the updated code would look like:
.. code:: python
+
def __array_function__(self, func, types, args, kwargs):
# Code not relevant for this example here
@@ -419,8 +423,9 @@ by downstream libraries is beyond the scope of the present proposal.
Discussion
----------
-.. [implementation] `Implementation's pull request on GitHub <https://github.com/numpy/numpy/pull/16935>`_
-.. [discussion] `Further discussion on implementation and the NEP's content <https://mail.python.org/pipermail/numpy-discussion/2020-August/080919.html>`_
+- `Further discussion on implementation and the NEP's content <https://mail.python.org/pipermail/numpy-discussion/2020-August/080919.html>`_
+- `Decision to release an experimental implementation in NumPy 1.20.0 <https://mail.python.org/pipermail/numpy-discussion/2020-November/081193.html>`__
+
References
----------
@@ -437,6 +442,8 @@ References
.. [6] `NEP 37 — A dispatch protocol for NumPy-like modules <https://numpy.org/neps/nep-0037-array-module.html>`_.
+.. [7] `Implementation's pull request on GitHub <https://github.com/numpy/numpy/pull/16935>`_
+
Copyright
---------
diff --git a/doc/neps/nep-0036-fair-play.rst b/doc/neps/nep-0036-fair-play.rst
index 32e5e1e75..906247fd3 100644
--- a/doc/neps/nep-0036-fair-play.rst
+++ b/doc/neps/nep-0036-fair-play.rst
@@ -3,10 +3,10 @@ NEP 36 — Fair play
==================
:Author: Stéfan van der Walt <stefanv@berkeley.edu>
-:Status: Draft
+:Status: Accepted
:Type: Informational
:Created: 2019-10-24
-:Resolution: Draft
+:Resolution: https://mail.python.org/pipermail/numpy-discussion/2021-June/081890.html
Abstract
@@ -26,31 +26,34 @@ troublesome, bothersome, and unacceptable.
Motivation
----------
-We sometimes learn of NumPy versions modified and circulated by outsiders.
-These patched versions can cause problems for the NumPy community.
+Every so often, we learn of NumPy versions modified and circulated by outsiders.
+These patched versions can cause problems for the NumPy community
+(see, e.g., [#erf]_ and [#CVE-2019-6446]_).
+When issues like these arise, our developers waste time identifying
+the problematic release, locating alterations, and determining an
+appropriate course of action.
-- In December 2018, a `bug report
- <https://github.com/numpy/numpy/issues/12515>`__ was filed against
- `np.erf` -- a function that didn't exist in the NumPy distribution.
- It came to light that a company had published a NumPy version with
- an extended API footprint. After several months of discussion, the
- company agreed to make its patches public, and we added a label to
- the NumPy issue tracker to identify issues pertaining to that
- distribution.
-
-- In another case, after a security issue (CVE-2019-6446) was filed
- against NumPy, distributions put in their own fixes, most often by
- changing a default keyword value. As a result the NumPy API was
- inconsistent across distributions.
-
-When issues arise in cases like these, our developers waste time
-identifying the problematic release, locating alterations,
-and determining an appropriate course of action.
+In addition, packages on the Python Packaging Index are sometimes
+named such that users assume they are sanctioned or maintained by
+NumPy. We wish to reduce the number of such incidents.
During a community call on `October 16th, 2019
-<https://github.com/numpy/archive/blob/master/status_meetings/status-2019-10-16.md>`__
-the community resolved to draft guidelines on the distribution of
-modified NumPy versions.
+<https://github.com/numpy/archive/blob/main/status_meetings/status-2019-10-16.md>`__
+the community resolved to draft guidelines to address these matters.
+
+.. [#erf] In December 2018, a
+ `bug report <https://github.com/numpy/numpy/issues/12515>`__
+ was filed against `np.erf` -- a function that didn't exist in the
+ NumPy distribution. It came to light that a company had published
+ a NumPy version with an extended API footprint. After several
+ months of discussion, the company agreed to make its patches
+ public, and we added a label to the NumPy issue tracker to identify
+ issues pertaining to that distribution.
+
+.. [#CVE-2019-6446] After a security issue (CVE-2019-6446) was filed
+ against NumPy, distributions put in their own fixes, most often by
+ changing a default keyword value. As a result the NumPy API was
+ inconsistent across distributions.
Scope
-----
@@ -100,15 +103,16 @@ Fair play rules
'1.17.2+mycompany.15`
We understand that minor patches are often required to make a
- library work under a certain distribution. E.g., Debian may patch
+ library work inside of a distribution. E.g., Debian may patch
NumPy so that it searches for optimized BLAS libraries in the
- correct locations. But we ask that no substantive changes are
- made.
+ correct locations. This is acceptable, but we ask that no
+ substantive changes are made.
-3. Do not extend NumPy's API footprint.
+3. Do not extend or modify NumPy's API.
If you absolutely have to break rule two, please do not add
- additional functions to the namespace. NumPy's API is already
+ additional functions to the namespace, or modify the API of
+ existing functions. NumPy's API is already
quite large, and we are working hard to reduce it where feasible.
Having additional functions exposed in distributed versions is
confusing for users and developers alike.
@@ -121,7 +125,7 @@ Fair play rules
<https://numpy.org/neps/nep-0018-array-function-protocol.html>`__
were designed to help external packages interact more easily with
NumPy. E.g., the latter allows objects from foreign libraries to
- pass through NumPy unharmed. We actively encourage using any of
+ pass through NumPy. We actively encourage using any of
these "officialy sanctioned" mechanisms for overriding or
interacting with NumPy.
@@ -129,7 +133,7 @@ Fair play rules
discussion on the mailing list before monkeypatching NumPy.
Questions and answers
--------------------
+---------------------
**Q:** We would like to distribute an optimized version of NumPy that
utilizes special instructions for our company's CPU. You recommend
diff --git a/doc/neps/nep-0040-legacy-datatype-impl.rst b/doc/neps/nep-0040-legacy-datatype-impl.rst
index 39889109d..7ea7f6df3 100644
--- a/doc/neps/nep-0040-legacy-datatype-impl.rst
+++ b/doc/neps/nep-0040-legacy-datatype-impl.rst
@@ -6,7 +6,7 @@ NEP 40 — Legacy Datatype Implementation in NumPy
:title: Legacy Datatype Implementation in NumPy
:Author: Sebastian Berg
-:Status: Draft
+:Status: Final
:Type: Informational
:Created: 2019-07-17
diff --git a/doc/neps/nep-0042-new-dtypes.rst b/doc/neps/nep-0042-new-dtypes.rst
index d1ddb7101..bb85f1d10 100644
--- a/doc/neps/nep-0042-new-dtypes.rst
+++ b/doc/neps/nep-0042-new-dtypes.rst
@@ -8,10 +8,10 @@ NEP 42 — New and extensible DTypes
:Author: Sebastian Berg
:Author: Ben Nathanson
:Author: Marten van Kerkwijk
-:Status: Draft
+:Status: Accepted
:Type: Standard
:Created: 2019-07-17
-
+:Resolution: https://mail.python.org/pipermail/numpy-discussion/2020-October/081038.html
.. note::
@@ -203,7 +203,7 @@ Other elements of the casting implementation is the ``CastingImpl``:
# Object describing and performing the cast
casting : casting
- def resolve_descriptors(self, Tuple[DType] : input) -> (casting, Tuple[DType]):
+ def resolve_descriptors(self, Tuple[DTypeMeta], Tuple[DType|None] : input) -> (casting, Tuple[DType]):
raise NotImplementedError
# initially private:
@@ -213,6 +213,8 @@ Other elements of the casting implementation is the ``CastingImpl``:
which describes the casting from one DType to another. In
:ref:`NEP 43 <NEP43>` this ``CastingImpl`` object is used unchanged to
support universal functions.
+Note that the name ``CastingImpl`` here will be generically called
+``ArrayMethod`` to accomodate both casting and universal functions.
******************************************************************************
@@ -525,7 +527,8 @@ This means the implementation will work like this::
# Find what dtype1 is cast to when cast to the common DType
# by using the CastingImpl as described below:
castingimpl = get_castingimpl(type(dtype1), common)
- safety, (_, dtype1) = castingimpl.resolve_descriptors((dtype1, None))
+ safety, (_, dtype1) = castingimpl.resolve_descriptors(
+ (common, common), (dtype1, None))
assert safety == "safe" # promotion should normally be a safe cast
if type(dtype2) is not common:
@@ -652,7 +655,7 @@ and implements the following methods and attributes:
* To report safeness,
- ``resolve_descriptors(self, Tuple[DType] : input) -> casting, Tuple[DType]``.
+ ``resolve_descriptors(self, Tuple[DTypeMeta], Tuple[DType|None] : input) -> casting, Tuple[DType]``.
The ``casting`` output reports safeness (safe, unsafe, or same-kind), and
the tuple is used for more multistep casting, as in the example below.
@@ -691,7 +694,7 @@ The full process is:
1. Call
- ``CastingImpl[Int24, String].resolve_descriptors((int24, "S20"))``.
+ ``CastingImpl[Int24, String].resolve_descriptors((Int24, String), (int24, "S20"))``.
This provides the information that ``CastingImpl[Int24, String]`` only
implements the cast of ``int24`` to ``"S8"``.
@@ -716,7 +719,7 @@ The full process is:
to call
- ``CastingImpl[Int24, String].resolve_descriptors((int24, None))``.
+ ``CastingImpl[Int24, String].resolve_descriptors((Int24, String), (int24, None))``.
In this case the result of ``(int24, "S8")`` defines the correct cast:
@@ -763,8 +766,8 @@ even if the user provides only an ``int16 -> int24`` cast. This proposal does
not provide that, but future work might find such casts dynamically, or at least
allow ``resolve_descriptors`` to return arbitrary ``dtypes``.
-If ``CastingImpl[Int8, Int24].resolve_descriptors((int8, int24))`` returns
-``(int16, int24)``, the actual casting process could be extended to include
+If ``CastingImpl[Int8, Int24].resolve_descriptors((Int8, Int24), (int8, int24))``
+returns ``(int16, int24)``, the actual casting process could be extended to include
the ``int8 -> int16`` cast. This adds a step.
@@ -774,7 +777,7 @@ The implementation for casting integers to datetime would generally
say that this cast is unsafe (because it is always an unsafe cast).
Its ``resolve_descriptors`` function may look like::
- def resolve_descriptors(self, given_dtypes):
+ def resolve_descriptors(self, DTypes, given_dtypes):
from_dtype, to_dtype = given_dtypes
from_dtype = from_dtype.ensure_canonical() # ensure not byte-swapped
if to_dtype is None:
@@ -835,9 +838,10 @@ Its ``resolve_descriptors`` function may look like::
**Notes:**
-The proposed ``CastingImpl`` is designed to be identical to the
-``PyArrayMethod`` proposed in NEP43 as part of restructuring ufuncs to handle
-new DTypes.
+``CastingImpl`` is used as a name in this NEP to clarify that it implements
+all functionality related to a cast. It is meant to be identical to the
+``ArrayMethod`` proposed in NEP 43 as part of restructuring ufuncs to handle
+new DTypes. All type definitions are expected to be named ``ArrayMethod``.
The way dispatching works for ``CastingImpl`` is planned to be limited
initially and fully opaque. In the future, it may or may not be moved into a
@@ -1297,8 +1301,9 @@ The external API for ``CastingImpl`` will be limited initially to defining:
instance if the second string is shorter. If neither type is parametric the
``resolve_descriptors`` must use it.
-* ``resolve_descriptors(dtypes_in[2], dtypes_out[2], casting_out) -> int {0,
- -1}`` The out
+* ``resolve_descriptors(PyArrayMethodObject *self, PyArray_DTypeMeta *DTypes[2],
+ PyArray_Descr *dtypes_in[2], PyArray_Descr *dtypes_out[2], NPY_CASTING *casting_out)
+ -> int {0, -1}`` The out
dtypes must be set correctly to dtypes which the strided loop
(transfer function) can handle. Initially the result must have instances
of the same DType class as the ``CastingImpl`` is defined for. The
@@ -1307,9 +1312,12 @@ The external API for ``CastingImpl`` will be limited initially to defining:
A new, additional flag,
``_NPY_CAST_IS_VIEW``, can be set to indicate that no cast is necessary and a
view is sufficient to perform the cast. The cast should return
- ``-1`` when a custom error is set and ``NPY_NO_CASTING`` to indicate
- that a generic casting error should be set (this is in most cases
- preferable).
+ ``-1`` when an error occurred. If a cast is not possible (but no error
+ occurred), a ``-1`` result should be returned *without* an error set.
+ *This point is under consideration, we may use ``-1`` to indicate
+ a general error, and use a different return value for an impossible cast.*
+ This means that it is *not* possible to inform the user about why a cast is
+ impossible.
* ``strided_loop(char **args, npy_intp *dimensions, npy_intp *strides,
...) -> int {0, -1}`` (signature will be fully defined in :ref:`NEP 43 <NEP43>`)
@@ -1326,7 +1334,7 @@ Although verbose, the API will mimic the one for creating a new DType:
typedef struct{
int flags; /* e.g. whether the cast requires the API */
int nin, nout; /* Number of Input and outputs (always 1) */
- NPY_CASTING casting; /* The default casting level */
+ NPY_CASTING casting; /* The "minimal casting level" */
PyArray_DTypeMeta *dtypes; /* input and output DType class */
/* NULL terminated slots defining the methods */
PyType_Slot *slots;
@@ -1334,7 +1342,7 @@ Although verbose, the API will mimic the one for creating a new DType:
The focus differs between casting and general ufuncs. For example, for casts
``nin == nout == 1`` is always correct, while for ufuncs ``casting`` is
-expected to be usually `"safe"`.
+expected to be usually `"no"`.
**Notes:** We may initially allow users to define only a single loop.
Internally NumPy optimizes far more, and this should be made public
@@ -1349,6 +1357,11 @@ incrementally in one of two ways:
* Or, more likely, expose the ``get_loop`` function which is passed additional
information, such as the fixed strides (similar to our internal API).
+* The casting level denotes the minimal guaranteed casting level and can be
+ ``-1`` if the cast may be impossible. For most non-parametric casts, this
+ value will be the casting level. NumPy may skip the ``resolve_descriptors``
+ call for ``np.can_cast()`` when the result is ``True`` based on this level.
+
The example does not yet include setup and error handling. Since these are
similar to the UFunc machinery, they will be defined in :ref:`NEP 43 <NEP43>` and then
incorporated identically into casting.
diff --git a/doc/neps/nep-0043-extensible-ufuncs.rst b/doc/neps/nep-0043-extensible-ufuncs.rst
index 96d4794f3..cd73108e4 100644
--- a/doc/neps/nep-0043-extensible-ufuncs.rst
+++ b/doc/neps/nep-0043-extensible-ufuncs.rst
@@ -150,6 +150,11 @@ The masked type resolvers specifically will *not* remain supported, but
has no known users (including NumPy itself, which only uses the default
version).
+Further, no compatibility attempt will be made for *calling* as opposed
+to providing either the normal or the masked type resolver. As NumPy
+will use it only as a fallback. There are no known users of this
+(undocumented) possibility.
+
While the above changes potentially break some workflows,
we believe that the long-term improvements vastly outweigh this.
Further, packages such as astropy and Numba are capable of adapting so that
@@ -235,20 +240,30 @@ to define string equality, will be added to a ufunc.
class StringEquality(BoundArrayMethod):
nin = 1
nout = 1
+ # DTypes are stored on the BoundArrayMethod and not on the internal
+ # ArrayMethod, to reference cyles.
DTypes = (String, String, Bool)
- def resolve_descriptors(context, given_descrs):
+ def resolve_descriptors(self: ArrayMethod, DTypes, given_descrs):
"""The strided loop supports all input string dtype instances
and always returns a boolean. (String is always native byte order.)
Defining this function is not necessary, since NumPy can provide
it by default.
+
+ The `self` argument here refers to the unbound array method, so
+ that DTypes are passed in explicitly.
"""
- assert isinstance(given_descrs[0], context.DTypes[0])
- assert isinstance(given_descrs[1], context.DTypes[1])
+ assert isinstance(given_descrs[0], DTypes[0])
+ assert isinstance(given_descrs[1], DTypes[1])
+ assert given_descrs[2] is None or isinstance(given_descrs[2], DTypes[2])
- # The operation is always "safe" casting (most ufuncs are)
- return (given_descrs[0], given_descrs[1], context.DTypes[2]()), "safe"
+ out_descr = given_descrs[2] # preserve input (e.g. metadata)
+ if given_descrs[2] is None:
+ out_descr = DTypes[2]()
+
+ # The operation is always "no" casting (most ufuncs are)
+ return (given_descrs[0], given_descrs[1], out_descr), "no"
def strided_loop(context, dimensions, data, strides, innerloop_data):
"""The 1-D strided loop, similar to those used in current ufuncs"""
@@ -322,12 +337,12 @@ steps involved in a call to a universal function in NumPy.
A UFunc call is split into the following steps:
-1. *Handle ``__array_ufunc__`` protocol:*
+1. Handle ``__array_ufunc__`` protocol:
* For array-likes such as a Dask arrays, NumPy can defer the operation.
This step is performed first, and unaffected by this NEP (compare :ref:`NEP18`).
-2. *Promotion and dispatching*
+2. Promotion and dispatching
* Given the DTypes of all inputs, find the correct implementation.
E.g. an implementation for ``float64``, ``int64`` or a user-defined DType.
@@ -336,7 +351,7 @@ A UFunc call is split into the following steps:
For example, adding a ``float32`` and a ``float64`` is implemented by
first casting the ``float32`` to ``float64``.
-3. *Parametric ``dtype`` resolution:*
+3. Parametric ``dtype`` resolution:
* In general, whenever an output DType is parametric the parameters have
to be found (resolved).
@@ -347,15 +362,16 @@ A UFunc call is split into the following steps:
which fills in the default dtype instances (ensuring for example native
byte order).
-4. *Preparing the iteration:*
+4. Preparing the iteration:
* This step is largely handled by ``NpyIter`` internally (the iterator).
* Allocate all outputs and temporary buffers necessary to perform casts.
+ This *requires* the dtypes as resolved in step 3.
* Find the best iteration order, which includes information to efficiently
implement broadcasting. For example, adding a single value to an array
repeats the same value.
-5. *Setup and fetch the C-level function:*
+5. Setup and fetch the C-level function:
* If necessary, allocate temporary working space.
* Find the C-implemented, light weight, inner-loop function.
@@ -368,33 +384,35 @@ A UFunc call is split into the following steps:
the GIL may be released (to allow threading).
* Clear floating point exception flags.
-6. *Perform the actual calculation:*
+6. Perform the actual calculation:
* Run the DType specific inner-loop function.
* The inner-loop may require access to additional data, such as dtypes or
additional data set in the previous step.
* The inner-loop function may be called an undefined number of times.
-7. *Finalize:*
+7. Finalize:
- * Free any temporary working space allocated in 5.
+ * Free any temporary working space allocated in step 5.
* Check for floating point exception flags.
* Return the result.
The ``ArrayMethod`` provides a concept to group steps 3 to 6 and partially 7.
-However, implementers of a new ufunc or ``ArrayMethod`` do not need to
-customize the behaviour in steps 4 or 6, aside from the inner-loop function.
-For the ``ArrayMethod`` implementer, the central steps to have control over
-are step 3 and step 5 to provide the custom inner-loop function.
-Further customization is a potential future extension.
+However, implementers of a new ufunc or ``ArrayMethod`` usually do not need to
+customize the behaviour in steps 4 or 6 which NumPy can and does provide.
+For the ``ArrayMethod`` implementer, the central steps to customize
+are step 3 and step 5. These provide the custom inner-loop function and
+potentially inner-loop specific setup.
+Further customization is possible and anticipated as future extensions.
-Step 2. is promotion and dispatching which will also be restructured
-with new API which allows influencing the process where necessary.
+Step 2. is promotion and dispatching and will be restructured
+with new API to allow customization of the process where necessary.
Step 1 is listed for completeness and is unaffected by this NEP.
The following sketch provides an overview of step 2 to 6 with an emphasize
-of how dtypes are handled:
+of how dtypes are handled and which parts are customizable ("Registered")
+and which are handled by NumPy:
.. figure:: _static/nep43-sketch.svg
:figclass: align-center
@@ -410,21 +428,19 @@ We use the ``class`` syntax to describe the information required to create
a new ``ArrayMethod`` object:
.. code-block:: python
- :dedent: 0
class ArrayMethod:
name: str # Name, mainly useful for debugging
# Casting safety information (almost always "safe", necessary to
# unify casting and universal functions)
- casting: Casting = "safe"
+ casting: Casting = "no"
# More general flags:
flags: int
- @staticmethod
- def resolve_descriptors(
- Context: context, Tuple[DType]: given_descrs)-> Casting, Tuple[DType]:
+ def resolve_descriptors(self,
+ Tuple[DTypeMeta], Tuple[DType|None]: given_descrs) -> Casting, Tuple[DType]:
"""Returns the safety of the operation (casting safety) and the
"""
# A default implementation can be provided for non-parametric
@@ -456,7 +472,6 @@ a new ``ArrayMethod`` object:
With ``Context`` providing mostly static information about the function call:
.. code-block:: python
- :dedent: 0
class Context:
# The ArrayMethod object itself:
@@ -468,8 +483,6 @@ With ``Context`` providing mostly static information about the function call:
int : nin = 1
# The number of output arguments:
int : nout = 1
- # The DTypes this Method operates on/is defined for:
- Tuple[DTypeMeta] : dtypes
# The actual dtypes instances the inner-loop operates on:
Tuple[DType] : descriptors
@@ -616,7 +629,8 @@ definitions (see also :ref:`NEP 42 <NEP42>` ``CastingImpl``):
NPY_CASTING
resolve_descriptors(
- PyArrayMethod_Context *context,
+ PyArrayMethodObject *self,
+ PyArray_DTypeMeta *dtypes,
PyArray_Descr *given_dtypes[nin+nout],
PyArray_Descr *loop_dtypes[nin+nout]);
@@ -647,25 +661,25 @@ definitions (see also :ref:`NEP 42 <NEP42>` ``CastingImpl``):
for example for implementing warnings (see Error and Warning Handling below).
To simplify this NumPy will pass a single zero initialized ``npy_intp *``
when ``user_data`` is not set.
- *NOTE that it would be possible to pass this as part of ``Context``.*
+ *Note that it would be possible to pass this as part of Context.*
* The optional ``get_loop`` function will not be public initially, to avoid
finalizing the API which requires design choices also with casting:
- .. code-block::
+ .. code-block:: C
innerloop *
get_loop(
PyArrayMethod_Context *context,
- /* (move_references is currently used internally for casting) */
int aligned, int move_references,
npy_intp *strides,
PyArray_StridedUnaryOp **out_loop,
NpyAuxData **innerloop_data,
NPY_ARRAYMETHOD_FLAGS *flags);
- The ``NPY_ARRAYMETHOD_FLAGS`` can indicate whether the Python API is required
- and floating point errors must be checked.
+ ``NPY_ARRAYMETHOD_FLAGS`` can indicate whether the Python API is required
+ and floating point errors must be checked. ``move_references`` is used
+ internally for NumPy casting at this time.
* The inner-loop function::
@@ -737,8 +751,15 @@ This step is required to allocate output arrays and has to happen before
casting can be prepared.
While the returned casting-safety (``NPY_CASTING``) will almost always be
-"safe" for universal functions, including it has two big advantages:
-
+"no" for universal functions, including it has two big advantages:
+
+* ``-1`` indicates that an error occurred. If a Python error is set, it will
+ be raised. If no Python error is set this will be considered an "impossible"
+ cast and a custom error will be set. (This distinction is important for the
+ ``np.can_cast()`` function, which should raise the first one and return
+ ``False`` in the second case, it is not noteworthy for typical ufuncs).
+ *This point is under consideration, we may use -1 to indicate
+ a general error, and use a different return value for an impossible cast.*
* Returning the casting safety is central to NEP 42 for casting and
allows the unmodified use of ``ArrayMethod`` there.
* There may be a future desire to implement fast but unsafe implementations.
@@ -746,7 +767,7 @@ While the returned casting-safety (``NPY_CASTING``) will almost always be
perspective. Currently, this would use ``int64 + int64 -> int64`` and then
cast to ``int32``. An implementation that skips the cast would
have to signal that it effectively includes the "same-kind" cast and is
- thus not considered "safe".
+ thus not considered "no".
``get_loop`` method
@@ -774,7 +795,7 @@ Extending the inner-loop signature
Extending the inner-loop signature is another central and necessary part of
the NEP.
-**Passing in the ``Context``:**
+**Passing in the Context:**
Passing in the ``Context`` potentially allows for the future extension of
the signature by adding new fields to the context struct.
@@ -802,8 +823,8 @@ exists in NumPy for this purpose, it seems a natural choice.
To simplify some use-cases (see "Error Handling" below), we will pass a
``npy_intp *innerloop_data = 0`` instead when ``innerloop_data`` is not provided.
-*Note: Since ``get_loop`` is expected to be private initially we can gain
-experience with ``innerloop_data`` before exposing it as public API.*
+*Note:* Since ``get_loop`` is expected to be private initially we can gain
+experience with ``innerloop_data`` before exposing it as public API.
**Return value:**
@@ -934,7 +955,7 @@ This wrapped ``ArrayMethod`` will have two additional methods:
have changed the byte-order), and further resolve the physical unit making
the final signature::
- ``Unit[Float64]("m") + Unit[Float64]("m") -> Unit[Float64]("m")``
+ Unit[Float64]("m") + Unit[Float64]("m") -> Unit[Float64]("m")
the UFunc machinery will take care of casting the "km" input to "m".
@@ -1019,8 +1040,8 @@ In the future we expect that ``ArrayMethod``\ s can also be defined for
**Promotion:**
If a matching ``ArrayMethod`` exists, dispatching is straight forward.
-However, when it does not, require additional definitions to implement
-promotion:
+However, when it does not, additional definitions are required to implement
+this "promotion":
* By default any UFunc has a promotion which uses the common DType of all
inputs and dispatches a second time. This is well-defined for most
@@ -1065,7 +1086,7 @@ In this case, just as a ``Timedelta64 * int64`` and ``int64 * timedelta64``
``ArrayMethod`` is necessary, a second promoter will have to be registered to
handle the case where the integer is passed first.
-**Dispatching rules for ``ArrayMethod`` and Promoters:**
+**Dispatching rules for ArrayMethod and Promoters:**
Promoter and ``ArrayMethod`` are discovered by finding the best match as
defined by the DType class hierarchy.
diff --git a/doc/neps/nep-0046-sponsorship-guidelines.rst b/doc/neps/nep-0046-sponsorship-guidelines.rst
new file mode 100644
index 000000000..b8b312aa5
--- /dev/null
+++ b/doc/neps/nep-0046-sponsorship-guidelines.rst
@@ -0,0 +1,256 @@
+.. _NEP46:
+
+=====================================
+NEP 46 — NumPy Sponsorship Guidelines
+=====================================
+
+:Author: Ralf Gommers <ralf.gommers@gmail.com>
+:Status: Accepted
+:Type: Process
+:Created: 2020-12-27
+:Resolution: https://mail.python.org/pipermail/numpy-discussion/2021-January/081424.html
+
+
+Abstract
+--------
+
+This NEP provides guidelines on how the NumPy project will acknowledge
+financial and in-kind support.
+
+
+Motivation and Scope
+--------------------
+
+In the past few years, the NumPy project has gotten significant financial
+support, as well as dedicated work time for maintainers to work on NumPy. There
+is a need to acknowledge that support - it's the right thing to do, it's
+helpful when looking for new funding, and funders and organizations expect or
+require it, Furthermore, having a clear policy for how NumPy acknowledges
+support is helpful when searching for new support. Finally, this policy may
+help set reasonable expectations for potential funders.
+
+This NEP is aimed at both the NumPy community - who can use it as a guideline
+when looking for support on behalf of the project and when acknowledging
+existing support - and at past, current and prospective sponsors, who often
+want or need to know what they get in return for their support other than a
+healthier NumPy.
+
+The scope of this proposal includes:
+
+- direct financial support, employers providing paid time for NumPy maintainers
+ and regular contributors, and in-kind support such as free hardware resources or
+ services,
+- where and how NumPy acknowledges support (e.g., logo placement on the website),
+- the amount and duration of support which leads to acknowledgement, and
+- who in the NumPy project is responsible for sponsorship related topics, and
+ how to contact them.
+
+
+How NumPy will acknowledge support
+----------------------------------
+
+There will be two different ways to acknowledge financial and in-kind support:
+one to recognize significant active support, and another one to recognize
+support received in the past and smaller amounts of support.
+
+Entities who fall under "significant active supporter" we'll call Sponsor.
+The minimum level of support given to NumPy to be considered a Sponsor are:
+
+- $30,000/yr for unrestricted financial contributions (e.g., donations)
+- $60,000/yr for financial contributions for a particular purpose (e.g., grants)
+- $100,000/yr for in-kind contributions (e.g., time for employees to contribute)
+
+We define support being active as:
+
+- for a one-off donation: it was received within the previous 12 months,
+- for recurring or financial or in-kind contributions: they should be ongoing.
+
+After support moves from "active" to "inactive" status, the acknowledgement
+will be left in its place for at least another 6 months. If appropriate, the
+funding team can discuss opportunities for renewal with the sponsor. After
+those 6 months, acknowledgement may be moved to the historical overview. The
+exact timing of this move is at the discretion of the funding team, because
+there may be reasons to keep it in the more prominent place for longer.
+
+The rationale for the above funding levels is that unrestricted financial
+contributions are typically the most valuable for the project, and the hardest
+to obtain. The opposite is true for in-kind contributions. The dollar value of
+the levels also reflect that NumPy's needs have grown to the point where we
+need multiple paid developers in order to effectively support our user base and
+continue to move the project forward. Financial support at or above these
+levels is needed to be able to make a significant difference.
+
+Sponsors will get acknowledged through:
+
+- a small logo displayed on the front page of the NumPy website
+- prominent logo placement on https://numpy.org/about/
+- logos displayed in talks about NumPy by maintainers
+- announcements of the sponsorship on the NumPy mailing list and the numpy-team
+ Twitter account
+
+In addition to Sponsors, we already have the concept of Institutional Partner
+(defined in NumPy's
+`governance document <https://numpy.org/devdocs/dev/governance/index.html>`__),
+for entities who employ a NumPy maintainer and let them work on NumPy as part
+of their official duties. The governance document doesn't currently define a
+minimum amount of paid maintainer time needed to be considered for partnership.
+Therefore we propose that level here, roughly in line with the sponsorship
+levels:
+
+- 6 person-months/yr of paid work time for one or more NumPy maintainers or
+ regular contributors to any NumPy team or activity
+
+Institutional Partners get the same benefits as Sponsors, in addition to what
+is specified in the NumPy governance document.
+
+Finally, a new page on the website (https://numpy.org/funding/, linked from the
+About page) will be added to acknowledge all current and previous sponsors,
+partners, and any other entities and individuals who provided $5,000 or more of
+financial or in-kind support. This page will include relevant details of
+support (dates, amounts, names, and purpose); no logos will be used on this
+page. The rationale for the $5,000 minimum level is to keep the amount of work
+maintaining the page reasonable; the level is the equivalent of, e.g., one GSoC
+or a person-week's worth of engineering time in a Western country, which seems
+like a reasonable lower limit.
+
+
+Implementation
+--------------
+
+The following content changes need to be made:
+
+- Add a section with small logos towards the bottom of the `numpy.org
+ <https://numpy.org/>`__ website.
+- Create a full list of historical and current support and deploy it to
+ https://numpy.org/funding.
+- Update the NumPy governance document for changes to Institutional Partner
+ eligibility requirements and benefits.
+- Update https://numpy.org/about with details on how to get in touch with the
+ NumPy project about sponsorship related matters (see next section).
+
+
+NumPy Funding Team
+~~~~~~~~~~~~~~~~~~
+
+At the moment NumPy has only one official body, the Steering Council, and no
+good way to get in touch with either that body or any person or group
+responsible for funding and sponsorship related matters. The way this is
+typically done now is to somehow find the personal email of a maintainer, and
+email them in private. There is a need to organize this more transparently - a
+potential sponsor isn't likely to inquire through the mailing list, nor is it
+easy for a potential sponsor to know if they're reaching out to the right
+person in private.
+
+https://numpy.org/about/ already says that NumPy has a "funding and grants"
+team. However that is not the case. We propose to organize this team, name team
+members on it, and add the names of those team members plus a dedicated email
+address for the team to the About page.
+
+
+Status before this proposal
+---------------------------
+
+Acknowledgement of support
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+At the time of writing (Dec 2020), the logos of the four largest financial
+sponsors and two institutional partners are displayed on
+https://numpy.org/about/. The `Nature paper about NumPy <https://www.nature.com/articles/s41586-020-2649-2>`__
+mentions some early funding. No comprehensive list of received funding and
+in-kind support is published anywhere.
+
+Decisions on which logos to list on the website have been made mostly by the
+website team. Decisions on which entities to recognize as Institutional Partner
+have been made by the NumPy Steering Council.
+
+
+NumPy governance, decision-making, and financial oversight
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+*This section is meant as context for the reader, to help put the rest of this
+NEP in perspective, and perhaps answer questions the reader has when reading
+this as a potential sponsor.*
+
+NumPy has a formal governance structure defined in
+`this governance document <https://numpy.org/devdocs/dev/governance/index.html>`__).
+Decisions are made by consensus among all active participants in a discussion
+(typically on the mailing list), and if consensus cannot be reached then the
+Steering Council takes the decision (also by consensus).
+
+NumPy is a sponsored project of NumFOCUS, a US-based 501(c)3 nonprofit.
+NumFOCUS administers NumPy funds, and ensures they are spent in accordance with
+its mission and nonprofit status. In practice, NumPy has a NumFOCUS
+subcommittee (with its members named in the NumPy governance document) who can
+authorize financial transactions. Those transactions, for example paying a
+contractor for a particular activity or deliverable, are decided on by the
+NumPy Steering Council.
+
+
+Alternatives
+------------
+
+*Tiered sponsorship levels.* We considered using tiered sponsorship levels, and
+rejected this alternative because it would be more complex, and not necessarily
+communicate the right intent - the minimum levels are for us to determine how
+to acknowledge support that we receive, not a commercial value proposition.
+Entities typically will support NumPy because they rely on the project or want
+to help advance it, and not to get brand awareness through logo placement.
+
+*Listing all donations*. Note that in the past we have received many smaller
+donations, mostly from individuals through NumFOCUS. It would be great to list
+all of those contributions, but given the way we receive information on those
+donations right now, that would be quite labor-intensive. If we manage to move
+to a more suitable platform, such as `Open Collective <https://opencollective.com/>`__,
+in the future, we should reconsider listing all individual donations.
+
+
+Related Work
+------------
+
+Here we provide a few examples of how other projects handle sponsorship
+guidelines and acknowledgements.
+
+*Scikit-learn* has a narrow banner with logos at the bottom of
+https://scikit-learn.org, and a list of present funding and past sponsors at
+https://scikit-learn.org/stable/about.html#funding. Plus a separate section
+"Infrastructure support" at the bottom of that same About page.
+
+*Jupyter* has logos of sponsors and institutional partners in two sections on
+https://jupyter.org/about. Some subprojects have separate approaches, for
+example sponsors are listed (by using the `all-contributors
+<https://github.com/all-contributors/all-contributors>`__ bot) in the README for
+`jupyterlab-git <https://github.com/jupyterlab/jupyterlab-git>`__. For a recent
+discussion on that, see `here <jupyterlab-git acknowledgements discussion>`_.
+
+*NumFOCUS* has a large banner with sponsor logos on its front page at
+https://numfocus.org, and a full page with sponsors at different sponsorship
+levels listed at https://numfocus.org/sponsors. They also have a
+`Corporate Sponsorship Prospectus <https://numfocus.org/blog/introducing-our-newest-corporate-sponsorship-prospectus>`__,
+which includes a lot of detail on both sponsorship levels and benefits, as well
+as how that helps NumFOCUS-affiliated projects (including NumPy).
+
+
+Discussion
+----------
+
+- `Mailing list thread discussing this NEP <https://mail.python.org/pipermail/numpy-discussion/2020-December/081353.html>`__
+- `PR with review of the NEP draft <https://github.com/numpy/numpy/pull/18084>`__
+
+
+References and Footnotes
+------------------------
+
+- `Inside NumPy: preparing for the next decade <https://github.com/numpy/archive/blob/main/content/inside_numpy_presentation_SciPy2019.pdf>`__ presentation at SciPy'19 discussing the impact of the first NumPy grant.
+- `Issue <https://github.com/numpy/numpy/issues/13393>`__ and
+ `email <https://mail.python.org/pipermail/numpy-discussion/2019-April/079371.html>`__
+ where IBM offered a $5,000 bounty for VSX SIMD support
+- `JupyterLab Corporate Engagement and Contribution Guide <https://github.com/jupyterlab/jupyterlab/blob/master/CORPORATE.md>`__
+
+
+.. _jupyterlab-git acknowledgements discussion: https://github.com/jupyterlab/jupyterlab-git/pull/530
+
+
+Copyright
+---------
+
+This document has been placed in the public domain.
diff --git a/doc/neps/nep-0047-array-api-standard.rst b/doc/neps/nep-0047-array-api-standard.rst
new file mode 100644
index 000000000..19965c20d
--- /dev/null
+++ b/doc/neps/nep-0047-array-api-standard.rst
@@ -0,0 +1,590 @@
+.. _NEP47:
+
+========================================
+NEP 47 — Adopting the array API standard
+========================================
+
+:Author: Ralf Gommers <ralf.gommers@gmail.com>
+:Author: Stephan Hoyer <shoyer@gmail.com>
+:Author: Aaron Meurer <asmeurer@gmail.com>
+:Status: Draft
+:Type: Standards Track
+:Created: 2021-01-21
+:Resolution:
+
+
+Abstract
+--------
+
+We propose to adopt the `Python array API standard`_, developed by the
+`Consortium for Python Data API Standards`_. Implementing this as a separate
+new namespace in NumPy will allow authors of libraries which depend on NumPy
+as well as end users to write code that is portable between NumPy and all
+other array/tensor libraries that adopt this standard.
+
+.. note::
+
+ We expect that this NEP will remain in a draft state for quite a while.
+ Given the large scope we don't expect to propose it for acceptance any
+ time soon; instead, we want to solicit feedback on both the high-level
+ design and implementation, and learn what needs describing better in this
+ NEP or changing in either the implementation or the array API standard
+ itself.
+
+
+Motivation and Scope
+--------------------
+
+Python users have a wealth of choice for libraries and frameworks for
+numerical computing, data science, machine learning, and deep learning. New
+frameworks pushing forward the state of the art in these fields are appearing
+every year. One unintended consequence of all this activity and creativity
+has been fragmentation in multidimensional array (a.k.a. tensor) libraries -
+which are the fundamental data structure for these fields. Choices include
+NumPy, Tensorflow, PyTorch, Dask, JAX, CuPy, MXNet, and others.
+
+The APIs of each of these libraries are largely similar, but with enough
+differences that it’s quite difficult to write code that works with multiple
+(or all) of these libraries. The array API standard aims to address that
+issue, by specifying an API for the most common ways arrays are constructed
+and used. The proposed API is quite similar to NumPy's API, and deviates mainly
+in places where (a) NumPy made design choices that are inherently not portable
+to other implementations, and (b) where other libraries consistently deviated
+from NumPy on purpose because NumPy's design turned out to have issues or
+unnecessary complexity.
+
+For a longer discussion on the purpose of the array API standard we refer to
+the `Purpose and Scope section of the array API standard <https://data-apis.github.io/array-api/latest/purpose_and_scope.html>`__
+and the two blog posts announcing the formation of the Consortium [1]_ and
+the release of the first draft version of the standard for community review [2]_.
+
+The scope of this NEP includes:
+
+- Adopting the 2021 version of the array API standard
+- Adding a separate namespace, tentatively named ``numpy.array_api``
+- Changes needed/desired outside of the new namespace, for example new dunder
+ methods on the ``ndarray`` object
+- Implementation choices, and differences between functions in the new
+ namespace with those in the main ``numpy`` namespace
+- A new array object conforming to the array API standard
+- Maintenance effort and testing strategy
+- Impact on NumPy's total exposed API surface and on other future and
+ under-discussion design choices
+- Relation to existing and proposed NumPy array protocols
+ (``__array_ufunc__``, ``__array_function__``, ``__array_module__``).
+- Required improvements to existing NumPy functionality
+
+Out of scope for this NEP are:
+
+- Changes in the array API standard itself. Those are likely to come up
+ during review of this NEP, but should be upstreamed as needed and this NEP
+ subsequently updated.
+
+
+Usage and Impact
+----------------
+
+*This section will be fleshed out later, for now we refer to the use cases given
+in* `the array API standard Use Cases section <https://data-apis.github.io/array-api/latest/use_cases.html>`__
+
+In addition to those use cases, the new namespace contains functionality that
+is widely used and supported by many array libraries. As such, it is a good
+set of functions to teach to newcomers to NumPy and recommend as "best
+practice". That contrasts with NumPy's main namespace, which contains many
+functions and objects that have been superceded or we consider mistakes - but
+that we can't remove because of backwards compatibility reasons.
+
+The usage of the ``numpy.array_api`` namespace by downstream libraries is
+intended to enable them to consume multiple kinds of arrays, *without having
+to have a hard dependency on all of those array libraries*:
+
+.. image:: _static/nep-0047-library-dependencies.png
+
+Adoption in downstream libraries
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The prototype implementation of the ``array_api`` namespace will be used with
+SciPy, scikit-learn and other libraries of interest that depend on NumPy, in
+order to get more experience with the design and find out if any important
+parts are missing.
+
+The pattern to support multiple array libraries is intended to be something
+like::
+
+ def somefunc(x, y):
+ # Retrieves standard namespace. Raises if x and y have different
+ # namespaces. See Appendix for possible get_namespace implementation
+ xp = get_namespace(x, y)
+ out = xp.mean(x, axis=0) + 2*xp.std(y, axis=0)
+ return out
+
+The ``get_namespace`` call is effectively the library author opting in to
+using the standard API namespace, and thereby explicitly supporting
+all conforming array libraries.
+
+
+The ``asarray`` / ``asanyarray`` pattern
+````````````````````````````````````````
+
+Many existing libraries use the same ``asarray`` (or ``asanyarray``) pattern
+as NumPy itself does; accepting any object that can be coerced into a ``np.ndarray``.
+We consider this design pattern problematic - keeping in mind the Zen of
+Python, *"explicit is better than implicit"*, as well as the pattern being
+historically problematic in the SciPy ecosystem for ``ndarray`` subclasses
+and with over-eager object creation. All other array/tensor libraries are
+more strict, and that works out fine in practice. We would advise authors of
+new libraries to avoid the ``asarray`` pattern. Instead they should either
+accept just NumPy arrays or, if they want to support multiple kinds of
+arrays, check if the incoming array object supports the array API standard
+by checking for ``__array_namespace__`` as shown in the example above.
+
+Existing libraries can do such a check as well, and only call ``asarray`` if
+the check fails. This is very similar to the ``__duckarray__`` idea in
+:ref:`NEP30`.
+
+
+.. _adoption-application-code:
+
+Adoption in application code
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The new namespace can be seen by end users as a cleaned up and slimmed down
+version of NumPy's main namespace. Encouraging end users to use this
+namespace like::
+
+ import numpy.array_api as xp
+
+ x = xp.linspace(0, 2*xp.pi, num=100)
+ y = xp.cos(x)
+
+seems perfectly reasonable, and potentially beneficial - users get offered only
+one function for each purpose (the one we consider best-practice), and they
+then write code that is more easily portable to other libraries.
+
+
+Backward compatibility
+----------------------
+
+No deprecations or removals of existing NumPy APIs or other backwards
+incompatible changes are proposed.
+
+
+High-level design
+-----------------
+
+The array API standard consists of approximately 120 objects, all of which
+have a direct NumPy equivalent. This figure shows what is included at a high level:
+
+.. image:: _static/nep-0047-scope-of-array-API.png
+
+The most important changes compared to what NumPy currently offers are:
+
+- A new array object which:
+
+ - conforms to the casting rules and indexing behaviour specified by the
+ standard,
+ - does not have methods other than dunder methods,
+ - does not support the full range of NumPy indexing behaviour. Advanced
+ indexing with integers is not supported. Only boolean indexing
+ with a single (possibly multi-dimensional) boolean array is supported.
+ An indexing expression that selects a single element returns a 0-D array
+ rather than a scalar.
+
+- Functions in the ``array_api`` namespace:
+
+ - do not accept ``array_like`` inputs, only NumPy arrays and Python scalars
+ - do not support ``__array_ufunc__`` and ``__array_function__``,
+ - use positional-only and keyword-only parameters in their signatures,
+ - have inline type annotations,
+ - may have minor changes to signatures and semantics of individual
+ functions compared to their equivalents already present in NumPy,
+ - only support dtype literals, not format strings or other ways of
+ specifying dtypes
+
+- DLPack_ support will be added to NumPy,
+- New syntax for "device support" will be added, through a ``.device``
+ attribute on the new array object, and ``device=`` keywords in array creation
+ functions in the ``array_api`` namespace,
+- Casting rules that differ from those NumPy currently has. Output dtypes can
+ be derived from input dtypes (i.e. no value-based casting), and 0-D arrays
+ are treated like >=1-D arrays.
+- Not all dtypes NumPy has are part of the standard. Only boolean, signed and
+ unsigned integers, and floating-point dtypes up to ``float64`` are supported.
+ Complex dtypes are expected to be added in the next version of the standard.
+ Extended precision, string, void, object and datetime dtypes, as well as
+ structured dtypes, are not included.
+
+Improvements to existing NumPy functionality that are needed include:
+
+- Add support for stacks of matrices to some functions in ``numpy.linalg``
+ that are currently missing such support.
+- Add the ``keepdims`` keyword to ``np.argmin`` and ``np.argmax``.
+- Add a "never copy" mode to ``np.asarray``.
+
+
+Functions in the ``array_api`` namespace
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Let's start with an example of a function implementation that shows the most
+important differences with the equivalent function in the main namespace::
+
+ def max(x: array, /, *,
+ axis: Optional[Union[int, Tuple[int, ...]]] = None,
+ keepdims: bool = False
+ ) -> array:
+ """
+ Array API compatible wrapper for :py:func:`np.max <numpy.max>`.
+ """
+ return np.max._implementation(x, axis=axis, keepdims=keepdims)
+
+This function does not accept ``array_like`` inputs, only ``ndarray``. There
+are multiple reasons for this. Other array libraries all work like this.
+Letting the user do coercion of lists, generators, or other foreign objects
+separately results in a cleaner design with less unexpected behaviour.
+It's higher-performance - less overhead from ``asarray`` calls. Static typing
+is easier. Subclasses will work as expected. And the slight increase in verbosity
+because users have to explicitly coerce to ``ndarray`` on rare occasions
+seems like a small price to pay.
+
+This function does not support ``__array_ufunc__`` nor ``__array_function__``.
+These protocols serve a similar purpose as the array API standard module itself,
+but through a different mechanisms. Because only ``ndarray`` instances are accepted,
+dispatching via one of these protocols isn't useful anymore.
+
+This function uses positional-only parameters in its signature. This makes code
+more portable - writing ``max(x=x, ...)`` is no longer valid, hence if other
+libraries call the first parameter ``input`` rather than ``x``, that is fine.
+The rationale for keyword-only parameters (not shown in the above example) is
+two-fold: clarity of end user code, and it being easier to extend the signature
+in the future with keywords in the desired order.
+
+This function has inline type annotations. Inline annotations are far easier to
+maintain than separate stub files. And because the types are simple, this will
+not result in a large amount of clutter with type aliases or unions like in the
+current stub files NumPy has.
+
+
+DLPack support for zero-copy data interchange
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The ability to convert one kind of array into another kind is valuable, and
+indeed necessary when downstream libraries want to support multiple kinds of
+arrays. This requires a well-specified data exchange protocol. NumPy already
+supports two of these, namely the buffer protocol (i.e., PEP 3118), and
+the ``__array_interface__`` (Python side) / ``__array_struct__`` (C side)
+protocol. Both work similarly, letting the "producer" describe how the data
+is laid out in memory so the "consumer" can construct its own kind of array
+with a view on that data.
+
+DLPack works in a very similar way. The main reasons to prefer DLPack over
+the options already present in NumPy are:
+
+1. DLPack is the only protocol with device support (e.g., GPUs using CUDA or
+ ROCm drivers, or OpenCL devices). NumPy is CPU-only, but other array
+ libraries are not. Having one protocol per device isn't tenable, hence
+ device support is a must.
+2. Widespread support. DLPack has the widest adoption of all protocols, only
+ NumPy is missing support. And the experiences of other libraries with it
+ are positive. This contrasts with the protocols NumPy does support, which
+ are used very little - when other libraries want to interoperate with
+ NumPy, they typically use the (more limited, and NumPy-specific)
+ ``__array__`` protocol.
+
+Adding support for DLPack to NumPy entails:
+
+- Adding a ``ndarray.__dlpack__`` method
+- Adding a ``from_dlpack`` function, which takes as input an object
+ supporting ``__dlpack__``, and returns an ``ndarray``.
+
+DLPack is currently a ~200 LoC header, and is meant to be included directly, so
+no external dependency is needed. Implementation should be straightforward.
+
+
+Syntax for device support
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+NumPy itself is CPU-only, so it clearly doesn't have a need for device support.
+However, other libraries (e.g. TensorFlow, PyTorch, JAX, MXNet) support
+multiple types of devices: CPU, GPU, TPU, and more exotic hardware.
+To write portable code on systems with multiple devices, it's often necessary
+to create new arrays on the same device as some other array, or check that
+two arrays live on the same device. Hence syntax for that is needed.
+
+The array object will have a ``.device`` attribute which enables comparing
+devices of different arrays (they only should compare equal if both arrays are
+from the same library and it's the same hardware device). Furthermore,
+``device=`` keywords in array creation functions are needed. For example::
+
+ def empty(shape: Union[int, Tuple[int, ...]], /, *,
+ dtype: Optional[dtype] = None,
+ device: Optional[device] = None) -> array:
+ """
+ Array API compatible wrapper for :py:func:`np.empty <numpy.empty>`.
+ """
+ return np.empty(shape, dtype=dtype, device=device)
+
+The implementation for NumPy may be as simple as setting the device attribute to
+the string ``'cpu'`` and raising an exception if array creation functions
+encounter any other value.
+
+
+Dtypes and casting rules
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+The supported dtypes in this namespace are boolean, 8/16/32/64-bit signed and
+unsigned integer, and 32/64-bit floating-point dtypes. These will be added to
+the namespace as dtype literals with the expected names (e.g., ``bool``,
+``uint16``, ``float64``).
+
+The most obvious omissions are the complex dtypes. The rationale for the lack
+of complex support in the first version of the array API standard is that several
+libraries (PyTorch, MXNet) are still in the process of adding support for
+complex dtypes. The next version of the standard is expected to include ``complex64``
+and ``complex128`` (see `this issue <https://github.com/data-apis/array-api/issues/102>`__
+for more details).
+
+Specifying dtypes to functions, e.g. via the ``dtype=`` keyword, is expected
+to only use the dtype literals. Format strings, Python builtin dtypes, or
+string representations of the dtype literals are not accepted - this will
+improve readability and portability of code at little cost.
+
+Casting rules are only defined between different dtypes of the same kind. The
+rationale for this is that mixed-kind (e.g., integer to floating-point)
+casting behavior differs between libraries. NumPy's mixed-kind casting
+behavior doesn't need to be changed or restricted, it only needs to be
+documented that if users use mixed-kind casting, their code may not be
+portable.
+
+.. image:: _static/nep-0047-casting-rules-lattice.png
+
+*Type promotion diagram. Promotion between any two types is given by their
+join on this lattice. Only the types of participating arrays matter, not
+their values. Dashed lines indicate that behaviour for Python scalars is
+undefined on overflow. Boolean, integer and floating-point dtypes are not
+connected, indicating mixed-kind promotion is undefined.*
+
+The most important difference between the casting rules in NumPy and in the
+array API standard is how scalars and 0-dimensional arrays are handled. In
+the standard, array scalars do not exist and 0-dimensional arrays follow the
+same casting rules as higher-dimensional arrays.
+
+See the `Type Promotion Rules section of the array API standard <https://data-apis.github.io/array-api/latest/API_specification/type_promotion.html>`__
+for more details.
+
+.. note::
+
+ It is not clear what the best way is to support the different casting rules
+ for 0-dimensional arrays and no value-based casting. One option may be to
+ implement this second set of casting rules, keep them private, mark the
+ array API functions with a private attribute that says they adhere to
+ these different rules, and let the casting machinery check whether for
+ that attribute.
+
+ This needs discussion.
+
+
+Indexing
+~~~~~~~~
+
+An indexing expression that would return a scalar with ``ndarray``, e.g.
+``arr_2d[0, 0]``, will return a 0-D array with the new array object. There are
+several reasons for that: array scalars are largely considered a design mistake
+which no other array library copied; it works better for non-CPU libraries
+(typically arrays can live on the device, scalars live on the host); and it's
+simply a consistent design. To get a Python scalar out of a 0-D array, one can
+simply use the builtin for the type, e.g. ``float(arr_0d)``.
+
+The other `indexing modes in the standard <https://data-apis.github.io/array-api/latest/API_specification/indexing.html>`__
+do work largely the same as they do for ``numpy.ndarray``. One noteworthy
+difference is that clipping in slice indexing (e.g., ``a[:n]`` where ``n`` is
+larger than the size of the first axis) is unspecified behaviour, because
+that kind of check can be expensive on accelerators.
+
+The lack of advanced indexing, and boolean indexing being limited to a single
+n-D boolean array, is due to those indexing modes not being suitable for all
+types of arrays or JIT compilation. Their absence does not seem to be
+problematic; if a user or library author wants to use them, they can do so
+through zero-copy conversion to ``numpy.ndarray``. This will signal correctly
+to whomever reads the code that it is then NumPy-specific rather than portable
+to all conforming array types.
+
+
+
+The array object
+~~~~~~~~~~~~~~~~
+
+The array object in the standard does not have methods other than dunder
+methods. The rationale for that is that not all array libraries have methods
+on their array object (e.g., TensorFlow does not). It also provides only a
+single way of doing something, rather than have functions and methods that
+are effectively duplicate.
+
+Mixing operations that may produce views (e.g., indexing, ``nonzero``)
+in combination with mutation (e.g., item or slice assignment) is
+`explicitly documented in the standard to not be supported <https://data-apis.github.io/array-api/latest/design_topics/copies_views_and_mutation.html>`__.
+This cannot easily be prohibited in the array object itself; instead this will
+be guidance to the user via documentation.
+
+The standard current does not prescribe a name for the array object itself.
+We propose to simply name it ``ndarray``. This is the most obvious name, and
+because of the separate namespace should not clash with ``numpy.ndarray``.
+
+
+Implementation
+--------------
+
+.. note::
+
+ This section needs a lot more detail, which will gradually be added when
+ the implementation progresses.
+
+A prototype of the ``array_api`` namespace can be found in
+https://github.com/data-apis/numpy/tree/array-api/numpy/_array_api.
+The docstring in its ``__init__.py`` has notes on completeness of the
+implementation. The code for the wrapper functions also contains ``# Note:``
+comments everywhere there is a difference with the NumPy API.
+Two important parts that are not implemented yet are the new array object and
+DLPack support. Functions may need changes to ensure the changed casting rules
+are respected.
+
+The array object
+~~~~~~~~~~~~~~~~
+
+Regarding the array object implementation, we plan to start with a regular
+Python class that wraps a ``numpy.ndarray`` instance. Attributes and methods
+can forward to that wrapped instance, applying input validation and
+implementing changed behaviour as needed.
+
+The casting rules are probably the most challenging part. The in-progress
+dtype system refactor (NEPs 40-43) should make implementing the correct casting
+behaviour easier - it is already moving away from value-based casting for
+example.
+
+
+The dtype objects
+~~~~~~~~~~~~~~~~~
+
+We must be able to compare dtypes for equality, and expressions like these must
+be possible::
+
+ np.array_api.some_func(..., dtype=x.dtype)
+
+The above implies it would be nice to have ``np.array_api.float32 ==
+np.array_api.ndarray(...).dtype``.
+
+Dtypes should not be assumed to have a class hierarchy by users, however we are
+free to implement it with a class hierarchy if that's convenient. We considered
+the following options to implement dtype objects:
+
+1. Alias dtypes to those in the main namespace. E.g., ``np.array_api.float32 =
+ np.float32``.
+2. Make the dtypes instances of ``np.dtype``. E.g., ``np.array_api.float32 =
+ np.dtype(np.float32)``.
+3. Create new singleton classes with only the required methods/attributes
+ (currently just ``__eq__``).
+
+It seems like (2) would be easiest from the perspective of interacting with
+functions outside the main namespace. And (3) would adhere best to the
+standard.
+
+TBD: the standard does not yet have a good way to inspect properties of a
+dtype, to ask questions like "is this an integer dtype?". Perhaps this is easy
+enough to do for users, like so::
+
+ def _get_dtype(dt_or_arr):
+ return dt_or_arr.dtype if hasattr(dt_or_arr, 'dtype') else dt_or_arr
+
+ def is_floating(dtype_or_array):
+ dtype = _get_dtype(dtype_or_array)
+ return dtype in (float32, float64)
+
+ def is_integer(dtype_or_array):
+ dtype = _get_dtype(dtype_or_array)
+ return dtype in (uint8, uint16, uint32, uint64, int8, int16, int32, int64)
+
+However it could make sense to add to the standard. Note that NumPy itself
+currently does not have a great for asking such questions, see
+`gh-17325 <https://github.com/numpy/numpy/issues/17325>`__.
+
+
+Feedback from downstream library authors
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+TODO - this can only be done after trying out some use cases
+
+Leo Fang (CuPy): *"My impression is for CuPy we could simply take this new array object and s/numpy/cupy"*
+
+
+Related Work
+------------
+
+:ref:`NEP37` contains a similar mechanism to retrieve a NumPy-like namespace.
+In fact, NEP 37 inspired the (slightly simpler) mechanism in the array API
+standard.
+
+Other libraries have adopted large parts of NumPy's API, made changes where
+necessary, and documented deviations. See for example
+`the jax.numpy documentation <https://jax.readthedocs.io/en/latest/jax.numpy.html>`__
+and `Difference between CuPy and NumPy <https://docs.cupy.dev/en/stable/reference/difference.html>`__.
+The array API standard was constructed with the help of such comparisons, only
+between many array libraries rather than only between NumPy and one other library.
+
+
+Alternatives
+------------
+
+
+
+
+Appendix - a possible ``get_namespace`` implementation
+------------------------------------------------------
+
+The ``get_namespace`` function mentioned in the
+:ref:`adoption-application-code` section can be implemented like::
+
+ def get_namespace(*xs):
+ # `xs` contains one or more arrays, or possibly Python scalars (accepting
+ # those is a matter of taste, but doesn't seem unreasonable).
+ namespaces = {
+ x.__array_namespace__() if hasattr(x, '__array_namespace__') else None for x in xs if not isinstance(x, (bool, int, float, complex))
+ }
+
+ if not namespaces:
+ # one could special-case np.ndarray above or use np.asarray here if
+ # older numpy versions need to be supported.
+ raise ValueError("Unrecognized array input")
+
+ if len(namespaces) != 1:
+ raise ValueError(f"Multiple namespaces for array inputs: {namespaces}")
+
+ xp, = namespaces
+ if xp is None:
+ raise ValueError("The input is not a supported array type")
+
+ return xp
+
+
+Discussion
+----------
+
+- `First discussion on the mailing list about the array API standard <https://mail.python.org/pipermail/numpy-discussion/2020-November/081181.html>`__
+
+
+References and Footnotes
+------------------------
+
+.. _Python array API standard: https://data-apis.github.io/array-api/latest
+
+.. _Consortium for Python Data API Standards: https://data-apis.org/
+
+.. _DLPack: https://github.com/dmlc/dlpack
+
+.. [1] https://data-apis.org/blog/announcing_the_consortium/
+
+.. [2] https://data-apis.org/blog/array_api_standard_release/
+
+
+Copyright
+---------
+
+This document has been placed in the public domain. [1]_
diff --git a/doc/neps/nep-0048-spending-project-funds.rst b/doc/neps/nep-0048-spending-project-funds.rst
new file mode 100644
index 000000000..3571eef2d
--- /dev/null
+++ b/doc/neps/nep-0048-spending-project-funds.rst
@@ -0,0 +1,458 @@
+.. _NEP48:
+
+=====================================
+NEP 48 — Spending NumPy Project Funds
+=====================================
+
+:Author: Ralf Gommers <ralf.gommers@gmail.com>
+:Author: Inessa Pawson <inessa@albuscode.org>
+:Author: Stefan van der Walt <stefanv@berkeley.edu>
+:Status: Draft
+:Type: Informational
+:Created: 2021-02-07
+:Resolution:
+
+
+Abstract
+--------
+
+The NumPy project has historically never received significant **unrestricted**
+funding. However, that is starting to change. This NEP aims to provide
+guidance about spending NumPy project unrestricted funds by formulating a set
+of principles about *what* to pay for and *who* to pay. It will also touch on
+how decisions regarding spending funds get made, how funds get administered,
+and transparency around these topics.
+
+
+Motivation and Scope
+--------------------
+
+NumPy is a fiscally sponsored project of NumFOCUS, a 501(c)(3) nonprofit
+organization headquartered in Austin, TX. Therefore, for all legal and
+accounting matters the NumPy project has to follow the rules and regulations
+for US nonprofits. All nonprofit donations are classified into two categories:
+**unrestricted funds** which may be used for any legal purpose appropriate
+to the organization and **restricted funds**, monies set aside for a
+particular purpose (e.g., project, educational program, etc.).
+
+For the detailed timeline of NumPy funding refer to
+:ref:`numpy-funding-history`.
+
+Since its inception and until 2020, the NumPy project has only spent on the order of
+$10,000 USD of funds that were not restricted to a particular program. Project
+income of this type has been relying on donations from individuals and, from
+mid 2019, recurring monthly contributions from Tidelift. By the end of 2020,
+the Tidelift contributions increased to $3,000/month, and there's also a
+potential for an increase of donations and grants going directly to the
+project. Having a clear set of principles around how to use these funds will
+facilitate spending them fairly and effectively. Additionally, it will make it
+easier to solicit donations and other contributions.
+
+A key assumption this NEP makes is that NumPy remains a largely
+volunteer-driven project, and that the project funds are not enough to employ
+maintainers full-time. If funding increases to the point where that assumption
+is no longer true, this NEP should be updated.
+
+In scope for this NEP are:
+
+- Principles of spending project funds: what to pay for, and who to pay.
+- Describing how NumPy's funds get administered.
+- Describing how decisions to spend funds get proposed and made.
+
+Out of scope for this NEP are:
+
+- Making any decisions about spending project funds on a specific project or
+ activity.
+- Principles for spending funds that are intended for NumPy development, but
+ don't fall in the category of NumPy unrestricted funds. This includes most of
+ the grant funding, which is usually earmarked for certain
+ activities/deliverables and goes to an Institutional Partner rather than
+ directly to the NumPy project, and companies or institutions funding specific
+ features.
+ *Rationale: As a project, we have no direct control over how this work gets
+ executed (at least formally, until issues or PRs show up). In some cases, we
+ may not even know the contributions were funded or done by an employee on
+ work time. (Whether that's the case or not should not change how we approach
+ a contribution). For grants though, we do expect the research/project leader
+ and funded team to align their work with the needs of NumPy and be
+ receptive to feedback from other NumPy maintainers and contributors.*
+
+
+Principles of spending project funds
+------------------------------------
+
+NumPy will likely always be a project with many times more volunteer
+contributors than funded people. Therefore having those funded people operate
+in ways that attract more volunteers and enhance their participation experience
+is critical. That key principle motivates many of the more detailed principles
+given below for what to pay for and whom to pay.
+
+The approach for spending funds will be:
+
+- first figure out what we want to fund,
+- then look for a great candidate,
+- after that's settled, determine a fair compensation level.
+
+The next sections go into detail on each of these three points.
+
+.. _section-what-to-pay-for:
+
+What to pay for
+```````````````
+
+1. Pay for things that are important *and* otherwise won't get done.
+ *Rationale: there is way more to be done than there are funds to do all
+ those things. So count on interested volunteers or external sponsored work
+ to do many of those things.*
+2. Plan for sustainability. Don't rely on money always being there.
+3. Consider potential positive benefits for NumPy maintainers and contributors,
+ maintainers of other projects, end users, and other stakeholders like
+ packagers and educators.
+4. Think broadly. There's more to a project than code: websites, documentation,
+ community building, governance - it's all important.
+5. For proposed funded work, include paid time for others to review your work
+ if such review is expected to be significant effort - do not just increase
+ the load on volunteer maintainers.
+ *Rationale: we want the effect of spending funds to be positive for
+ everyone, not just for the people getting paid. This is also a matter of
+ fairness.*
+
+When considering development work, principle (1) implies that priority should
+be giving to (a) the most boring/painful tasks that no one likes doing, and to
+necessary structural changes to the code base that are too large to be done by
+a volunteer in a reasonable amount of time.
+
+There are also many tasks, activities, and projects outside of
+development work that are important and could enhance the project or community
+- think of, for example, user surveys, translations, outreach, dedicated
+mentoring of newcomers, community organizating, website improvements, and
+administrative tasks.
+
+Time of people to perform tasks is also not the only thing that funds can be
+used for: expenses for in-person developer meetings or sprints, hosted hardware
+for benchmarking or development work, and CI or other software services could
+all be good candidates to spend funds on.
+
+Whom to pay
+```````````
+
+1. All else being equal, give preference to existing maintainers/contributors.
+2. When looking outside of the current team, consider this an opportunity to
+ make the project more diverse.
+3. Pay attention to the following when considering paying someone:
+
+ - the necessary technical or domain-specific skills to execute the tasks,
+ - communication and self-management skills,
+ - experience contributing to and working with open source projects.
+
+It will likely depend on the project/tasks whether there's already a clear best
+candidate within the NumPy team, or whether we look for new people to get
+involved. Before making any decisions, the decision makers (according to the
+NumPy governance document - currently that's the Steering Council) should think
+about whether an opportunity should be advertised to give a wider group of
+people a chance to apply for it.
+
+Compensating fairly
+```````````````````
+
+.. note::
+
+ This section on compensating fairly will be considered *Draft* even if this
+ NEP as a whole is accepted. Once we have applied the approach outlined here
+ at least 2-3 times and we are happy with it, will we remove this note and
+ consider this section *Accepted*.
+
+Paying people fairly is a difficult topic, especially when it comes to
+distributed teams. Therefore, we will only offer some guidance here. Final
+decisions will always have to be considered and approved by the group of people
+that bears this responsibility (according to the current NumPy governance
+structure, this would be the NumPy Steering Council).
+
+Discussions on remote employee compensation tend to be dominated by two
+narratives: "pay local market rates" and "same work -- same pay".
+
+We consider them both extreme:
+
+- "Same work -- same pay" is unfair to people living in locations with a higher
+ cost of living. For example, the average rent for a single family apartment
+ can differ by a large factor (from a few hundred dollars to thousands of
+ dollars per month).
+- "Pay local market rates" bakes in existing inequalities between countries
+ and makes fixed-cost items like a development machine or a holiday trip
+ abroad relatively harder to afford in locations where market rates are lower.
+
+We seek to find a middle ground between these two extremes.
+
+Useful points of reference include companies like GitLab and
+Buffer who are transparent about their remuneration policies ([3]_, [4]_),
+Google Summer of Code stipends ([5]_), other open source projects that manage
+their budget in a transparent manner (e.g., Babel and Webpack on Open
+Collective ([6]_, [7]_)), and standard salary comparison sites.
+
+Since NumPy is a not-for-profit project, we also looked to the nonprofit sector
+for guidelines on remuneration policies and compensation levels. Our findings
+show that most smaller non-profits tend to pay a median salary/wage. We
+recognize merit in this approach: applying candidates are likely to have a
+genuine interest in open source, rather than to be motivated purely by
+financial incentives.
+
+Considering all of the above, we will use the following guidelines for
+determining compensation:
+
+1. Aim to compensate people appropriately, up to a level that's expected for
+ senior engineers or other professionals as applicable.
+2. Establish a compensation cap of $125,000 USD that cannot be exceeded even
+ for the residents from the most expensive/competitive locations ([#f-pay]_).
+3. For equivalent work and seniority, a pay differential between locations
+ should never be more than 2x.
+ For example, if we pay $110,000 USD to a senior-level developer from New
+ York, for equivalent work a senior-level developer from South-East Asia
+ should be paid at least $55,000 USD. To compare locations, we will use
+ `Numbeo Cost of Living calculator <https://www.numbeo.com/cost-of-living/>`__
+ (or its equivalent).
+
+Some other considerations:
+
+- Often, compensated work is offered for a limited amount of hours or fixed
+ term. In those cases, consider compensation equivalent to a remuneration
+ package that comes with permanent employment (e.g., one month of work should
+ be compensated by at most 1/12th of a full-year salary + benefits).
+- When comparing rates, an individual contractor should typically make 20% more
+ than someone who is employed since they have to take care of their benefits
+ and accounting on their own.
+- Some people may be happy with one-off payments towards a particular
+ deliverable (e.g., "triage all open issues for label X for $x,xxx").
+ This should be compensated at a lower rate compared to an individual
+ contractor. Or they may motivate lower amounts for another reason (e.g., "I
+ want to receive $x,xxx to hire a cleaner or pay for childcare, to free up
+ time for work on open source).
+- When funding someone's time through their employer, that employer may want to
+ set the compensation level based on its internal rules (e.g., overhead rates).
+ Small deviations from the guidelines in this NEP may be needed in such cases,
+ however they should be within reason.
+- It's entirely possible that another strategy rather than paying people for
+ their time on certain tasks may turn out to be more effective. Anything that
+ helps the project and community grow and improve is worth considering.
+- Transparency helps. If everyone involved is comfortable sharing their
+ compensation levels with the rest of the team (or better make it public),
+ it's least likely to be way off the mark for fairness.
+
+We highly recommend that the individuals involved in decision-making about
+hiring and compensation peruse the content of the References section of this
+NEP. It offers a lot of helpful advice on this topic.
+
+
+Defining fundable activities and projects
+-----------------------------------------
+
+We'd like to have a broader set of fundable ideas that we will prioritize with
+input from NumPy team members and the wider community. All ideas will be
+documented on a single wiki page. Anyone may propose an idea. Only members of a
+NumPy team may edit the wiki page.
+
+Each listed idea must meet the following requirements:
+
+1. It must be clearly scoped: its description must explain the importance to
+ the project, referencing the NumPy Roadmap if possible, the items to pay for
+ or activities and deliverables, and why it should be a funded activity (see
+ :ref:`section-what-to-pay-for`).
+2. It must contain the following metadata: title, cost, time duration or effort
+ estimate, and (if known) names of the team member(s) to execute or coordinate.
+3. It must have an assigned priority (low, medium, or high). This discussion
+ can originate at a NumPy community meeting or on the mailing list. However,
+ it must be finalized on the mailing list allowing everyone to weigh in.
+
+If a proposed idea has been assigned a high priority level, a decision on
+allocating funding for it will be made on the private NumPy Steering Council
+mailing list. *Rationale: these will often involve decisions about individuals,
+which is typically hard to do in public. This is the current practice that
+seems to be working well.*
+
+Sometimes, it may be practical to make a single funding decision ad-hoc (e.g.,
+"Here's a great opportunity plus the right person to execute it right now”).
+However, this approach to decision-making should be used rarely.
+
+
+Strategy for spending/saving funds
+----------------------------------
+
+There is an expectation from NumPy individual, corporate, and institutional
+donors that the funds will be used for the benefit of the project and the
+community. Therefore, we should spend available funds, thoughtfully,
+strategically, and fairly, as they come in. For emergencies, we should keep a
+$10,000 - $15,000 USD reserve which could cover, for example, a year of CI and
+hosting services, 1-2 months of full-time maintenance work, or contracting a
+consultant for a specific need.
+
+
+How project funds get administered
+----------------------------------
+
+We will first summarize how administering of funds works today, and then
+discuss how to make this process more efficient and transparent.
+
+Currently, the project funds are held by NumFOCUS in a dedicated account.
+NumFOCUS has a small accounting team, which produces an account overview as a
+set of spreadsheets on a monthly basis. These land in a shared drive, typically
+with about a one month delay (e.g., the balance and transactions for February
+are available at the end of March), where a few NumPy team members can access
+them. Expense claims and invoices are submitted through the NumFOCUS website.
+Those then show up in another spreadsheet, where a NumPy team member must
+review and approve each of them before payments are made. Following NumPy
+bylaws, the NumFOCUS finance subcommittee, consisting of five people, meets
+every six months to review all the project related transactions. (In practice,
+there have been so few transactions that we skipped some of these meetings.)
+
+The existing process is time-consuming and error-prone. More transparency and
+automation are desirable.
+
+
+Transparency about project funds and in decision making
+```````````````````````````````````````````````````````
+
+**To discuss: do we want full transparency by publishing our accounts,
+transparency to everyone on a NumPy team, or some other level?**
+
+Ralf: I'd personally like it to be fully transparent, like through Open
+Collective, so the whole community can see current balance, income and expenses
+paid out at any moment in time. Moving to Open Collective is nontrivial,
+however we can publish the data elsewhere for now if we'd want to.
+*Note: Google Season of Docs this year requires having an Open Collective
+account, so this is likely to happen soon enough.*
+
+Stefan/Inessa: at least a summary overview should be fully public, and all
+transactions should be visible to the Steering Council. Full transparency of
+all transactions is probably fine, but not necessary.
+
+*The options here may be determined by the accounting system and amount of
+effort required.*
+
+
+.. _numpy-funding-history:
+
+NumPy funding – history and current status
+------------------------------------------
+
+The NumPy project received its first major funding in 2017. For an overview of
+the early history of NumPy (and SciPy), including some institutions sponsoring
+time for their employees or contractors to work on NumPy, see [1]_ and [2]_. To
+date, NumPy has received four grants:
+
+- Two grants, from the Alfred P. Sloan Foundation and the Gordon and Betty
+ Moore Foundation respectively, of about $1.3M combined to the Berkeley
+ Institute of Data Science. Work performed during the period 2017-2020;
+ PI Stéfan van der Walt.
+- Two grants from the Chan Zuckerberg Foundation to NumFOCUS, for a combined
+ amount of $335k. Work performed during the period 2020-2021; PI's Ralf
+ Gommers (first grant) and Melissa Mendonça (second grant).
+
+From 2012 onwards NumPy has been a fiscally sponsored project of NumFOCUS.
+Note that fiscal sponsorship doesn't mean NumPy gets funding, rather that it
+can receive funds under the umbrella of a nonprofit. See `NumFOCUS Project
+Support <https://numfocus.org/projects-overview>`__ for more details.
+
+Only since 2017 has the NumPy website displayed a "Donate" button, and since
+2019 the NumPy repositories have had the GitHub Sponsors button. Before that,
+it was possible to donate to NumPy on the NumFOCUS website. The sum total of
+donations from individuals to NumPy for 2017-2020 was about $6,100.
+
+From May 2019 onwards, Tidelift has supported NumPy financially as part of
+its "managed open source" business model. From May 2019 till July 2020 this was
+$1,000/month, and it started steadily growing after that to about $3,000/month
+(as of Feb 2021).
+
+Finally, there has been other incidental project income, for example, some book
+royalties from Packt Publishing, GSoC mentoring fees from Google, and
+merchandise sales revenue through the NumFOCUS web shop. All of these were
+small (two or three figure) amounts.
+
+This brings the total amount of project income which did not already have a
+spending target to about $35,000. Most of that is recent, from Tidelift.
+Over the past 1.5 years we spent about $10,000 for work on the new NumPy
+website and Sphinx theme. Those spending decisions were made by the NumPy
+Steering Council and announced on the mailing list.
+
+That leaves about $25,000 in available funds at the time of writing, and
+that amount is currently growing at a rate of about $3,000/month.
+
+
+Related Work
+------------
+
+See references. We assume that other open source projects have also developed
+guidelines on spending project funds. However, we were unable to find any
+examples at the time of writing.
+
+
+Alternatives
+------------
+
+*Alternative spending strategy*: not having cash reserves. The rationale
+being that NumPy is important enough that in a real emergency some person or
+entity will likely jump in to help out. This is not a responsible approach to
+financial stewardship of the project though. Hence, we decided against it.
+
+
+Discussion
+----------
+
+
+
+References and Footnotes
+------------------------
+
+.. [1] Pauli Virtanen et al., "SciPy 1.0: fundamental algorithms for scientific
+ computing in Python", https://www.nature.com/articles/s41592-019-0686-2,
+ 2020
+
+.. [2] Charles Harris et al., "Array programming with NumPy", https://www.nature.com/articles/s41586-020-2649-2, 2020
+
+.. [3] https://remote.com/blog/remote-compensation
+
+.. [4] https://about.gitlab.com/company/culture/all-remote/compensation/#how-do-you-decide-how-much-to-pay-people
+
+.. [5] https://developers.google.com/open-source/gsoc/help/student-stipends
+
+.. [6] Jurgen Appelo, "Compensation: what is fair?", https://blog.agilityscales.com/compensation-what-is-fair-38a65a822c29, 2016
+
+.. [7] Project Include, "Compensating fairly", https://projectinclude.org/compensating_fairly
+
+.. [#f-pay] This cap is derived from comparing with compensation levels at
+ other open source projects (e.g., Babel, Webpack, Drupal - all in
+ the $100,000 -- $125,000 range) and Partner Institutions.
+
+- Nadia Eghbal, "Roads and Bridges: The Unseen Labor Behind Our Digital
+ Infrastructure", 2016
+- Nadia Eghbal, "Working in Public: The Making and Maintenance of Open
+ Source", 2020
+- https://github.com/nayafia/lemonade-stand
+- Daniel Oberhaus, `"The Internet Was Built on the Free Labor of Open Source
+ Developers. Is That Sustainable?"
+ <https://www.vice.com/en/article/43zak3/the-internet-was-built-on-the-free-labor-of-open-source-developers-is-that-sustainable>`_, 2019
+- David Heinemeier Hansson, `"The perils of mixing open source and money" <https://dhh.dk/2013/the-perils-of-mixing-open-source-and-money.html>`_, 2013
+- Danny Crichton, `"Open source sustainability" <https://techcrunch.com/2018/06/23/open-source-sustainability/?guccounter=1>`_, 2018
+- Nadia Eghbal, "Rebuilding the Cathedral", https://www.youtube.com/watch?v=VS6IpvTWwkQ, 2017
+- Nadia Eghbal, "Where money meets open source", https://www.youtube.com/watch?v=bjAinwgvQqc&t=246s, 2017
+- Eileen Uchitelle, ""The unbearable vulnerability of open source", https://www.youtube.com/watch?v=VdwO3LQ56oM, 2017 (the inverted triangle, open source is a funnel)
+- Dries Buytaert, "Balancing Makers and Takers to scale and sustain Open Source", https://dri.es/balancing-makers-and-takers-to-scale-and-sustain-open-source, 2019
+- Safia Abdalla, "Beyond Maintenance", https://increment.com/open-source/beyond-maintenance/, 2019
+- Xavier Damman, "Money and Open Source Communities", https://blog.opencollective.com/money-and-open-source-communities/, 2016
+- Aseem Sood, "Let's talk about money", https://blog.opencollective.com/lets-talk-about-money/, 2017
+- Alanna Irving, "Has your open source community raised money? Here's how to spend it.", https://blog.opencollective.com/has-your-open-source-community-raised-money-heres-how-to-spend-it/, 2017
+- Alanna Irving, "Funding open source, how Webpack reached $400k+/year", https://blog.opencollective.com/funding-open-source-how-webpack-reached-400k-year/, 2017
+- Alanna Irving, "Babel's rise to financial sustainability", https://blog.opencollective.com/babels-rise-to-financial-sustainability/, 2019
+- Devon Zuegel, "The city guide to open source", https://www.youtube.com/watch?v=80KTVu6GGSE, 2020 + blog: https://increment.com/open-source/the-city-guide-to-open-source/
+
+GitHub Sponsors:
+
+- https://github.blog/2019-05-23-announcing-github-sponsors-a-new-way-to-contribute-to-open-source/
+- https://github.blog/2020-05-12-github-sponsors-is-out-of-beta-for-sponsored-organizations/
+- https://blog.opencollective.com/on-github-sponsors/, 2019
+- https://blog.opencollective.com/double-the-love/, 2020
+- https://blog.opencollective.com/github-sponsors-for-companies-open-source-collective-for-people/
+
+
+Copyright
+---------
+
+This document has been placed in the public domain.
diff --git a/doc/neps/nep-0049.rst b/doc/neps/nep-0049.rst
new file mode 100644
index 000000000..4a5edae81
--- /dev/null
+++ b/doc/neps/nep-0049.rst
@@ -0,0 +1,321 @@
+===================================
+NEP 49 — Data allocation strategies
+===================================
+
+:Author: Matti Picus
+:Status: Draft
+:Type: Standards Track
+:Created: 2021-04-18
+:Resolution: http://numpy-discussion.10968.n7.nabble.com/NEP-49-Data-allocation-strategies-tt49185.html
+
+
+Abstract
+--------
+
+The ``numpy.ndarray`` requires additional memory allocations
+to hold ``numpy.ndarray.strides``, ``numpy.ndarray.shape`` and
+``numpy.ndarray.data`` attributes. These attributes are specially allocated
+after creating the python object in ``__new__`` method.
+
+This NEP proposes a mechanism to override the memory management strategy used
+for ``ndarray->data`` with user-provided alternatives. This allocation holds
+the data and can be very large. As accessing this data often becomes
+a performance bottleneck, custom allocation strategies to guarantee data
+alignment or pinning allocations to specialized memory hardware can enable
+hardware-specific optimizations. The other allocations remain unchanged.
+
+Motivation and Scope
+--------------------
+
+Users may wish to override the internal data memory routines with ones of their
+own. Two such use-cases are to ensure data alignment and to pin certain
+allocations to certain NUMA cores. This desire for alignment was discussed
+multiple times on the mailing list `in 2005`_, and in `issue 5312`_ in 2014,
+which led to `PR 5457`_ and more mailing list discussions here_ `and here`_. In
+a comment on the issue `from 2017`_, a user described how 64-byte alignment
+improved performance by 40x.
+
+Also related is `issue 14177`_ around the use of ``madvise`` and huge pages on
+Linux.
+
+Various tracing and profiling libraries like filprofiler_ or `electric fence`_
+override ``malloc``.
+
+The long CPython discussion of `BPO 18835`_ began with discussing the need for
+``PyMem_Alloc32`` and ``PyMem_Alloc64``. The early conclusion was that the
+cost (of wasted padding) vs. the benifit of aligned memory is best left to the
+user, but then evolves into a discussion of various proposals to deal with
+memory allocations, including `PEP 445`_ `memory interfaces`_ to
+``PyTraceMalloc_Track`` which apparently was explictly added for NumPy.
+
+Allowing users to implement different strategies via the NumPy C-API will
+enable exploration of this rich area of possible optimizations. The intention
+is to create a flexible enough interface without burdening normative users.
+
+.. _`issue 5312`: https://github.com/numpy/numpy/issues/5312
+.. _`from 2017`: https://github.com/numpy/numpy/issues/5312#issuecomment-315234656
+.. _`in 2005`: https://numpy-discussion.scipy.narkive.com/MvmMkJcK/numpy-arrays-data-allocation-and-simd-alignement
+.. _`here`: http://numpy-discussion.10968.n7.nabble.com/Aligned-configurable-memory-allocation-td39712.html
+.. _`and here`: http://numpy-discussion.10968.n7.nabble.com/Numpy-s-policy-for-releasing-memory-td1533.html
+.. _`issue 14177`: https://github.com/numpy/numpy/issues/14177
+.. _`filprofiler`: https://github.com/pythonspeed/filprofiler/blob/master/design/allocator-overrides.md
+.. _`electric fence`: https://github.com/boundarydevices/efence
+.. _`memory interfaces`: https://docs.python.org/3/c-api/memory.html#customize-memory-allocators
+.. _`BPO 18835`: https://bugs.python.org/issue18835
+.. _`PEP 445`: https://www.python.org/dev/peps/pep-0445/
+
+Usage and Impact
+----------------
+
+The new functions can only be accessed via the NumPy C-API. An example is
+included later in this NEP. The added ``struct`` will increase the size of the
+``ndarray`` object. It is a necessary price to pay for this approach. We
+can be reasonably sure that the change in size will have a minimal impact on
+end-user code because NumPy version 1.20 already changed the object size.
+
+The implementation preserves the use of ``PyTraceMalloc_Track`` to track
+allocations already present in NumPy.
+
+Backward compatibility
+----------------------
+
+The design will not break backward compatibility. Projects that were assigning
+to the ``ndarray->data`` pointer were already breaking the current memory
+management strategy and should restore
+``ndarray->data`` before calling ``Py_DECREF``. As mentioned above, the change
+in size should not impact end-users.
+
+Detailed description
+--------------------
+
+High level design
+=================
+
+Users who wish to change the NumPy data memory management routines will use
+:c:func:`PyDataMem_SetHandler`, which uses a :c:type:`PyDataMem_Handler`
+structure to hold pointers to functions used to manage the data memory.
+
+Since a call to ``PyDataMem_SetHandler`` will change the default functions, but
+that function may be called during the lifetime of an ``ndarray`` object, each
+``ndarray`` will carry with it the ``PyDataMem_Handler`` struct used at the
+time of its instantiation, and these will be used to reallocate or free the
+data memory of the instance. Internally NumPy may use ``memcpy`` or ``memset``
+on the pointer to the data memory.
+
+The name of the handler will be exposed on the python level via a
+``numpy.core.multiarray.get_handler_name(arr)`` function. If called as
+``numpy.core.multiarray.get_handler_name()`` it will return the name of the
+global handler that will be used to allocate data for the next new `ndarrray`.
+
+NumPy C-API functions
+=====================
+
+.. c:type:: PyDataMem_Handler
+
+ A struct to hold function pointers used to manipulate memory
+
+ .. code-block:: c
+
+ typedef struct {
+ char name[128]; /* multiple of 64 to keep the struct aligned */
+ PyDataMemAllocator allocator;
+ } PyDataMem_Handler;
+
+ where the allocator structure is
+
+ .. code-block:: c
+
+ /* The declaration of free differs from PyMemAllocatorEx */
+ typedef struct {
+ void *ctx;
+ void* (*malloc) (void *ctx, size_t size);
+ void* (*calloc) (void *ctx, size_t nelem, size_t elsize);
+ void* (*realloc) (void *ctx, void *ptr, size_t new_size);
+ void (*free) (void *ctx, void *ptr, size_t size);
+ } PyDataMemAllocator;
+
+ The use of a ``size`` parameter in ``free`` differentiates this struct from
+ the :c:type:`PyMemAllocatorEx` struct in Python. This call signature is
+ used internally in NumPy currently, and also in other places for instance
+ `C++98 <https://en.cppreference.com/w/cpp/memory/allocator/deallocate>`,
+ `C++11 <https://en.cppreference.com/w/cpp/memory/allocator_traits/deallocate>`, and
+ `Rust (allocator_api) <https://doc.rust-lang.org/std/alloc/trait.Allocator.html#tymethod.deallocate>`.
+
+ The consumer of the `PyDataMemAllocator` interface must keep track of ``size`` and make sure it is
+ consistent with the parameter passed to the ``(m|c|re)alloc`` functions.
+
+.. c:function:: const PyDataMem_Handler * PyDataMem_SetHandler(PyDataMem_Handler *handler)
+
+ Sets a new allocation policy. If the input value is ``NULL``, will reset
+ the policy to the default. Returns the previous policy, ``NULL`` if the
+ previous policy was the default. We wrap the user-provided functions
+ so they will still call the Python and NumPy memory management callback
+ hooks. All the function pointers must be filled in, ``NULL`` is not
+ accepted.
+
+.. c:function:: const char * PyDataMem_GetHandlerName(PyArrayObject *obj)
+
+ Return the const char name of the ``PyDataMem_Handler`` used by the
+ ``PyArrayObject``. If ``NULL``, return the name of the current global policy
+ that will be used to allocate data for the next ``PyArrayObject``.
+
+
+Sample code
+===========
+
+This code adds a 64-byte header to each ``data`` pointer and stores information
+about the allocation in the header. Before calling ``free``, a check ensures
+the ``sz`` argument is correct.
+
+.. code-block:: c
+
+ #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
+ #include <numpy/arrayobject.h>
+ NPY_NO_EXPORT void *
+
+ typedef struct {
+ void *(*malloc)(size_t);
+ void *(*calloc)(size_t, size_t);
+ void *(*realloc)(void *, size_t);
+ void (*free)(void *);
+ } Allocator;
+
+ NPY_NO_EXPORT void *
+ shift_alloc(Allocator *ctx, size_t sz) {
+ char *real = (char *)ctx->malloc(sz + 64);
+ if (real == NULL) {
+ return NULL;
+ }
+ snprintf(real, 64, "originally allocated %ld", (unsigned long)sz);
+ return (void *)(real + 64);
+ }
+
+ NPY_NO_EXPORT void *
+ shift_zero(Allocator *ctx, size_t sz, size_t cnt) {
+ char *real = (char *)ctx->calloc(sz + 64, cnt);
+ if (real == NULL) {
+ return NULL;
+ }
+ snprintf(real, 64, "originally allocated %ld via zero",
+ (unsigned long)sz);
+ return (void *)(real + 64);
+ }
+
+ NPY_NO_EXPORT void
+ shift_free(Allocator *ctx, void * p, npy_uintp sz) {
+ if (p == NULL) {
+ return ;
+ }
+ char *real = (char *)p - 64;
+ if (strncmp(real, "originally allocated", 20) != 0) {
+ fprintf(stdout, "uh-oh, unmatched shift_free, "
+ "no appropriate prefix\\n");
+ /* Make C runtime crash by calling free on the wrong address */
+ ctx->free((char *)p + 10);
+ /* ctx->free(real); */
+ }
+ else {
+ npy_uintp i = (npy_uintp)atoi(real +20);
+ if (i != sz) {
+ fprintf(stderr, "uh-oh, unmatched shift_free"
+ "(ptr, %ld) but allocated %ld\\n", sz, i);
+ /* This happens in some places, only print */
+ ctx->free(real);
+ }
+ else {
+ ctx->free(real);
+ }
+ }
+ }
+
+ NPY_NO_EXPORT void *
+ shift_realloc(Allocator *ctx, void * p, npy_uintp sz) {
+ if (p != NULL) {
+ char *real = (char *)p - 64;
+ if (strncmp(real, "originally allocated", 20) != 0) {
+ fprintf(stdout, "uh-oh, unmatched shift_realloc\\n");
+ return realloc(p, sz);
+ }
+ return (void *)((char *)ctx->realloc(real, sz + 64) + 64);
+ }
+ else {
+ char *real = (char *)ctx->realloc(p, sz + 64);
+ if (real == NULL) {
+ return NULL;
+ }
+ snprintf(real, 64, "originally allocated "
+ "%ld via realloc", (unsigned long)sz);
+ return (void *)(real + 64);
+ }
+ }
+
+ static Allocator new_handler_ctx = {
+ malloc,
+ calloc,
+ realloc,
+ free
+ };
+
+ static PyDataMem_Handler new_handler = {
+ "secret_data_allocator",
+ {
+ &new_handler_ctx,
+ shift_alloc, /* malloc */
+ shift_zero, /* calloc */
+ shift_realloc, /* realloc */
+ shift_free /* free */
+ }
+ };
+ '''
+
+Related Work
+------------
+
+This NEP is being tracked by the pnumpy_ project and a `comment in the PR`_
+mentions use in orchestrating FPGA DMAs.
+
+Implementation
+--------------
+
+This NEP has been implemented in `PR 17582`_.
+
+Alternatives
+------------
+
+These were discussed in `issue 17467`_. `PR 5457`_ and `PR 5470`_ proposed a
+global interface for specifying aligned allocations.
+
+``PyArray_malloc_aligned`` and friends were added to NumPy with the
+`numpy.random` module API refactor. and are used there for performance.
+
+`PR 390`_ had two parts: expose ``PyDataMem_*`` via the NumPy C-API, and a hook
+mechanism. The PR was merged with no example code for using these features.
+
+Discussion
+----------
+
+The discussion on the mailing list led to the ``PyDataMemAllocator`` struct
+with a ``context`` field like :c:type:`PyMemAllocatorEx` but with a different
+signature for ``free``.
+
+
+References and Footnotes
+------------------------
+
+.. [1] Each NEP must either be explicitly labeled as placed in the public domain (see
+ this NEP as an example) or licensed under the `Open Publication License`_.
+
+.. _Open Publication License: https://www.opencontent.org/openpub/
+
+.. _`PR 17582`: https://github.com/numpy/numpy/pull/17582
+.. _`PR 5457`: https://github.com/numpy/numpy/pull/5457
+.. _`PR 5470`: https://github.com/numpy/numpy/pull/5470
+.. _`PR 390`: https://github.com/numpy/numpy/pull/390
+.. _`issue 17467`: https://github.com/numpy/numpy/issues/17467
+.. _`comment in the PR`: https://github.com/numpy/numpy/pull/17582#issuecomment-809145547
+.. _pnumpy: https://quansight.github.io/pnumpy/stable/index.html
+
+Copyright
+---------
+
+This document has been placed in the public domain. [1]_
diff --git a/doc/neps/roadmap.rst b/doc/neps/roadmap.rst
index 40fcbd325..7e5d1a03b 100644
--- a/doc/neps/roadmap.rst
+++ b/doc/neps/roadmap.rst
@@ -17,6 +17,12 @@ facilitate interoperability with all such packages, and the code that uses them,
may include (among other things) interoperability protocols, better duck typing
support and ndarray subclass handling.
+The key goal is: *make it easy for code written for NumPy to also work with
+other NumPy-like projects.* This will enable GPU support via, e.g, CuPy or JAX,
+distributed array support via Dask, and writing special-purpose arrays (either
+from scratch, or as a ``numpy.ndarray`` subclass) that work well with SciPy,
+scikit-learn and other such packages.
+
The ``__array_ufunc__`` and ``__array_function__`` protocols are stable, but
do not cover the whole API. New protocols for overriding other functionality
in NumPy are needed. Work in this area aims to bring to completion one or more
@@ -33,56 +39,59 @@ of the API, as discussed in `this section of NEP 37
<https://numpy.org/neps/nep-0037-array-module.html#requesting-restricted-subsets-of-numpy-s-api>`__.
-Extensibility
--------------
-
-We aim to make it much easier to extend NumPy. The primary topic here is to
-improve the dtype system.
-
-- Easier custom dtypes:
-
- - Simplify and/or wrap the current C-API
- - More consistent support for dtype metadata
- - Support for writing a dtype in Python
-
-- New string dtype(s):
-
- - Encoded strings with fixed-width storage (utf8, latin1, ...) and/or
- - Variable length strings (could share implementation with dtype=object,
- but are explicitly type-checked)
- - One of these should probably be the default for text data. The current
- behavior on Python 3 is neither efficient nor user friendly.
-
-
Performance
-----------
-Improvements to NumPy's performance are important to many users. The primary
-topic at the moment is better use of SIMD instructions, also on platforms other
-than x86 - see :ref:`NEP38`.
+Improvements to NumPy's performance are important to many users. We have
+focused this effort on Universal SIMD (see :ref:`NEP38`) intrinsics which
+provide nice improvements across various hardware platforms via an abstraction
+layer. The infrastructure is in place, and we welcome follow-on PRs to add
+SIMD support across all relevant NumPy functions.
Other performance improvement ideas include:
-- Reducing ufunc and ``__array_function__`` overhead.
-- Optimizations in individual functions.
- A better story around parallel execution.
+- Optimizations in individual functions.
+- Reducing ufunc and ``__array_function__`` overhead.
Furthermore we would like to improve the benchmarking system, in terms of coverage,
easy of use, and publication of the results (now
`here <https://pv.github.io/numpy-bench>`__) as part of the docs or website.
-Website and documentation
+Documentation and website
-------------------------
The NumPy `documentation <https://www.numpy.org/devdocs>`__ is of varying
quality. The API documentation is in good shape; tutorials and high-level
documentation on many topics are missing or outdated. See :ref:`NEP44` for
-planned improvements.
+planned improvements. Adding more tutorials is underway in the
+`numpy-tutorials repo <https://github.com/numpy/numpy-tutorials>`__.
Our website (https://numpy.org) was completely redesigned recently. We aim to
-further improve it by adding translations, better Hugo-Sphinx integration via a
-new Sphinx theme, and more (see `this tracking issue <https://github.com/numpy/numpy.org/issues/266>`__).
+further improve it by adding translations, more case studies and other
+high-level content, and more (see `this tracking issue <https://github.com/numpy/numpy.org/issues/266>`__).
+
+
+Extensibility
+-------------
+
+We aim to make it much easier to extend NumPy. The primary topic here is to
+improve the dtype system - see :ref:`NEP41` and related NEPs linked from it.
+Concrete goals for the dtype system rewrite are:
+
+- Easier custom dtypes:
+
+ - Simplify and/or wrap the current C-API
+ - More consistent support for dtype metadata
+ - Support for writing a dtype in Python
+
+- Allow adding (a) new string dtype(s). This could be encoded strings with
+ fixed-width storage (e.g., ``utf8`` or ``latin1``), and/or a variable length
+ string dtype. The latter could share an implementation with ``dtype=object``,
+ but be explicitly type-checked.
+ One of these should probably be the default for text data. The current
+ string dtype support is neither efficient nor user friendly.
User experience
@@ -90,18 +99,17 @@ User experience
Type annotations
````````````````
-We aim to add type annotations for all NumPy functionality, so users can use
+NumPy 1.20 adds type annotations for most NumPy functionality, so users can use
tools like `mypy`_ to type check their code and IDEs can improve their support
-for NumPy. The existing type stubs in the `numpy-stubs`_ repository are being
-improved and will be moved into the NumPy code base.
+for NumPy. Improving those type annotations, for example to support annotating
+array shapes and dtypes, is ongoing.
Platform support
````````````````
We aim to increase our support for different hardware architectures. This
includes adding CI coverage when CI services are available, providing wheels on
-PyPI for ARM64 (``aarch64``) and POWER8/9 (``ppc64le``), providing better
-build and install documentation, and resolving build issues on other platforms
-like AIX.
+PyPI for POWER8/9 (``ppc64le``), providing better build and install
+documentation, and resolving build issues on other platforms like AIX.
Maintenance
@@ -126,4 +134,3 @@ Maintenance
.. _`mypy`: https://mypy.readthedocs.io
-.. _`numpy-stubs`: https://github.com/numpy/numpy-stubs
diff --git a/doc/release/upcoming_changes/18536.improvement.rst b/doc/release/upcoming_changes/18536.improvement.rst
new file mode 100644
index 000000000..8693916db
--- /dev/null
+++ b/doc/release/upcoming_changes/18536.improvement.rst
@@ -0,0 +1,7 @@
+Add ``smallest_normal`` and ``smallest_subnormal`` attributes to `finfo`
+-------------------------------------------------------------------------
+
+The attributes ``smallest_normal`` and ``smallest_subnormal`` are available as
+an extension of `finfo` class for any floating-point data type. To use these
+new attributes, write ``np.finfo(np.float64).smallest_normal`` or
+``np.finfo(np.float64).smallest_subnormal``.
diff --git a/doc/release/upcoming_changes/19062.new_feature.rst b/doc/release/upcoming_changes/19062.new_feature.rst
new file mode 100644
index 000000000..171715568
--- /dev/null
+++ b/doc/release/upcoming_changes/19062.new_feature.rst
@@ -0,0 +1,21 @@
+Assign the platform-specific ``c_intp`` precision via a mypy plugin
+-------------------------------------------------------------------
+
+The mypy_ plugin, introduced in `numpy/numpy#17843`_, has again been expanded:
+the plugin now is now responsible for setting the platform-specific precision
+of `numpy.ctypeslib.c_intp`, the latter being used as data type for various
+`numpy.ndarray.ctypes` attributes.
+
+Without the plugin, aforementioned type will default to `ctypes.c_int64`.
+
+To enable the plugin, one must add it to their mypy `configuration file`_:
+
+.. code-block:: ini
+
+ [mypy]
+ plugins = numpy.typing.mypy_plugin
+
+
+.. _mypy: http://mypy-lang.org/
+.. _configuration file: https://mypy.readthedocs.io/en/stable/config_file.html
+.. _`numpy/numpy#17843`: https://github.com/numpy/numpy/pull/17843
diff --git a/doc/release/upcoming_changes/19135.change.rst b/doc/release/upcoming_changes/19135.change.rst
new file mode 100644
index 000000000..0b900a16a
--- /dev/null
+++ b/doc/release/upcoming_changes/19135.change.rst
@@ -0,0 +1,10 @@
+Removed floor division support for complex types
+------------------------------------------------
+
+Floor division of complex types will now result in a `TypeError`
+
+.. code-block:: python
+
+ >>> a = np.arange(10) + 1j* np.arange(10)
+ >>> a // 1
+ TypeError: ufunc 'floor_divide' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe''
diff --git a/doc/release/upcoming_changes/19151.improvement.rst b/doc/release/upcoming_changes/19151.improvement.rst
new file mode 100644
index 000000000..2108b9c4f
--- /dev/null
+++ b/doc/release/upcoming_changes/19151.improvement.rst
@@ -0,0 +1,6 @@
+`numpy.linalg.qr` accepts stacked matrices as inputs
+----------------------------------------------------
+
+`numpy.linalg.qr` is able to produce results for stacked matrices as inputs.
+Moreover, the implementation of QR decomposition has been shifted to C
+from Python.
diff --git a/doc/release/upcoming_changes/19211.new_feature.rst b/doc/release/upcoming_changes/19211.new_feature.rst
new file mode 100644
index 000000000..40e42387c
--- /dev/null
+++ b/doc/release/upcoming_changes/19211.new_feature.rst
@@ -0,0 +1,7 @@
+``keepdims`` optional argument added to `numpy.argmin`, `numpy.argmax`
+----------------------------------------------------------------------
+
+``keepdims`` argument is added to `numpy.argmin`, `numpy.argmax`.
+If set to ``True``, the axes which are reduced are left in the result as dimensions with size one.
+The resulting array has the same number of dimensions and will broadcast with the
+input array.
diff --git a/doc/release/upcoming_changes/19259.c_api.rst b/doc/release/upcoming_changes/19259.c_api.rst
new file mode 100644
index 000000000..dac9f520a
--- /dev/null
+++ b/doc/release/upcoming_changes/19259.c_api.rst
@@ -0,0 +1,12 @@
+Masked inner-loops cannot be customized anymore
+-----------------------------------------------
+The masked inner-loop selector is now never used. A warning
+will be given in the unlikely event that it was customized.
+
+We do not expect that any code uses this. If you do use it,
+you must unset the selector on newer NumPy version.
+Please also contact the NumPy developers, we do anticipate
+providing a new, more specific, mechanism.
+
+The customization was part of a never-implemented feature to allow
+for faster masked operations.
diff --git a/doc/release/upcoming_changes/19356.change.rst b/doc/release/upcoming_changes/19356.change.rst
new file mode 100644
index 000000000..3c5ef4a91
--- /dev/null
+++ b/doc/release/upcoming_changes/19356.change.rst
@@ -0,0 +1,7 @@
+`numpy.vectorize` functions now produce the same output class as the base function
+----------------------------------------------------------------------------------
+When a function that respects `numpy.ndarray` subclasses is vectorized using
+`numpy.vectorize`, the vectorized function will now be subclass-safe
+also for cases that a signature is given (i.e., when creating a ``gufunc``):
+the output class will be the same as that returned by the first call to
+the underlying function.
diff --git a/doc/release/upcoming_changes/19459.new_feature.rst b/doc/release/upcoming_changes/19459.new_feature.rst
new file mode 100644
index 000000000..aecae670f
--- /dev/null
+++ b/doc/release/upcoming_changes/19459.new_feature.rst
@@ -0,0 +1,4 @@
+The ``ndim`` and ``axis`` attributes have been added to `numpy.AxisError`
+-------------------------------------------------------------------------
+The ``ndim`` and ``axis`` parameters are now also stored as attributes
+within each `numpy.AxisError` instance.
diff --git a/doc/release/upcoming_changes/19462.change.rst b/doc/release/upcoming_changes/19462.change.rst
new file mode 100644
index 000000000..8fbadb394
--- /dev/null
+++ b/doc/release/upcoming_changes/19462.change.rst
@@ -0,0 +1,3 @@
+OpenBLAS v0.3.17
+----------------
+Update the OpenBLAS used in testing and in wheels to v0.3.17
diff --git a/doc/release/upcoming_changes/19479.compatibility.rst b/doc/release/upcoming_changes/19479.compatibility.rst
new file mode 100644
index 000000000..83533a305
--- /dev/null
+++ b/doc/release/upcoming_changes/19479.compatibility.rst
@@ -0,0 +1,7 @@
+Distutils forces strict floating point model on clang
+-----------------------------------------------------
+NumPy now sets the ``-ftrapping-math`` option on clang to enforce correct
+floating point error handling for universal functions.
+Clang defaults to non-IEEE and C99 conform behaviour otherwise.
+This change (using the equivalent but newer ``-ffp-exception-behavior=strict``)
+was attempted in NumPy 1.21, but was effectively never used.
diff --git a/doc/release/upcoming_changes/19513.new_feature.rst b/doc/release/upcoming_changes/19513.new_feature.rst
new file mode 100644
index 000000000..5f945cea2
--- /dev/null
+++ b/doc/release/upcoming_changes/19513.new_feature.rst
@@ -0,0 +1,4 @@
+Preliminary support for `windows/arm64` target
+----------------------------------------------
+``numpy`` added support for windows/arm64 target. Please note
+``OpenBLAS`` support is not yet available for windows/arm64 target.
diff --git a/doc/release/upcoming_changes/README.rst b/doc/release/upcoming_changes/README.rst
index ff5ca514c..436535ecd 100644
--- a/doc/release/upcoming_changes/README.rst
+++ b/doc/release/upcoming_changes/README.rst
@@ -50,7 +50,7 @@ and double-backticks for code.
If you are unsure what pull request type to use, don't hesitate to ask in your
PR.
-You can install ``towncrier`` and run ``towncrier --draft --version 1.18``
+You can install ``towncrier`` and run ``towncrier build --draft --version 1.18``
if you want to get a preview of how your change will look in the final release
notes.
diff --git a/doc/source/_static/favicon/apple-touch-icon.png b/doc/source/_static/favicon/apple-touch-icon.png
new file mode 100644
index 000000000..e6cd57426
--- /dev/null
+++ b/doc/source/_static/favicon/apple-touch-icon.png
Binary files differ
diff --git a/doc/source/_static/favicon/favicon-16x16.png b/doc/source/_static/favicon/favicon-16x16.png
new file mode 100644
index 000000000..95beb0834
--- /dev/null
+++ b/doc/source/_static/favicon/favicon-16x16.png
Binary files differ
diff --git a/doc/source/_static/favicon/favicon-32x32.png b/doc/source/_static/favicon/favicon-32x32.png
new file mode 100644
index 000000000..cc06622fa
--- /dev/null
+++ b/doc/source/_static/favicon/favicon-32x32.png
Binary files differ
diff --git a/doc/source/_static/favicon/favicon.ico b/doc/source/_static/favicon/favicon.ico
new file mode 100644
index 000000000..4ed63bf67
--- /dev/null
+++ b/doc/source/_static/favicon/favicon.ico
Binary files differ
diff --git a/doc/source/_static/numpy.css b/doc/source/_static/numpy.css
index 22d08cc0d..53b610bf1 100644
--- a/doc/source/_static/numpy.css
+++ b/doc/source/_static/numpy.css
@@ -18,14 +18,8 @@ pre, code {
}
h1 {
- font-style: "Lato", sans-serif;
+ font-family: "Lato", sans-serif;
color: #013243; /* warm black */
- font-weight: 700;
- letter-spacing: -.04em;
- text-align: right;
- margin-top: 3rem;
- margin-bottom: 4rem;
- font-size: 3rem;
}
diff --git a/doc/source/_static/numpylogo.svg b/doc/source/_static/numpylogo.svg
index 5f0dac700..a566851b8 100644
--- a/doc/source/_static/numpylogo.svg
+++ b/doc/source/_static/numpylogo.svg
@@ -1,23 +1,23 @@
-<?xml version="1.0" standalone="no"?>
-<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
-<!--Generator: Xara Designer (www.xara.com), SVG filter version: 6.4.0.3-->
-<svg fill="none" fill-rule="evenodd" stroke="black" stroke-width="0.501" stroke-linejoin="bevel" stroke-miterlimit="10" font-family="Times New Roman" font-size="16" style="font-variant-ligatures:none" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1" overflow="visible" width="255.845pt" height="123.322pt" viewBox="0 -123.322 255.845 123.322">
- <defs>
- </defs>
- <g id="Layer 1" transform="scale(1 -1)">
- <path d="M 107.188,79.018 C 107.386,78.994 107.58,78.94 107.762,78.859 C 107.941,78.774 108.106,78.663 108.252,78.529 C 108.44,78.349 108.616,78.158 108.78,77.955 L 123.492,59.358 C 123.432,59.95 123.393,60.531 123.364,61.088 C 123.336,61.644 123.322,62.176 123.322,62.672 L 123.322,79.079 L 129.655,79.079 L 129.655,48.109 L 125.913,48.109 C 125.433,48.095 124.956,48.182 124.513,48.364 C 124.073,48.581 123.693,48.902 123.407,49.3 L 108.801,67.73 C 108.847,67.195 108.879,66.667 108.907,66.149 C 108.936,65.632 108.953,65.146 108.953,64.692 L 108.953,48.091 L 102.616,48.091 L 102.616,79.079 L 106.398,79.079 C 106.662,79.076 106.926,79.056 107.188,79.018 Z" fill="#013243" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
- <path d="M 138.934,70.158 L 138.934,56.172 C 138.934,55.08 139.182,54.237 139.679,53.641 C 140.233,53.023 141.04,52.693 141.869,52.748 C 142.571,52.744 143.265,52.896 143.9,53.195 C 144.571,53.52 145.191,53.943 145.739,54.45 L 145.739,70.158 L 152.328,70.158 L 152.328,48.116 L 148.249,48.116 C 147.515,48.055 146.839,48.516 146.629,49.222 L 146.228,50.498 C 145.814,50.096 145.373,49.722 144.91,49.378 C 144.455,49.046 143.966,48.763 143.453,48.531 C 142.913,48.287 142.349,48.099 141.77,47.971 C 141.128,47.831 140.473,47.763 139.817,47.769 C 138.721,47.749 137.634,47.962 136.627,48.396 C 135.723,48.797 134.92,49.395 134.277,50.147 C 133.624,50.928 133.132,51.832 132.831,52.805 C 132.495,53.893 132.33,55.026 132.342,56.165 L 132.342,70.158 Z" fill="#013243" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
- <path d="M 156.578,48.109 L 156.578,70.158 L 160.661,70.158 C 161.024,70.171 161.384,70.075 161.692,69.881 C 161.978,69.682 162.185,69.388 162.277,69.052 L 162.631,67.861 C 162.989,68.24 163.371,68.596 163.776,68.924 C 164.175,69.245 164.606,69.522 165.063,69.754 C 166.067,70.263 167.18,70.522 168.306,70.509 C 169.494,70.555 170.661,70.191 171.612,69.477 C 172.508,68.755 173.194,67.805 173.597,66.727 C 173.947,67.379 174.403,67.969 174.948,68.471 C 175.463,68.94 176.043,69.333 176.67,69.637 C 177.291,69.936 177.947,70.157 178.623,70.296 C 179.299,70.437 179.988,70.508 180.679,70.509 C 181.822,70.528 182.96,70.337 184.035,69.945 C 184.97,69.598 185.811,69.037 186.491,68.308 C 187.174,67.546 187.685,66.647 187.99,65.671 C 188.347,64.524 188.519,63.327 188.501,62.126 L 188.501,48.119 L 181.908,48.119 L 181.908,62.116 C 181.908,64.398 180.931,65.538 178.977,65.536 C 178.146,65.563 177.341,65.243 176.755,64.653 C 176.167,64.07 175.873,63.224 175.873,62.116 L 175.873,48.109 L 169.291,48.109 L 169.291,62.116 C 169.291,63.378 169.043,64.264 168.547,64.774 C 168.05,65.284 167.32,65.536 166.356,65.536 C 165.769,65.537 165.19,65.4 164.666,65.135 C 164.115,64.85 163.61,64.484 163.166,64.051 L 163.166,48.102 Z" fill="#013243" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
- <path d="M 199.516,58.462 L 199.516,48.109 L 192.332,48.109 L 192.332,79.079 L 203.255,79.079 C 205.159,79.121 207.058,78.861 208.88,78.309 C 210.302,77.874 211.618,77.15 212.747,76.183 C 213.741,75.307 214.51,74.206 214.991,72.972 C 215.476,71.697 215.716,70.342 215.699,68.977 C 215.716,67.526 215.464,66.084 214.955,64.724 C 214.472,63.453 213.692,62.316 212.68,61.407 C 211.553,60.424 210.232,59.69 208.802,59.252 C 207.007,58.695 205.135,58.429 203.255,58.462 Z M 199.516,63.881 L 203.255,63.881 C 205.127,63.881 206.474,64.324 207.296,65.221 C 208.118,66.117 208.529,67.347 208.529,68.96 C 208.538,69.619 208.43,70.274 208.21,70.895 C 208.007,71.462 207.676,71.975 207.243,72.394 C 206.774,72.832 206.215,73.162 205.605,73.362 C 204.847,73.607 204.053,73.726 203.255,73.716 L 199.516,73.716 Z" fill="#013243" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
- <path d="M 228.466,42.388 C 228.316,42.012 228.072,41.68 227.757,41.424 C 227.345,41.186 226.87,41.078 226.396,41.116 L 221.452,41.116 L 225.705,50.04 L 216.908,70.158 L 222.731,70.158 C 223.157,70.179 223.577,70.054 223.922,69.803 C 224.192,69.595 224.398,69.315 224.517,68.995 L 228.129,59.493 C 228.463,58.637 228.74,57.759 228.958,56.867 C 229.1,57.32 229.256,57.767 229.426,58.203 C 229.596,58.639 229.759,59.089 229.915,59.543 L 233.19,69.002 C 233.314,69.343 233.55,69.632 233.86,69.821 C 234.174,70.034 234.544,70.148 234.923,70.151 L 240.24,70.151 Z" fill="#013243" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
- <path d="M 46.918,89.155 L 33.759,95.797 L 19.312,88.588 L 32.83,81.801 L 46.918,89.155 Z" fill="#4dabcf" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
- <path d="M 52.954,86.11 L 66.752,79.142 L 52.437,71.955 L 38.898,78.752 L 52.954,86.11 Z" fill="#4dabcf" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
- <path d="M 71.384,95.698 L 85.561,88.588 L 72.88,82.222 L 59.054,89.197 L 71.384,95.698 Z" fill="#4dabcf" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
- <path d="M 65.281,98.76 L 52.518,105.161 L 39.894,98.859 L 53.046,92.228 L 65.281,98.76 Z" fill="#4dabcf" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
- <path d="M 55.304,43.803 L 55.304,26.386 L 70.764,34.102 L 70.75,51.526 L 55.304,43.803 Z" fill="#4dabcf" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
- <path d="M 70.743,57.607 L 70.725,74.847 L 55.304,67.18 L 55.304,49.934 L 70.743,57.607 Z" fill="#4dabcf" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
- <path d="M 89.304,60.836 L 89.304,43.352 L 76.116,36.774 L 76.105,54.177 L 89.304,60.836 Z" fill="#4dabcf" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
- <path d="M 89.304,66.95 L 89.304,84.083 L 76.091,77.516 L 76.102,60.241 L 89.304,66.95 Z" fill="#4dabcf" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
- <path d="M 49.846,67.18 L 39.433,72.419 L 39.433,49.792 C 39.433,49.792 26.695,76.892 25.518,79.327 C 25.366,79.642 24.742,79.986 24.582,80.071 C 22.286,81.269 15.594,84.657 15.594,84.657 L 15.594,44.667 L 24.852,39.705 L 24.852,60.617 C 24.852,60.617 37.452,36.402 37.583,36.136 C 37.714,35.871 38.972,33.322 40.326,32.426 C 42.123,31.231 49.839,26.592 49.839,26.592 Z" fill="#4d77cf" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
- </g>
-</svg>
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<!--Generator: Xara Designer (www.xara.com), SVG filter version: 6.4.0.3-->
+<svg fill="none" fill-rule="evenodd" stroke="black" stroke-width="0.501" stroke-linejoin="bevel" stroke-miterlimit="10" font-family="Times New Roman" font-size="16" style="font-variant-ligatures:none" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1" overflow="visible" width="255.845pt" height="123.322pt" viewBox="0 -123.322 255.845 123.322">
+ <defs>
+ </defs>
+ <g id="Layer 1" transform="scale(1 -1)">
+ <path d="M 107.188,79.018 C 107.386,78.994 107.58,78.94 107.762,78.859 C 107.941,78.774 108.106,78.663 108.252,78.529 C 108.44,78.349 108.616,78.158 108.78,77.955 L 123.492,59.358 C 123.432,59.95 123.393,60.531 123.364,61.088 C 123.336,61.644 123.322,62.176 123.322,62.672 L 123.322,79.079 L 129.655,79.079 L 129.655,48.109 L 125.913,48.109 C 125.433,48.095 124.956,48.182 124.513,48.364 C 124.073,48.581 123.693,48.902 123.407,49.3 L 108.801,67.73 C 108.847,67.195 108.879,66.667 108.907,66.149 C 108.936,65.632 108.953,65.146 108.953,64.692 L 108.953,48.091 L 102.616,48.091 L 102.616,79.079 L 106.398,79.079 C 106.662,79.076 106.926,79.056 107.188,79.018 Z" fill="#013243" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
+ <path d="M 138.934,70.158 L 138.934,56.172 C 138.934,55.08 139.182,54.237 139.679,53.641 C 140.233,53.023 141.04,52.693 141.869,52.748 C 142.571,52.744 143.265,52.896 143.9,53.195 C 144.571,53.52 145.191,53.943 145.739,54.45 L 145.739,70.158 L 152.328,70.158 L 152.328,48.116 L 148.249,48.116 C 147.515,48.055 146.839,48.516 146.629,49.222 L 146.228,50.498 C 145.814,50.096 145.373,49.722 144.91,49.378 C 144.455,49.046 143.966,48.763 143.453,48.531 C 142.913,48.287 142.349,48.099 141.77,47.971 C 141.128,47.831 140.473,47.763 139.817,47.769 C 138.721,47.749 137.634,47.962 136.627,48.396 C 135.723,48.797 134.92,49.395 134.277,50.147 C 133.624,50.928 133.132,51.832 132.831,52.805 C 132.495,53.893 132.33,55.026 132.342,56.165 L 132.342,70.158 Z" fill="#013243" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
+ <path d="M 156.578,48.109 L 156.578,70.158 L 160.661,70.158 C 161.024,70.171 161.384,70.075 161.692,69.881 C 161.978,69.682 162.185,69.388 162.277,69.052 L 162.631,67.861 C 162.989,68.24 163.371,68.596 163.776,68.924 C 164.175,69.245 164.606,69.522 165.063,69.754 C 166.067,70.263 167.18,70.522 168.306,70.509 C 169.494,70.555 170.661,70.191 171.612,69.477 C 172.508,68.755 173.194,67.805 173.597,66.727 C 173.947,67.379 174.403,67.969 174.948,68.471 C 175.463,68.94 176.043,69.333 176.67,69.637 C 177.291,69.936 177.947,70.157 178.623,70.296 C 179.299,70.437 179.988,70.508 180.679,70.509 C 181.822,70.528 182.96,70.337 184.035,69.945 C 184.97,69.598 185.811,69.037 186.491,68.308 C 187.174,67.546 187.685,66.647 187.99,65.671 C 188.347,64.524 188.519,63.327 188.501,62.126 L 188.501,48.119 L 181.908,48.119 L 181.908,62.116 C 181.908,64.398 180.931,65.538 178.977,65.536 C 178.146,65.563 177.341,65.243 176.755,64.653 C 176.167,64.07 175.873,63.224 175.873,62.116 L 175.873,48.109 L 169.291,48.109 L 169.291,62.116 C 169.291,63.378 169.043,64.264 168.547,64.774 C 168.05,65.284 167.32,65.536 166.356,65.536 C 165.769,65.537 165.19,65.4 164.666,65.135 C 164.115,64.85 163.61,64.484 163.166,64.051 L 163.166,48.102 Z" fill="#013243" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
+ <path d="M 199.516,58.462 L 199.516,48.109 L 192.332,48.109 L 192.332,79.079 L 203.255,79.079 C 205.159,79.121 207.058,78.861 208.88,78.309 C 210.302,77.874 211.618,77.15 212.747,76.183 C 213.741,75.307 214.51,74.206 214.991,72.972 C 215.476,71.697 215.716,70.342 215.699,68.977 C 215.716,67.526 215.464,66.084 214.955,64.724 C 214.472,63.453 213.692,62.316 212.68,61.407 C 211.553,60.424 210.232,59.69 208.802,59.252 C 207.007,58.695 205.135,58.429 203.255,58.462 Z M 199.516,63.881 L 203.255,63.881 C 205.127,63.881 206.474,64.324 207.296,65.221 C 208.118,66.117 208.529,67.347 208.529,68.96 C 208.538,69.619 208.43,70.274 208.21,70.895 C 208.007,71.462 207.676,71.975 207.243,72.394 C 206.774,72.832 206.215,73.162 205.605,73.362 C 204.847,73.607 204.053,73.726 203.255,73.716 L 199.516,73.716 Z" fill="#013243" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
+ <path d="M 228.466,42.388 C 228.316,42.012 228.072,41.68 227.757,41.424 C 227.345,41.186 226.87,41.078 226.396,41.116 L 221.452,41.116 L 225.705,50.04 L 216.908,70.158 L 222.731,70.158 C 223.157,70.179 223.577,70.054 223.922,69.803 C 224.192,69.595 224.398,69.315 224.517,68.995 L 228.129,59.493 C 228.463,58.637 228.74,57.759 228.958,56.867 C 229.1,57.32 229.256,57.767 229.426,58.203 C 229.596,58.639 229.759,59.089 229.915,59.543 L 233.19,69.002 C 233.314,69.343 233.55,69.632 233.86,69.821 C 234.174,70.034 234.544,70.148 234.923,70.151 L 240.24,70.151 Z" fill="#013243" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
+ <path d="M 46.918,89.155 L 33.759,95.797 L 19.312,88.588 L 32.83,81.801 L 46.918,89.155 Z" fill="#4dabcf" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
+ <path d="M 52.954,86.11 L 66.752,79.142 L 52.437,71.955 L 38.898,78.752 L 52.954,86.11 Z" fill="#4dabcf" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
+ <path d="M 71.384,95.698 L 85.561,88.588 L 72.88,82.222 L 59.054,89.197 L 71.384,95.698 Z" fill="#4dabcf" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
+ <path d="M 65.281,98.76 L 52.518,105.161 L 39.894,98.859 L 53.046,92.228 L 65.281,98.76 Z" fill="#4dabcf" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
+ <path d="M 55.304,43.803 L 55.304,26.386 L 70.764,34.102 L 70.75,51.526 L 55.304,43.803 Z" fill="#4dabcf" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
+ <path d="M 70.743,57.607 L 70.725,74.847 L 55.304,67.18 L 55.304,49.934 L 70.743,57.607 Z" fill="#4dabcf" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
+ <path d="M 89.304,60.836 L 89.304,43.352 L 76.116,36.774 L 76.105,54.177 L 89.304,60.836 Z" fill="#4dabcf" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
+ <path d="M 89.304,66.95 L 89.304,84.083 L 76.091,77.516 L 76.102,60.241 L 89.304,66.95 Z" fill="#4dabcf" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
+ <path d="M 49.846,67.18 L 39.433,72.419 L 39.433,49.792 C 39.433,49.792 26.695,76.892 25.518,79.327 C 25.366,79.642 24.742,79.986 24.582,80.071 C 22.286,81.269 15.594,84.657 15.594,84.657 L 15.594,44.667 L 24.852,39.705 L 24.852,60.617 C 24.852,60.617 37.452,36.402 37.583,36.136 C 37.714,35.871 38.972,33.322 40.326,32.426 C 42.123,31.231 49.839,26.592 49.839,26.592 Z" fill="#4d77cf" stroke="none" stroke-width="0.354" fill-rule="nonzero" stroke-linejoin="miter" marker-start="none" marker-end="none"/>
+ </g>
+</svg>
diff --git a/doc/source/_static/scipy-mathjax b/doc/source/_static/scipy-mathjax
new file mode 160000
+Subproject 36f4c898f2255e0c98eb6949cd67381552d5ffe
diff --git a/doc/source/_templates/autosummary/module.rst b/doc/source/_templates/autosummary/module.rst
new file mode 100644
index 000000000..e1f428d65
--- /dev/null
+++ b/doc/source/_templates/autosummary/module.rst
@@ -0,0 +1,40 @@
+{% extends "!autosummary/module.rst" %}
+
+{# This file is almost the same as the default, but adds :toctree: to the autosummary directives.
+ The original can be found at `sphinx/ext/autosummary/templates/autosummary/module.rst`. #}
+
+{% block attributes %}
+{% if attributes %}
+ .. rubric:: Module Attributes
+
+ .. autosummary::
+ :toctree:
+ {% for item in attributes %}
+ {{ item }}
+ {%- endfor %}
+{% endif %}
+{% endblock %}
+
+{% block functions %}
+{% if functions %}
+ .. rubric:: Functions
+
+ .. autosummary::
+ :toctree:
+ {% for item in functions %}
+ {{ item }}
+ {%- endfor %}
+{% endif %}
+{% endblock %}
+
+{% block classes %}
+{% if classes %}
+ .. rubric:: Classes
+
+ .. autosummary::
+ :toctree:
+ {% for item in classes %}
+ {{ item }}
+ {%- endfor %}
+{% endif %}
+{% endblock %}
diff --git a/doc/source/_templates/indexcontent.html b/doc/source/_templates/indexcontent.html
index 6dd6bf9b0..4cbe7d4d5 100644
--- a/doc/source/_templates/indexcontent.html
+++ b/doc/source/_templates/indexcontent.html
@@ -6,31 +6,31 @@
{% block body %}
<h1>{{ docstitle|e }}</h1>
<p>
- Welcome! This is the documentation for NumPy {{ release|e }}
- {% if last_updated %}, last updated {{ last_updated|e }}{% endif %}.
+ Welcome! This is the documentation for NumPy {{ release|e }}
+ {%- if last_updated %}, last updated {{ last_updated|e }}{% endif %}.
+ For a PDF version of the documentation, go to <a href="https://numpy.org/doc/">https://numpy.org/doc/</a>.
</p>
<p><strong>For users:</strong></p>
<table class="contentstable" align="center"><tr>
<td width="50%">
<p class="biglink"><a class="biglink" href="{{ pathto("user/whatisnumpy") }}">What is NumPy?</a><br/>
<span class="linkdescr">Who uses it and why</span></p>
+ <p class="biglink"><a class ="biglink" href="{{ pathto("user/absolute_beginners") }}">NumPy: the absolute beginner's guide</a><br/>
<p class="biglink"><a class="biglink" href="https://numpy.org/install/">Installation</a><br/>
- <p class="biglink"><a class="biglink" href="{{ pathto("user/quickstart") }}">Quickstart</a><br/>
- <span class="linkdescr">Aimed at domain experts or people migrating to NumPy</span></p>
- <p class="biglink"><a class="biglink" href="{{ pathto("user/absolute_beginners") }}">Absolute beginner's guide</a><br/>
- <span class="linkdescr">Start here for an overview of NumPy features and syntax</span></p>
- <p class="biglink"><a class="biglink" href="{{ pathto("user/tutorials_index") }}">Tutorials</a><br/>
+ <p class="biglink"><a class="biglink" href="{{ pathto("user/quickstart") }}">NumPy quickstart</a><br/>
+ <span class="linkdescr">Aimed at domain experts or people migrating to NumPy</span></p>
+ <p class="biglink"><a class="biglink" href="{{ pathto("user/numpy-for-matlab-users") }}">NumPy for MATLAB users</a><br/>
+ <p class="biglink"><a class="biglink" href="https://numpy.org/numpy-tutorials/">NumPy Tutorials</a><br/>
<span class="linkdescr">Learn about concepts and submodules</span></p>
- <p class="biglink"><a class="biglink" href="{{ pathto("user/howtos_index") }}">How-tos</a><br/>
+ <p class="biglink"><a class="biglink" href="{{ pathto("user/howtos_index") }}">NumPy How Tos</a><br/>
<span class="linkdescr">How to do common tasks with NumPy</span></p>
- <p class="biglink"><a class="biglink" href="{{ pathto("reference/index") }}">NumPy API reference</a><br/>
- <span class="linkdescr">Automatically generated reference documentation</span></p>
- <p class="biglink"><a class="biglink" href="{{ pathto("user/explanations_index") }}">Explanations</a><br/>
- <span class="linkdescr">In depth explanation of concepts, best practices and techniques</span></p>
- <p class="biglink"><a class="biglink" href="{{ pathto("f2py/index") }}">F2Py guide</a><br/>
- <span class="linkdescr">Documentation for the f2py module (Fortran extensions for Python)</span></p>
+ <p class="biglink"><a class="biglink" href="{{ pathto("user/basics") }}">NumPy fundamentals</a><br/>
+ <p class="biglink"><a class="biglink" href="{{ pathto("user/building") }}">Building from source</a><br/>
+ <p class="biglink"><a class="biglink" href="{{ pathto("user/c-info") }}">Using NumPy C-API</a><br/>
+ <p class="biglink"><a class="biglink" href="{{ pathto("f2py/index") }}">F2PY Users Guide and Reference Manual</a><br/>
+ <span class="linkdescr">Documentation for the f2py module (Fortran extensions for Python)</span></p>
<p class="biglink"><a class="biglink" href="{{ pathto("glossary") }}">Glossary</a><br/>
- <span class="linkdescr">List of the most important terms</span></p>
+ <span class="linkdescr">List of the most important terms</span></p>
</td></tr>
</table>
@@ -41,10 +41,8 @@
<span class="linkdescr">Contributing to NumPy</span></p>
<p class="biglink"><a class="biglink" href="{{ pathto("dev/underthehood") }}">Under-the-hood docs</a><br/>
<span class="linkdescr">Specialized, in-depth documentation</span></p>
- <p class="biglink"><a class="biglink" href="{{ pathto("docs/index") }}">Building and extending the documentation</a><br/>
- <span class="linkdescr">How to contribute to this documentation (user and API)</span></p>
- <p class="biglink"><a class="biglink" href="{{ pathto("docs/howto_document") }}">The numpydoc docstring guide</a><br/>
- <span class="linkdescr">How to write docstrings in the numpydoc format</span></p>
+ <p class="biglink"><a class="biglink" href="{{ pathto("docs/howto_document") }}">A guide to NumPy documentation</a><br/>
+ <p class="biglink"><a class="biglink" href="{{ pathto("docs/howto_build_docs") }}">Building the NumPy API and reference docs</a><br/>
<p class="biglink"><a class="biglink" href="{{ pathto("benchmarking") }}">Benchmarking</a><br/>
<span class="linkdescr">benchmarking NumPy</span></p>
<p class="biglink"><a class="biglink" href="https://www.numpy.org/neps/index.html">NumPy Enhancement Proposals</a><br/>
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 381a01612..587307cf9 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -4,7 +4,7 @@ import re
import sys
# Minimum version, enforced by sphinx
-needs_sphinx = '2.2.0'
+needs_sphinx = '3.2.0'
# This is a nasty hack to use platform-agnostic names for types in the
@@ -83,22 +83,21 @@ extensions = [
'matplotlib.sphinxext.plot_directive',
'IPython.sphinxext.ipython_console_highlighting',
'IPython.sphinxext.ipython_directive',
- 'sphinx.ext.imgmath',
+ 'sphinx.ext.mathjax',
]
-imgmath_image_format = 'svg'
-
# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
# The suffix of source filenames.
source_suffix = '.rst'
-master_doc = 'contents'
+# Will change to `root_doc` in Sphinx 4
+master_doc = 'index'
# General substitutions.
project = 'NumPy'
-copyright = '2008-2020, The SciPy community'
+copyright = '2008-2021, The NumPy community'
# The default replacements for |version| and |release|, also used in various
# other places throughout the built documents.
@@ -138,14 +137,19 @@ add_function_parentheses = False
# output. They are ignored by default.
#show_authors = False
-# The name of the Pygments (syntax highlighting) style to use.
-pygments_style = 'sphinx'
-
def setup(app):
# add a config value for `ifconfig` directives
app.add_config_value('python_version_major', str(sys.version_info.major), 'env')
app.add_lexer('NumPyC', NumPyLexer)
+# While these objects do have type `module`, the names are aliases for modules
+# elsewhere. Sphinx does not support referring to modules by an aliases name,
+# so we make the alias look like a "real" module for it.
+# If we deemed it desirable, we could in future make these real modules, which
+# would make `from numpy.char import split` work.
+sys.modules['numpy.char'] = numpy.char
+sys.modules['numpy.testing.dec'] = numpy.testing.dec
+
# -----------------------------------------------------------------------------
# HTML output
# -----------------------------------------------------------------------------
@@ -154,9 +158,16 @@ html_theme = 'pydata_sphinx_theme'
html_logo = '_static/numpylogo.svg'
+html_favicon = '_static/favicon/favicon.ico'
+
html_theme_options = {
+ "logo_link": "index",
"github_url": "https://github.com/numpy/numpy",
"twitter_url": "https://twitter.com/numpy_team",
+ "collapse_navigation": True,
+ "external_links": [
+ {"name": "Learn", "url": "https://numpy.org/numpy-tutorials/"}
+ ],
}
@@ -179,6 +190,8 @@ if 'sphinx.ext.pngmath' in extensions:
pngmath_use_preview = True
pngmath_dvipng_args = ['-gamma', '1.5', '-D', '96', '-bg', 'Transparent']
+mathjax_path = "scipy-mathjax/MathJax.js?config=scipy-mathjax"
+
plot_html_show_formats = False
plot_html_show_source_link = False
@@ -280,11 +293,13 @@ intersphinx_mapping = {
'neps': ('https://numpy.org/neps', None),
'python': ('https://docs.python.org/dev', None),
'scipy': ('https://docs.scipy.org/doc/scipy/reference', None),
- 'matplotlib': ('https://matplotlib.org', None),
+ 'matplotlib': ('https://matplotlib.org/stable', None),
'imageio': ('https://imageio.readthedocs.io/en/stable', None),
'skimage': ('https://scikit-image.org/docs/stable', None),
'pandas': ('https://pandas.pydata.org/pandas-docs/stable', None),
'scipy-lecture-notes': ('https://scipy-lectures.org', None),
+ 'pytest': ('https://docs.pytest.org/en/stable', None),
+ 'numpy-tutorials': ('https://numpy.org/numpy-tutorials', None),
}
@@ -424,6 +439,11 @@ def linkcode_resolve(domain, info):
if not fn:
return None
+ # Ignore re-exports as their source files are not within the numpy repo
+ module = inspect.getmodule(obj)
+ if module is not None and not module.__name__.startswith("numpy"):
+ return None
+
try:
source, lineno = inspect.getsourcelines(obj)
except Exception:
@@ -437,7 +457,7 @@ def linkcode_resolve(domain, info):
linespec = ""
if 'dev' in numpy.__version__:
- return "https://github.com/numpy/numpy/blob/master/numpy/%s%s" % (
+ return "https://github.com/numpy/numpy/blob/main/numpy/%s%s" % (
fn, linespec)
else:
return "https://github.com/numpy/numpy/blob/v%s/numpy/%s%s" % (
diff --git a/doc/source/dev/development_advanced_debugging.rst b/doc/source/dev/development_advanced_debugging.rst
new file mode 100644
index 000000000..fa4014fdb
--- /dev/null
+++ b/doc/source/dev/development_advanced_debugging.rst
@@ -0,0 +1,190 @@
+========================
+Advanced debugging tools
+========================
+
+If you reached here, you want to dive into, or use, more advanced tooling.
+This is usually not necessary for first time contributers and most
+day-to-day developement.
+These are used more rarely, for example close to a new NumPy release,
+or when a large or particular complex change was made.
+
+Since not all of these tools are used on a regular bases and only available
+on some systems, please expect differences, issues, or quirks;
+we will be happy to help if you get stuck and appreciate any improvements
+or suggestions to these workflows.
+
+
+Finding C errors with additional tooling
+########################################
+
+Most development will not require more than a typical debugging toolchain
+as shown in :ref:`Debugging <debugging>`.
+But for example memory leaks can be particularly subtle or difficult to
+narrow down.
+
+We do not expect any of these tools to be run by most contributors.
+However, you can ensure that we can track down such issues more easily easier:
+
+* Tests should cover all code paths, incluing error paths.
+* Try to write short and simple tests. If you have a very complicated test
+ consider creating an additional simpler test as well.
+ This can be helpful, because often it is only easy to find which test
+ triggers an issue and not which line of the test.
+* Never use ``np.empty`` if data is read/used. ``valgrind`` will notice this
+ and report an error. When you do not care about values, you can generate
+ random values instead.
+
+This will help us catch any oversights before your change is released
+and means you do not have to worry about making reference counting errors,
+which can be intimidating.
+
+
+Python debug build for finding memory leaks
+===========================================
+
+Debug builds of Python are easily available for example on ``debian`` systems,
+and can be used on all platforms.
+Running a test or terminal is usually as easy as::
+
+ python3.8d runtests.py
+ # or
+ python3.8d runtests.py --ipython
+
+and were already mentioned in :ref:`Debugging <debugging>`.
+
+A Python debug build will help:
+
+- Find bugs which may otherwise cause random behaviour.
+ One example is when an object is still used after it has been deleted.
+
+- Python debug builds allows to check correct reference counting.
+ This works using the additional commands::
+
+ sys.gettotalrefcount()
+ sys.getallocatedblocks()
+
+
+Use together with ``pytest``
+----------------------------
+
+Running the test suite only with a debug python build will not find many
+errors on its own. An additional advantage of a debug build of Python is that
+it allows detecting memory leaks.
+
+A tool to make this easier is `pytest-leaks`_, which can be installed using ``pip``.
+Unfortunately, ``pytest`` itself may leak memory, but good results can usually
+(currently) be achieved by removing::
+
+ @pytest.fixture(autouse=True)
+ def add_np(doctest_namespace):
+ doctest_namespace['np'] = numpy
+
+ @pytest.fixture(autouse=True)
+ def env_setup(monkeypatch):
+ monkeypatch.setenv('PYTHONHASHSEED', '0')
+
+from ``numpy/conftest.py`` (This may change with new ``pytest-leaks`` versions
+or ``pytest`` updates).
+
+This allows to run the test suite, or part of it, conveniently::
+
+ python3.8d runtests.py -t numpy/core/tests/test_multiarray.py -- -R2:3 -s
+
+where ``-R2:3`` is the ``pytest-leaks`` command (see its documentation), the
+``-s`` causes output to print and may be necessary (in some versions captured
+output was detected as a leak).
+
+Note that some tests are known (or even designed) to leak references, we try
+to mark them, but expect some false positives.
+
+.. _pytest-leaks: https://github.com/abalkin/pytest-leaks
+
+``valgrind``
+============
+
+Valgrind is a powerful tool to find certain memory access problems and should
+be run on complicated C code.
+Basic use of ``valgrind`` usually requires no more than::
+
+ PYTHONMALLOC=malloc python runtests.py
+
+where ``PYTHONMALLOC=malloc`` is necessary to avoid false positives from python
+itself.
+Depending on the system and valgrind version, you may see more false positives.
+``valgrind`` supports "suppressions" to ignore some of these, and Python does
+have a supression file (and even a compile time option) which may help if you
+find it necessary.
+
+Valgrind helps:
+
+- Find use of uninitialized variables/memory.
+
+- Detect memory access violations (reading or writing outside of allocated
+ memory).
+
+- Find *many* memory leaks. Note that for *most* leaks the python
+ debug build approach (and ``pytest-leaks``) is much more sensitive.
+ The reason is that ``valgrind`` can only detect if memory is definitely
+ lost. If::
+
+ dtype = np.dtype(np.int64)
+ arr.astype(dtype=dtype)
+
+ Has incorrect reference counting for ``dtype``, this is a bug, but valgrind
+ cannot see it because ``np.dtype(np.int64)`` always returns the same object.
+ However, not all dtypes are singletons, so this might leak memory for
+ different input.
+ In rare cases NumPy uses ``malloc`` and not the Python memory allocators
+ which are invisible to the Python debug build.
+ ``malloc`` should normally be avoided, but there are some exceptions
+ (e.g. the ``PyArray_Dims`` structure is public API and cannot use the
+ Python allocators.)
+
+Even though using valgrind for memory leak detection is slow and less sensitive
+it can be a convenient: you can run most programs with valgrind without
+modification.
+
+Things to be aware of:
+
+- Valgrind does not support the numpy ``longdouble``, this means that tests
+ will fail or be flagged errors that are completely fine.
+
+- Expect some errors before and after running your NumPy code.
+
+- Caches can mean that errors (specifically memory leaks) may not be detected
+ or are only detect at a later, unrelated time.
+
+A big advantage of valgrind is that it has no requirements aside from valgrind
+itself (although you probably want to use debug builds for better tracebacks).
+
+
+Use together with ``pytest``
+----------------------------
+You can run the test suite with valgrind which may be sufficient
+when you are only interested in a few tests::
+
+ PYTHOMMALLOC=malloc valgrind python runtests.py \
+ -t numpy/core/tests/test_multiarray.py -- --continue-on-collection-errors
+
+Note the ``--continue-on-collection-errors``, which is currently necessary due to
+missing ``longdouble`` support causing failures (this will usually not be
+necessary if you do not run the full test suite).
+
+If you wish to detect memory leaks you will also require ``--show-leak-kinds=definite``
+and possibly more valgrind options. Just as for ``pytest-leaks`` certain
+tests are known to leak cause errors in valgrind and may or may not be marked
+as such.
+
+We have developed `pytest-valgrind`_ which:
+
+- Reports errors for each test individually
+
+- Narrows down memory leaks to individual tests (by default valgrind
+ only checks for memory leaks after a program stops, which is very
+ cumbersome).
+
+Please refer to its ``README`` for more information (it includes an example
+command for NumPy).
+
+.. _pytest-valgrind: https://github.com/seberg/pytest-valgrind
+
diff --git a/doc/source/dev/development_environment.rst b/doc/source/dev/development_environment.rst
index cb027c662..665198c69 100644
--- a/doc/source/dev/development_environment.rst
+++ b/doc/source/dev/development_environment.rst
@@ -57,7 +57,8 @@ When using pytest as a target (the default), you can
Using ``runtests.py`` is the recommended approach to running tests.
There are also a number of alternatives to it, for example in-place
-build or installing to a virtualenv. See the FAQ below for details.
+build or installing to a virtualenv or a conda environment. See the FAQ below
+for details.
.. note::
@@ -130,17 +131,27 @@ to see this output, you can run the ``build_src`` stage verbosely::
$ python build build_src -v
-Using virtualenvs
------------------
+Using virtual environments
+--------------------------
A frequently asked question is "How do I set up a development version of NumPy
in parallel to a released version that I use to do my job/research?".
One simple way to achieve this is to install the released version in
-site-packages, by using a binary installer or pip for example, and set
-up the development version in a virtualenv. First install
+site-packages, by using pip or conda for example, and set
+up the development version in a virtual environment.
+
+If you use conda, we recommend creating a separate virtual environment for
+numpy development using the ``environment.yml`` file in the root of the repo
+(this will create the environment and install all development dependencies at
+once)::
+
+ $ conda env create -f environment.yml # `mamba` works too for this command
+ $ conda activate numpy-dev
+
+If you installed Python some other way than conda, first install
`virtualenv`_ (optionally use `virtualenvwrapper`_), then create your
-virtualenv (named numpy-dev here) with::
+virtualenv (named ``numpy-dev`` here) with::
$ virtualenv numpy-dev
@@ -188,6 +199,35 @@ For more extensive information, see :ref:`testing-guidelines`
*Note: do not run the tests from the root directory of your numpy git repo without ``runtests.py``,
that will result in strange test errors.*
+Running Linting
+---------------
+Lint checks can be performed on newly added lines of Python code.
+
+Install all dependent packages using pip::
+
+ $ python -m pip install -r linter_requirements.txt
+
+To run lint checks before committing new code, run::
+
+ $ python runtests.py --lint uncommitted
+
+To check all changes in newly added Python code of current branch with target branch, run::
+
+ $ python runtests.py --lint main
+
+If there are no errors, the script exits with no message. In case of errors::
+
+ $ python runtests.py --lint main
+ ./numpy/core/tests/test_scalarmath.py:34:5: E303 too many blank lines (3)
+ 1 E303 too many blank lines (3)
+
+It is advisable to run lint checks before pushing commits to a remote branch
+since the linter runs as part of the CI pipeline.
+
+For more details on Style Guidelines:
+
+ - `Python Style Guide`_
+ - `C Style Guide`_
Rebuilding & cleaning the workspace
-----------------------------------
@@ -207,6 +247,8 @@ repo, use one of::
$ git reset --hard
+.. _debugging:
+
Debugging
---------
@@ -262,6 +304,8 @@ typically packaged as ``python-dbg``) is highly recommended.
.. _virtualenvwrapper: http://www.doughellmann.com/projects/virtualenvwrapper/
.. _Waf: https://code.google.com/p/waf/
.. _`match test names using python operators`: https://docs.pytest.org/en/latest/usage.html#specifying-tests-selecting-tests
+.. _`Python Style Guide`: https://www.python.org/dev/peps/pep-0008/
+.. _`C Style Guide`: https://numpy.org/neps/nep-0045-c_style_guide.html
Understanding the code & getting started
----------------------------------------
diff --git a/doc/source/dev/development_gitpod.rst b/doc/source/dev/development_gitpod.rst
new file mode 100644
index 000000000..92cca81fc
--- /dev/null
+++ b/doc/source/dev/development_gitpod.rst
@@ -0,0 +1,271 @@
+.. _development-gitpod:
+
+
+Using Gitpod for NumPy development
+=======================================================
+
+This section of the documentation will guide you through:
+
+* using GitPod for your NumPy development environment
+* creating a personal fork of the NumPy repository on GitHub
+* a quick tour of Gitpod and VSCode
+* working on the NumPy documentation in Gitpod
+
+Gitpod
+-------
+
+`Gitpod`_ is an open-source platform for automated and ready-to-code
+development environments. It enables developers to describe their dev
+environment as code and start instant and fresh development environments for
+each new task directly from your browser. This reduces the need to install local
+development environments and deal with incompatible dependencies.
+
+Gitpod GitHub integration
+--------------------------
+
+To be able to use Gitpod, you will need to have the Gitpod app installed on your
+GitHub account, so if
+you do not have an account yet, you will need to create one first.
+
+Head over to the `Gitpod`_ website and click on the **Continue with GitHub**
+button. You will be redirected to the GitHub authentication page.
+You will then be asked to install the `Gitpod GitHub app <https://github.com/marketplace/gitpod-io>`_.
+
+Make sure to select **All repositories** access option to avoid issues with
+permissions later on. Click on the green **Install** button
+
+.. image:: ./gitpod-imgs/installing-gitpod-io.png
+ :alt: Gitpod repository access and installation screenshot
+
+This will install the necessary hooks for the integration.
+
+Forking the NumPy repository
+-----------------------------
+
+The best way to work on NumPy as a contributor is by making a fork of the
+repository first.
+
+#. Browse to the `NumPy repository on GitHub`_ and `create your own fork`_.
+#. Browse to your fork. Your fork will have a URL like
+ https://github.com/melissawm/NumPy, except with your GitHub username in place of ``melissawm``.
+
+Starting Gitpod
+----------------
+Once you have authenticated to Gitpod through GitHub, you can install the
+`Gitpod browser extension <https://www.gitpod.io/docs/browser-extension>`_
+which will add a **Gitpod** button next to the **Code** button in the
+repository:
+
+.. image:: ./gitpod-imgs/NumPy-github.png
+ :alt: NumPy repository with Gitpod button screenshot
+
+#. If you install the extension - you can click the **Gitpod** button to start
+ a new workspace.
+
+#. Alternatively, if you do not want to install the browser extension, you can
+ visit https://gitpod.io/#https://github.com/USERNAME/NumPy replacing
+ ``USERNAME`` with your GitHub username.
+
+#. In both cases, this will open a new tab on your web browser and start
+ building your development environment. Please note this can take a few
+ minutes.
+
+#. Once the build is complete, you will be directed to your workspace,
+ including the VSCode editor and all the dependencies you need to work on
+ NumPy. The first time you start your workspace, you will notice that there
+ might be some actions running. This will ensure that you have a development
+ version of NumPy installed and that the docs are being pre-built for you.
+
+#. When your workspace is ready, you can :ref:`test the build<testing-builds>` by
+ entering::
+
+ $ python runtests.py -v
+
+``runtests.py`` is another script in the NumPy root directory. It runs a suite
+of tests that make sure NumPy is working as it should, and ``-v`` activates the
+``--verbose`` option to show all the test output.
+
+Quick workspace tour
+---------------------
+Gitpod uses VSCode as the editor. If you have not used this editor before, you
+can check the Getting started `VSCode docs`_ to familiarize yourself with it.
+
+Your workspace will look similar to the image below:
+
+.. image:: ./gitpod-imgs/gitpod-workspace.png
+ :alt: Gitpod workspace screenshot
+
+.. note:: By default, VSCode initializes with a light theme. You can change to
+ a dark theme by with the keyboard shortcut :kbd:`Cmd-K Cmd-T` in Mac or
+ :kbd:`Ctrl-K Ctrl-T` in Linux and Windows.
+
+We have marked some important sections in the editor:
+
+#. Your current Python interpreter - by default, this is ``numpy-dev`` and
+ should be displayed in the status bar and on your terminal. You do not need
+ to activate the conda environment as this will always be activated for you.
+#. Your current branch is always displayed in the status bar. You can also use
+ this button to change or create branches.
+#. GitHub Pull Requests extension - you can use this to work with Pull Requests
+ from your workspace.
+#. Marketplace extensions - we have added some essential extensions to the NumPy
+ Gitpod. Still, you can also install other extensions or syntax highlighting
+ themes for your user, and these will be preserved for you.
+#. Your workspace directory - by default, it is ``/workspace/numpy``. **Do not
+ change this** as this is the only directory preserved in Gitpod.
+
+We have also pre-installed a few tools and VSCode extensions to help with the
+development experience:
+
+* `GitHub CLI <https://cli.github.com/>`_
+* `VSCode rst extension <https://marketplace.visualstudio.com/items?itemName=lextudio.restructuredtext>`_
+* `VSCode Live server extension <https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer>`_
+* `VSCode Gitlens extension <https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens>`_
+* `VSCode autodocstrings extension <https://marketplace.visualstudio.com/items?itemName=njpwerner.autodocstring>`_
+* `VSCode Git Graph extension <https://marketplace.visualstudio.com/items?itemName=mhutchie.git-graph>`_
+
+Development workflow with Gitpod
+---------------------------------
+The :ref:`development-workflow` section of this documentation contains
+information regarding the NumPy development workflow. Make sure to check this
+before working on your contributions.
+
+When using Gitpod, git is pre configured for you:
+
+#. You do not need to configure your git username, and email as this should be
+ done for you as you authenticated through GitHub. You can check the git
+ configuration with the command ``git config --list`` in your terminal.
+#. As you started your workspace from your own NumPy fork, you will by default
+ have both ``upstream`` and ``origin`` added as remotes. You can verify this by
+ typing ``git remote`` on your terminal or by clicking on the **branch name**
+ on the status bar (see image below).
+
+ .. image:: ./gitpod-imgs/NumPy-gitpod-branches.png
+ :alt: Gitpod workspace branches plugin screenshot
+
+Rendering the NumPy documentation
+----------------------------------
+You can find the detailed documentation on how rendering the documentation with
+Sphinx works in the :ref:`howto-build-docs` section.
+
+The documentation is pre-built during your workspace initialization. So once
+this task is completed, you have two main options to render the documentation
+in Gitpod.
+
+Option 1: Using Liveserve
+***************************
+
+#. View the documentation in ``NumPy/doc/build/html``. You can start with
+ ``index.html`` and browse, or you can jump straight to the file you're
+ interested in.
+#. To see the rendered version of a page, you can right-click on the ``.html``
+ file and click on **Open with Live Serve**. Alternatively, you can open the
+ file in the editor and click on the **Go live** button on the status bar.
+
+ .. image:: ./gitpod-imgs/vscode-statusbar.png
+ :alt: Gitpod workspace VSCode start live serve screenshot
+
+#. A simple browser will open to the right-hand side of the editor. We recommend
+ closing it and click on the **Open in browser** button in the pop-up.
+#. To stop the server click on the **Port: 5500** button on the status bar.
+
+Option 2: Using the rst extension
+***********************************
+
+A quick and easy way to see live changes in a ``.rst`` file as you work on it
+uses the rst extension with docutils.
+
+.. note:: This will generate a simple live preview of the document without the
+ ``html`` theme, and some backlinks might not be added correctly. But it is an
+ easy and lightweight way to get instant feedback on your work.
+
+#. Open any of the source documentation files located in ``doc/source`` in the
+ editor.
+#. Open VSCode Command Palette with :kbd:`Cmd-Shift-P` in Mac or
+ :kbd:`Ctrl-Shift-P` in Linux and Windows. Start typing "restructured"
+ and choose either "Open preview" or "Open preview to the Side".
+
+ .. image:: ./gitpod-imgs/vscode-rst.png
+ :alt: Gitpod workspace VSCode open rst screenshot
+
+#. As you work on the document, you will see a live rendering of it on the editor.
+
+ .. image:: ./gitpod-imgs/rst-rendering.png
+ :alt: Gitpod workspace VSCode rst rendering screenshot
+
+If you want to see the final output with the ``html`` theme you will need to
+rebuild the docs with ``make html`` and use Live Serve as described in option 1.
+
+FAQ's and troubleshooting
+-------------------------
+
+How long is my Gitpod workspace kept for?
+*****************************************
+
+Your stopped workspace will be kept for 14 days and deleted afterwards if you do
+not use them.
+
+Can I come back to a previous workspace?
+*****************************************
+
+Yes, let's say you stepped away for a while and you want to carry on working on
+your NumPy contributions. You need to visit https://gitpod.io/workspaces and
+click on the workspace you want to spin up again. All your changes will be there
+as you last left them.
+
+Can I install additional VSCode extensions?
+*******************************************
+
+Absolutely! Any extensions you installed will be installed in your own workspace
+and preserved.
+
+I registered on Gitpod but I still cannot see a ``Gitpod`` button in my repositories.
+*************************************************************************************
+
+Head to https://gitpod.io/integrations and make sure you are logged in.
+Hover over GitHub and click on the three buttons that appear on the right.
+Click on edit permissions and make sure you have ``user:email``,
+``read:user``, and ``public_repo`` checked. Click on **Update Permissions**
+and confirm the changes in the GitHub application page.
+
+.. image:: ./gitpod-imgs/gitpod-edit-permissions-gh.png
+ :alt: Gitpod integrations - edit GH permissions screenshot
+
+How long does my workspace stay active if I'm not using it?
+***********************************************************
+
+If you keep your workspace open in a browser tab but don't interact with it,
+it will shut down after 30 minutes. If you close the browser tab, it will
+shut down after 3 minutes.
+
+My terminal is blank - there is no cursor and it's completely unresponsive
+**************************************************************************
+
+Unfortunately this is a known-issue on Gitpod's side. You can sort this
+issue in two ways:
+
+#. Create a new Gitpod workspace altogether.
+#. Head to your `Gitpod dashboard <https://gitpod.io/workspaces>`_ and locate
+ the running workspace. Hover on it and click on the **three dots menu**
+ and then click on **Stop**. When the workspace is completely stopped you
+ can click on its name to restart it again.
+
+.. image:: ./gitpod-imgs/gitpod-dashboard-stop.png
+ :alt: Gitpod dashboard and workspace menu screenshot
+
+I authenticated through GitHub but I still cannot commit to the repository through Gitpod.
+******************************************************************************************
+
+Head to https://gitpod.io/integrations and make sure you are logged in.
+Hover over GitHub and click on the three buttons that appear on the right.
+Click on edit permissions and make sure you have ``public_repo`` checked.
+Click on **Update Permissions** and confirm the changes in the
+GitHub application page.
+
+.. image:: ./gitpod-imgs/gitpod-edit-permissions-repo.png
+ :alt: Gitpod integrations - edit GH repository permissions screenshot
+
+.. _Gitpod: https://www.gitpod.io/
+.. _NumPy repository on GitHub: https://github.com/NumPy/NumPy
+.. _create your own fork: https://help.github.com/en/articles/fork-a-repo
+.. _VSCode docs: https://code.visualstudio.com/docs/getstarted/tips-and-tricks
diff --git a/doc/source/dev/development_workflow.rst b/doc/source/dev/development_workflow.rst
index 34535b2f5..8c56f6fb2 100644
--- a/doc/source/dev/development_workflow.rst
+++ b/doc/source/dev/development_workflow.rst
@@ -49,10 +49,10 @@ First, fetch new commits from the ``upstream`` repository:
git fetch upstream
-Then, create a new branch based on the master branch of the upstream
+Then, create a new branch based on the main branch of the upstream
repository::
- git checkout -b my-new-feature upstream/master
+ git checkout -b my-new-feature upstream/main
.. _editing-workflow:
@@ -147,7 +147,7 @@ In more detail
It may be the case that while you were working on your edits, new commits have
been added to ``upstream`` that affect your work. In this case, follow the
-:ref:`rebasing-on-master` section of this document to apply those changes to
+:ref:`rebasing-on-main` section of this document to apply those changes to
your branch.
.. _writing-the-commit-message:
@@ -226,10 +226,10 @@ mailing list may also be useful.
-.. _rebasing-on-master:
+.. _rebasing-on-main:
-Rebasing on master
-==================
+Rebasing on main
+================
This updates your feature branch with changes from the upstream `NumPy
github`_ repo. If you do not absolutely need to do this, try to avoid doing
@@ -244,8 +244,8 @@ Next, you need to update the feature branch::
git checkout my-new-feature
# make a backup in case you mess up
git branch tmp my-new-feature
- # rebase on upstream master branch
- git rebase upstream/master
+ # rebase on upstream main branch
+ git rebase upstream/main
If you have made changes to files that have changed also upstream,
this may generate merge conflicts that you need to resolve. See
@@ -258,7 +258,7 @@ Finally, remove the backup branch upon a successful rebase::
.. note::
- Rebasing on master is preferred over merging upstream back to your
+ Rebasing on main is preferred over merging upstream back to your
branch. Using ``git merge`` and ``git pull`` is discouraged when
working on feature branches.
@@ -325,7 +325,7 @@ Suppose that the commit history looks like this::
29001ed Add pre-nep for a couple of structured_array_extensions.
...
-and ``6ad92e5`` is the last commit in the ``master`` branch. Suppose we
+and ``6ad92e5`` is the last commit in the ``main`` branch. Suppose we
want to make the following changes:
* Rewrite the commit message for ``13d7934`` to something more sensible.
@@ -392,7 +392,7 @@ Deleting a branch on github_
::
- git checkout master
+ git checkout main
# delete branch locally
git branch -D my-unwanted-branch
# delete branch on github
@@ -451,25 +451,25 @@ Backporting
===========
Backporting is the process of copying new feature/fixes committed in
-`numpy/master`_ back to stable release branches. To do this you make a branch
+`numpy/main`_ back to stable release branches. To do this you make a branch
off the branch you are backporting to, cherry pick the commits you want from
-``numpy/master``, and then submit a pull request for the branch containing the
+``numpy/main``, and then submit a pull request for the branch containing the
backport.
1. First, you need to make the branch you will work on. This needs to be
- based on the older version of NumPy (not master)::
+ based on the older version of NumPy (not main)::
# Make a new branch based on numpy/maintenance/1.8.x,
# backport-3324 is our new name for the branch.
git checkout -b backport-3324 upstream/maintenance/1.8.x
-2. Now you need to apply the changes from master to this branch using
+2. Now you need to apply the changes from main to this branch using
`git cherry-pick`_::
# Update remote
git fetch upstream
# Check the commit log for commits to cherry pick
- git log upstream/master
+ git log upstream/main
# This pull request included commits aa7a047 to c098283 (inclusive)
# so you use the .. syntax (for a range of commits), the ^ makes the
# range inclusive.
@@ -480,7 +480,7 @@ backport.
3. You might run into some conflicts cherry picking here. These are
resolved the same way as merge/rebase conflicts. Except here you can
- use `git blame`_ to see the difference between master and the
+ use `git blame`_ to see the difference between main and the
backported branch to make sure nothing gets screwed up.
4. Push the new branch to your Github repository::
@@ -488,8 +488,8 @@ backport.
git push -u origin backport-3324
5. Finally make a pull request using Github. Make sure it is against the
- maintenance branch and not master, Github will usually suggest you
- make the pull request against master.
+ maintenance branch and not main, Github will usually suggest you
+ make the pull request against main.
.. _pushing-to-main:
@@ -499,7 +499,7 @@ Pushing changes to the main repo
*Requires commit rights to the main NumPy repo.*
When you have a set of "ready" changes in a feature branch ready for
-NumPy's ``master`` or ``maintenance`` branches, you can push
+NumPy's ``main`` or ``maintenance`` branches, you can push
them to ``upstream`` as follows:
1. First, merge or rebase on the target branch.
@@ -507,23 +507,23 @@ them to ``upstream`` as follows:
a) Only a few, unrelated commits then prefer rebasing::
git fetch upstream
- git rebase upstream/master
+ git rebase upstream/main
- See :ref:`rebasing-on-master`.
+ See :ref:`rebasing-on-main`.
b) If all of the commits are related, create a merge commit::
git fetch upstream
- git merge --no-ff upstream/master
+ git merge --no-ff upstream/main
2. Check that what you are going to push looks sensible::
- git log -p upstream/master..
+ git log -p upstream/main..
git log --oneline --graph
3. Push to upstream::
- git push upstream my-feature-branch:master
+ git push upstream my-feature-branch:main
.. note::
diff --git a/doc/source/dev/gitpod-imgs/NumPy-github.png b/doc/source/dev/gitpod-imgs/NumPy-github.png
new file mode 100644
index 000000000..010b0fc5e
--- /dev/null
+++ b/doc/source/dev/gitpod-imgs/NumPy-github.png
Binary files differ
diff --git a/doc/source/dev/gitpod-imgs/NumPy-gitpod-branches.png b/doc/source/dev/gitpod-imgs/NumPy-gitpod-branches.png
new file mode 100644
index 000000000..3ee6c5f20
--- /dev/null
+++ b/doc/source/dev/gitpod-imgs/NumPy-gitpod-branches.png
Binary files differ
diff --git a/doc/source/dev/gitpod-imgs/gitpod-dashboard-stop.png b/doc/source/dev/gitpod-imgs/gitpod-dashboard-stop.png
new file mode 100644
index 000000000..40f137745
--- /dev/null
+++ b/doc/source/dev/gitpod-imgs/gitpod-dashboard-stop.png
Binary files differ
diff --git a/doc/source/dev/gitpod-imgs/gitpod-edit-permissions-gh.png b/doc/source/dev/gitpod-imgs/gitpod-edit-permissions-gh.png
new file mode 100644
index 000000000..8955e907a
--- /dev/null
+++ b/doc/source/dev/gitpod-imgs/gitpod-edit-permissions-gh.png
Binary files differ
diff --git a/doc/source/dev/gitpod-imgs/gitpod-edit-permissions-repo.png b/doc/source/dev/gitpod-imgs/gitpod-edit-permissions-repo.png
new file mode 100644
index 000000000..8bfaff81c
--- /dev/null
+++ b/doc/source/dev/gitpod-imgs/gitpod-edit-permissions-repo.png
Binary files differ
diff --git a/doc/source/dev/gitpod-imgs/gitpod-workspace.png b/doc/source/dev/gitpod-imgs/gitpod-workspace.png
new file mode 100644
index 000000000..a65c9bd7e
--- /dev/null
+++ b/doc/source/dev/gitpod-imgs/gitpod-workspace.png
Binary files differ
diff --git a/doc/source/dev/gitpod-imgs/installing-gitpod-io.png b/doc/source/dev/gitpod-imgs/installing-gitpod-io.png
new file mode 100644
index 000000000..97319a729
--- /dev/null
+++ b/doc/source/dev/gitpod-imgs/installing-gitpod-io.png
Binary files differ
diff --git a/doc/source/dev/gitpod-imgs/rst-rendering.png b/doc/source/dev/gitpod-imgs/rst-rendering.png
new file mode 100644
index 000000000..41cc305f3
--- /dev/null
+++ b/doc/source/dev/gitpod-imgs/rst-rendering.png
Binary files differ
diff --git a/doc/source/dev/gitpod-imgs/vscode-rst.png b/doc/source/dev/gitpod-imgs/vscode-rst.png
new file mode 100644
index 000000000..5b574c115
--- /dev/null
+++ b/doc/source/dev/gitpod-imgs/vscode-rst.png
Binary files differ
diff --git a/doc/source/dev/gitpod-imgs/vscode-statusbar.png b/doc/source/dev/gitpod-imgs/vscode-statusbar.png
new file mode 100644
index 000000000..3febbcee0
--- /dev/null
+++ b/doc/source/dev/gitpod-imgs/vscode-statusbar.png
Binary files differ
diff --git a/doc/source/dev/gitwash/development_setup.rst b/doc/source/dev/gitwash/development_setup.rst
index a7e9c28b9..2be7125da 100644
--- a/doc/source/dev/gitwash/development_setup.rst
+++ b/doc/source/dev/gitwash/development_setup.rst
@@ -100,8 +100,8 @@ Make the local copy
#. Set up your repository so ``git pull`` pulls from ``upstream`` by
default: ::
- git config branch.master.remote upstream
- git config branch.master.merge refs/heads/master
+ git config branch.main.remote upstream
+ git config branch.main.merge refs/heads/main
******************************************************************************
Look it over
@@ -109,17 +109,17 @@ Look it over
#. The branches shown by ``git branch -a`` will include
- - the ``master`` branch you just cloned on your own machine
- - the ``master`` branch from your fork on GitHub, which git named
+ - the ``main`` branch you just cloned on your own machine
+ - the ``main`` branch from your fork on GitHub, which git named
``origin`` by default
- - the ``master`` branch on the the main NumPy repo, which you named
+ - the ``main`` branch on the the main NumPy repo, which you named
``upstream``.
::
- master
- remotes/origin/master
- remotes/upstream/master
+ main
+ remotes/origin/main
+ remotes/upstream/main
If ``upstream`` isn't there, it will be added after you access the
NumPy repo with a command like ``git fetch`` or ``git pull``.
@@ -139,8 +139,8 @@ Look it over
user.name=Your Name
remote.origin.url=git@github.com:your-github-id/numpy.git
remote.origin.fetch=+refs/heads/*:refs/remotes/origin/*
- branch.master.remote=upstream
- branch.master.merge=refs/heads/master
+ branch.main.remote=upstream
+ branch.main.merge=refs/heads/main
remote.upstream.url=https://github.com/numpy/numpy.git
remote.upstream.fetch=+refs/heads/*:refs/remotes/upstream/*
@@ -165,7 +165,7 @@ slightly. Instead of ::
run ::
- git clone git@github.com:numpy/numpy.git
+ git clone git@github.com:your-user-name/numpy.git
and instead of showing an ``https`` URL, ``git remote -v`` will show ::
diff --git a/doc/source/dev/gitwash/dot2_dot3.rst b/doc/source/dev/gitwash/dot2_dot3.rst
index 7759e2e60..30852b5ad 100644
--- a/doc/source/dev/gitwash/dot2_dot3.rst
+++ b/doc/source/dev/gitwash/dot2_dot3.rst
@@ -7,22 +7,22 @@
Thanks to Yarik Halchenko for this explanation.
Imagine a series of commits A, B, C, D... Imagine that there are two
-branches, *topic* and *master*. You branched *topic* off *master* when
-*master* was at commit 'E'. The graph of the commits looks like this::
+branches, *topic* and *main*. You branched *topic* off *main* when
+*main* was at commit 'E'. The graph of the commits looks like this::
A---B---C topic
/
- D---E---F---G master
+ D---E---F---G main
Then::
- git diff master..topic
+ git diff main..topic
will output the difference from G to C (i.e. with effects of F and G),
while::
- git diff master...topic
+ git diff main...topic
would output just differences in the topic branch (i.e. only A, B, and
C).
diff --git a/doc/source/dev/gitwash/git_links.inc b/doc/source/dev/gitwash/git_links.inc
index 8032dca41..8126cf9ac 100644
--- a/doc/source/dev/gitwash/git_links.inc
+++ b/doc/source/dev/gitwash/git_links.inc
@@ -47,7 +47,7 @@
.. _ipython git workflow: https://mail.python.org/pipermail/ipython-dev/2010-October/005632.html
.. _git parable: http://tom.preston-werner.com/2009/05/19/the-git-parable.html
.. _git foundation: http://matthew-brett.github.com/pydagogue/foundation.html
-.. _numpy/master: https://github.com/numpy/numpy
+.. _numpy/main: https://github.com/numpy/numpy
.. _git cherry-pick: https://www.kernel.org/pub/software/scm/git/docs/git-cherry-pick.html
.. _git blame: https://www.kernel.org/pub/software/scm/git/docs/git-blame.html
.. _this blog post: https://github.com/blog/612-introducing-github-compare-view
diff --git a/doc/source/dev/governance/governance.rst b/doc/source/dev/governance/governance.rst
index 9209f26b7..3ed39c4c1 100644
--- a/doc/source/dev/governance/governance.rst
+++ b/doc/source/dev/governance/governance.rst
@@ -203,7 +203,7 @@ Council membership
~~~~~~~~~~~~~~~~~~
A list of current Steering Council Members is maintained at the
-page :ref:`governance-people`.
+page `About Us <https://numpy.org/about/>`_.
To become eligible to join the Steering Council, an individual must be
a Project Contributor who has produced contributions that are
@@ -307,7 +307,7 @@ its interactions with NumFOCUS.
resting on one person.
The current membership of the NumFOCUS Subcommittee is listed at the
-page :ref:`governance-people`.
+page `About Us <https://numpy.org/about/>`_.
Institutional Partners and Funding
@@ -375,13 +375,13 @@ Institutional Partner benefits are:
- Council Members invited to NumPy Developer Meetings.
A list of current Institutional Partners is maintained at the page
-:ref:`governance-people`.
+`About Us <https://numpy.org/about/>`_.
Document history
================
-https://github.com/numpy/numpy/commits/master/doc/source/dev/governance/governance.rst
+https://github.com/numpy/numpy/commits/main/doc/source/dev/governance/governance.rst
Acknowledgements
================
diff --git a/doc/source/dev/governance/index.rst b/doc/source/dev/governance/index.rst
index 3919e5e66..4dcc3002b 100644
--- a/doc/source/dev/governance/index.rst
+++ b/doc/source/dev/governance/index.rst
@@ -6,4 +6,3 @@ NumPy governance
:maxdepth: 3
governance
- people
diff --git a/doc/source/dev/governance/people.rst b/doc/source/dev/governance/people.rst
deleted file mode 100644
index 18366402e..000000000
--- a/doc/source/dev/governance/people.rst
+++ /dev/null
@@ -1,65 +0,0 @@
-.. _governance-people:
-
-Current steering council and institutional partners
-===================================================
-
-Steering council
-----------------
-
-* Sebastian Berg
-
-* Jaime Fernández del Río
-
-* Ralf Gommers
-
-* Allan Haldane
-
-* Charles Harris
-
-* Stephan Hoyer
-
-* Matti Picus
-
-* Nathaniel Smith
-
-* Julian Taylor
-
-* Pauli Virtanen
-
-* Stéfan van der Walt
-
-* Eric Wieser
-
-
-
-Emeritus members
-----------------
-
-* Travis Oliphant -- project founder / emeritus leader (2005-2012)
-
-* Alex Griffing (2015-2017)
-
-* Marten van Kerkwijk (2017-2019)
-
-
-NumFOCUS Subcommittee
----------------------
-
-* Chuck Harris
-
-* Ralf Gommers
-
-* Jaime Fernández del Río
-
-* Sebastian Berg
-
-* External member: Thomas Caswell
-
-
-Institutional Partners
-----------------------
-
-* UC Berkeley (Stéfan van der Walt, Sebastian Berg, Warren Weckesser, Ross Barnowski)
-
-* Quansight (Ralf Gommers, Hameer Abbasi, Melissa Weber Mendonça, Mars Lee, Matti Picus)
-
diff --git a/doc/source/dev/howto-docs.rst b/doc/source/dev/howto-docs.rst
index 17194bd58..9354357e8 100644
--- a/doc/source/dev/howto-docs.rst
+++ b/doc/source/dev/howto-docs.rst
@@ -7,9 +7,9 @@ How to contribute to the NumPy documentation
This guide will help you decide what to contribute and how to submit it to the
official NumPy documentation.
-******************************************************************************
+***************************
Documentation team meetings
-******************************************************************************
+***************************
The NumPy community has set a firm goal of improving its documentation. We
hold regular documentation meetings on Zoom (dates are announced on the
@@ -21,20 +21,23 @@ Minutes are taken `on hackmd.io <https://hackmd.io/oB_boakvRqKR-_2jRV-Qjg>`__
and stored in the `NumPy Archive repository
<https://github.com/numpy/archive>`__.
-*************************
+*************
What's needed
-*************************
-NumPy docs have the details covered. API reference
-documentation is generated directly from
-`docstrings <https://www.python.org/dev/peps/pep-0257/>`_ in the code
-when the documentation is :ref:`built<howto-build-docs>`.
+*************
-What we lack are docs with broader scope -- tutorials, how-tos, and explanations.
-Reporting defects is another way to contribute. We discuss both.
+The :ref:`NumPy Documentation <numpy_docs_mainpage>` has the details covered.
+API reference documentation is generated directly from
+`docstrings <https://www.python.org/dev/peps/pep-0257/>`_ in the code when the
+documentation is :ref:`built<howto-build-docs>`. Although we have mostly
+complete reference documentation for each function and class exposed to users,
+there is a lack of usage examples for some of them.
-*************************
+What we lack are docs with broader scope -- tutorials, how-tos, and
+explanations. Reporting defects is another way to contribute. We discuss both.
+
+******************
Contributing fixes
-*************************
+******************
We're eager to hear about and fix doc defects. But to attack the biggest
problems we end up having to defer or overlook some bug reports. Here are the
@@ -48,17 +51,21 @@ a `pull request (PR) <https://numpy.org/devdocs/dev/index.html#devindex>`__
with the fix, if you know how to do that; otherwise please `open an issue
<https://github.com/numpy/numpy/issues>`__.
-**Typos and misspellings** fall on a lower rung; we welcome hearing about them but
-may not be able to fix them promptly. These too can be handled as pull
+**Typos and misspellings** fall on a lower rung; we welcome hearing about them
+but may not be able to fix them promptly. These too can be handled as pull
requests or issues.
Obvious **wording** mistakes (like leaving out a "not") fall into the typo
category, but other rewordings -- even for grammar -- require a judgment call,
which raises the bar. Test the waters by first presenting the fix as an issue.
-******************************************************************************
+Some functions/objects like numpy.ndarray.transpose, numpy.array etc. defined in
+C-extension modules have their docstrings defined seperately in `_add_newdocs.py
+<https://github.com/numpy/numpy/blob/main/numpy/core/_add_newdocs.py>`__
+
+**********************
Contributing new pages
-******************************************************************************
+**********************
Your frustrations using our documents are our best guide to what needs fixing.
@@ -74,31 +81,39 @@ If you're looking for subjects, our formal roadmap for documentation is a
*NumPy Enhancement Proposal (NEP)*,
`NEP 44 - Restructuring the NumPy Documentation <https://www.numpy.org/neps/nep-0044-restructuring-numpy-docs>`__.
It identifies areas where our docs need help and lists several
-additions we'd like to see, including Jupyter notebooks.
-
-You can find larger planned and in-progress ideas `at
-our GitHub project <https://github.com/orgs/numpy/projects/2>`__.
+additions we'd like to see, including :ref:`Jupyter notebooks <numpy_tutorials>`.
.. _tutorials_howtos_explanations:
+Documentation framework
+=======================
-Formula writing
-==============================================================================
There are formulas for writing useful documents, and four formulas
cover nearly everything. There are four formulas because there are four
categories of document -- ``tutorial``, ``how-to guide``, ``explanation``,
and ``reference``. The insight that docs divide up this way belongs to
-Daniele Procida, who goes on
-`in this short article <https://documentation.divio.com/>`__ to explain
-the differences and reveal the formulas. When you begin a document or
-propose one, have in mind which of these types it will be.
+Daniele Procida and his `Diátaxis Framework <https://diataxis.fr/>`__. When you
+begin a document or propose one, have in mind which of these types it will be.
+.. _numpy_tutorials:
-.. _contributing:
+NumPy tutorials
+===============
+
+In addition to the documentation that is part of the NumPy source tree, you can
+submit content in Jupyter Notebook format to the
+`NumPy Tutorials <https://numpy.org/numpy-tutorials>`__ page. This
+set of tutorials and educational materials is meant to provide high-quality
+resources by the NumPy project, both for self-learning and for teaching classes
+with. These resources are developed in a separate GitHub repository,
+`numpy-tutorials <https://github.com/numpy/numpy-tutorials>`__, where you can
+check out existing notebooks, open issues to suggest new topics or submit your
+own tutorials as pull requests.
+.. _contributing:
More on contributing
-==============================================================================
+====================
Don't worry if English is not your first language, or if you can only come up
with a rough draft. Open source is a community effort. Do your best -- we'll
@@ -126,9 +141,9 @@ rST, see the `Quick reStructuredText Guide
<http://www.sphinx-doc.org/en/stable/usage/restructuredtext/basics.html>`__
-************************************************************
+***********************
Contributing indirectly
-************************************************************
+***********************
If you run across outside material that would be a useful addition to the
NumPy docs, let us know by `opening an issue <https://github.com/numpy/numpy/issues>`__.
@@ -138,9 +153,9 @@ if you write a tutorial on your blog, create a YouTube video, or answer question
on Stack Overflow and other sites.
-************************************************************
+*********************
Documentation reading
-************************************************************
+*********************
- The leading organization of technical writers,
`Write the Docs <https://www.writethedocs.org/>`__,
diff --git a/doc/source/dev/index.rst b/doc/source/dev/index.rst
index 4641a7e2f..b9347a58c 100644
--- a/doc/source/dev/index.rst
+++ b/doc/source/dev/index.rst
@@ -4,21 +4,6 @@
Contributing to NumPy
#####################
-.. TODO: this is hidden because there's a bug in the pydata theme that won't render TOC items under headers
-
-.. toctree::
- :hidden:
-
- Git Basics <gitwash/index>
- development_environment
- development_workflow
- ../benchmarking
- NumPy C style guide <https://numpy.org/neps/nep-0045-c_style_guide.html>
- releasing
- governance/index
- howto-docs
-
-
Not a coder? Not a problem! NumPy is multi-faceted, and we can use a lot of help.
These are all activities we'd like to get help with (they're all important, so
we list them in alphabetical order):
@@ -77,8 +62,8 @@ Here's the short summary, complete TOC links are below:
* Pull the latest changes from upstream::
- git checkout master
- git pull upstream master
+ git checkout main
+ git pull upstream main
* Create a branch for the feature you want to work on. Since the
branch name will appear in the merge message, use a sensible name
@@ -172,13 +157,13 @@ Here's the short summary, complete TOC links are below:
For a more detailed discussion, read on and follow the links at the bottom of
this page.
-Divergence between ``upstream/master`` and your feature branch
---------------------------------------------------------------
+Divergence between ``upstream/main`` and your feature branch
+------------------------------------------------------------
If GitHub indicates that the branch of your Pull Request can no longer
be merged automatically, you have to incorporate changes that have been made
since you started into your branch. Our recommended way to do this is to
-:ref:`rebase on master<rebasing-on-master>`.
+:ref:`rebase on main <rebasing-on-main>`.
.. _guidelines:
@@ -201,7 +186,7 @@ Stylistic Guidelines
pep-0008/>`_ (remove trailing white space, no tabs, etc.). Check code with
pyflakes / flake8.
-* Use numpy data types instead of strings (``np.uint8`` instead of
+* Use NumPy data types instead of strings (``np.uint8`` instead of
``"uint8"``).
* Use the following import conventions::
@@ -244,42 +229,12 @@ Building docs
-------------
To build docs, run ``make`` from the ``doc`` directory. ``make help`` lists
-all targets. For example, to build the HTML documentation, you can run:
-
-.. code:: sh
+all targets. For example, to build the HTML documentation, you can run::
make html
-Then, all the HTML files will be generated in ``doc/build/html/``.
-Since the documentation is based on docstrings, the appropriate version of
-numpy must be installed in the host python used to run sphinx.
-
-Requirements
-~~~~~~~~~~~~
-
-`Sphinx <http://www.sphinx-doc.org/en/stable/>`__ is needed to build
-the documentation. Matplotlib, SciPy, and IPython are also required.
-
-These additional dependencies for building the documentation are listed in
-``doc_requirements.txt`` and can be conveniently installed with::
-
- pip install -r doc_requirements.txt
-
-The numpy documentation also depends on the
-`numpydoc <https://numpydoc.readthedocs.io/en/latest/>`__ sphinx extension
-as well as an external sphinx theme.
-These extensions are included as git submodules and must be initialized
-before building the docs.
-From the ``doc/`` directory:
-
-.. code:: sh
-
- git submodule update --init
-
-The documentation includes mathematical formulae with LaTeX formatting.
-A working LaTeX document production system
-(e.g. `texlive <https://www.tug.org/texlive/>`__) is required for the
-proper rendering of the LaTeX math in the documentation.
+To get the appropriate dependencies and other requirements,
+see :ref:`howto-build-docs`.
Fixing Warnings
~~~~~~~~~~~~~~~
@@ -301,7 +256,9 @@ The rest of the story
Git Basics <gitwash/index>
development_environment
+ development_gitpod
development_workflow
+ development_advanced_debugging
reviewer_guidelines
../benchmarking
NumPy C style guide <https://numpy.org/neps/nep-0045-c_style_guide.html>
diff --git a/doc/source/dev/releasing.rst b/doc/source/dev/releasing.rst
index 61fa19514..75081aec1 100644
--- a/doc/source/dev/releasing.rst
+++ b/doc/source/dev/releasing.rst
@@ -1,5 +1,5 @@
===================
-Releasing a Version
+Releasing a version
===================
------------------------
diff --git a/doc/source/dev/reviewer_guidelines.rst b/doc/source/dev/reviewer_guidelines.rst
index 0b225b9b6..ffac85f77 100644
--- a/doc/source/dev/reviewer_guidelines.rst
+++ b/doc/source/dev/reviewer_guidelines.rst
@@ -37,9 +37,8 @@ Communication Guidelines
style or grammar, consider merging the current PR when all important concerns
are addressed. Then, either push a commit directly (if you are a maintainer)
or open a follow-up PR yourself.
-- If you need help writing replies in reviews, check out some `Standard replies
- for reviewing
- <https://scikit-learn.org/stable/developers/tips.html#saved-replies>`_.
+- If you need help writing replies in reviews, check out some
+ :ref:`standard replies for reviewing<saved-replies>`.
Reviewer Checklist
==================
@@ -74,8 +73,8 @@ For maintainers
- Make sure all automated CI tests pass before merging a PR, and that the
:ref:`documentation builds <building-docs>` without any errors.
-- In case of merge conflicts, ask the PR submitter to :ref:`rebase on master
- <rebasing-on-master>`.
+- In case of merge conflicts, ask the PR submitter to :ref:`rebase on main
+ <rebasing-on-main>`.
- For PRs that add new features or are in some way complex, wait at least a day
or two before merging it. That way, others get a chance to comment before the
code goes in. Consider adding it to the release notes.
@@ -116,4 +115,67 @@ the PR page.
Assuming you have your :ref:`development environment<development-environment>`
set up, you can now build the code and test it.
+.. _saved-replies:
+
+Standard replies for reviewing
+==============================
+
+It may be helpful to store some of these in GitHub's `saved
+replies <https://github.com/settings/replies/>`_ for reviewing:
+
+**Usage question**
+ .. code-block:: md
+
+ You are asking a usage question. The issue tracker is for bugs and new features.
+ I'm going to close this issue, feel free to ask for help via our [help channels](https://numpy.org/gethelp/).
+
+**You’re welcome to update the docs**
+ .. code-block:: md
+
+ Please feel free to offer a pull request updating the documentation if you feel it could be improved.
+
+**Self-contained example for bug**
+ .. code-block:: md
+
+ Please provide a [self-contained example code](https://stackoverflow.com/help/mcve), including imports and data (if possible), so that other contributors can just run it and reproduce your issue.
+ Ideally your example code should be minimal.
+
+**Software versions**
+ .. code-block:: md
+
+ To help diagnose your issue, please paste the output of:
+ ```
+ python -c 'import numpy; print(numpy.version.version)'
+ ```
+ Thanks.
+
+**Code blocks**
+ .. code-block:: md
+
+ Readability can be greatly improved if you [format](https://help.github.com/articles/creating-and-highlighting-code-blocks/) your code snippets and complete error messages appropriately.
+ You can edit your issue descriptions and comments at any time to improve readability.
+ This helps maintainers a lot. Thanks!
+
+**Linking to code**
+ .. code-block:: md
+
+ For clarity's sake, you can link to code like [this](https://help.github.com/articles/creating-a-permanent-link-to-a-code-snippet/).
+
+**Better description and title**
+ .. code-block:: md
+
+ Please make the title of the PR more descriptive.
+ The title will become the commit message when this is merged.
+ You should state what issue (or PR) it fixes/resolves in the description using the syntax described [here](https://docs.github.com/en/github/managing-your-work-on-github/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword).
+
+**Regression test needed**
+ .. code-block:: md
+
+ Please add a [non-regression test](https://en.wikipedia.org/wiki/Non-regression_testing) that would fail at main but pass in this PR.
+
+**Don’t change unrelated**
+ .. code-block:: md
+
+ Please do not change unrelated lines. It makes your contribution harder to review and may introduce merge conflicts to other pull requests.
+
.. include:: gitwash/git_links.inc
diff --git a/doc/source/docs/howto_build_docs.rst b/doc/source/docs/howto_build_docs.rst
index 29912a5af..884cf7935 100644
--- a/doc/source/docs/howto_build_docs.rst
+++ b/doc/source/docs/howto_build_docs.rst
@@ -4,9 +4,6 @@
Building the NumPy API and reference docs
=========================================
-We currently use Sphinx_ for generating the API and reference
-documentation for NumPy. You will need Sphinx >= 2.2.0.
-
If you only want to get the documentation, note that pre-built
versions can be found at
@@ -14,59 +11,104 @@ versions can be found at
in several different formats.
-.. _Sphinx: http://www.sphinx-doc.org/
+Development environments
+------------------------
+Before proceeding further it should be noted that the documentation is built with the ``make`` tool,
+which is not natively available on Windows. MacOS or Linux users can jump
+to :ref:`how-todoc.prerequisites`. It is recommended for Windows users to set up their development
+environment on :ref:`Gitpod <development-gitpod>` or `Windows Subsystem
+for Linux (WSL) <https://docs.microsoft.com/en-us/windows/wsl/install-win10>`_. WSL is a good option
+for a persistent local set-up.
-Instructions
-------------
+Gitpod
+^^^^^^
+Gitpod is an open-source platform that automatically creates the correct development environment right
+in your browser, reducing the need to install local development environments and deal with
+incompatible dependencies.
-If you obtained NumPy via git, get also the git submodules that contain
-additional parts required for building the documentation::
+If you have good internet connectivity and want a temporary set-up,
+it is often faster to build with Gitpod. Here are the in-depth instructions for
+:ref:`building NumPy with Gitpod <development-gitpod>`.
- git submodule update --init
-In addition, building the documentation requires the Sphinx extension
-`plot_directive`, which is shipped with Matplotlib_. This Sphinx extension can
-be installed by installing Matplotlib. You will also need Python>=3.6.
+.. _how-todoc.prerequisites:
-Since large parts of the main documentation are obtained from numpy via
-``import numpy`` and examining the docstrings, you will need to first build
-NumPy, and install it so that the correct version is imported.
+Prerequisites
+-------------
-After NumPy is installed, install SciPy since some of the plots in the random
-module require `scipy.special` to display properly.
+Building the NumPy documentation and API reference requires the following:
-Note that you can eg. install NumPy to a temporary location and set
+NumPy
+^^^^^
+
+Since large parts of the main documentation are obtained from NumPy via
+``import numpy`` and examining the docstrings, you will need to first
+:ref:`build <building-from-source>` and install it so that the correct version is imported.
+NumPy has to be re-built and re-installed every time you fetch the latest version of the
+repository, before generating the documentation. This ensures that the NumPy version and
+the git repository version are in sync.
+
+Note that you can e.g. install NumPy to a temporary location and set
the PYTHONPATH environment variable appropriately.
Alternatively, if using Python virtual environments (via e.g. ``conda``,
-``virtualenv`` or the ``venv`` module), installing numpy into a
+``virtualenv`` or the ``venv`` module), installing NumPy into a
new virtual environment is recommended.
+
+Dependencies
+^^^^^^^^^^^^
+
All of the necessary dependencies for building the NumPy docs can be installed
with::
pip install -r doc_requirements.txt
+We currently use Sphinx_ for generating the API and reference
+documentation for NumPy. In addition, building the documentation requires
+the Sphinx extension `plot_directive`, which is shipped with
+:doc:`Matplotlib <matplotlib:index>`. We also use numpydoc_ to render docstrings in
+the generated API documentation. :doc:`SciPy <scipy:index>`
+is installed since some parts of the documentation require SciPy functions.
+
+Submodules
+^^^^^^^^^^
+
+If you obtained NumPy via git, also get the git submodules that contain
+additional parts required for building the documentation::
+
+ git submodule update --init
+
+.. _Sphinx: http://www.sphinx-doc.org/
+.. _numpydoc: https://numpydoc.readthedocs.io/en/latest/index.html
+
+Instructions
+------------
+
Now you are ready to generate the docs, so write::
+ cd doc
make html
-in the ``doc/`` directory. If all goes well, this will generate a
-``build/html`` subdirectory containing the built documentation. If you get
-a message about ``installed numpy != current repo git version``, you must
+If all goes well, this will generate a
+``build/html`` subdirectory in the ``/doc`` directory, containing the built documentation. If
+you get a message about ``installed numpy != current repo git version``, you must
either override the check by setting ``GITVER`` or re-install NumPy.
-Note that building the documentation on Windows is currently not actively
-supported, though it should be possible. (See Sphinx_ documentation
-for more information.)
+If you have built NumPy into a virtual environment and get an error
+that says ``numpy not found, cannot build documentation without...``,
+you need to override the makefile ``PYTHON`` variable at the command
+line, so instead of writing ``make html`` write::
+
+ make PYTHON=python html
To build the PDF documentation, do instead::
make latex
make -C build/latex all-pdf
-You will need to have Latex installed for this, inclusive of support for
+You will need to have LaTeX_ installed for this, inclusive of support for
Greek letters. For example, on Ubuntu xenial ``texlive-lang-greek`` and
-``cm-super`` are needed. Also ``latexmk`` is needed on non-Windows systems.
+``cm-super`` are needed. Also, ``latexmk`` is needed on non-Windows systems.
Instead of the above, you can also do::
@@ -80,18 +122,5 @@ The documentation for NumPy distributed at https://numpy.org/doc in html and
pdf format is also built with ``make dist``. See `HOWTO RELEASE`_ for details
on how to update https://numpy.org/doc.
-.. _Matplotlib: https://matplotlib.org/
-.. _HOWTO RELEASE: https://github.com/numpy/numpy/blob/master/doc/HOWTO_RELEASE.rst.txt
-
-Sphinx extensions
------------------
-
-NumPy's documentation uses several custom extensions to Sphinx. These
-are shipped in the ``sphinxext/`` directory (as git submodules, as discussed
-above), and are automatically enabled when building NumPy's documentation.
-
-If you want to make use of these extensions in third-party
-projects, they are available on PyPi_ as the numpydoc_ package.
-
-.. _PyPi: https://pypi.org/
-.. _numpydoc: https://python.org/pypi/numpydoc
+.. _LaTeX: https://www.latex-project.org/
+.. _HOWTO RELEASE: https://github.com/numpy/numpy/blob/main/doc/HOWTO_RELEASE.rst.txt
diff --git a/doc/source/glossary.rst b/doc/source/glossary.rst
index 57e3bcf92..aa2dc13df 100644
--- a/doc/source/glossary.rst
+++ b/doc/source/glossary.rst
@@ -166,9 +166,10 @@ Glossary
array scalar
- For uniformity in handling operands, NumPy treats
- a :doc:`scalar <reference/arrays.scalars>` as an array of zero
- dimension.
+ An :doc:`array scalar <reference/arrays.scalars>` is an instance of the types/classes float32, float64,
+ etc.. For uniformity in handling operands, NumPy treats a scalar as
+ an array of zero dimension. In contrast, a 0-dimensional array is an :doc:`ndarray <reference/arrays.ndarray>` instance
+ containing precisely one value.
axis
diff --git a/doc/source/contents.rst b/doc/source/index.rst
index 5d4e12097..21dec00fe 100644
--- a/doc/source/contents.rst
+++ b/doc/source/index.rst
@@ -6,6 +6,7 @@ NumPy Documentation
.. toctree::
:maxdepth: 1
+ :hidden:
User Guide <user/index>
API reference <reference/index>
diff --git a/doc/source/reference/arrays.classes.rst b/doc/source/reference/arrays.classes.rst
index 3a4ed2168..92c271f6b 100644
--- a/doc/source/reference/arrays.classes.rst
+++ b/doc/source/reference/arrays.classes.rst
@@ -330,6 +330,8 @@ NumPy provides several hooks that classes can customize:
returned by :func:`__array__`. This practice will return ``TypeError``.
+.. _matrix-objects:
+
Matrix objects
==============
diff --git a/doc/source/reference/arrays.datetime.rst b/doc/source/reference/arrays.datetime.rst
index c5947620e..e3b8d270d 100644
--- a/doc/source/reference/arrays.datetime.rst
+++ b/doc/source/reference/arrays.datetime.rst
@@ -13,16 +13,15 @@ support datetime functionality. The data type is called "datetime64",
so named because "datetime" is already taken by the datetime library
included in Python.
-.. note:: The datetime API is *experimental* in 1.7.0, and may undergo changes
- in future versions of NumPy.
Basic Datetimes
===============
-The most basic way to create datetimes is from strings in
-ISO 8601 date or datetime format. The unit for internal storage
-is automatically selected from the form of the string, and can
-be either a :ref:`date unit <arrays.dtypes.dateunits>` or a
+The most basic way to create datetimes is from strings in ISO 8601 date
+or datetime format. It is also possible to create datetimes from an integer by
+offset relative to the Unix epoch (00:00:00 UTC on 1 January 1970).
+The unit for internal storage is automatically selected from the
+form of the string, and can be either a :ref:`date unit <arrays.dtypes.dateunits>` or a
:ref:`time unit <arrays.dtypes.timeunits>`. The date units are years ('Y'),
months ('M'), weeks ('W'), and days ('D'), while the time units are
hours ('h'), minutes ('m'), seconds ('s'), milliseconds ('ms'), and
@@ -36,6 +35,11 @@ letters, for a "Not A Time" value.
>>> np.datetime64('2005-02-25')
numpy.datetime64('2005-02-25')
+
+ From an integer and a date unit, 1 year since the UNIX epoch:
+
+ >>> np.datetime64(1, 'Y')
+ numpy.datetime64('1971')
Using months for the unit:
diff --git a/doc/source/reference/arrays.ndarray.rst b/doc/source/reference/arrays.ndarray.rst
index 191367058..f2204752d 100644
--- a/doc/source/reference/arrays.ndarray.rst
+++ b/doc/source/reference/arrays.ndarray.rst
@@ -567,10 +567,8 @@ Matrix Multiplication:
.. note::
Matrix operators ``@`` and ``@=`` were introduced in Python 3.5
- following PEP465. NumPy 1.10.0 has a preliminary implementation of ``@``
- for testing purposes. Further documentation can be found in the
- :func:`matmul` documentation.
-
+ following :pep:`465`, and the ``@`` operator has been introduced in NumPy
+ 1.10.0. Further information can be found in the :func:`matmul` documentation.
Special methods
===============
diff --git a/doc/source/reference/arrays.scalars.rst b/doc/source/reference/arrays.scalars.rst
index 4b5da2e13..abef66692 100644
--- a/doc/source/reference/arrays.scalars.rst
+++ b/doc/source/reference/arrays.scalars.rst
@@ -94,112 +94,180 @@ Python Boolean scalar.
.. tip:: The default data type in NumPy is :class:`float_`.
.. autoclass:: numpy.generic
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.number
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
Integer types
~~~~~~~~~~~~~
.. autoclass:: numpy.integer
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
+
+.. note::
+
+ The numpy integer types mirror the behavior of C integers, and can therefore
+ be subject to :ref:`overflow-errors`.
Signed integer types
++++++++++++++++++++
.. autoclass:: numpy.signedinteger
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.byte
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.short
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.intc
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.int_
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.longlong
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
Unsigned integer types
++++++++++++++++++++++
.. autoclass:: numpy.unsignedinteger
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.ubyte
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.ushort
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.uintc
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.uint
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.ulonglong
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
Inexact types
~~~~~~~~~~~~~
.. autoclass:: numpy.inexact
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
+
+.. note::
+
+ Inexact scalars are printed using the fewest decimal digits needed to
+ distinguish their value from other values of the same datatype,
+ by judicious rounding. See the ``unique`` parameter of
+ `format_float_positional` and `format_float_scientific`.
+
+ This means that variables with equal binary values but whose datatypes are of
+ different precisions may display differently::
+
+ >>> f16 = np.float16("0.1")
+ >>> f32 = np.float32(f16)
+ >>> f64 = np.float64(f32)
+ >>> f16 == f32 == f64
+ True
+ >>> f16, f32, f64
+ (0.1, 0.099975586, 0.0999755859375)
+
+ Note that none of these floats hold the exact value :math:`\frac{1}{10}`;
+ ``f16`` prints as ``0.1`` because it is as close to that value as possible,
+ whereas the other types do not as they have more precision and therefore have
+ closer values.
+
+ Conversely, floating-point scalars of different precisions which approximate
+ the same decimal value may compare unequal despite printing identically:
+
+ >>> f16 = np.float16("0.1")
+ >>> f32 = np.float32("0.1")
+ >>> f64 = np.float64("0.1")
+ >>> f16 == f32 == f64
+ False
+ >>> f16, f32, f64
+ (0.1, 0.1, 0.1)
Floating-point types
++++++++++++++++++++
.. autoclass:: numpy.floating
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.half
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.single
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.double
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.longdouble
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
Complex floating-point types
++++++++++++++++++++++++++++
.. autoclass:: numpy.complexfloating
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.csingle
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.cdouble
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.clongdouble
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
Other types
~~~~~~~~~~~
.. autoclass:: numpy.bool_
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.datetime64
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.timedelta64
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.object_
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. note::
@@ -222,16 +290,20 @@ arrays. (In the character codes ``#`` is an integer denoting how many
elements the data type consists of.)
.. autoclass:: numpy.flexible
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.bytes_
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.str_
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. autoclass:: numpy.void
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
.. warning::
@@ -246,6 +318,8 @@ elements the data type consists of.)
convention more consistent with other Python modules such as the
:mod:`struct` module.
+.. _sized-aliases:
+
Sized aliases
~~~~~~~~~~~~~
@@ -278,8 +352,8 @@ are also provided.
uint32
uint64
- Alias for the unsigned integer types (one of `numpy.byte`, `numpy.short`,
- `numpy.intc`, `numpy.int_` and `numpy.longlong`) with the specified number
+ Alias for the unsigned integer types (one of `numpy.ubyte`, `numpy.ushort`,
+ `numpy.uintc`, `numpy.uint` and `numpy.ulonglong`) with the specified number
of bits.
Compatible with the C99 ``uint8_t``, ``uint16_t``, ``uint32_t``, and
@@ -297,8 +371,8 @@ are also provided.
.. attribute:: uintp
- Alias for the unsigned integer type (one of `numpy.byte`, `numpy.short`,
- `numpy.intc`, `numpy.int_` and `np.longlong`) that is the same size as a
+ Alias for the unsigned integer type (one of `numpy.ubyte`, `numpy.ushort`,
+ `numpy.uintc`, `numpy.uint` and `np.ulonglong`) that is the same size as a
pointer.
Compatible with the C ``uintptr_t``.
diff --git a/doc/source/reference/c-api/array.rst b/doc/source/reference/c-api/array.rst
index 3aa541b79..26a8f643d 100644
--- a/doc/source/reference/c-api/array.rst
+++ b/doc/source/reference/c-api/array.rst
@@ -22,8 +22,8 @@ Array structure and data access
These macros access the :c:type:`PyArrayObject` structure members and are
defined in ``ndarraytypes.h``. The input argument, *arr*, can be any
-:c:type:`PyObject *<PyObject>` that is directly interpretable as a
-:c:type:`PyArrayObject *` (any instance of the :c:data:`PyArray_Type`
+:c:expr:`PyObject *` that is directly interpretable as a
+:c:expr:`PyArrayObject *` (any instance of the :c:data:`PyArray_Type`
and its sub-types).
.. c:function:: int PyArray_NDIM(PyArrayObject *arr)
@@ -151,6 +151,16 @@ and its sub-types).
`numpy.ndarray.item` is identical to PyArray_GETITEM.
+.. c:function:: int PyArray_FinalizeFunc(PyArrayObject* arr, PyObject* obj)
+
+ The function pointed to by the CObject
+ :obj:`~numpy.class.__array_finalize__`.
+ The first argument is the newly created sub-type. The second argument
+ (if not NULL) is the "parent" array (if the array was created using
+ slicing or some other operation where a clearly-distinguishable parent
+ is present). This routine can do anything it wants to. It should
+ return a -1 on error and 0 otherwise.
+
Data access
^^^^^^^^^^^
@@ -825,7 +835,7 @@ General check of Python Type
Evaluates true if *op* is an instance of (a subclass of)
:c:data:`PyArray_Type` and has 0 dimensions.
-.. c:function:: PyArray_IsScalar(op, cls)
+.. c:macro:: PyArray_IsScalar(op, cls)
Evaluates true if *op* is an instance of ``Py{cls}ArrType_Type``.
@@ -864,8 +874,8 @@ Data-type checking
For the typenum macros, the argument is an integer representing an
enumerated array data type. For the array type checking macros the
-argument must be a :c:type:`PyObject *<PyObject>` that can be directly interpreted as a
-:c:type:`PyArrayObject *`.
+argument must be a :c:expr:`PyObject *` that can be directly interpreted as a
+:c:expr:`PyArrayObject *`.
.. c:function:: int PyTypeNum_ISUNSIGNED(int num)
@@ -1022,7 +1032,7 @@ argument must be a :c:type:`PyObject *<PyObject>` that can be directly interpret
.. c:function:: int PyArray_EquivByteorders(int b1, int b2)
- True if byteorder characters ( :c:data:`NPY_LITTLE`,
+ True if byteorder characters *b1* and *b2* ( :c:data:`NPY_LITTLE`,
:c:data:`NPY_BIG`, :c:data:`NPY_NATIVE`, :c:data:`NPY_IGNORE` ) are
either equal or equivalent as to their specification of a native
byte order. Thus, on a little-endian machine :c:data:`NPY_LITTLE`
@@ -1250,8 +1260,8 @@ Converting data types
function returns :c:data:`NPY_FALSE`.
-New data types
-^^^^^^^^^^^^^^
+User-defined data types
+^^^^^^^^^^^^^^^^^^^^^^^
.. c:function:: void PyArray_InitArrFuncs(PyArray_ArrFuncs* f)
@@ -1295,6 +1305,13 @@ New data types
*descr* can be cast safely to a data-type whose type_number is
*totype*.
+.. c:function:: int PyArray_TypeNumFromName( \
+ char const *str)
+
+ Given a string return the type-number for the data-type with that string as
+ the type-object name.
+ Returns ``NPY_NOTYPE`` without setting an error if no type can be found.
+ Only works for user-defined data-types.
Special functions for NPY_OBJECT
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -2647,6 +2664,12 @@ cost of a slight overhead.
- If the position of iter is changed, any subsequent call to
PyArrayNeighborhoodIter_Next is undefined behavior, and
PyArrayNeighborhoodIter_Reset must be called.
+ - If the position of iter is not the beginning of the data and the
+ underlying data for iter is contiguous, the iterator will point to the
+ start of the data instead of position pointed by iter.
+ To avoid this situation, iter should be moved to the required position
+ only after the creation of iterator, and PyArrayNeighborhoodIter_Reset
+ must be called.
.. code-block:: c
@@ -2656,7 +2679,7 @@ cost of a slight overhead.
/*For a 3x3 kernel */
bounds = {-1, 1, -1, 1};
- neigh_iter = (PyArrayNeighborhoodIterObject*)PyArrayNeighborhoodIter_New(
+ neigh_iter = (PyArrayNeighborhoodIterObject*)PyArray_NeighborhoodIterNew(
iter, bounds, NPY_NEIGHBORHOOD_ITER_ZERO_PADDING, NULL);
for(i = 0; i < iter->size; ++i) {
@@ -2781,14 +2804,14 @@ Data-type descriptors
Data-type objects must be reference counted so be aware of the
action on the data-type reference of different C-API calls. The
standard rule is that when a data-type object is returned it is a
- new reference. Functions that take :c:type:`PyArray_Descr *` objects and
+ new reference. Functions that take :c:expr:`PyArray_Descr *` objects and
return arrays steal references to the data-type their inputs
unless otherwise noted. Therefore, you must own a reference to any
data-type object used as input to such a function.
.. c:function:: int PyArray_DescrCheck(PyObject* obj)
- Evaluates as true if *obj* is a data-type object ( :c:type:`PyArray_Descr *` ).
+ Evaluates as true if *obj* is a data-type object ( :c:expr:`PyArray_Descr *` ).
.. c:function:: PyArray_Descr* PyArray_DescrNew(PyArray_Descr* obj)
@@ -2815,12 +2838,14 @@ Data-type descriptors
(recursively).
The value of *newendian* is one of these macros:
+..
+ dedent the enumeration of flags to avoid missing references sphinx warnings
- .. c:macro:: NPY_IGNORE
- NPY_SWAP
- NPY_NATIVE
- NPY_LITTLE
- NPY_BIG
+.. c:macro:: NPY_IGNORE
+ NPY_SWAP
+ NPY_NATIVE
+ NPY_LITTLE
+ NPY_BIG
If a byteorder of :c:data:`NPY_IGNORE` is encountered it
is left alone. If newendian is :c:data:`NPY_SWAP`, then all byte-orders
@@ -3485,10 +3510,6 @@ Miscellaneous Macros
Evaluates as True if arrays *a1* and *a2* have the same shape.
-.. c:var:: a
-
-.. c:var:: b
-
.. c:macro:: PyArray_MAX(a,b)
Returns the maximum of *a* and *b*. If (*a*) or (*b*) are
@@ -3547,22 +3568,22 @@ Miscellaneous Macros
Enumerated Types
^^^^^^^^^^^^^^^^
-.. c:type:: NPY_SORTKIND
+.. c:enum:: NPY_SORTKIND
A special variable-type which can take on different values to indicate
the sorting algorithm being used.
- .. c:var:: NPY_QUICKSORT
+ .. c:enumerator:: NPY_QUICKSORT
- .. c:var:: NPY_HEAPSORT
+ .. c:enumerator:: NPY_HEAPSORT
- .. c:var:: NPY_MERGESORT
+ .. c:enumerator:: NPY_MERGESORT
- .. c:var:: NPY_STABLESORT
+ .. c:enumerator:: NPY_STABLESORT
Used as an alias of :c:data:`NPY_MERGESORT` and vica versa.
- .. c:var:: NPY_NSORTS
+ .. c:enumerator:: NPY_NSORTS
Defined to be the number of sorts. It is fixed at three by the need for
backwards compatibility, and consequently :c:data:`NPY_MERGESORT` and
@@ -3570,90 +3591,90 @@ Enumerated Types
of several stable sorting algorithms depending on the data type.
-.. c:type:: NPY_SCALARKIND
+.. c:enum:: NPY_SCALARKIND
A special variable type indicating the number of "kinds" of
scalars distinguished in determining scalar-coercion rules. This
variable can take on the values:
- .. c:var:: NPY_NOSCALAR
+ .. c:enumerator:: NPY_NOSCALAR
- .. c:var:: NPY_BOOL_SCALAR
+ .. c:enumerator:: NPY_BOOL_SCALAR
- .. c:var:: NPY_INTPOS_SCALAR
+ .. c:enumerator:: NPY_INTPOS_SCALAR
- .. c:var:: NPY_INTNEG_SCALAR
+ .. c:enumerator:: NPY_INTNEG_SCALAR
- .. c:var:: NPY_FLOAT_SCALAR
+ .. c:enumerator:: NPY_FLOAT_SCALAR
- .. c:var:: NPY_COMPLEX_SCALAR
+ .. c:enumerator:: NPY_COMPLEX_SCALAR
- .. c:var:: NPY_OBJECT_SCALAR
+ .. c:enumerator:: NPY_OBJECT_SCALAR
- .. c:var:: NPY_NSCALARKINDS
+ .. c:enumerator:: NPY_NSCALARKINDS
Defined to be the number of scalar kinds
(not including :c:data:`NPY_NOSCALAR`).
-.. c:type:: NPY_ORDER
+.. c:enum:: NPY_ORDER
An enumeration type indicating the element order that an array should be
interpreted in. When a brand new array is created, generally
only **NPY_CORDER** and **NPY_FORTRANORDER** are used, whereas
when one or more inputs are provided, the order can be based on them.
- .. c:var:: NPY_ANYORDER
+ .. c:enumerator:: NPY_ANYORDER
Fortran order if all the inputs are Fortran, C otherwise.
- .. c:var:: NPY_CORDER
+ .. c:enumerator:: NPY_CORDER
C order.
- .. c:var:: NPY_FORTRANORDER
+ .. c:enumerator:: NPY_FORTRANORDER
Fortran order.
- .. c:var:: NPY_KEEPORDER
+ .. c:enumerator:: NPY_KEEPORDER
An order as close to the order of the inputs as possible, even
if the input is in neither C nor Fortran order.
-.. c:type:: NPY_CLIPMODE
+.. c:enum:: NPY_CLIPMODE
A variable type indicating the kind of clipping that should be
applied in certain functions.
- .. c:var:: NPY_RAISE
+ .. c:enumerator:: NPY_RAISE
The default for most operations, raises an exception if an index
is out of bounds.
- .. c:var:: NPY_CLIP
+ .. c:enumerator:: NPY_CLIP
Clips an index to the valid range if it is out of bounds.
- .. c:var:: NPY_WRAP
+ .. c:enumerator:: NPY_WRAP
Wraps an index to the valid range if it is out of bounds.
-.. c:type:: NPY_SEARCHSIDE
+.. c:enum:: NPY_SEARCHSIDE
A variable type indicating whether the index returned should be that of
the first suitable location (if :c:data:`NPY_SEARCHLEFT`) or of the last
(if :c:data:`NPY_SEARCHRIGHT`).
- .. c:var:: NPY_SEARCHLEFT
+ .. c:enumerator:: NPY_SEARCHLEFT
- .. c:var:: NPY_SEARCHRIGHT
+ .. c:enumerator:: NPY_SEARCHRIGHT
-.. c:type:: NPY_SELECTKIND
+.. c:enum:: NPY_SELECTKIND
A variable type indicating the selection algorithm being used.
- .. c:var:: NPY_INTROSELECT
+ .. c:enumerator:: NPY_INTROSELECT
-.. c:type:: NPY_CASTING
+.. c:enum:: NPY_CASTING
.. versionadded:: 1.6
@@ -3661,25 +3682,25 @@ Enumerated Types
be. This is used by the iterator added in NumPy 1.6, and is intended
to be used more broadly in a future version.
- .. c:var:: NPY_NO_CASTING
+ .. c:enumerator:: NPY_NO_CASTING
Only allow identical types.
- .. c:var:: NPY_EQUIV_CASTING
+ .. c:enumerator:: NPY_EQUIV_CASTING
Allow identical and casts involving byte swapping.
- .. c:var:: NPY_SAFE_CASTING
+ .. c:enumerator:: NPY_SAFE_CASTING
Only allow casts which will not cause values to be rounded,
truncated, or otherwise changed.
- .. c:var:: NPY_SAME_KIND_CASTING
+ .. c:enumerator:: NPY_SAME_KIND_CASTING
Allow any safe casts, and casts between types of the same kind.
For example, float64 -> float32 is permitted with this rule.
- .. c:var:: NPY_UNSAFE_CASTING
+ .. c:enumerator:: NPY_UNSAFE_CASTING
Allow any cast, no matter what kind of data loss may occur.
diff --git a/doc/source/reference/c-api/coremath.rst b/doc/source/reference/c-api/coremath.rst
index 338c584a1..e129fdd77 100644
--- a/doc/source/reference/c-api/coremath.rst
+++ b/doc/source/reference/c-api/coremath.rst
@@ -46,30 +46,30 @@ Floating point classification
corresponding single and extension precision macro are available with the
suffix F and L.
-.. c:function:: int npy_isnan(x)
+.. c:macro:: npy_isnan(x)
This is a macro, and is equivalent to C99 isnan: works for single, double
- and extended precision, and return a non 0 value is x is a NaN.
+ and extended precision, and return a non 0 value if x is a NaN.
-.. c:function:: int npy_isfinite(x)
+.. c:macro:: npy_isfinite(x)
This is a macro, and is equivalent to C99 isfinite: works for single,
- double and extended precision, and return a non 0 value is x is neither a
+ double and extended precision, and return a non 0 value if x is neither a
NaN nor an infinity.
-.. c:function:: int npy_isinf(x)
+.. c:macro:: npy_isinf(x)
This is a macro, and is equivalent to C99 isinf: works for single, double
- and extended precision, and return a non 0 value is x is infinite (positive
+ and extended precision, and return a non 0 value if x is infinite (positive
and negative).
-.. c:function:: int npy_signbit(x)
+.. c:macro:: npy_signbit(x)
This is a macro, and is equivalent to C99 signbit: works for single, double
- and extended precision, and return a non 0 value is x has the signbit set
+ and extended precision, and return a non 0 value if x has the signbit set
(that is the number is negative).
-.. c:function:: double npy_copysign(double x, double y)
+.. c:macro:: npy_copysign(x, y)
This is a function equivalent to C99 copysign: return x with the same sign
as y. Works for any value, including inf and nan. Single and extended
diff --git a/doc/source/reference/c-api/dtype.rst b/doc/source/reference/c-api/dtype.rst
index a1a53cdb6..382e45dc0 100644
--- a/doc/source/reference/c-api/dtype.rst
+++ b/doc/source/reference/c-api/dtype.rst
@@ -25,157 +25,157 @@ select the precision desired.
Enumerated Types
----------------
-.. c:var:: NPY_TYPES
+.. c:enumerator:: NPY_TYPES
There is a list of enumerated types defined providing the basic 24
data types plus some useful generic names. Whenever the code requires
a type number, one of these enumerated types is requested. The types
are all called ``NPY_{NAME}``:
-.. c:var:: NPY_BOOL
+.. c:enumerator:: NPY_BOOL
The enumeration value for the boolean type, stored as one byte.
It may only be set to the values 0 and 1.
-.. c:var:: NPY_BYTE
-.. c:var:: NPY_INT8
+.. c:enumerator:: NPY_BYTE
+.. c:enumerator:: NPY_INT8
The enumeration value for an 8-bit/1-byte signed integer.
-.. c:var:: NPY_SHORT
-.. c:var:: NPY_INT16
+.. c:enumerator:: NPY_SHORT
+.. c:enumerator:: NPY_INT16
The enumeration value for a 16-bit/2-byte signed integer.
-.. c:var:: NPY_INT
-.. c:var:: NPY_INT32
+.. c:enumerator:: NPY_INT
+.. c:enumerator:: NPY_INT32
The enumeration value for a 32-bit/4-byte signed integer.
-.. c:var:: NPY_LONG
+.. c:enumerator:: NPY_LONG
Equivalent to either NPY_INT or NPY_LONGLONG, depending on the
platform.
-.. c:var:: NPY_LONGLONG
-.. c:var:: NPY_INT64
+.. c:enumerator:: NPY_LONGLONG
+.. c:enumerator:: NPY_INT64
The enumeration value for a 64-bit/8-byte signed integer.
-.. c:var:: NPY_UBYTE
-.. c:var:: NPY_UINT8
+.. c:enumerator:: NPY_UBYTE
+.. c:enumerator:: NPY_UINT8
The enumeration value for an 8-bit/1-byte unsigned integer.
-.. c:var:: NPY_USHORT
-.. c:var:: NPY_UINT16
+.. c:enumerator:: NPY_USHORT
+.. c:enumerator:: NPY_UINT16
The enumeration value for a 16-bit/2-byte unsigned integer.
-.. c:var:: NPY_UINT
-.. c:var:: NPY_UINT32
+.. c:enumerator:: NPY_UINT
+.. c:enumerator:: NPY_UINT32
The enumeration value for a 32-bit/4-byte unsigned integer.
-.. c:var:: NPY_ULONG
+.. c:enumerator:: NPY_ULONG
Equivalent to either NPY_UINT or NPY_ULONGLONG, depending on the
platform.
-.. c:var:: NPY_ULONGLONG
-.. c:var:: NPY_UINT64
+.. c:enumerator:: NPY_ULONGLONG
+.. c:enumerator:: NPY_UINT64
The enumeration value for a 64-bit/8-byte unsigned integer.
-.. c:var:: NPY_HALF
-.. c:var:: NPY_FLOAT16
+.. c:enumerator:: NPY_HALF
+.. c:enumerator:: NPY_FLOAT16
The enumeration value for a 16-bit/2-byte IEEE 754-2008 compatible floating
point type.
-.. c:var:: NPY_FLOAT
-.. c:var:: NPY_FLOAT32
+.. c:enumerator:: NPY_FLOAT
+.. c:enumerator:: NPY_FLOAT32
The enumeration value for a 32-bit/4-byte IEEE 754 compatible floating
point type.
-.. c:var:: NPY_DOUBLE
-.. c:var:: NPY_FLOAT64
+.. c:enumerator:: NPY_DOUBLE
+.. c:enumerator:: NPY_FLOAT64
The enumeration value for a 64-bit/8-byte IEEE 754 compatible floating
point type.
-.. c:var:: NPY_LONGDOUBLE
+.. c:enumerator:: NPY_LONGDOUBLE
The enumeration value for a platform-specific floating point type which is
at least as large as NPY_DOUBLE, but larger on many platforms.
-.. c:var:: NPY_CFLOAT
-.. c:var:: NPY_COMPLEX64
+.. c:enumerator:: NPY_CFLOAT
+.. c:enumerator:: NPY_COMPLEX64
The enumeration value for a 64-bit/8-byte complex type made up of
two NPY_FLOAT values.
-.. c:var:: NPY_CDOUBLE
-.. c:var:: NPY_COMPLEX128
+.. c:enumerator:: NPY_CDOUBLE
+.. c:enumerator:: NPY_COMPLEX128
The enumeration value for a 128-bit/16-byte complex type made up of
two NPY_DOUBLE values.
-.. c:var:: NPY_CLONGDOUBLE
+.. c:enumerator:: NPY_CLONGDOUBLE
The enumeration value for a platform-specific complex floating point
type which is made up of two NPY_LONGDOUBLE values.
-.. c:var:: NPY_DATETIME
+.. c:enumerator:: NPY_DATETIME
The enumeration value for a data type which holds dates or datetimes with
a precision based on selectable date or time units.
-.. c:var:: NPY_TIMEDELTA
+.. c:enumerator:: NPY_TIMEDELTA
The enumeration value for a data type which holds lengths of times in
integers of selectable date or time units.
-.. c:var:: NPY_STRING
+.. c:enumerator:: NPY_STRING
The enumeration value for ASCII strings of a selectable size. The
strings have a fixed maximum size within a given array.
-.. c:var:: NPY_UNICODE
+.. c:enumerator:: NPY_UNICODE
The enumeration value for UCS4 strings of a selectable size. The
strings have a fixed maximum size within a given array.
-.. c:var:: NPY_OBJECT
+.. c:enumerator:: NPY_OBJECT
The enumeration value for references to arbitrary Python objects.
-.. c:var:: NPY_VOID
+.. c:enumerator:: NPY_VOID
Primarily used to hold struct dtypes, but can contain arbitrary
binary data.
Some useful aliases of the above types are
-.. c:var:: NPY_INTP
+.. c:enumerator:: NPY_INTP
The enumeration value for a signed integer type which is the same
size as a (void \*) pointer. This is the type used by all
arrays of indices.
-.. c:var:: NPY_UINTP
+.. c:enumerator:: NPY_UINTP
The enumeration value for an unsigned integer type which is the
same size as a (void \*) pointer.
-.. c:var:: NPY_MASK
+.. c:enumerator:: NPY_MASK
The enumeration value of the type used for masks, such as with
the :c:data:`NPY_ITER_ARRAYMASK` iterator flag. This is equivalent
to :c:data:`NPY_UINT8`.
-.. c:var:: NPY_DEFAULT_TYPE
+.. c:enumerator:: NPY_DEFAULT_TYPE
The default type to use when no dtype is explicitly specified, for
example when calling np.zero(shape). This is equivalent to
@@ -297,9 +297,13 @@ Boolean
Unsigned versions of the integers can be defined by pre-pending a 'u'
to the front of the integer name.
-.. c:type:: npy_(u)byte
+.. c:type:: npy_byte
- (unsigned) char
+ char
+
+.. c:type:: npy_ubyte
+
+ unsigned char
.. c:type:: npy_short
@@ -309,14 +313,14 @@ to the front of the integer name.
unsigned short
-.. c:type:: npy_uint
-
- unsigned int
-
.. c:type:: npy_int
int
+.. c:type:: npy_uint
+
+ unsigned int
+
.. c:type:: npy_int16
16-bit integer
@@ -341,13 +345,21 @@ to the front of the integer name.
64-bit unsigned integer
-.. c:type:: npy_(u)long
+.. c:type:: npy_long
- (unsigned) long int
+ long int
-.. c:type:: npy_(u)longlong
+.. c:type:: npy_ulong
- (unsigned long long int)
+ unsigned long int
+
+.. c:type:: npy_longlong
+
+ long long int
+
+.. c:type:: npy_ulonglong
+
+ unsigned long long int
.. c:type:: npy_intp
@@ -367,18 +379,30 @@ to the front of the integer name.
16-bit float
-.. c:type:: npy_(c)float
+.. c:type:: npy_float
32-bit float
-.. c:type:: npy_(c)double
+.. c:type:: npy_cfloat
+
+ 32-bit complex float
+
+.. c:type:: npy_double
64-bit double
-.. c:type:: npy_(c)longdouble
+.. c:type:: npy_cdouble
+
+ 64-bit complex double
+
+.. c:type:: npy_longdouble
long double
+.. c:type:: npy_clongdouble
+
+ long complex double
+
complex types are structures with **.real** and **.imag** members (in
that order).
diff --git a/doc/source/reference/c-api/iterator.rst b/doc/source/reference/c-api/iterator.rst
index ae96bb3fb..2208cdd2f 100644
--- a/doc/source/reference/c-api/iterator.rst
+++ b/doc/source/reference/c-api/iterator.rst
@@ -312,318 +312,322 @@ Construction and Destruction
Flags that may be passed in ``flags``, applying to the whole
iterator, are:
+..
+ dedent the enumeration of flags to avoid missing references sphinx warnings
- .. c:macro:: NPY_ITER_C_INDEX
+.. c:macro:: NPY_ITER_C_INDEX
- Causes the iterator to track a raveled flat index matching C
- order. This option cannot be used with :c:data:`NPY_ITER_F_INDEX`.
+ Causes the iterator to track a raveled flat index matching C
+ order. This option cannot be used with :c:data:`NPY_ITER_F_INDEX`.
- .. c:macro:: NPY_ITER_F_INDEX
+.. c:macro:: NPY_ITER_F_INDEX
- Causes the iterator to track a raveled flat index matching Fortran
- order. This option cannot be used with :c:data:`NPY_ITER_C_INDEX`.
+ Causes the iterator to track a raveled flat index matching Fortran
+ order. This option cannot be used with :c:data:`NPY_ITER_C_INDEX`.
+
+.. c:macro:: NPY_ITER_MULTI_INDEX
- .. c:macro:: NPY_ITER_MULTI_INDEX
-
- Causes the iterator to track a multi-index.
- This prevents the iterator from coalescing axes to
- produce bigger inner loops. If the loop is also not buffered
- and no index is being tracked (`NpyIter_RemoveAxis` can be called),
- then the iterator size can be ``-1`` to indicate that the iterator
- is too large. This can happen due to complex broadcasting and
- will result in errors being created when the setting the iterator
- range, removing the multi index, or getting the next function.
- However, it is possible to remove axes again and use the iterator
- normally if the size is small enough after removal.
-
- .. c:macro:: NPY_ITER_EXTERNAL_LOOP
-
- Causes the iterator to skip iteration of the innermost
- loop, requiring the user of the iterator to handle it.
-
- This flag is incompatible with :c:data:`NPY_ITER_C_INDEX`,
- :c:data:`NPY_ITER_F_INDEX`, and :c:data:`NPY_ITER_MULTI_INDEX`.
-
- .. c:macro:: NPY_ITER_DONT_NEGATE_STRIDES
-
- This only affects the iterator when :c:type:`NPY_KEEPORDER` is
- specified for the order parameter. By default with
- :c:type:`NPY_KEEPORDER`, the iterator reverses axes which have
- negative strides, so that memory is traversed in a forward
- direction. This disables this step. Use this flag if you
- want to use the underlying memory-ordering of the axes,
- but don't want an axis reversed. This is the behavior of
- ``numpy.ravel(a, order='K')``, for instance.
-
- .. c:macro:: NPY_ITER_COMMON_DTYPE
-
- Causes the iterator to convert all the operands to a common
- data type, calculated based on the ufunc type promotion rules.
- Copying or buffering must be enabled.
-
- If the common data type is known ahead of time, don't use this
- flag. Instead, set the requested dtype for all the operands.
-
- .. c:macro:: NPY_ITER_REFS_OK
-
- Indicates that arrays with reference types (object
- arrays or structured arrays containing an object type)
- may be accepted and used in the iterator. If this flag
- is enabled, the caller must be sure to check whether
- :c:func:`NpyIter_IterationNeedsAPI(iter)` is true, in which case
- it may not release the GIL during iteration.
-
- .. c:macro:: NPY_ITER_ZEROSIZE_OK
-
- Indicates that arrays with a size of zero should be permitted.
- Since the typical iteration loop does not naturally work with
- zero-sized arrays, you must check that the IterSize is larger
- than zero before entering the iteration loop.
- Currently only the operands are checked, not a forced shape.
-
- .. c:macro:: NPY_ITER_REDUCE_OK
-
- Permits writeable operands with a dimension with zero
- stride and size greater than one. Note that such operands
- must be read/write.
-
- When buffering is enabled, this also switches to a special
- buffering mode which reduces the loop length as necessary to
- not trample on values being reduced.
-
- Note that if you want to do a reduction on an automatically
- allocated output, you must use :c:func:`NpyIter_GetOperandArray`
- to get its reference, then set every value to the reduction
- unit before doing the iteration loop. In the case of a
- buffered reduction, this means you must also specify the
- flag :c:data:`NPY_ITER_DELAY_BUFALLOC`, then reset the iterator
- after initializing the allocated operand to prepare the
- buffers.
-
- .. c:macro:: NPY_ITER_RANGED
-
- Enables support for iteration of sub-ranges of the full
- ``iterindex`` range ``[0, NpyIter_IterSize(iter))``. Use
- the function :c:func:`NpyIter_ResetToIterIndexRange` to specify
- a range for iteration.
-
- This flag can only be used with :c:data:`NPY_ITER_EXTERNAL_LOOP`
- when :c:data:`NPY_ITER_BUFFERED` is enabled. This is because
- without buffering, the inner loop is always the size of the
- innermost iteration dimension, and allowing it to get cut up
- would require special handling, effectively making it more
- like the buffered version.
-
- .. c:macro:: NPY_ITER_BUFFERED
-
- Causes the iterator to store buffering data, and use buffering
- to satisfy data type, alignment, and byte-order requirements.
- To buffer an operand, do not specify the :c:data:`NPY_ITER_COPY`
- or :c:data:`NPY_ITER_UPDATEIFCOPY` flags, because they will
- override buffering. Buffering is especially useful for Python
- code using the iterator, allowing for larger chunks
- of data at once to amortize the Python interpreter overhead.
-
- If used with :c:data:`NPY_ITER_EXTERNAL_LOOP`, the inner loop
- for the caller may get larger chunks than would be possible
- without buffering, because of how the strides are laid out.
-
- Note that if an operand is given the flag :c:data:`NPY_ITER_COPY`
- or :c:data:`NPY_ITER_UPDATEIFCOPY`, a copy will be made in preference
- to buffering. Buffering will still occur when the array was
- broadcast so elements need to be duplicated to get a constant
- stride.
-
- In normal buffering, the size of each inner loop is equal
- to the buffer size, or possibly larger if
- :c:data:`NPY_ITER_GROWINNER` is specified. If
- :c:data:`NPY_ITER_REDUCE_OK` is enabled and a reduction occurs,
- the inner loops may become smaller depending
- on the structure of the reduction.
-
- .. c:macro:: NPY_ITER_GROWINNER
-
- When buffering is enabled, this allows the size of the inner
- loop to grow when buffering isn't necessary. This option
- is best used if you're doing a straight pass through all the
- data, rather than anything with small cache-friendly arrays
- of temporary values for each inner loop.
-
- .. c:macro:: NPY_ITER_DELAY_BUFALLOC
-
- When buffering is enabled, this delays allocation of the
- buffers until :c:func:`NpyIter_Reset` or another reset function is
- called. This flag exists to avoid wasteful copying of
- buffer data when making multiple copies of a buffered
- iterator for multi-threaded iteration.
-
- Another use of this flag is for setting up reduction operations.
- After the iterator is created, and a reduction output
- is allocated automatically by the iterator (be sure to use
- READWRITE access), its value may be initialized to the reduction
- unit. Use :c:func:`NpyIter_GetOperandArray` to get the object.
- Then, call :c:func:`NpyIter_Reset` to allocate and fill the buffers
- with their initial values.
-
- .. c:macro:: NPY_ITER_COPY_IF_OVERLAP
-
- If any write operand has overlap with any read operand, eliminate all
- overlap by making temporary copies (enabling UPDATEIFCOPY for write
- operands, if necessary). A pair of operands has overlap if there is
- a memory address that contains data common to both arrays.
-
- Because exact overlap detection has exponential runtime
- in the number of dimensions, the decision is made based
- on heuristics, which has false positives (needless copies in unusual
- cases) but has no false negatives.
-
- If any read/write overlap exists, this flag ensures the result of the
- operation is the same as if all operands were copied.
- In cases where copies would need to be made, **the result of the
- computation may be undefined without this flag!**
+ Causes the iterator to track a multi-index.
+ This prevents the iterator from coalescing axes to
+ produce bigger inner loops. If the loop is also not buffered
+ and no index is being tracked (`NpyIter_RemoveAxis` can be called),
+ then the iterator size can be ``-1`` to indicate that the iterator
+ is too large. This can happen due to complex broadcasting and
+ will result in errors being created when the setting the iterator
+ range, removing the multi index, or getting the next function.
+ However, it is possible to remove axes again and use the iterator
+ normally if the size is small enough after removal.
+
+.. c:macro:: NPY_ITER_EXTERNAL_LOOP
+
+ Causes the iterator to skip iteration of the innermost
+ loop, requiring the user of the iterator to handle it.
+
+ This flag is incompatible with :c:data:`NPY_ITER_C_INDEX`,
+ :c:data:`NPY_ITER_F_INDEX`, and :c:data:`NPY_ITER_MULTI_INDEX`.
+
+.. c:macro:: NPY_ITER_DONT_NEGATE_STRIDES
+
+ This only affects the iterator when :c:type:`NPY_KEEPORDER` is
+ specified for the order parameter. By default with
+ :c:type:`NPY_KEEPORDER`, the iterator reverses axes which have
+ negative strides, so that memory is traversed in a forward
+ direction. This disables this step. Use this flag if you
+ want to use the underlying memory-ordering of the axes,
+ but don't want an axis reversed. This is the behavior of
+ ``numpy.ravel(a, order='K')``, for instance.
+
+.. c:macro:: NPY_ITER_COMMON_DTYPE
+
+ Causes the iterator to convert all the operands to a common
+ data type, calculated based on the ufunc type promotion rules.
+ Copying or buffering must be enabled.
+
+ If the common data type is known ahead of time, don't use this
+ flag. Instead, set the requested dtype for all the operands.
+
+.. c:macro:: NPY_ITER_REFS_OK
+
+ Indicates that arrays with reference types (object
+ arrays or structured arrays containing an object type)
+ may be accepted and used in the iterator. If this flag
+ is enabled, the caller must be sure to check whether
+ :c:expr:`NpyIter_IterationNeedsAPI(iter)` is true, in which case
+ it may not release the GIL during iteration.
+
+.. c:macro:: NPY_ITER_ZEROSIZE_OK
+
+ Indicates that arrays with a size of zero should be permitted.
+ Since the typical iteration loop does not naturally work with
+ zero-sized arrays, you must check that the IterSize is larger
+ than zero before entering the iteration loop.
+ Currently only the operands are checked, not a forced shape.
+
+.. c:macro:: NPY_ITER_REDUCE_OK
+
+ Permits writeable operands with a dimension with zero
+ stride and size greater than one. Note that such operands
+ must be read/write.
+
+ When buffering is enabled, this also switches to a special
+ buffering mode which reduces the loop length as necessary to
+ not trample on values being reduced.
+
+ Note that if you want to do a reduction on an automatically
+ allocated output, you must use :c:func:`NpyIter_GetOperandArray`
+ to get its reference, then set every value to the reduction
+ unit before doing the iteration loop. In the case of a
+ buffered reduction, this means you must also specify the
+ flag :c:data:`NPY_ITER_DELAY_BUFALLOC`, then reset the iterator
+ after initializing the allocated operand to prepare the
+ buffers.
+
+.. c:macro:: NPY_ITER_RANGED
+
+ Enables support for iteration of sub-ranges of the full
+ ``iterindex`` range ``[0, NpyIter_IterSize(iter))``. Use
+ the function :c:func:`NpyIter_ResetToIterIndexRange` to specify
+ a range for iteration.
+
+ This flag can only be used with :c:data:`NPY_ITER_EXTERNAL_LOOP`
+ when :c:data:`NPY_ITER_BUFFERED` is enabled. This is because
+ without buffering, the inner loop is always the size of the
+ innermost iteration dimension, and allowing it to get cut up
+ would require special handling, effectively making it more
+ like the buffered version.
+
+.. c:macro:: NPY_ITER_BUFFERED
+
+ Causes the iterator to store buffering data, and use buffering
+ to satisfy data type, alignment, and byte-order requirements.
+ To buffer an operand, do not specify the :c:data:`NPY_ITER_COPY`
+ or :c:data:`NPY_ITER_UPDATEIFCOPY` flags, because they will
+ override buffering. Buffering is especially useful for Python
+ code using the iterator, allowing for larger chunks
+ of data at once to amortize the Python interpreter overhead.
+
+ If used with :c:data:`NPY_ITER_EXTERNAL_LOOP`, the inner loop
+ for the caller may get larger chunks than would be possible
+ without buffering, because of how the strides are laid out.
+
+ Note that if an operand is given the flag :c:data:`NPY_ITER_COPY`
+ or :c:data:`NPY_ITER_UPDATEIFCOPY`, a copy will be made in preference
+ to buffering. Buffering will still occur when the array was
+ broadcast so elements need to be duplicated to get a constant
+ stride.
+
+ In normal buffering, the size of each inner loop is equal
+ to the buffer size, or possibly larger if
+ :c:data:`NPY_ITER_GROWINNER` is specified. If
+ :c:data:`NPY_ITER_REDUCE_OK` is enabled and a reduction occurs,
+ the inner loops may become smaller depending
+ on the structure of the reduction.
+
+.. c:macro:: NPY_ITER_GROWINNER
+
+ When buffering is enabled, this allows the size of the inner
+ loop to grow when buffering isn't necessary. This option
+ is best used if you're doing a straight pass through all the
+ data, rather than anything with small cache-friendly arrays
+ of temporary values for each inner loop.
+
+.. c:macro:: NPY_ITER_DELAY_BUFALLOC
+
+ When buffering is enabled, this delays allocation of the
+ buffers until :c:func:`NpyIter_Reset` or another reset function is
+ called. This flag exists to avoid wasteful copying of
+ buffer data when making multiple copies of a buffered
+ iterator for multi-threaded iteration.
+
+ Another use of this flag is for setting up reduction operations.
+ After the iterator is created, and a reduction output
+ is allocated automatically by the iterator (be sure to use
+ READWRITE access), its value may be initialized to the reduction
+ unit. Use :c:func:`NpyIter_GetOperandArray` to get the object.
+ Then, call :c:func:`NpyIter_Reset` to allocate and fill the buffers
+ with their initial values.
+
+.. c:macro:: NPY_ITER_COPY_IF_OVERLAP
+
+ If any write operand has overlap with any read operand, eliminate all
+ overlap by making temporary copies (enabling UPDATEIFCOPY for write
+ operands, if necessary). A pair of operands has overlap if there is
+ a memory address that contains data common to both arrays.
+
+ Because exact overlap detection has exponential runtime
+ in the number of dimensions, the decision is made based
+ on heuristics, which has false positives (needless copies in unusual
+ cases) but has no false negatives.
+
+ If any read/write overlap exists, this flag ensures the result of the
+ operation is the same as if all operands were copied.
+ In cases where copies would need to be made, **the result of the
+ computation may be undefined without this flag!**
Flags that may be passed in ``op_flags[i]``, where ``0 <= i < nop``:
+..
+ dedent the enumeration of flags to avoid missing references sphinx warnings
+
+.. c:macro:: NPY_ITER_READWRITE
+.. c:macro:: NPY_ITER_READONLY
+.. c:macro:: NPY_ITER_WRITEONLY
+
+ Indicate how the user of the iterator will read or write
+ to ``op[i]``. Exactly one of these flags must be specified
+ per operand. Using ``NPY_ITER_READWRITE`` or ``NPY_ITER_WRITEONLY``
+ for a user-provided operand may trigger `WRITEBACKIFCOPY``
+ semantics. The data will be written back to the original array
+ when ``NpyIter_Deallocate`` is called.
+
+.. c:macro:: NPY_ITER_COPY
+
+ Allow a copy of ``op[i]`` to be made if it does not
+ meet the data type or alignment requirements as specified
+ by the constructor flags and parameters.
+
+.. c:macro:: NPY_ITER_UPDATEIFCOPY
- .. c:macro:: NPY_ITER_READWRITE
- .. c:macro:: NPY_ITER_READONLY
- .. c:macro:: NPY_ITER_WRITEONLY
+ Triggers :c:data:`NPY_ITER_COPY`, and when an array operand
+ is flagged for writing and is copied, causes the data
+ in a copy to be copied back to ``op[i]`` when
+ ``NpyIter_Deallocate`` is called.
- Indicate how the user of the iterator will read or write
- to ``op[i]``. Exactly one of these flags must be specified
- per operand. Using ``NPY_ITER_READWRITE`` or ``NPY_ITER_WRITEONLY``
- for a user-provided operand may trigger `WRITEBACKIFCOPY``
- semantics. The data will be written back to the original array
- when ``NpyIter_Deallocate`` is called.
-
- .. c:macro:: NPY_ITER_COPY
+ If the operand is flagged as write-only and a copy is needed,
+ an uninitialized temporary array will be created and then copied
+ to back to ``op[i]`` on calling ``NpyIter_Deallocate``, instead of
+ doing the unnecessary copy operation.
- Allow a copy of ``op[i]`` to be made if it does not
- meet the data type or alignment requirements as specified
- by the constructor flags and parameters.
+.. c:macro:: NPY_ITER_NBO
+.. c:macro:: NPY_ITER_ALIGNED
+.. c:macro:: NPY_ITER_CONTIG
- .. c:macro:: NPY_ITER_UPDATEIFCOPY
-
- Triggers :c:data:`NPY_ITER_COPY`, and when an array operand
- is flagged for writing and is copied, causes the data
- in a copy to be copied back to ``op[i]`` when
- ``NpyIter_Deallocate`` is called.
-
- If the operand is flagged as write-only and a copy is needed,
- an uninitialized temporary array will be created and then copied
- to back to ``op[i]`` on calling ``NpyIter_Deallocate``, instead of
- doing the unnecessary copy operation.
-
- .. c:macro:: NPY_ITER_NBO
- .. c:macro:: NPY_ITER_ALIGNED
- .. c:macro:: NPY_ITER_CONTIG
-
- Causes the iterator to provide data for ``op[i]``
- that is in native byte order, aligned according to
- the dtype requirements, contiguous, or any combination.
-
- By default, the iterator produces pointers into the
- arrays provided, which may be aligned or unaligned, and
- with any byte order. If copying or buffering is not
- enabled and the operand data doesn't satisfy the constraints,
- an error will be raised.
+ Causes the iterator to provide data for ``op[i]``
+ that is in native byte order, aligned according to
+ the dtype requirements, contiguous, or any combination.
- The contiguous constraint applies only to the inner loop,
- successive inner loops may have arbitrary pointer changes.
+ By default, the iterator produces pointers into the
+ arrays provided, which may be aligned or unaligned, and
+ with any byte order. If copying or buffering is not
+ enabled and the operand data doesn't satisfy the constraints,
+ an error will be raised.
- If the requested data type is in non-native byte order,
- the NBO flag overrides it and the requested data type is
- converted to be in native byte order.
+ The contiguous constraint applies only to the inner loop,
+ successive inner loops may have arbitrary pointer changes.
- .. c:macro:: NPY_ITER_ALLOCATE
+ If the requested data type is in non-native byte order,
+ the NBO flag overrides it and the requested data type is
+ converted to be in native byte order.
- This is for output arrays, and requires that the flag
- :c:data:`NPY_ITER_WRITEONLY` or :c:data:`NPY_ITER_READWRITE`
- be set. If ``op[i]`` is NULL, creates a new array with
- the final broadcast dimensions, and a layout matching
- the iteration order of the iterator.
+.. c:macro:: NPY_ITER_ALLOCATE
- When ``op[i]`` is NULL, the requested data type
- ``op_dtypes[i]`` may be NULL as well, in which case it is
- automatically generated from the dtypes of the arrays which
- are flagged as readable. The rules for generating the dtype
- are the same is for UFuncs. Of special note is handling
- of byte order in the selected dtype. If there is exactly
- one input, the input's dtype is used as is. Otherwise,
- if more than one input dtypes are combined together, the
- output will be in native byte order.
+ This is for output arrays, and requires that the flag
+ :c:data:`NPY_ITER_WRITEONLY` or :c:data:`NPY_ITER_READWRITE`
+ be set. If ``op[i]`` is NULL, creates a new array with
+ the final broadcast dimensions, and a layout matching
+ the iteration order of the iterator.
+
+ When ``op[i]`` is NULL, the requested data type
+ ``op_dtypes[i]`` may be NULL as well, in which case it is
+ automatically generated from the dtypes of the arrays which
+ are flagged as readable. The rules for generating the dtype
+ are the same is for UFuncs. Of special note is handling
+ of byte order in the selected dtype. If there is exactly
+ one input, the input's dtype is used as is. Otherwise,
+ if more than one input dtypes are combined together, the
+ output will be in native byte order.
+
+ After being allocated with this flag, the caller may retrieve
+ the new array by calling :c:func:`NpyIter_GetOperandArray` and
+ getting the i-th object in the returned C array. The caller
+ must call Py_INCREF on it to claim a reference to the array.
- After being allocated with this flag, the caller may retrieve
- the new array by calling :c:func:`NpyIter_GetOperandArray` and
- getting the i-th object in the returned C array. The caller
- must call Py_INCREF on it to claim a reference to the array.
+.. c:macro:: NPY_ITER_NO_SUBTYPE
- .. c:macro:: NPY_ITER_NO_SUBTYPE
+ For use with :c:data:`NPY_ITER_ALLOCATE`, this flag disables
+ allocating an array subtype for the output, forcing
+ it to be a straight ndarray.
- For use with :c:data:`NPY_ITER_ALLOCATE`, this flag disables
- allocating an array subtype for the output, forcing
- it to be a straight ndarray.
+ TODO: Maybe it would be better to introduce a function
+ ``NpyIter_GetWrappedOutput`` and remove this flag?
- TODO: Maybe it would be better to introduce a function
- ``NpyIter_GetWrappedOutput`` and remove this flag?
+.. c:macro:: NPY_ITER_NO_BROADCAST
- .. c:macro:: NPY_ITER_NO_BROADCAST
+ Ensures that the input or output matches the iteration
+ dimensions exactly.
- Ensures that the input or output matches the iteration
- dimensions exactly.
+.. c:macro:: NPY_ITER_ARRAYMASK
- .. c:macro:: NPY_ITER_ARRAYMASK
+ .. versionadded:: 1.7
+
+ Indicates that this operand is the mask to use for
+ selecting elements when writing to operands which have
+ the :c:data:`NPY_ITER_WRITEMASKED` flag applied to them.
+ Only one operand may have :c:data:`NPY_ITER_ARRAYMASK` flag
+ applied to it.
- .. versionadded:: 1.7
+ The data type of an operand with this flag should be either
+ :c:data:`NPY_BOOL`, :c:data:`NPY_MASK`, or a struct dtype
+ whose fields are all valid mask dtypes. In the latter case,
+ it must match up with a struct operand being WRITEMASKED,
+ as it is specifying a mask for each field of that array.
- Indicates that this operand is the mask to use for
- selecting elements when writing to operands which have
- the :c:data:`NPY_ITER_WRITEMASKED` flag applied to them.
- Only one operand may have :c:data:`NPY_ITER_ARRAYMASK` flag
- applied to it.
+ This flag only affects writing from the buffer back to
+ the array. This means that if the operand is also
+ :c:data:`NPY_ITER_READWRITE` or :c:data:`NPY_ITER_WRITEONLY`,
+ code doing iteration can write to this operand to
+ control which elements will be untouched and which ones will be
+ modified. This is useful when the mask should be a combination
+ of input masks.
- The data type of an operand with this flag should be either
- :c:data:`NPY_BOOL`, :c:data:`NPY_MASK`, or a struct dtype
- whose fields are all valid mask dtypes. In the latter case,
- it must match up with a struct operand being WRITEMASKED,
- as it is specifying a mask for each field of that array.
+.. c:macro:: NPY_ITER_WRITEMASKED
- This flag only affects writing from the buffer back to
- the array. This means that if the operand is also
- :c:data:`NPY_ITER_READWRITE` or :c:data:`NPY_ITER_WRITEONLY`,
- code doing iteration can write to this operand to
- control which elements will be untouched and which ones will be
- modified. This is useful when the mask should be a combination
- of input masks.
+ .. versionadded:: 1.7
- .. c:macro:: NPY_ITER_WRITEMASKED
+ This array is the mask for all `writemasked <numpy.nditer>`
+ operands. Code uses the ``writemasked`` flag which indicates
+ that only elements where the chosen ARRAYMASK operand is True
+ will be written to. In general, the iterator does not enforce
+ this, it is up to the code doing the iteration to follow that
+ promise.
- .. versionadded:: 1.7
+ When ``writemasked`` flag is used, and this operand is buffered,
+ this changes how data is copied from the buffer into the array.
+ A masked copying routine is used, which only copies the
+ elements in the buffer for which ``writemasked``
+ returns true from the corresponding element in the ARRAYMASK
+ operand.
- This array is the mask for all `writemasked <numpy.nditer>`
- operands. Code uses the ``writemasked`` flag which indicates
- that only elements where the chosen ARRAYMASK operand is True
- will be written to. In general, the iterator does not enforce
- this, it is up to the code doing the iteration to follow that
- promise.
-
- When ``writemasked`` flag is used, and this operand is buffered,
- this changes how data is copied from the buffer into the array.
- A masked copying routine is used, which only copies the
- elements in the buffer for which ``writemasked``
- returns true from the corresponding element in the ARRAYMASK
- operand.
+.. c:macro:: NPY_ITER_OVERLAP_ASSUME_ELEMENTWISE
- .. c:macro:: NPY_ITER_OVERLAP_ASSUME_ELEMENTWISE
+ In memory overlap checks, assume that operands with
+ ``NPY_ITER_OVERLAP_ASSUME_ELEMENTWISE`` enabled are accessed only
+ in the iterator order.
- In memory overlap checks, assume that operands with
- ``NPY_ITER_OVERLAP_ASSUME_ELEMENTWISE`` enabled are accessed only
- in the iterator order.
+ This enables the iterator to reason about data dependency,
+ possibly avoiding unnecessary copies.
- This enables the iterator to reason about data dependency,
- possibly avoiding unnecessary copies.
-
- This flag has effect only if ``NPY_ITER_COPY_IF_OVERLAP`` is enabled
- on the iterator.
+ This flag has effect only if ``NPY_ITER_COPY_IF_OVERLAP`` is enabled
+ on the iterator.
.. c:function:: NpyIter* NpyIter_AdvancedNew( \
npy_intp nop, PyArrayObject** op, npy_uint32 flags, NPY_ORDER order, \
@@ -738,7 +742,7 @@ Construction and Destruction
the iterator. Any cached functions or pointers from the iterator
must be retrieved again!
- After calling this function, :c:func:`NpyIter_HasMultiIndex(iter)` will
+ After calling this function, :c:expr:`NpyIter_HasMultiIndex(iter)` will
return false.
Returns ``NPY_SUCCEED`` or ``NPY_FAIL``.
diff --git a/doc/source/reference/c-api/types-and-structures.rst b/doc/source/reference/c-api/types-and-structures.rst
index 763f985a6..54a1e09e1 100644
--- a/doc/source/reference/c-api/types-and-structures.rst
+++ b/doc/source/reference/c-api/types-and-structures.rst
@@ -7,7 +7,7 @@ Python Types and C-Structures
Several new types are defined in the C-code. Most of these are
accessible from Python, but a few are not exposed due to their limited
-use. Every new Python type has an associated :c:type:`PyObject *<PyObject>` with an
+use. Every new Python type has an associated :c:expr:`PyObject *` with an
internal structure that includes a pointer to a "method table" that
defines how the new object behaves in Python. When you receive a
Python object into C code, you always get a pointer to a
@@ -61,7 +61,7 @@ hierarchy of actual Python types.
PyArray_Type and PyArrayObject
------------------------------
-.. c:var:: PyArray_Type
+.. c:var:: PyTypeObject PyArray_Type
The Python type of the ndarray is :c:data:`PyArray_Type`. In C, every
ndarray is a pointer to a :c:type:`PyArrayObject` structure. The ob_type
@@ -201,7 +201,7 @@ PyArray_Type and PyArrayObject
PyArrayDescr_Type and PyArray_Descr
-----------------------------------
-.. c:var:: PyArrayDescr_Type
+.. c:var:: PyTypeObject PyArrayDescr_Type
The :c:data:`PyArrayDescr_Type` is the built-in type of the
data-type-descriptor objects used to describe how the bytes comprising
@@ -636,7 +636,7 @@ PyArrayDescr_Type and PyArray_Descr
Either ``NULL`` or a dictionary containing low-level casting
functions for user- defined data-types. Each function is
- wrapped in a :c:type:`PyCapsule *<PyCapsule>` and keyed by
+ wrapped in a :c:expr:`PyCapsule *` and keyed by
the data-type number.
.. c:member:: NPY_SCALARKIND scalarkind(PyArrayObject* arr)
@@ -754,7 +754,7 @@ The :c:data:`PyArray_Type` can also be sub-typed.
PyUFunc_Type and PyUFuncObject
------------------------------
-.. c:var:: PyUFunc_Type
+.. c:var:: PyTypeObject PyUFunc_Type
The ufunc object is implemented by creation of the
:c:data:`PyUFunc_Type`. It is a very simple type that implements only
@@ -811,13 +811,14 @@ PyUFunc_Type and PyUFuncObject
char *core_signature;
PyUFunc_TypeResolutionFunc *type_resolver;
PyUFunc_LegacyInnerLoopSelectionFunc *legacy_inner_loop_selector;
- PyUFunc_MaskedInnerLoopSelectionFunc *masked_inner_loop_selector;
+ void *reserved2;
npy_uint32 *op_flags;
npy_uint32 *iter_flags;
/* new in API version 0x0000000D */
npy_intp *core_dim_sizes;
npy_uint32 *core_dim_flags;
PyObject *identity_value;
+ /* Further private slots (size depends on the NumPy version) */
} PyUFuncObject;
.. c:macro: PyObject_HEAD
@@ -957,18 +958,17 @@ PyUFunc_Type and PyUFuncObject
.. c:member:: PyUFunc_LegacyInnerLoopSelectionFunc *legacy_inner_loop_selector
- A function which returns an inner loop. The ``legacy`` in the name arises
- because for NumPy 1.6 a better variant had been planned. This variant
- has not yet come about.
+ .. deprecated:: 1.22
+
+ Some fallback support for this slot exists, but will be removed
+ eventually. A univiersal function which relied on this will have
+ eventually have to be ported.
+ See ref:`NEP 41 <NEP41>` and ref:`NEP 43 <NEP43>`
.. c:member:: void *reserved2
For a possible future loop selector with a different signature.
- .. c:member:: PyUFunc_MaskedInnerLoopSelectionFunc *masked_inner_loop_selector
-
- Function which returns a masked inner loop for the ufunc
-
.. c:member:: npy_uint32 op_flags
Override the default operand flags for each ufunc operand.
@@ -1006,7 +1006,7 @@ PyUFunc_Type and PyUFuncObject
PyArrayIter_Type and PyArrayIterObject
--------------------------------------
-.. c:var:: PyArrayIter_Type
+.. c:var:: PyTypeObject PyArrayIter_Type
This is an iterator object that makes it easy to loop over an
N-dimensional array. It is the object returned from the flat
@@ -1110,13 +1110,13 @@ the internal structure of the iterator object, and merely interact
with it through the use of the macros :c:func:`PyArray_ITER_NEXT` (it),
:c:func:`PyArray_ITER_GOTO` (it, dest), or :c:func:`PyArray_ITER_GOTO1D`
(it, index). All of these macros require the argument *it* to be a
-:c:type:`PyArrayIterObject *`.
+:c:expr:`PyArrayIterObject *`.
PyArrayMultiIter_Type and PyArrayMultiIterObject
------------------------------------------------
-.. c:var:: PyArrayMultiIter_Type
+.. c:var:: PyTypeObject PyArrayMultiIter_Type
This type provides an iterator that encapsulates the concept of
broadcasting. It allows :math:`N` arrays to be broadcast together
@@ -1178,7 +1178,7 @@ PyArrayMultiIter_Type and PyArrayMultiIterObject
PyArrayNeighborhoodIter_Type and PyArrayNeighborhoodIterObject
--------------------------------------------------------------
-.. c:var:: PyArrayNeighborhoodIter_Type
+.. c:var:: PyTypeObject PyArrayNeighborhoodIter_Type
This is an iterator object that makes it easy to loop over an
N-dimensional neighborhood.
@@ -1217,7 +1217,7 @@ PyArrayNeighborhoodIter_Type and PyArrayNeighborhoodIterObject
PyArrayFlags_Type and PyArrayFlagsObject
----------------------------------------
-.. c:var:: PyArrayFlags_Type
+.. c:var:: PyTypeObject PyArrayFlags_Type
When the flags attribute is retrieved from Python, a special
builtin object of this type is constructed. This special type makes
@@ -1466,7 +1466,7 @@ for completeness and assistance in understanding the code.
to define a 1-d loop for a ufunc for every defined signature of a
user-defined data-type.
-.. c:var:: PyArrayMapIter_Type
+.. c:var:: PyTypeObject PyArrayMapIter_Type
Advanced indexing is handled with this Python type. It is simply a
loose wrapper around the C-structure containing the variables
diff --git a/doc/source/reference/c-api/ufunc.rst b/doc/source/reference/c-api/ufunc.rst
index 9eb70c3fb..95dc47839 100644
--- a/doc/source/reference/c-api/ufunc.rst
+++ b/doc/source/reference/c-api/ufunc.rst
@@ -283,20 +283,6 @@ Functions
signature is an array of data-type numbers indicating the inputs
followed by the outputs assumed by the 1-d loop.
-.. c:function:: int PyUFunc_GenericFunction( \
- PyUFuncObject* self, PyObject* args, PyObject* kwds, PyArrayObject** mps)
-
- .. deprecated:: NumPy 1.19
-
- Unless NumPy is made aware of an issue with this, this function
- is scheduled for rapid removal without replacement.
-
- Instead of this function ``PyObject_Call(ufunc, args, kwds)`` should be
- used. The above function differs from this because it ignores support
- for non-array, or array subclasses as inputs.
- To ensure identical behaviour, it may be necessary to convert all inputs
- using ``PyArray_FromAny(obj, NULL, 0, 0, NPY_ARRAY_ENSUREARRAY, NULL)``.
-
.. c:function:: int PyUFunc_checkfperr(int errmask, PyObject* errobj)
A simple interface to the IEEE error-flag checking support. The
diff --git a/doc/source/reference/global_state.rst b/doc/source/reference/global_state.rst
index b59467210..f18481235 100644
--- a/doc/source/reference/global_state.rst
+++ b/doc/source/reference/global_state.rst
@@ -84,17 +84,3 @@ contiguous in memory.
Most users will have no reason to change these; for details
see the :ref:`memory layout <memory-layout>` documentation.
-Using the new casting implementation
-------------------------------------
-
-Within NumPy 1.20 it is possible to enable the new experimental casting
-implementation for testing purposes. To do this set::
-
- NPY_USE_NEW_CASTINGIMPL=1
-
-Setting the flag is only useful to aid with NumPy developement to ensure the
-new version is bug free and should be avoided for production code.
-It is a helpful test for projects that either create custom datatypes or
-use for example complicated structured dtypes. The flag is expected to be
-removed in 1.21 with the new version being always in use.
-
diff --git a/doc/source/reference/index.rst b/doc/source/reference/index.rst
index 6eb74cd77..f12d923df 100644
--- a/doc/source/reference/index.rst
+++ b/doc/source/reference/index.rst
@@ -1,5 +1,7 @@
.. _reference:
+.. module:: numpy
+
###############
NumPy Reference
###############
@@ -7,9 +9,6 @@ NumPy Reference
:Release: |version|
:Date: |today|
-
-.. module:: numpy
-
This reference manual details functions, modules, and objects
included in NumPy, describing what they are and what they do.
For learning how to use NumPy, see the :ref:`complete documentation <numpy_docs_mainpage>`.
diff --git a/doc/source/reference/random/bit_generators/index.rst b/doc/source/reference/random/bit_generators/index.rst
index 315657172..c5c349806 100644
--- a/doc/source/reference/random/bit_generators/index.rst
+++ b/doc/source/reference/random/bit_generators/index.rst
@@ -15,10 +15,13 @@ Supported BitGenerators
The included BitGenerators are:
-* PCG-64 - The default. A fast generator that supports many parallel streams
- and can be advanced by an arbitrary amount. See the documentation for
- :meth:`~.PCG64.advance`. PCG-64 has a period of :math:`2^{128}`. See the `PCG
- author's page`_ for more details about this class of PRNG.
+* PCG-64 - The default. A fast generator that can be advanced by an arbitrary
+ amount. See the documentation for :meth:`~.PCG64.advance`. PCG-64 has
+ a period of :math:`2^{128}`. See the `PCG author's page`_ for more details
+ about this class of PRNG.
+* PCG-64 DXSM - An upgraded version of PCG-64 with better statistical
+ properties in parallel contexts. See :ref:`upgrading-pcg64` for more
+ information on these improvements.
* MT19937 - The standard Python BitGenerator. Adds a `MT19937.jumped`
function that returns a new generator with state as-if :math:`2^{128}` draws have
been made.
@@ -43,6 +46,7 @@ The included BitGenerators are:
MT19937 <mt19937>
PCG64 <pcg64>
+ PCG64DXSM <pcg64dxsm>
Philox <philox>
SFC64 <sfc64>
@@ -105,6 +109,44 @@ If you need to generate a good seed "offline", then ``SeedSequence().entropy``
or using ``secrets.randbits(128)`` from the standard library are both
convenient ways.
+If you need to run several stochastic simulations in parallel, best practice
+is to construct a random generator instance for each simulation.
+To make sure that the random streams have distinct initial states, you can use
+the `spawn` method of `~SeedSequence`. For instance, here we construct a list
+of 12 instances:
+
+.. code-block:: python
+
+ from numpy.random import PCG64, SeedSequence
+
+ # High quality initial entropy
+ entropy = 0x87351080e25cb0fad77a44a3be03b491
+ base_seq = SeedSequence(entropy)
+ child_seqs = base_seq.spawn(12) # a list of 12 SeedSequences
+ generators = [PCG64(seq) for seq in child_seqs]
+
+.. end_block
+
+
+An alternative way is to use the fact that a `~SeedSequence` can be initialized
+by a tuple of elements. Here we use a base entropy value and an integer
+``worker_id``
+
+.. code-block:: python
+
+ from numpy.random import PCG64, SeedSequence
+
+ # High quality initial entropy
+ entropy = 0x87351080e25cb0fad77a44a3be03b491
+ sequences = [SeedSequence((entropy, worker_id)) for worker_id in range(12)]
+ generators = [PCG64(seq) for seq in sequences]
+
+.. end_block
+
+Note that the sequences produced by the latter method will be distinct from
+those constructed via `~SeedSequence.spawn`.
+
+
.. autosummary::
:toctree: generated/
diff --git a/doc/source/reference/random/bit_generators/mt19937.rst b/doc/source/reference/random/bit_generators/mt19937.rst
index 71875db4e..d05ea7c6f 100644
--- a/doc/source/reference/random/bit_generators/mt19937.rst
+++ b/doc/source/reference/random/bit_generators/mt19937.rst
@@ -4,7 +4,8 @@ Mersenne Twister (MT19937)
.. currentmodule:: numpy.random
.. autoclass:: MT19937
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
State
=====
diff --git a/doc/source/reference/random/bit_generators/pcg64.rst b/doc/source/reference/random/bit_generators/pcg64.rst
index edac4620b..889965f77 100644
--- a/doc/source/reference/random/bit_generators/pcg64.rst
+++ b/doc/source/reference/random/bit_generators/pcg64.rst
@@ -4,7 +4,8 @@ Permuted Congruential Generator (64-bit, PCG64)
.. currentmodule:: numpy.random
.. autoclass:: PCG64
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
State
=====
diff --git a/doc/source/reference/random/bit_generators/pcg64dxsm.rst b/doc/source/reference/random/bit_generators/pcg64dxsm.rst
new file mode 100644
index 000000000..e37efa5d3
--- /dev/null
+++ b/doc/source/reference/random/bit_generators/pcg64dxsm.rst
@@ -0,0 +1,32 @@
+Permuted Congruential Generator (64-bit, PCG64 DXSM)
+----------------------------------------------------
+
+.. currentmodule:: numpy.random
+
+.. autoclass:: PCG64DXSM
+ :members: __init__
+ :exclude-members: __init__
+
+State
+=====
+
+.. autosummary::
+ :toctree: generated/
+
+ ~PCG64DXSM.state
+
+Parallel generation
+===================
+.. autosummary::
+ :toctree: generated/
+
+ ~PCG64DXSM.advance
+ ~PCG64DXSM.jumped
+
+Extending
+=========
+.. autosummary::
+ :toctree: generated/
+
+ ~PCG64DXSM.cffi
+ ~PCG64DXSM.ctypes
diff --git a/doc/source/reference/random/bit_generators/philox.rst b/doc/source/reference/random/bit_generators/philox.rst
index 8eba2d351..3c2fa4cc5 100644
--- a/doc/source/reference/random/bit_generators/philox.rst
+++ b/doc/source/reference/random/bit_generators/philox.rst
@@ -4,7 +4,8 @@ Philox Counter-based RNG
.. currentmodule:: numpy.random
.. autoclass:: Philox
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
State
=====
diff --git a/doc/source/reference/random/bit_generators/sfc64.rst b/doc/source/reference/random/bit_generators/sfc64.rst
index d34124a33..8cb255bc1 100644
--- a/doc/source/reference/random/bit_generators/sfc64.rst
+++ b/doc/source/reference/random/bit_generators/sfc64.rst
@@ -4,7 +4,8 @@ SFC64 Small Fast Chaotic PRNG
.. currentmodule:: numpy.random
.. autoclass:: SFC64
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
State
=====
diff --git a/doc/source/reference/random/c-api.rst b/doc/source/reference/random/c-api.rst
index a79da7a49..de403ce98 100644
--- a/doc/source/reference/random/c-api.rst
+++ b/doc/source/reference/random/c-api.rst
@@ -3,6 +3,8 @@ C API for random
.. currentmodule:: numpy.random
+.. versionadded:: 1.19.0
+
Access to various distributions below is available via Cython or C-wrapper
libraries like CFFI. All the functions accept a :c:type:`bitgen_t` as their
first argument. To access these from Cython or C, you must link with the
@@ -40,9 +42,9 @@ The functions are named with the following conventions:
- The functions without "standard" in their name require additional parameters
to describe the distributions.
-- ``zig`` in the name are based on a ziggurat lookup algorithm is used instead
- of calculating the ``log``, which is significantly faster. The non-ziggurat
- variants are used in corner cases and for legacy compatibility.
+- Functions with ``inv`` in their name are based on the slower inverse method
+ instead of a ziggurat lookup algorithm, which is significantly faster. The
+ non-ziggurat variants are used in corner cases and for legacy compatibility.
.. c:function:: double random_standard_uniform(bitgen_t *bitgen_state)
@@ -53,6 +55,8 @@ The functions are named with the following conventions:
.. c:function:: void random_standard_exponential_fill(bitgen_t *bitgen_state, npy_intp cnt, double *out)
+.. c:function:: void random_standard_exponential_inv_fill(bitgen_t *bitgen_state, npy_intp cnt, double *out)
+
.. c:function:: double random_standard_normal(bitgen_t* bitgen_state)
.. c:function:: void random_standard_normal_fill(bitgen_t *bitgen_state, npy_intp count, double *out)
@@ -69,6 +73,8 @@ The functions are named with the following conventions:
.. c:function:: void random_standard_exponential_fill_f(bitgen_t *bitgen_state, npy_intp cnt, float *out)
+.. c:function:: void random_standard_exponential_inv_fill_f(bitgen_t *bitgen_state, npy_intp cnt, float *out)
+
.. c:function:: float random_standard_normal_f(bitgen_t* bitgen_state)
.. c:function:: float random_standard_gamma_f(bitgen_t *bitgen_state, float shape)
diff --git a/doc/source/reference/random/generator.rst b/doc/source/reference/random/generator.rst
index 8706e1de2..7934be98a 100644
--- a/doc/source/reference/random/generator.rst
+++ b/doc/source/reference/random/generator.rst
@@ -15,7 +15,8 @@ can be changed by passing an instantized BitGenerator to ``Generator``.
.. autofunction:: default_rng
.. autoclass:: Generator
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
Accessing the BitGenerator
==========================
@@ -70,13 +71,13 @@ By default, `Generator.permuted` returns a copy. To operate in-place with
`Generator.permuted`, pass the same array as the first argument *and* as
the value of the ``out`` parameter. For example,
- >>> rg = np.random.default_rng()
+ >>> rng = np.random.default_rng()
>>> x = np.arange(0, 15).reshape(3, 5)
>>> x
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
- >>> y = rg.permuted(x, axis=1, out=x)
+ >>> y = rng.permuted(x, axis=1, out=x)
>>> x
array([[ 1, 0, 2, 4, 3], # random
[ 6, 7, 8, 9, 5],
@@ -96,13 +97,13 @@ which dimension of the input array to use as the sequence. In the case of a
two-dimensional array, ``axis=0`` will, in effect, rearrange the rows of the
array, and ``axis=1`` will rearrange the columns. For example
- >>> rg = np.random.default_rng()
+ >>> rng = np.random.default_rng()
>>> x = np.arange(0, 15).reshape(3, 5)
>>> x
array([[ 0, 1, 2, 3, 4],
[ 5, 6, 7, 8, 9],
[10, 11, 12, 13, 14]])
- >>> rg.permutation(x, axis=1)
+ >>> rng.permutation(x, axis=1)
array([[ 1, 3, 2, 0, 4], # random
[ 6, 8, 7, 5, 9],
[11, 13, 12, 10, 14]])
@@ -115,7 +116,7 @@ how `numpy.sort` treats it. Each slice along the given axis is shuffled
independently of the others. Compare the following example of the use of
`Generator.permuted` to the above example of `Generator.permutation`:
- >>> rg.permuted(x, axis=1)
+ >>> rng.permuted(x, axis=1)
array([[ 1, 0, 2, 4, 3], # random
[ 5, 7, 6, 9, 8],
[10, 14, 12, 13, 11]])
@@ -130,9 +131,9 @@ Shuffling non-NumPy sequences
a sequence that is not a NumPy array, it shuffles that sequence in-place.
For example,
- >>> rg = np.random.default_rng()
+ >>> rng = np.random.default_rng()
>>> a = ['A', 'B', 'C', 'D', 'E']
- >>> rg.shuffle(a) # shuffle the list in-place
+ >>> rng.shuffle(a) # shuffle the list in-place
>>> a
['B', 'D', 'A', 'E', 'C'] # random
diff --git a/doc/source/reference/random/index.rst b/doc/source/reference/random/index.rst
index 13ce7c40c..96cd47017 100644
--- a/doc/source/reference/random/index.rst
+++ b/doc/source/reference/random/index.rst
@@ -25,7 +25,7 @@ nep-0019-rng-policy.html>`_ for context on the updated random Numpy number
routines. The legacy `RandomState` random number routines are still
available, but limited to a single BitGenerator. See :ref:`new-or-different`
for a complete list of improvements and differences from the legacy
-``Randomstate``.
+``RandomState``.
For convenience and backward compatibility, a single `RandomState`
instance's methods are imported into the numpy.random namespace, see
@@ -84,10 +84,10 @@ different
.. code-block:: python
try:
- rg_integers = rg.integers
+ rng_integers = rng.integers
except AttributeError:
- rg_integers = rg.randint
- a = rg_integers(1000)
+ rng_integers = rng.randint
+ a = rng_integers(1000)
Seeds can be passed to any of the BitGenerators. The provided value is mixed
via `SeedSequence` to spread a possible sequence of seeds across a wider
@@ -97,8 +97,8 @@ is wrapped with a `Generator`.
.. code-block:: python
from numpy.random import Generator, PCG64
- rg = Generator(PCG64(12345))
- rg.standard_normal()
+ rng = Generator(PCG64(12345))
+ rng.standard_normal()
Here we use `default_rng` to create an instance of `Generator` to generate a
random float:
@@ -146,10 +146,10 @@ As a convenience NumPy provides the `default_rng` function to hide these
details:
>>> from numpy.random import default_rng
->>> rg = default_rng(12345)
->>> print(rg)
+>>> rng = default_rng(12345)
+>>> print(rng)
Generator(PCG64)
->>> print(rg.random())
+>>> print(rng.random())
0.22733602246716966
One can also instantiate `Generator` directly with a `BitGenerator` instance.
@@ -158,16 +158,16 @@ To use the default `PCG64` bit generator, one can instantiate it directly and
pass it to `Generator`:
>>> from numpy.random import Generator, PCG64
->>> rg = Generator(PCG64(12345))
->>> print(rg)
+>>> rng = Generator(PCG64(12345))
+>>> print(rng)
Generator(PCG64)
Similarly to use the older `MT19937` bit generator (not recommended), one can
instantiate it directly and pass it to `Generator`:
>>> from numpy.random import Generator, MT19937
->>> rg = Generator(MT19937(12345))
->>> print(rg)
+>>> rng = Generator(MT19937(12345))
+>>> print(rng)
Generator(MT19937)
What's New or Different
@@ -222,6 +222,9 @@ one of three ways:
* :ref:`independent-streams`
* :ref:`parallel-jumped`
+Users with a very large amount of parallelism will want to consult
+:ref:`upgrading-pcg64`.
+
Concepts
--------
.. toctree::
@@ -230,6 +233,7 @@ Concepts
generator
Legacy Generator (RandomState) <legacy>
BitGenerators, SeedSequences <bit_generators/index>
+ Upgrading PCG64 with PCG64DXSM <upgrading-pcg64>
Features
--------
diff --git a/doc/source/reference/random/legacy.rst b/doc/source/reference/random/legacy.rst
index 6cf4775b8..42437dbb6 100644
--- a/doc/source/reference/random/legacy.rst
+++ b/doc/source/reference/random/legacy.rst
@@ -48,7 +48,8 @@ using the state of the `RandomState`:
.. autoclass:: RandomState
- :exclude-members:
+ :members: __init__
+ :exclude-members: __init__
Seeding and State
=================
diff --git a/doc/source/reference/random/new-or-different.rst b/doc/source/reference/random/new-or-different.rst
index 6cab0f729..a81543926 100644
--- a/doc/source/reference/random/new-or-different.rst
+++ b/doc/source/reference/random/new-or-different.rst
@@ -58,18 +58,18 @@ And in more detail:
from numpy.random import Generator, PCG64
import numpy.random
- rg = Generator(PCG64())
- %timeit -n 1 rg.standard_normal(100000)
+ rng = Generator(PCG64())
+ %timeit -n 1 rng.standard_normal(100000)
%timeit -n 1 numpy.random.standard_normal(100000)
.. ipython:: python
- %timeit -n 1 rg.standard_exponential(100000)
+ %timeit -n 1 rng.standard_exponential(100000)
%timeit -n 1 numpy.random.standard_exponential(100000)
.. ipython:: python
- %timeit -n 1 rg.standard_gamma(3.0, 100000)
+ %timeit -n 1 rng.standard_gamma(3.0, 100000)
%timeit -n 1 numpy.random.standard_gamma(3.0, 100000)
@@ -94,9 +94,9 @@ And in more detail:
.. ipython:: python
- rg = Generator(PCG64(0))
- rg.random(3, dtype='d')
- rg.random(3, dtype='f')
+ rng = Generator(PCG64(0))
+ rng.random(3, dtype='d')
+ rng.random(3, dtype='f')
* Optional ``out`` argument that allows existing arrays to be filled for
select distributions
@@ -112,7 +112,7 @@ And in more detail:
.. ipython:: python
existing = np.zeros(4)
- rg.random(out=existing[:2])
+ rng.random(out=existing[:2])
print(existing)
* Optional ``axis`` argument for methods like `~.Generator.choice`,
@@ -121,9 +121,9 @@ And in more detail:
.. ipython:: python
- rg = Generator(PCG64(123456789))
+ rng = Generator(PCG64(123456789))
a = np.arange(12).reshape((3, 4))
a
- rg.choice(a, axis=1, size=5)
- rg.shuffle(a, axis=1) # Shuffle in-place
+ rng.choice(a, axis=1, size=5)
+ rng.shuffle(a, axis=1) # Shuffle in-place
a
diff --git a/doc/source/reference/random/parallel.rst b/doc/source/reference/random/parallel.rst
index 721584014..7f0207bde 100644
--- a/doc/source/reference/random/parallel.rst
+++ b/doc/source/reference/random/parallel.rst
@@ -88,10 +88,11 @@ territory ([2]_).
estimate the naive upper bound on a napkin and take comfort knowing
that the probability is actually lower.
-.. [2] In this calculation, we can ignore the amount of numbers drawn from each
- stream. Each of the PRNGs we provide has some extra protection built in
+.. [2] In this calculation, we can mostly ignore the amount of numbers drawn from each
+ stream. See :ref:`upgrading-pcg64` for the technical details about
+ `PCG64`. The other PRNGs we provide have some extra protection built in
that avoids overlaps if the `~SeedSequence` pools differ in the
- slightest bit. `PCG64` has :math:`2^{127}` separate cycles
+ slightest bit. `PCG64DXSM` has :math:`2^{127}` separate cycles
determined by the seed in addition to the position in the
:math:`2^{128}` long period for each cycle, so one has to both get on or
near the same cycle *and* seed a nearby position in the cycle.
@@ -150,12 +151,14 @@ BitGenerator, the size of the jump and the bits in the default unsigned random
are listed below.
+-----------------+-------------------------+-------------------------+-------------------------+
-| BitGenerator | Period | Jump Size | Bits |
+| BitGenerator | Period | Jump Size | Bits per Draw |
+=================+=========================+=========================+=========================+
-| MT19937 | :math:`2^{19937}` | :math:`2^{128}` | 32 |
+| MT19937 | :math:`2^{19937}-1` | :math:`2^{128}` | 32 |
+-----------------+-------------------------+-------------------------+-------------------------+
| PCG64 | :math:`2^{128}` | :math:`~2^{127}` ([3]_) | 64 |
+-----------------+-------------------------+-------------------------+-------------------------+
+| PCG64DXSM | :math:`2^{128}` | :math:`~2^{127}` ([3]_) | 64 |
++-----------------+-------------------------+-------------------------+-------------------------+
| Philox | :math:`2^{256}` | :math:`2^{128}` | 64 |
+-----------------+-------------------------+-------------------------+-------------------------+
diff --git a/doc/source/reference/random/performance.py b/doc/source/reference/random/performance.py
index 28a42eb0d..794142836 100644
--- a/doc/source/reference/random/performance.py
+++ b/doc/source/reference/random/performance.py
@@ -1,14 +1,13 @@
-from collections import OrderedDict
from timeit import repeat
import pandas as pd
import numpy as np
-from numpy.random import MT19937, PCG64, Philox, SFC64
+from numpy.random import MT19937, PCG64, PCG64DXSM, Philox, SFC64
-PRNGS = [MT19937, PCG64, Philox, SFC64]
+PRNGS = [MT19937, PCG64, PCG64DXSM, Philox, SFC64]
-funcs = OrderedDict()
+funcs = {}
integers = 'integers(0, 2**{bits},size=1000000, dtype="uint{bits}")'
funcs['32-bit Unsigned Ints'] = integers.format(bits=32)
funcs['64-bit Unsigned Ints'] = integers.format(bits=64)
@@ -26,10 +25,10 @@ rg = Generator({prng}())
"""
test = "rg.{func}"
-table = OrderedDict()
+table = {}
for prng in PRNGS:
print(prng)
- col = OrderedDict()
+ col = {}
for key in funcs:
t = repeat(test.format(func=funcs[key]),
setup.format(prng=prng().__class__.__name__),
@@ -38,7 +37,7 @@ for prng in PRNGS:
col = pd.Series(col)
table[prng().__class__.__name__] = col
-npfuncs = OrderedDict()
+npfuncs = {}
npfuncs.update(funcs)
npfuncs['32-bit Unsigned Ints'] = 'randint(2**32,dtype="uint32",size=1000000)'
npfuncs['64-bit Unsigned Ints'] = 'randint(2**64,dtype="uint64",size=1000000)'
@@ -54,7 +53,7 @@ for key in npfuncs:
col[key] = 1000 * min(t)
table['RandomState'] = pd.Series(col)
-columns = ['MT19937','PCG64','Philox','SFC64', 'RandomState']
+columns = ['MT19937', 'PCG64', 'PCG64DXSM', 'Philox', 'SFC64', 'RandomState']
table = pd.DataFrame(table)
order = np.log(table).mean().sort_values().index
table = table.T
diff --git a/doc/source/reference/random/performance.rst b/doc/source/reference/random/performance.rst
index 74dad4cc3..85855be59 100644
--- a/doc/source/reference/random/performance.rst
+++ b/doc/source/reference/random/performance.rst
@@ -5,9 +5,12 @@ Performance
Recommendation
**************
-The recommended generator for general use is `PCG64`. It is
-statistically high quality, full-featured, and fast on most platforms, but
-somewhat slow when compiled for 32-bit processes.
+
+The recommended generator for general use is `PCG64` or its upgraded variant
+`PCG64DXSM` for heavily-parallel use cases. They are statistically high quality,
+full-featured, and fast on most platforms, but somewhat slow when compiled for
+32-bit processes. See :ref:`upgrading-pcg64` for details on when heavy
+parallelism would indicate using `PCG64DXSM`.
`Philox` is fairly slow, but its statistical properties have
very high quality, and it is easy to get assuredly-independent stream by using
@@ -39,49 +42,48 @@ Integer performance has a similar ordering.
The pattern is similar for other, more complex generators. The normal
performance of the legacy `RandomState` generator is much
-lower than the other since it uses the Box-Muller transformation rather
-than the Ziggurat generator. The performance gap for Exponentials is also
+lower than the other since it uses the Box-Muller transform rather
+than the Ziggurat method. The performance gap for Exponentials is also
large due to the cost of computing the log function to invert the CDF.
-The column labeled MT19973 is used the same 32-bit generator as
-`RandomState` but produces random values using
-`Generator`.
+The column labeled MT19973 uses the same 32-bit generator as
+`RandomState` but produces random variates using `Generator`.
.. csv-table::
- :header: ,MT19937,PCG64,Philox,SFC64,RandomState
- :widths: 14,14,14,14,14,14
-
- 32-bit Unsigned Ints,3.2,2.7,4.9,2.7,3.2
- 64-bit Unsigned Ints,5.6,3.7,6.3,2.9,5.7
- Uniforms,7.3,4.1,8.1,3.1,7.3
- Normals,13.1,10.2,13.5,7.8,34.6
- Exponentials,7.9,5.4,8.5,4.1,40.3
- Gammas,34.8,28.0,34.7,25.1,58.1
- Binomials,25.0,21.4,26.1,19.5,25.2
- Laplaces,45.1,40.7,45.5,38.1,45.6
- Poissons,67.6,52.4,69.2,46.4,78.1
+ :header: ,MT19937,PCG64,PCG64DXSM,Philox,SFC64,RandomState
+ :widths: 14,14,14,14,14,14,14
+
+ 32-bit Unsigned Ints,3.3,1.9,2.0,3.3,1.8,3.1
+ 64-bit Unsigned Ints,5.6,3.2,2.9,4.9,2.5,5.5
+ Uniforms,5.9,3.1,2.9,5.0,2.6,6.0
+ Normals,13.9,10.8,10.5,12.0,8.3,56.8
+ Exponentials,9.1,6.0,5.8,8.1,5.4,63.9
+ Gammas,37.2,30.8,28.9,34.0,27.5,77.0
+ Binomials,21.3,17.4,17.6,19.3,15.6,21.4
+ Laplaces,73.2,72.3,76.1,73.0,72.3,82.5
+ Poissons,111.7,103.4,100.5,109.4,90.7,115.2
The next table presents the performance in percentage relative to values
generated by the legacy generator, ``RandomState(MT19937())``. The overall
performance was computed using a geometric mean.
.. csv-table::
- :header: ,MT19937,PCG64,Philox,SFC64
- :widths: 14,14,14,14,14
-
- 32-bit Unsigned Ints,101,121,67,121
- 64-bit Unsigned Ints,102,156,91,199
- Uniforms,100,179,90,235
- Normals,263,338,257,443
- Exponentials,507,752,474,985
- Gammas,167,207,167,231
- Binomials,101,118,96,129
- Laplaces,101,112,100,120
- Poissons,116,149,113,168
- Overall,144,192,132,225
+ :header: ,MT19937,PCG64,PCG64DXSM,Philox,SFC64
+ :widths: 14,14,14,14,14,14
+
+ 32-bit Unsigned Ints,96,162,160,96,175
+ 64-bit Unsigned Ints,97,171,188,113,218
+ Uniforms,102,192,206,121,233
+ Normals,409,526,541,471,684
+ Exponentials,701,1071,1101,784,1179
+ Gammas,207,250,266,227,281
+ Binomials,100,123,122,111,138
+ Laplaces,113,114,108,113,114
+ Poissons,103,111,115,105,127
+ Overall,159,219,225,174,251
.. note::
- All timings were taken using Linux on an i5-3570 processor.
+ All timings were taken using Linux on an AMD Ryzen 9 3900X processor.
Performance on different Operating Systems
******************************************
@@ -98,33 +100,33 @@ across tables.
64-bit Linux
~~~~~~~~~~~~
-=================== ========= ======= ======== =======
-Distribution MT19937 PCG64 Philox SFC64
-=================== ========= ======= ======== =======
-32-bit Unsigned Int 100 119.8 67.7 120.2
-64-bit Unsigned Int 100 152.9 90.8 213.3
-Uniforms 100 179.0 87.0 232.0
-Normals 100 128.5 99.2 167.8
-Exponentials 100 148.3 93.0 189.3
-**Overall** 100 144.3 86.8 180.0
-=================== ========= ======= ======== =======
+===================== ========= ======= =========== ======== =======
+Distribution MT19937 PCG64 PCG64DXSM Philox SFC64
+===================== ========= ======= =========== ======== =======
+32-bit Unsigned Ints 100 168 166 100 182
+64-bit Unsigned Ints 100 176 193 116 224
+Uniforms 100 188 202 118 228
+Normals 100 128 132 115 167
+Exponentials 100 152 157 111 168
+Overall 100 161 168 112 192
+===================== ========= ======= =========== ======== =======
64-bit Windows
~~~~~~~~~~~~~~
-The relative performance on 64-bit Linux and 64-bit Windows is broadly similar.
-
+The relative performance on 64-bit Linux and 64-bit Windows is broadly similar
+with the notable exception of the Philox generator.
-=================== ========= ======= ======== =======
-Distribution MT19937 PCG64 Philox SFC64
-=================== ========= ======= ======== =======
-32-bit Unsigned Int 100 129.1 35.0 135.0
-64-bit Unsigned Int 100 146.9 35.7 176.5
-Uniforms 100 165.0 37.0 192.0
-Normals 100 128.5 48.5 158.0
-Exponentials 100 151.6 39.0 172.8
-**Overall** 100 143.6 38.7 165.7
-=================== ========= ======= ======== =======
+===================== ========= ======= =========== ======== =======
+Distribution MT19937 PCG64 PCG64DXSM Philox SFC64
+===================== ========= ======= =========== ======== =======
+32-bit Unsigned Ints 100 155 131 29 150
+64-bit Unsigned Ints 100 157 143 25 154
+Uniforms 100 151 144 24 155
+Normals 100 129 128 37 150
+Exponentials 100 150 145 28 159
+**Overall** 100 148 138 28 154
+===================== ========= ======= =========== ======== =======
32-bit Windows
@@ -134,20 +136,20 @@ The performance of 64-bit generators on 32-bit Windows is much lower than on 64-
operating systems due to register width. MT19937, the generator that has been
in NumPy since 2005, operates on 32-bit integers.
-=================== ========= ======= ======== =======
-Distribution MT19937 PCG64 Philox SFC64
-=================== ========= ======= ======== =======
-32-bit Unsigned Int 100 30.5 21.1 77.9
-64-bit Unsigned Int 100 26.3 19.2 97.0
-Uniforms 100 28.0 23.0 106.0
-Normals 100 40.1 31.3 112.6
-Exponentials 100 33.7 26.3 109.8
-**Overall** 100 31.4 23.8 99.8
-=================== ========= ======= ======== =======
+===================== ========= ======= =========== ======== =======
+Distribution MT19937 PCG64 PCG64DXSM Philox SFC64
+===================== ========= ======= =========== ======== =======
+32-bit Unsigned Ints 100 24 34 14 57
+64-bit Unsigned Ints 100 21 32 14 74
+Uniforms 100 21 34 16 73
+Normals 100 36 57 28 101
+Exponentials 100 28 44 20 88
+**Overall** 100 25 39 18 77
+===================== ========= ======= =========== ======== =======
.. note::
- Linux timings used Ubuntu 18.04 and GCC 7.4. Windows timings were made on
+ Linux timings used Ubuntu 20.04 and GCC 9.3.0. Windows timings were made on
Windows 10 using Microsoft C/C++ Optimizing Compiler Version 19 (Visual
- Studio 2015). All timings were produced on an i5-3570 processor.
+ Studio 2019). All timings were produced on an AMD Ryzen 9 3900X processor.
diff --git a/doc/source/reference/random/upgrading-pcg64.rst b/doc/source/reference/random/upgrading-pcg64.rst
new file mode 100644
index 000000000..9e540ace9
--- /dev/null
+++ b/doc/source/reference/random/upgrading-pcg64.rst
@@ -0,0 +1,152 @@
+.. _upgrading-pcg64:
+
+.. currentmodule:: numpy.random
+
+Upgrading ``PCG64`` with ``PCG64DXSM``
+--------------------------------------
+
+Uses of the `PCG64` `BitGenerator` in a massively-parallel context have been
+shown to have statistical weaknesses that were not apparent at the first
+release in numpy 1.17. Most users will never observe this weakness and are
+safe to continue to use `PCG64`. We have introduced a new `PCG64DXSM`
+`BitGenerator` that will eventually become the new default `BitGenerator`
+implementation used by `default_rng` in future releases. `PCG64DXSM` solves
+the statistical weakness while preserving the performance and the features of
+`PCG64`.
+
+Does this affect me?
+====================
+
+If you
+
+ 1. only use a single `Generator` instance,
+ 2. only use `RandomState` or the functions in `numpy.random`,
+ 3. only use the `PCG64.jumped` method to generate parallel streams,
+ 4. explicitly use a `BitGenerator` other than `PCG64`,
+
+then this weakness does not affect you at all. Carry on.
+
+If you use moderate numbers of parallel streams created with `default_rng` or
+`SeedSequence.spawn`, in the 1000s, then the chance of observing this weakness
+is negligibly small. You can continue to use `PCG64` comfortably.
+
+If you use very large numbers of parallel streams, in the millions, and draw
+large amounts of numbers from each, then the chance of observing this weakness
+can become non-negligible, if still small. An example of such a use case would
+be a very large distributed reinforcement learning problem with millions of
+long Monte Carlo playouts each generating billions of random number draws. Such
+use cases should consider using `PCG64DXSM` explicitly or another
+modern `BitGenerator` like `SFC64` or `Philox`, but it is unlikely that any
+old results you may have calculated are invalid. In any case, the weakness is
+a kind of `Birthday Paradox <https://en.wikipedia.org/wiki/Birthday_problem>`_
+collision. That is, a single pair of parallel streams out of the millions,
+considered together, might fail a stringent set of statistical tests of
+randomness. The remaining millions of streams would all be perfectly fine, and
+the effect of the bad pair in the whole calculation is very likely to be
+swamped by the remaining streams in most applications.
+
+.. _upgrading-pcg64-details:
+
+Technical Details
+=================
+
+Like many PRNG algorithms, `PCG64` is constructed from a transition function,
+which advances a 128-bit state, and an output function, that mixes the 128-bit
+state into a 64-bit integer to be output. One of the guiding design principles
+of the PCG family of PRNGs is to balance the computational cost (and
+pseudorandomness strength) between the transition function and the output
+function. The transition function is a 128-bit linear congruential generator
+(LCG), which consists of multiplying the 128-bit state with a fixed
+multiplication constant and then adding a user-chosen increment, in 128-bit
+modular arithmetic. LCGs are well-analyzed PRNGs with known weaknesses, though
+128-bit LCGs are large enough to pass stringent statistical tests on their own,
+with only the trivial output function. The output function of `PCG64` is
+intended to patch up some of those known weaknesses by doing "just enough"
+scrambling of the bits to assist in the statistical properties without adding
+too much computational cost.
+
+One of these known weaknesses is that advancing the state of the LCG by steps
+numbering a power of two (``bg.advance(2**N)``) will leave the lower ``N`` bits
+identical to the state that was just left. For a single stream drawn from
+sequentially, this is of little consequence. The remaining :math:`128-N` bits provide
+plenty of pseudorandomness that will be mixed in for any practical ``N`` that can
+be observed in a single stream, which is why one does not need to worry about
+this if you only use a single stream in your application. Similarly, the
+`PCG64.jumped` method uses a carefully chosen number of steps to avoid creating
+these collisions. However, once you start creating "randomly-initialized"
+parallel streams, either using OS entropy by calling `default_rng` repeatedly
+or using `SeedSequence.spawn`, then we need to consider how many lower bits
+need to "collide" in order to create a bad pair of streams, and then evaluate
+the probability of creating such a collision.
+`Empirically <https://github.com/numpy/numpy/issues/16313>`_, it has been
+determined that if one shares the lower 58 bits of state and shares an
+increment, then the pair of streams, when interleaved, will fail
+`PractRand <http://pracrand.sourceforge.net/>`_ in
+a reasonable amount of time, after drawing a few gigabytes of data. Following
+the standard Birthday Paradox calculations for a collision of 58 bits, we can
+see that we can create :math:`2^{29}`, or about half a billion, streams which is when
+the probability of such a collision becomes high. Half a billion streams is
+quite high, and the amount of data each stream needs to draw before the
+statistical correlations become apparent to even the strict ``PractRand`` tests
+is in the gigabytes. But this is on the horizon for very large applications
+like distributed reinforcement learning. There are reasons to expect that even
+in these applications a collision probably will not have a practical effect in
+the total result, since the statistical problem is constrained to just the
+colliding pair.
+
+Now, let us consider the case when the increment is not constrained to be the
+same. Our implementation of `PCG64` seeds both the state and the increment;
+that is, two calls to `default_rng` (almost certainly) have different states
+and increments. Upon our first release, we believed that having the seeded
+increment would provide a certain amount of extra protection, that one would
+have to be "close" in both the state space and increment space in order to
+observe correlations (``PractRand`` failures) in a pair of streams. If that were
+true, then the "bottleneck" for collisions would be the 128-bit entropy pool
+size inside of `SeedSequence` (and 128-bit collisions are in the
+"preposterously unlikely" category). Unfortunately, this is not true.
+
+One of the known properties of an LCG is that different increments create
+*distinct* streams, but with a known relationship. Each LCG has an orbit that
+traverses all :math:`2^{128}` different 128-bit states. Two LCGs with different
+increments are related in that one can "rotate" the orbit of the first LCG
+(advance it by a number of steps that we can compute from the two increments)
+such that then both LCGs will always then have the same state, up to an
+additive constant and maybe an inversion of the bits. If you then iterate both
+streams in lockstep, then the states will *always* remain related by that same
+additive constant (and the inversion, if present). Recall that `PCG64` is
+constructed from both a transition function (the LCG) and an output function.
+It was expected that the scrambling effect of the output function would have
+been strong enough to make the distinct streams practically independent (i.e.
+"passing the ``PractRand`` tests") unless the two increments were
+pathologically related to each other (e.g. 1 and 3). The output function XSL-RR
+of the then-standard PCG algorithm that we implemented in `PCG64` turns out to
+be too weak to cover up for the 58-bit collision of the underlying LCG that we
+described above. For any given pair of increments, the size of the "colliding"
+space of states is the same, so for this weakness, the extra distinctness
+provided by the increments does not translate into extra protection from
+statistical correlations that ``PractRand`` can detect.
+
+Fortunately, strengthening the output function is able to correct this weakness
+and *does* turn the extra distinctness provided by differing increments into
+additional protection from these low-bit collisions. To the `PCG author's
+credit <https://github.com/numpy/numpy/issues/13635#issuecomment-506088698>`_,
+she had developed a stronger output function in response to related discussions
+during the long birth of the new `BitGenerator` system. We NumPy developers
+chose to be "conservative" and use the XSL-RR variant that had undergone
+a longer period of testing at that time. The DXSM output function adopts
+a "xorshift-multiply" construction used in strong integer hashes that has much
+better avalanche properties than the XSL-RR output function. While there are
+"pathological" pairs of increments that induce "bad" additive constants that
+relate the two streams, the vast majority of pairs induce "good" additive
+constants that make the merely-distinct streams of LCG states into
+practically-independent output streams. Indeed, now the claim we once made
+about `PCG64` is actually true of `PCG64DXSM`: collisions are possible, but
+both streams have to simultaneously be both "close" in the 128 bit state space
+*and* "close" in the 127-bit increment space, so that would be less likely than
+the negligible chance of colliding in the 128-bit internal `SeedSequence` pool.
+The DXSM output function is more computationally intensive than XSL-RR, but
+some optimizations in the LCG more than make up for the performance hit on most
+machines, so `PCG64DXSM` is a good, safe upgrade. There are, of course, an
+infinite number of stronger output functions that one could consider, but most
+will have a greater computational cost, and the DXSM output function has now
+received many CPU cycles of testing via ``PractRand`` at this time.
diff --git a/doc/source/reference/routines.array-creation.rst b/doc/source/reference/routines.array-creation.rst
index e718f0052..30780c286 100644
--- a/doc/source/reference/routines.array-creation.rst
+++ b/doc/source/reference/routines.array-creation.rst
@@ -7,8 +7,8 @@ Array creation routines
.. currentmodule:: numpy
-Ones and zeros
---------------
+From shape or value
+-------------------
.. autosummary::
:toctree: generated/
diff --git a/doc/source/reference/routines.ctypeslib.rst b/doc/source/reference/routines.ctypeslib.rst
index 3a059f5d9..c6127ca64 100644
--- a/doc/source/reference/routines.ctypeslib.rst
+++ b/doc/source/reference/routines.ctypeslib.rst
@@ -11,3 +11,10 @@ C-Types Foreign Function Interface (:mod:`numpy.ctypeslib`)
.. autofunction:: as_ctypes_type
.. autofunction:: load_library
.. autofunction:: ndpointer
+
+.. class:: c_intp
+
+ A `ctypes` signed integer type of the same size as `numpy.intp`.
+
+ Depending on the platform, it can be an alias for either `~ctypes.c_int`,
+ `~ctypes.c_long` or `~ctypes.c_longlong`.
diff --git a/doc/source/reference/routines.linalg.rst b/doc/source/reference/routines.linalg.rst
index 86e168b26..76b7ab82c 100644
--- a/doc/source/reference/routines.linalg.rst
+++ b/doc/source/reference/routines.linalg.rst
@@ -30,10 +30,26 @@ flexible broadcasting options. For example, `numpy.linalg.solve` can handle
"stacked" arrays, while `scipy.linalg.solve` accepts only a single square
array as its first argument.
+.. note::
+
+ The term *matrix* as it is used on this page indicates a 2d `numpy.array`
+ object, and *not* a `numpy.matrix` object. The latter is no longer
+ recommended, even for linear algebra. See
+ :ref:`the matrix object documentation<matrix-objects>` for
+ more information.
+
+The ``@`` operator
+------------------
+
+Introduced in NumPy 1.10.0, the ``@`` operator is preferable to
+other methods when computing the matrix product between 2d arrays. The
+:func:`numpy.matmul` function implements the ``@`` operator.
+
.. currentmodule:: numpy
Matrix and vector products
--------------------------
+
.. autosummary::
:toctree: generated/
diff --git a/doc/source/reference/routines.other.rst b/doc/source/reference/routines.other.rst
index aefd680bb..339857409 100644
--- a/doc/source/reference/routines.other.rst
+++ b/doc/source/reference/routines.other.rst
@@ -55,4 +55,11 @@ Matlab-like Functions
:toctree: generated/
who
- disp \ No newline at end of file
+ disp
+
+Exceptions
+----------
+.. autosummary::
+ :toctree: generated/
+
+ AxisError
diff --git a/doc/source/reference/routines.polynomials.classes.rst b/doc/source/reference/routines.polynomials.classes.rst
index 10331e9c1..5f575bed1 100644
--- a/doc/source/reference/routines.polynomials.classes.rst
+++ b/doc/source/reference/routines.polynomials.classes.rst
@@ -290,7 +290,8 @@ polynomials up to degree 5 are plotted below.
>>> import matplotlib.pyplot as plt
>>> from numpy.polynomial import Chebyshev as T
>>> x = np.linspace(-1, 1, 100)
- >>> for i in range(6): ax = plt.plot(x, T.basis(i)(x), lw=2, label="$T_%d$"%i)
+ >>> for i in range(6):
+ ... ax = plt.plot(x, T.basis(i)(x), lw=2, label=f"$T_{i}$")
...
>>> plt.legend(loc="upper left")
<matplotlib.legend.Legend object at 0x3b3ee10>
@@ -304,7 +305,8 @@ The same plots over the range -2 <= `x` <= 2 look very different:
>>> import matplotlib.pyplot as plt
>>> from numpy.polynomial import Chebyshev as T
>>> x = np.linspace(-2, 2, 100)
- >>> for i in range(6): ax = plt.plot(x, T.basis(i)(x), lw=2, label="$T_%d$"%i)
+ >>> for i in range(6):
+ ... ax = plt.plot(x, T.basis(i)(x), lw=2, label=f"$T_{i}$")
...
>>> plt.legend(loc="lower right")
<matplotlib.legend.Legend object at 0x3b3ee10>
diff --git a/doc/source/reference/routines.polynomials.rst b/doc/source/reference/routines.polynomials.rst
index e74c5a683..ecfb012f0 100644
--- a/doc/source/reference/routines.polynomials.rst
+++ b/doc/source/reference/routines.polynomials.rst
@@ -9,24 +9,165 @@ of the `numpy.polynomial` package, introduced in NumPy 1.4.
Prior to NumPy 1.4, `numpy.poly1d` was the class of choice and it is still
available in order to maintain backward compatibility.
-However, the newer Polynomial package is more complete than `numpy.poly1d`
-and its convenience classes are better behaved in the numpy environment.
+However, the newer `polynomial package <numpy.polynomial>` is more complete
+and its `convenience classes <routines.polynomials.classes>` provide a
+more consistent, better-behaved interface for working with polynomial
+expressions.
Therefore :mod:`numpy.polynomial` is recommended for new coding.
-Transition notice
------------------
-The various routines in the Polynomial package all deal with
-series whose coefficients go from degree zero upward,
-which is the *reverse order* of the Poly1d convention.
-The easy way to remember this is that indexes
-correspond to degree, i.e., coef[i] is the coefficient of the term of
-degree i.
+.. note:: **Terminology**
+ The term *polynomial module* refers to the old API defined in
+ `numpy.lib.polynomial`, which includes the :class:`numpy.poly1d` class and
+ the polynomial functions prefixed with *poly* accessible from the `numpy`
+ namespace (e.g. `numpy.polyadd`, `numpy.polyval`, `numpy.polyfit`, etc.).
+
+ The term *polynomial package* refers to the new API definied in
+ `numpy.polynomial`, which includes the convenience classes for the
+ different kinds of polynomials (`numpy.polynomial.Polynomial`,
+ `numpy.polynomial.Chebyshev`, etc.).
+
+Transitioning from `numpy.poly1d` to `numpy.polynomial`
+-------------------------------------------------------
+
+As noted above, the :class:`poly1d class <numpy.poly1d>` and associated
+functions defined in ``numpy.lib.polynomial``, such as `numpy.polyfit`
+and `numpy.poly`, are considered legacy and should **not** be used in new
+code.
+Since NumPy version 1.4, the `numpy.polynomial` package is preferred for
+working with polynomials.
+
+Quick Reference
+~~~~~~~~~~~~~~~
+
+The following table highlights some of the main differences between the
+legacy polynomial module and the polynomial package for common tasks.
+The `~numpy.polynomial.polynomial.Polynomial` class is imported for brevity::
+
+ from numpy.polynomial import Polynomial
+
+
++------------------------+------------------------------+---------------------------------------+
+| **How to...** | Legacy (`numpy.poly1d`) | `numpy.polynomial` |
++------------------------+------------------------------+---------------------------------------+
+| Create a | ``p = np.poly1d([1, 2, 3])`` | ``p = Polynomial([3, 2, 1])`` |
+| polynomial object | | |
+| from coefficients [1]_ | | |
++------------------------+------------------------------+---------------------------------------+
+| Create a polynomial | ``r = np.poly([-1, 1])`` | ``p = Polynomial.fromroots([-1, 1])`` |
+| object from roots | ``p = np.poly1d(r)`` | |
++------------------------+------------------------------+---------------------------------------+
+| Fit a polynomial of | | |
+| degree ``deg`` to data | ``np.polyfit(x, y, deg)`` | ``Polynomial.fit(x, y, deg)`` |
++------------------------+------------------------------+---------------------------------------+
+
+
+.. [1] Note the reversed ordering of the coefficients
+
+Transition Guide
+~~~~~~~~~~~~~~~~
+
+There are significant differences between ``numpy.lib.polynomial`` and
+`numpy.polynomial`.
+The most significant difference is the ordering of the coefficients for the
+polynomial expressions.
+The various routines in `numpy.polynomial` all
+deal with series whose coefficients go from degree zero upward,
+which is the *reverse order* of the poly1d convention.
+The easy way to remember this is that indices
+correspond to degree, i.e., ``coef[i]`` is the coefficient of the term of
+degree *i*.
+
+Though the difference in convention may be confusing, it is straightforward to
+convert from the legacy polynomial API to the new.
+For example, the following demonstrates how you would convert a `numpy.poly1d`
+instance representing the expression :math:`x^{2} + 2x + 3` to a
+`~numpy.polynomial.polynomial.Polynomial` instance representing the same
+expression::
+
+ >>> p1d = np.poly1d([1, 2, 3])
+ >>> p = np.polynomial.Polynomial(p1d.coef[::-1])
+
+In addition to the ``coef`` attribute, polynomials from the polynomial
+package also have ``domain`` and ``window`` attributes.
+These attributes are most relevant when fitting
+polynomials to data, though it should be noted that polynomials with
+different ``domain`` and ``window`` attributes are not considered equal, and
+can't be mixed in arithmetic::
+
+ >>> p1 = np.polynomial.Polynomial([1, 2, 3])
+ >>> p1
+ Polynomial([1., 2., 3.], domain=[-1, 1], window=[-1, 1])
+ >>> p2 = np.polynomial.Polynomial([1, 2, 3], domain=[-2, 2])
+ >>> p1 == p2
+ False
+ >>> p1 + p2
+ Traceback (most recent call last):
+ ...
+ TypeError: Domains differ
+
+See the documentation for the
+`convenience classes <routines.polynomials.classes>`_ for further details on
+the ``domain`` and ``window`` attributes.
+
+Another major difference bewteen the legacy polynomial module and the
+polynomial package is polynomial fitting. In the old module, fitting was
+done via the `~numpy.polyfit` function. In the polynomial package, the
+`~numpy.polynomial.polynomial.Polynomial.fit` class method is preferred. For
+example, consider a simple linear fit to the following data:
+
+.. ipython:: python
+
+ rng = np.random.default_rng()
+ x = np.arange(10)
+ y = np.arange(10) + rng.standard_normal(10)
+
+With the legacy polynomial module, a linear fit (i.e. polynomial of degree 1)
+could be applied to these data with `~numpy.polyfit`:
+
+.. ipython:: python
+
+ np.polyfit(x, y, deg=1)
+
+With the new polynomial API, the `~numpy.polynomial.polynomial.Polynomial.fit`
+class method is preferred:
+
+.. ipython:: python
+
+ p_fitted = np.polynomial.Polynomial.fit(x, y, deg=1)
+ p_fitted
+
+Note that the coefficients are given *in the scaled domain* defined by the
+linear mapping between the ``window`` and ``domain``.
+`~numpy.polynomial.polynomial.Polynomial.convert` can be used to get the
+coefficients in the unscaled data domain.
+
+.. ipython:: python
+
+ p_fitted.convert()
+
+Documentation for the `~numpy.polynomial` Package
+-------------------------------------------------
+
+In addition to standard power series polynomials, the polynomial package
+provides several additional kinds of polynomials including Chebyshev,
+Hermite (two subtypes), Laguerre, and Legendre polynomials.
+Each of these has an associated
+`convenience class <routines.polynomials.classes>` available from the
+`numpy.polynomial` namespace that provides a consistent interface for working
+with polynomials regardless of their type.
.. toctree::
:maxdepth: 1
routines.polynomials.classes
+
+Documentation pertaining to specific functions defined for each kind of
+polynomial individually can be found in the corresponding module documentation:
+
+.. toctree::
+ :maxdepth: 1
+
routines.polynomials.polynomial
routines.polynomials.chebyshev
routines.polynomials.hermite
@@ -36,6 +177,9 @@ degree i.
routines.polynomials.polyutils
+Documentation for Legacy Polynomials
+------------------------------------
+
.. toctree::
:maxdepth: 2
diff --git a/doc/source/reference/routines.testing.rst b/doc/source/reference/routines.testing.rst
index 98ce3f377..d9e98e941 100644
--- a/doc/source/reference/routines.testing.rst
+++ b/doc/source/reference/routines.testing.rst
@@ -18,9 +18,6 @@ Asserts
.. autosummary::
:toctree: generated/
- assert_almost_equal
- assert_approx_equal
- assert_array_almost_equal
assert_allclose
assert_array_almost_equal_nulp
assert_array_max_ulp
@@ -32,6 +29,19 @@ Asserts
assert_warns
assert_string_equal
+Asserts (not recommended)
+-------------------------
+It is recommended to use one of `assert_allclose`,
+`assert_array_almost_equal_nulp` or `assert_array_max_ulp` instead of these
+functions for more consistent floating point comparisons.
+
+.. autosummary::
+ :toctree: generated/
+
+ assert_almost_equal
+ assert_approx_equal
+ assert_array_almost_equal
+
Decorators
----------
.. autosummary::
diff --git a/doc/source/reference/simd/simd-optimizations.py b/doc/source/reference/simd/simd-optimizations.py
index 5d6da50e3..a78302db5 100644
--- a/doc/source/reference/simd/simd-optimizations.py
+++ b/doc/source/reference/simd/simd-optimizations.py
@@ -8,7 +8,7 @@ gen_path = path.dirname(path.realpath(__file__))
from numpy.distutils.ccompiler_opt import CCompilerOpt
class FakeCCompilerOpt(CCompilerOpt):
- fake_info = ""
+ fake_info = ("arch", "compiler", "extra_args")
# disable caching no need for it
conf_nocache = True
def __init__(self, *args, **kwargs):
@@ -101,7 +101,7 @@ def features_table_sections(name, ftable=None, gtable=None, tab_size=4):
return content
def features_table(arch, cc="gcc", pretty_name=None, **kwargs):
- FakeCCompilerOpt.fake_info = arch + cc
+ FakeCCompilerOpt.fake_info = (arch, cc, '')
ccopt = FakeCCompilerOpt(cpu_baseline="max")
features = ccopt.cpu_baseline_names()
ftable = ccopt.gen_features_table(features, **kwargs)
@@ -112,12 +112,12 @@ def features_table(arch, cc="gcc", pretty_name=None, **kwargs):
return features_table_sections(pretty_name, ftable, gtable, **kwargs)
def features_table_diff(arch, cc, cc_vs="gcc", pretty_name=None, **kwargs):
- FakeCCompilerOpt.fake_info = arch + cc
+ FakeCCompilerOpt.fake_info = (arch, cc, '')
ccopt = FakeCCompilerOpt(cpu_baseline="max")
fnames = ccopt.cpu_baseline_names()
features = {f:ccopt.feature_implies(f) for f in fnames}
- FakeCCompilerOpt.fake_info = arch + cc_vs
+ FakeCCompilerOpt.fake_info = (arch, cc_vs, '')
ccopt_vs = FakeCCompilerOpt(cpu_baseline="max")
fnames_vs = ccopt_vs.cpu_baseline_names()
features_vs = {f:ccopt_vs.feature_implies(f) for f in fnames_vs}
diff --git a/doc/source/reference/simd/simd-optimizations.rst b/doc/source/reference/simd/simd-optimizations.rst
index 59a4892b2..956824321 100644
--- a/doc/source/reference/simd/simd-optimizations.rst
+++ b/doc/source/reference/simd/simd-optimizations.rst
@@ -96,8 +96,8 @@ NOTES
arguments must be enclosed in quotes.
- The operand ``+`` is only added for nominal reasons, For example:
- ``--cpu-basline= "min avx2"`` is equivalent to ``--cpu-basline="min + avx2"``.
- ``--cpu-basline="min,avx2"`` is equivalent to ``--cpu-basline`="min,+avx2"``
+ ``--cpu-baseline= "min avx2"`` is equivalent to ``--cpu-baseline="min + avx2"``.
+ ``--cpu-baseline="min,avx2"`` is equivalent to ``--cpu-baseline`="min,+avx2"``
- If the CPU feature is not supported by the user platform or
compiler, it will be skipped rather than raising a fatal error.
diff --git a/doc/source/reference/ufuncs.rst b/doc/source/reference/ufuncs.rst
index 06fbe28dd..3eae4e159 100644
--- a/doc/source/reference/ufuncs.rst
+++ b/doc/source/reference/ufuncs.rst
@@ -266,7 +266,7 @@ can generate this table for your system with the code given in the Figure.
S - - - - - - - - - - - - - - - - - - - - Y Y Y Y - -
U - - - - - - - - - - - - - - - - - - - - - Y Y Y - -
V - - - - - - - - - - - - - - - - - - - - - - Y Y - -
- O - - - - - - - - - - - - - - - - - - - - - - Y Y - -
+ O - - - - - - - - - - - - - - - - - - - - - - - Y - -
M - - - - - - - - - - - - - - - - - - - - - - Y Y Y -
m - - - - - - - - - - - - - - - - - - - - - - Y Y - Y
@@ -430,8 +430,10 @@ advanced usage and will not typically be used.
.. versionadded:: 1.6
- Overrides the dtype of the calculation and output arrays. Similar to
- *signature*.
+ Overrides the DType of the output arrays the same way as the *signature*.
+ This should ensure a matching precision of the calculation. The exact
+ calculation DTypes chosen may depend on the ufunc and the inputs may be
+ cast to this DType to perform the calculation.
*subok*
@@ -442,20 +444,31 @@ advanced usage and will not typically be used.
*signature*
- Either a data-type, a tuple of data-types, or a special signature
- string indicating the input and output types of a ufunc. This argument
- allows you to provide a specific signature for the 1-d loop to use
- in the underlying calculation. If the loop specified does not exist
- for the ufunc, then a TypeError is raised. Normally, a suitable loop is
- found automatically by comparing the input types with what is
- available and searching for a loop with data-types to which all inputs
- can be cast safely. This keyword argument lets you bypass that
- search and choose a particular loop. A list of available signatures is
- provided by the **types** attribute of the ufunc object. For backwards
- compatibility this argument can also be provided as *sig*, although
- the long form is preferred. Note that this should not be confused with
- the generalized ufunc :ref:`signature <details-of-signature>` that is
- stored in the **signature** attribute of the of the ufunc object.
+ Either a Dtype, a tuple of DTypes, or a special signature string
+ indicating the input and output types of a ufunc.
+
+ This argument allows the user to specify exact DTypes to be used for the
+ calculation. Casting will be used as necessary. The actual DType of the
+ input arrays is not considered unless ``signature`` is ``None`` for
+ that array.
+
+ When all DTypes are fixed, a specific loop is chosen or an error raised
+ if no matching loop exists.
+ If some DTypes are not specified and left ``None``, the behaviour may
+ depend on the ufunc.
+ At this time, a list of available signatures is provided by the **types**
+ attribute of the ufunc. (This list may be missing DTypes not defined
+ by NumPy.)
+
+ The ``signature`` only specifies the DType class/type. For example, it
+ can specifiy that the operation should be ``datetime64`` or ``float64``
+ operation. It does not specify the ``datetime64`` time-unit or the
+ ``float64`` byte-order.
+
+ For backwards compatibility this argument can also be provided as *sig*,
+ although the long form is preferred. Note that this should not be
+ confused with the generalized ufunc :ref:`signature <details-of-signature>`
+ that is stored in the **signature** attribute of the of the ufunc object.
*extobj*
@@ -628,8 +641,8 @@ Math operations
for large calculations. If your arrays are large, complicated
expressions can take longer than absolutely necessary due to the
creation and (later) destruction of temporary calculation
- spaces. For example, the expression ``G = a * b + c`` is equivalent to
- ``t1 = A * B; G = T1 + C; del t1``. It will be more quickly executed
+ spaces. For example, the expression ``G = A * B + C`` is equivalent to
+ ``T1 = A * B; G = T1 + C; del T1``. It will be more quickly executed
as ``G = A * B; add(G, C, G)`` which is the same as
``G = A * B; G += C``.
diff --git a/doc/source/release.rst b/doc/source/release.rst
index 29199fb83..484181a4f 100644
--- a/doc/source/release.rst
+++ b/doc/source/release.rst
@@ -5,13 +5,20 @@ Release Notes
.. toctree::
:maxdepth: 3
+ 1.22.0 <release/1.22.0-notes>
+ 1.21.1 <release/1.21.1-notes>
1.21.0 <release/1.21.0-notes>
+ 1.20.3 <release/1.20.3-notes>
+ 1.20.2 <release/1.20.2-notes>
+ 1.20.1 <release/1.20.1-notes>
1.20.0 <release/1.20.0-notes>
+ 1.19.5 <release/1.19.5-notes>
1.19.4 <release/1.19.4-notes>
1.19.3 <release/1.19.3-notes>
1.19.2 <release/1.19.2-notes>
1.19.1 <release/1.19.1-notes>
1.19.0 <release/1.19.0-notes>
+ 1.18.5 <release/1.18.5-notes>
1.18.4 <release/1.18.4-notes>
1.18.3 <release/1.18.3-notes>
1.18.2 <release/1.18.2-notes>
diff --git a/doc/source/release/1.18.5-notes.rst b/doc/source/release/1.18.5-notes.rst
new file mode 100644
index 000000000..e704c001a
--- /dev/null
+++ b/doc/source/release/1.18.5-notes.rst
@@ -0,0 +1,31 @@
+.. currentmodule:: numpy
+
+==========================
+NumPy 1.18.5 Release Notes
+==========================
+
+This is a short release to allow pickle ``protocol=5`` to be used in
+Python3.5. It is motivated by the recent backport of pickle5 to Python3.5.
+
+The Python versions supported in this release are 3.5-3.8. Downstream
+developers should use Cython >= 0.29.15 for Python 3.8 support and
+OpenBLAS >= 3.7 to avoid errors on the Skylake architecture.
+
+Contributors
+============
+
+A total of 3 people contributed to this release. People with a "+" by their
+names contributed a patch for the first time.
+
+* Charles Harris
+* Matti Picus
+* Siyuan Zhuang +
+
+Pull requests merged
+====================
+
+A total of 2 pull requests were merged for this release.
+
+* `#16439 <https://github.com/numpy/numpy/pull/16439>`__: ENH: enable pickle protocol 5 support for python3.5
+* `#16441 <https://github.com/numpy/numpy/pull/16441>`__: BUG: relpath fails for different drives on windows
+
diff --git a/doc/source/release/1.19.5-notes.rst b/doc/source/release/1.19.5-notes.rst
new file mode 100644
index 000000000..048f2718c
--- /dev/null
+++ b/doc/source/release/1.19.5-notes.rst
@@ -0,0 +1,42 @@
+.. currentmodule:: numpy
+
+==========================
+NumPy 1.19.5 Release Notes
+==========================
+
+NumPy 1.19.5 is a short bugfix release. Apart from fixing several bugs, the
+main improvement is the update to OpenBLAS 0.3.13 that works around the windows
+2004 bug while not breaking execution on other platforms. This release supports
+Python 3.6-3.9 and is planned to be the last release in the 1.19.x cycle.
+
+Contributors
+============
+
+A total of 8 people contributed to this release. People with a "+" by their
+names contributed a patch for the first time.
+
+* Charles Harris
+* Christoph Gohlke
+* Matti Picus
+* Raghuveer Devulapalli
+* Sebastian Berg
+* Simon Graham +
+* Veniamin Petrenko +
+* Bernie Gray +
+
+Pull requests merged
+====================
+
+A total of 11 pull requests were merged for this release.
+
+* `#17756 <https://github.com/numpy/numpy/pull/17756>`__: BUG: Fix segfault due to out of bound pointer in floatstatus...
+* `#17774 <https://github.com/numpy/numpy/pull/17774>`__: BUG: fix np.timedelta64('nat').__format__ throwing an exception
+* `#17775 <https://github.com/numpy/numpy/pull/17775>`__: BUG: Fixed file handle leak in array_tofile.
+* `#17786 <https://github.com/numpy/numpy/pull/17786>`__: BUG: Raise recursion error during dimension discovery
+* `#17917 <https://github.com/numpy/numpy/pull/17917>`__: BUG: Fix subarray dtype used with too large count in fromfile
+* `#17918 <https://github.com/numpy/numpy/pull/17918>`__: BUG: 'bool' object has no attribute 'ndim'
+* `#17919 <https://github.com/numpy/numpy/pull/17919>`__: BUG: ensure _UFuncNoLoopError can be pickled
+* `#17924 <https://github.com/numpy/numpy/pull/17924>`__: BLD: use BUFFERSIZE=20 in OpenBLAS
+* `#18026 <https://github.com/numpy/numpy/pull/18026>`__: BLD: update to OpenBLAS 0.3.13
+* `#18036 <https://github.com/numpy/numpy/pull/18036>`__: BUG: make a variable volatile to work around clang compiler bug
+* `#18114 <https://github.com/numpy/numpy/pull/18114>`__: REL: Prepare for the NumPy 1.19.5 release.
diff --git a/doc/source/release/1.20.0-notes.rst b/doc/source/release/1.20.0-notes.rst
index 73b470f3f..b8b7a0c79 100644
--- a/doc/source/release/1.20.0-notes.rst
+++ b/doc/source/release/1.20.0-notes.rst
@@ -3,8 +3,8 @@
==========================
NumPy 1.20.0 Release Notes
==========================
-This NumPy release is the largest so made to date, some 648 PRs contributed by
-182 people have been merged. See the list of highlights below for more details.
+This NumPy release is the largest so made to date, some 684 PRs contributed by
+184 people have been merged. See the list of highlights below for more details.
The Python versions supported for this release are 3.7-3.9, support for Python
3.6 has been dropped. Highlights are
@@ -75,32 +75,60 @@ Using the aliases of builtin types like ``np.int`` is deprecated
----------------------------------------------------------------
For a long time, ``np.int`` has been an alias of the builtin ``int``. This is
-repeatedly a cause of confusion for newcomers, and is also simply not useful.
+repeatedly a cause of confusion for newcomers, and existed mainly for historic
+reasons.
These aliases have been deprecated. The table below shows the full list of
deprecated aliases, along with their exact meaning. Replacing uses of items in
the first column with the contents of the second column will work identically
and silence the deprecation warning.
-In many cases, it may have been intended to use the types from the third column.
-Be aware that use of these types may result in subtle but desirable behavior
-changes.
-
-================== ================================= ==================================================================
-Deprecated name Identical to Possibly intended numpy type
-================== ================================= ==================================================================
-``numpy.bool`` ``bool`` `numpy.bool_`
-``numpy.int`` ``int`` `numpy.int_` (default int dtype), `numpy.cint` (C ``int``)
-``numpy.float`` ``float`` `numpy.float_`, `numpy.double` (equivalent)
-``numpy.complex`` ``complex`` `numpy.complex_`, `numpy.cdouble` (equivalent)
-``numpy.object`` ``object`` `numpy.object_`
-``numpy.str`` ``str`` `numpy.str_`
-``numpy.long`` ``int`` (``long`` on Python 2) `numpy.int_` (C ``long``), `numpy.longlong` (largest integer type)
-``numpy.unicode`` ``str`` (``unicode`` on Python 2) `numpy.unicode_`
-================== ================================= ==================================================================
-
-Note that for technical reasons these deprecation warnings will only be emitted
-on Python 3.7 and above.
+The third column lists alternative NumPy names which may occasionally be
+preferential. See also :ref:`basics.types` for additional details.
+
+================= ============ ==================================================================
+Deprecated name Identical to NumPy scalar type names
+================= ============ ==================================================================
+``numpy.bool`` ``bool`` `numpy.bool_`
+``numpy.int`` ``int`` `numpy.int_` (default), ``numpy.int64``, or ``numpy.int32``
+``numpy.float`` ``float`` `numpy.float64`, `numpy.float_`, `numpy.double` (equivalent)
+``numpy.complex`` ``complex`` `numpy.complex128`, `numpy.complex_`, `numpy.cdouble` (equivalent)
+``numpy.object`` ``object`` `numpy.object_`
+``numpy.str`` ``str`` `numpy.str_`
+``numpy.long`` ``int`` `numpy.int_` (C ``long``), `numpy.longlong` (largest integer type)
+``numpy.unicode`` ``str`` `numpy.unicode_`
+================= ============ ==================================================================
+
+To give a clear guideline for the vast majority of cases, for the types
+``bool``, ``object``, ``str`` (and ``unicode``) using the plain version
+is shorter and clear, and generally a good replacement.
+For ``float`` and ``complex`` you can use ``float64`` and ``complex128``
+if you wish to be more explicit about the precision.
+
+For ``np.int`` a direct replacement with ``np.int_`` or ``int`` is also
+good and will not change behavior, but the precision will continue to depend
+on the computer and operating system.
+If you want to be more explicit and review the current use, you have the
+following alternatives:
+
+* ``np.int64`` or ``np.int32`` to specify the precision exactly.
+ This ensures that results cannot depend on the computer or operating system.
+* ``np.int_`` or ``int`` (the default), but be aware that it depends on
+ the computer and operating system.
+* The C types: ``np.cint`` (int), ``np.int_`` (long), ``np.longlong``.
+* ``np.intp`` which is 32bit on 32bit machines 64bit on 64bit machines.
+ This can be the best type to use for indexing.
+
+When used with ``np.dtype(...)`` or ``dtype=...`` changing it to the
+NumPy name as mentioned above will have no effect on the output.
+If used as a scalar with::
+
+ np.float(123)
+
+changing it can subtly change the result. In this case, the Python version
+``float(123)`` or ``int(12.)`` is normally preferable, although the NumPy
+version may be useful for consistency with NumPy arrays (for example,
+NumPy behaves differently for things like division by zero).
(`gh-14882 <https://github.com/numpy/numpy/pull/14882>`__)
@@ -184,6 +212,43 @@ Use ``next(it)`` instead of ``it.ndincr()``.
(`gh-17233 <https://github.com/numpy/numpy/pull/17233>`__)
+ArrayLike objects which do not define ``__len__`` and ``__getitem__``
+---------------------------------------------------------------------
+Objects which define one of the protocols ``__array__``,
+``__array_interface__``, or ``__array_struct__`` but are not sequences
+(usually defined by having a ``__len__`` and ``__getitem__``) will behave
+differently during array-coercion in the future.
+
+When nested inside sequences, such as ``np.array([array_like])``, these
+were handled as a single Python object rather than an array.
+In the future they will behave identically to::
+
+ np.array([np.array(array_like)])
+
+This change should only have an effect if ``np.array(array_like)`` is not 0-D.
+The solution to this warning may depend on the object:
+
+* Some array-likes may expect the new behaviour, and users can ignore the
+ warning. The object can choose to expose the sequence protocol to opt-in
+ to the new behaviour.
+* For example, ``shapely`` will allow conversion to an array-like using
+ ``line.coords`` rather than ``np.asarray(line)``. Users may work around
+ the warning, or use the new convention when it becomes available.
+
+Unfortunately, using the new behaviour can only be achieved by
+calling ``np.array(array_like)``.
+
+If you wish to ensure that the old behaviour remains unchanged, please create
+an object array and then fill it explicitly, for example::
+
+ arr = np.empty(3, dtype=object)
+ arr[:] = [array_like1, array_like2, array_like3]
+
+This will ensure NumPy knows to not enter the array-like and use it as
+a object instead.
+
+(`gh-17973 <https://github.com/numpy/numpy/pull/17973>`__)
+
Future Changes
==============
@@ -253,6 +318,18 @@ library.
Compatibility notes
===================
+``isinstance(dtype, np.dtype)`` and not ``type(dtype) is not np.dtype``
+-----------------------------------------------------------------------
+NumPy dtypes are not direct instances of ``np.dtype`` anymore. Code that
+may have used ``type(dtype) is np.dtype`` will always return ``False`` and
+must be updated to use the correct version ``isinstance(dtype, np.dtype)``.
+
+This change also affects the C-side macro ``PyArray_DescrCheck`` if compiled
+against a NumPy older than 1.16.6. If code uses this macro and wishes to
+compile against an older version of NumPy, it must replace the macro
+(see also `C API changes`_ section).
+
+
Same kind casting in concatenate with ``axis=None``
---------------------------------------------------
When `~numpy.concatenate` is called with ``axis=None``,
@@ -337,9 +414,15 @@ Things will now be more consistent with::
np.array([np.array(array_like1)])
-This could potentially subtly change output for badly defined array-likes.
-We are not aware of any such case where the results were not clearly
-incorrect previously.
+This can subtly change output for some badly defined array-likes.
+One example for this are array-like objects which are not also sequences
+of matching shape.
+In NumPy 1.20, a warning will be given when an array-like is not also a
+sequence (but behaviour remains identical, see deprecations).
+If an array like is also a sequence (defines ``__getitem__`` and ``__len__``)
+NumPy will now only use the result given by ``__array__``,
+``__array_interface__``, or ``__array_struct__``. This will result in
+differences when the (nested) sequence describes a different shape.
(`gh-16200 <https://github.com/numpy/numpy/pull/16200>`__)
@@ -524,6 +607,23 @@ cannot represent ``b"1"`` faithfully.
C API changes
=============
+The ``PyArray_DescrCheck`` macro is modified
+--------------------------------------------
+The ``PyArray_DescrCheck`` macro has been updated since NumPy 1.16.6 to be::
+
+ #define PyArray_DescrCheck(op) PyObject_TypeCheck(op, &PyArrayDescr_Type)
+
+Starting with NumPy 1.20 code that is compiled against an earlier version
+will be API incompatible with NumPy 1.20.
+The fix is to either compile against 1.16.6 (if the NumPy 1.16 release is
+the oldest release you wish to support), or manually inline the macro by
+replacing it with the new definition::
+
+ PyObject_TypeCheck(op, &PyArrayDescr_Type)
+
+which is compatible with all NumPy versions.
+
+
Size of ``np.ndarray`` and ``np.void_`` changed
-----------------------------------------------
The size of the ``PyArrayObject`` and ``PyVoidScalarObject``
@@ -900,5 +1000,3 @@ The former result can still be obtained with::
(`gh-16841 <https://github.com/numpy/numpy/pull/16841>`__)
-
-
diff --git a/doc/source/release/1.20.1-notes.rst b/doc/source/release/1.20.1-notes.rst
new file mode 100644
index 000000000..f95b5847d
--- /dev/null
+++ b/doc/source/release/1.20.1-notes.rst
@@ -0,0 +1,53 @@
+.. currentmodule:: numpy
+
+==========================
+NumPy 1.20.1 Release Notes
+==========================
+
+NumPy 1,20.1 is a rapid bugfix release fixing several bugs and regressions
+reported after the 1.20.0 release.
+
+
+Highlights
+==========
+
+- The distutils bug that caused problems with downstream projects is fixed.
+- The ``random.shuffle`` regression is fixed.
+
+
+Contributors
+============
+
+A total of 8 people contributed to this release. People with a "+" by their
+names contributed a patch for the first time.
+
+* Bas van Beek
+* Charles Harris
+* Nicholas McKibben +
+* Pearu Peterson
+* Ralf Gommers
+* Sebastian Berg
+* Tyler Reddy
+* @Aerysv +
+
+
+Pull requests merged
+====================
+
+A total of 15 pull requests were merged for this release.
+
+* `#18306 <https://github.com/numpy/numpy/pull/18306>`__: MAINT: Add missing placeholder annotations
+* `#18310 <https://github.com/numpy/numpy/pull/18310>`__: BUG: Fix typo in ``numpy.__init__.py``
+* `#18326 <https://github.com/numpy/numpy/pull/18326>`__: BUG: don't mutate list of fake libraries while iterating over...
+* `#18327 <https://github.com/numpy/numpy/pull/18327>`__: MAINT: gracefully shuffle memoryviews
+* `#18328 <https://github.com/numpy/numpy/pull/18328>`__: BUG: Use C linkage for random distributions
+* `#18336 <https://github.com/numpy/numpy/pull/18336>`__: CI: fix when GitHub Actions builds trigger, and allow ci skips
+* `#18337 <https://github.com/numpy/numpy/pull/18337>`__: BUG: Allow unmodified use of isclose, allclose, etc. with timedelta
+* `#18345 <https://github.com/numpy/numpy/pull/18345>`__: BUG: Allow pickling all relevant DType types/classes
+* `#18351 <https://github.com/numpy/numpy/pull/18351>`__: BUG: Fix missing signed_char dependency. Closes #18335.
+* `#18352 <https://github.com/numpy/numpy/pull/18352>`__: DOC: Change license date 2020 -> 2021
+* `#18353 <https://github.com/numpy/numpy/pull/18353>`__: CI: CircleCI seems to occasionally time out, increase the limit
+* `#18354 <https://github.com/numpy/numpy/pull/18354>`__: BUG: Fix f2py bugs when wrapping F90 subroutines.
+* `#18356 <https://github.com/numpy/numpy/pull/18356>`__: MAINT: crackfortran regex simplify
+* `#18357 <https://github.com/numpy/numpy/pull/18357>`__: BUG: threads.h existence test requires GLIBC > 2.12.
+* `#18359 <https://github.com/numpy/numpy/pull/18359>`__: REL: Prepare for the NumPy 1.20.1 release.
diff --git a/doc/source/release/1.20.2-notes.rst b/doc/source/release/1.20.2-notes.rst
new file mode 100644
index 000000000..10d39f7f6
--- /dev/null
+++ b/doc/source/release/1.20.2-notes.rst
@@ -0,0 +1,48 @@
+.. currentmodule:: numpy
+
+==========================
+NumPy 1.20.2 Release Notes
+==========================
+
+NumPy 1.20.2 is a bugfix release containing several fixes merged to the main
+branch after the NumPy 1.20.1 release.
+
+Contributors
+============
+
+A total of 7 people contributed to this release. People with a "+" by their
+names contributed a patch for the first time.
+
+* Allan Haldane
+* Bas van Beek
+* Charles Harris
+* Christoph Gohlke
+* Mateusz Sokół +
+* Michael Lamparski
+* Sebastian Berg
+
+Pull requests merged
+====================
+
+A total of 20 pull requests were merged for this release.
+
+* `#18382 <https://github.com/numpy/numpy/pull/18382>`__: MAINT: Update f2py from master.
+* `#18459 <https://github.com/numpy/numpy/pull/18459>`__: BUG: ``diagflat`` could overflow on windows or 32-bit platforms
+* `#18460 <https://github.com/numpy/numpy/pull/18460>`__: BUG: Fix refcount leak in f2py ``complex_double_from_pyobj``.
+* `#18461 <https://github.com/numpy/numpy/pull/18461>`__: BUG: Fix tiny memory leaks when ``like=`` overrides are used
+* `#18462 <https://github.com/numpy/numpy/pull/18462>`__: BUG: Remove temporary change of descr/flags in VOID functions
+* `#18469 <https://github.com/numpy/numpy/pull/18469>`__: BUG: Segfault in nditer buffer dealloc for Object arrays
+* `#18485 <https://github.com/numpy/numpy/pull/18485>`__: BUG: Remove suspicious type casting
+* `#18486 <https://github.com/numpy/numpy/pull/18486>`__: BUG: remove nonsensical comparison of pointer < 0
+* `#18487 <https://github.com/numpy/numpy/pull/18487>`__: BUG: verify pointer against NULL before using it
+* `#18488 <https://github.com/numpy/numpy/pull/18488>`__: BUG: check if PyArray_malloc succeeded
+* `#18546 <https://github.com/numpy/numpy/pull/18546>`__: BUG: incorrect error fallthrough in nditer
+* `#18559 <https://github.com/numpy/numpy/pull/18559>`__: CI: Backport CI fixes from main.
+* `#18599 <https://github.com/numpy/numpy/pull/18599>`__: MAINT: Add annotations for `dtype.__getitem__`, `__mul__` and...
+* `#18611 <https://github.com/numpy/numpy/pull/18611>`__: BUG: NameError in numpy.distutils.fcompiler.compaq
+* `#18612 <https://github.com/numpy/numpy/pull/18612>`__: BUG: Fixed ``where`` keyword for ``np.mean`` & ``np.var`` methods
+* `#18617 <https://github.com/numpy/numpy/pull/18617>`__: CI: Update apt package list before Python install
+* `#18636 <https://github.com/numpy/numpy/pull/18636>`__: MAINT: Ensure that re-exported sub-modules are properly annotated
+* `#18638 <https://github.com/numpy/numpy/pull/18638>`__: BUG: Fix ma coercion list-of-ma-arrays if they do not cast to...
+* `#18661 <https://github.com/numpy/numpy/pull/18661>`__: BUG: Fix small valgrind-found issues
+* `#18671 <https://github.com/numpy/numpy/pull/18671>`__: BUG: Fix small issues found with pytest-leaks
diff --git a/doc/source/release/1.20.3-notes.rst b/doc/source/release/1.20.3-notes.rst
new file mode 100644
index 000000000..8c25b3cc3
--- /dev/null
+++ b/doc/source/release/1.20.3-notes.rst
@@ -0,0 +1,43 @@
+.. currentmodule:: numpy
+
+==========================
+NumPy 1.20.3 Release Notes
+==========================
+
+NumPy 1.20.3 is a bugfix release containing several fixes merged to the main
+branch after the NumPy 1.20.2 release.
+
+Contributors
+============
+
+A total of 7 people contributed to this release. People with a "+" by their
+names contributed a patch for the first time.
+
+* Anne Archibald
+* Bas van Beek
+* Charles Harris
+* Dong Keun Oh +
+* Kamil Choudhury +
+* Sayed Adel
+* Sebastian Berg
+
+Pull requests merged
+====================
+
+A total of 15 pull requests were merged for this release.
+
+* `#18763 <https://github.com/numpy/numpy/pull/18763>`__: BUG: Correct ``datetime64`` missing type overload for ``datetime.date``...
+* `#18764 <https://github.com/numpy/numpy/pull/18764>`__: MAINT: Remove ``__all__`` in favor of explicit re-exports
+* `#18768 <https://github.com/numpy/numpy/pull/18768>`__: BLD: Strip extra newline when dumping gfortran version on MacOS
+* `#18769 <https://github.com/numpy/numpy/pull/18769>`__: BUG: fix segfault in object/longdouble operations
+* `#18794 <https://github.com/numpy/numpy/pull/18794>`__: MAINT: Use towncrier build explicitly
+* `#18887 <https://github.com/numpy/numpy/pull/18887>`__: MAINT: Relax certain integer-type constraints
+* `#18915 <https://github.com/numpy/numpy/pull/18915>`__: MAINT: Remove unsafe unions and ABCs from return-annotations
+* `#18921 <https://github.com/numpy/numpy/pull/18921>`__: MAINT: Allow more recursion depth for scalar tests.
+* `#18922 <https://github.com/numpy/numpy/pull/18922>`__: BUG: Initialize the full nditer buffer in case of error
+* `#18923 <https://github.com/numpy/numpy/pull/18923>`__: BLD: remove unnecessary flag ``-faltivec`` on macOS
+* `#18924 <https://github.com/numpy/numpy/pull/18924>`__: MAINT, CI: treats _SIMD module build warnings as errors through...
+* `#18925 <https://github.com/numpy/numpy/pull/18925>`__: BUG: for MINGW, threads.h existence test requires GLIBC > 2.12
+* `#18941 <https://github.com/numpy/numpy/pull/18941>`__: BUG: Make changelog recognize gh- as a PR number prefix.
+* `#18948 <https://github.com/numpy/numpy/pull/18948>`__: REL, DOC: Prepare for the NumPy 1.20.3 release.
+* `#18953 <https://github.com/numpy/numpy/pull/18953>`__: BUG: Fix failing mypy test in 1.20.x.
diff --git a/doc/source/release/1.21.0-notes.rst b/doc/source/release/1.21.0-notes.rst
index 5fda1f631..270cc32de 100644
--- a/doc/source/release/1.21.0-notes.rst
+++ b/doc/source/release/1.21.0-notes.rst
@@ -3,4 +3,577 @@
==========================
NumPy 1.21.0 Release Notes
==========================
+The NumPy 1.21.0 release highlights are
+* continued SIMD work covering more functions and platforms,
+* initial work on the new dtype infrastructure and casting,
+* universal2 wheels for Python 3.8 and Python 3.9 on Mac,
+* improved documentation,
+* improved annotations,
+* new ``PCG64DXSM`` bitgenerator for random numbers.
+
+In addition there are the usual large number of bug fixes and other improvements.
+
+The Python versions supported for this release are 3.7-3.9. Official support
+for Python 3.10 will be added when it is released.
+
+.. warning::
+ There are unresolved problems compiling NumPy 1.20.0 with gcc-11.1.
+
+ * Optimization level `-O3` results in many incorrect warnings when
+ running the tests.
+ * On some hardware NumPY will hang in an infinite loop.
+
+
+
+
+
+New functions
+=============
+
+.. currentmodule:: numpy.random
+
+Add `PCG64DXSM` `BitGenerator`
+------------------------------
+
+Uses of the ``PCG64`` ``BitGenerator`` in a massively-parallel context have been
+shown to have statistical weaknesses that were not apparent at the first
+release in numpy 1.17. Most users will never observe this weakness and are
+safe to continue to use ``PCG64``. We have introduced a new ``PCG64DXSM``
+``BitGenerator`` that will eventually become the new default ``BitGenerator``
+implementation used by ``default_rng`` in future releases. ``PCG64DXSM`` solves
+the statistical weakness while preserving the performance and the features of
+``PCG64``.
+
+See :ref:`upgrading-pcg64` for more details.
+
+.. currentmodule:: numpy
+
+(`gh-18906 <https://github.com/numpy/numpy/pull/18906>`__)
+
+
+Expired deprecations
+====================
+
+* The ``shape`` argument `~numpy.unravel_index` cannot be passed
+ as ``dims`` keyword argument anymore. (Was deprecated in NumPy 1.16.)
+
+ (`gh-17900 <https://github.com/numpy/numpy/pull/17900>`__)
+
+* The function ``PyUFunc_GenericFunction`` has been disabled.
+ It was deprecated in NumPy 1.19. Users should call the ufunc
+ directly using the Python API.
+
+ (`gh-18697 <https://github.com/numpy/numpy/pull/18697>`__)
+
+* The function ``PyUFunc_SetUsesArraysAsData`` has been disabled.
+ It was deprecated in NumPy 1.19.
+
+ (`gh-18697 <https://github.com/numpy/numpy/pull/18697>`__)
+
+* The class ``PolyBase`` has been removed (deprecated in numpy 1.9.0). Please
+ use the abstract ``ABCPolyBase`` class instead.
+
+ (`gh-18963 <https://github.com/numpy/numpy/pull/18963>`__)
+
+* The unused ``PolyError`` and ``PolyDomainError`` exceptions are
+ removed.
+
+ (`gh-18963 <https://github.com/numpy/numpy/pull/18963>`__)
+
+
+Deprecations
+============
+
+The ``.dtype`` attribute must return a ``dtype``
+------------------------------------------------
+
+A ``DeprecationWarning`` is now given if the ``.dtype`` attribute
+of an object passed into ``np.dtype`` or as a ``dtype=obj`` argument
+is not a dtype. NumPy will stop attempting to recursively coerce the
+result of ``.dtype``.
+
+(`gh-13578 <https://github.com/numpy/numpy/pull/13578>`__)
+
+Inexact matches for ``numpy.convolve`` and ``numpy.correlate`` are deprecated
+-----------------------------------------------------------------------------
+
+`~numpy.convolve` and `~numpy.correlate` now emit a warning when there are case
+insensitive and/or inexact matches found for ``mode`` argument in the functions.
+Pass full ``"same"``, ``"valid"``, ``"full"`` strings instead of
+``"s"``, ``"v"``, ``"f"`` for the ``mode`` argument.
+
+(`gh-17492 <https://github.com/numpy/numpy/pull/17492>`__)
+
+``np.typeDict`` has been formally deprecated
+--------------------------------------------
+``np.typeDict`` is a deprecated alias for ``np.sctypeDict`` and
+has been so for over 14 years (6689502_).
+A deprecation warning will now be issued whenever getting ``np.typeDict``.
+
+.. _6689502: https://github.com/numpy/numpy/commit/668950285c407593a368336ff2e737c5da84af7d
+
+(`gh-17586 <https://github.com/numpy/numpy/pull/17586>`__)
+
+Exceptions will be raised during array-like creation
+----------------------------------------------------
+When an object raised an exception during access of the special
+attributes ``__array__`` or ``__array_interface__``, this exception
+was usually ignored.
+A warning is now given when the exception is anything but AttributeError.
+To silence the warning, the type raising the exception has to be adapted
+to raise an ``AttributeError``.
+
+(`gh-19001 <https://github.com/numpy/numpy/pull/19001>`__)
+
+Four ``ndarray.ctypes`` methods have been deprecated
+----------------------------------------------------
+Four methods of the `ndarray.ctypes` object have been deprecated,
+as they are (undocumentated) implementation artifacts of their respective
+properties.
+
+The methods in question are:
+
+* ``_ctypes.get_data`` (use ``_ctypes.data`` instead)
+* ``_ctypes.get_shape`` (use ``_ctypes.shape`` instead)
+* ``_ctypes.get_strides`` (use ``_ctypes.strides`` instead)
+* ``_ctypes.get_as_parameter`` (use ``_ctypes._as_parameter_`` instead)
+
+(`gh-19031 <https://github.com/numpy/numpy/pull/19031>`__)
+
+
+Expired deprecations
+====================
+
+* The ``shape`` argument `numpy.unravel_index` cannot be passed
+ as ``dims`` keyword argument anymore. (Was deprecated in NumPy 1.16.)
+
+ (`gh-17900 <https://github.com/numpy/numpy/pull/17900>`__)
+
+* The function ``PyUFunc_GenericFunction`` has been disabled.
+ It was deprecated in NumPy 1.19. Users should call the ufunc
+ directly using the Python API.
+
+ (`gh-18697 <https://github.com/numpy/numpy/pull/18697>`__)
+
+* The function ``PyUFunc_SetUsesArraysAsData`` has been disabled.
+ It was deprecated in NumPy 1.19.
+
+ (`gh-18697 <https://github.com/numpy/numpy/pull/18697>`__)
+
+Remove deprecated ``PolyBase`` and unused ``PolyError`` and ``PolyDomainError``
+-------------------------------------------------------------------------------
+
+The class ``PolyBase`` has been removed (deprecated in numpy 1.9.0). Please use
+the abstract ``ABCPolyBase`` class instead.
+
+Furthermore, the unused ``PolyError`` and ``PolyDomainError`` exceptions are
+removed from the `numpy.polynomial`.
+
+(`gh-18963 <https://github.com/numpy/numpy/pull/18963>`__)
+
+
+Compatibility notes
+===================
+
+Error type changes in universal functions
+-----------------------------------------
+The universal functions may now raise different errors on invalid input in some
+cases. The main changes should be that a ``RuntimeError`` was replaced with a
+more fitting ``TypeError``. When multiple errors were present in the same
+call, NumPy may now raise a different one.
+
+(`gh-15271 <https://github.com/numpy/numpy/pull/15271>`__)
+
+``__array_ufunc__`` argument validation
+---------------------------------------
+NumPy will now partially validate arguments before calling ``__array_ufunc__``.
+Previously, it was possible to pass on invalid arguments (such as a
+non-existing keyword argument) when dispatch was known to occur.
+
+(`gh-15271 <https://github.com/numpy/numpy/pull/15271>`__)
+
+``__array_ufunc__`` and additional positional arguments
+-------------------------------------------------------
+Previously, all positionally passed arguments were checked for
+``__array_ufunc__`` support. In the case of ``reduce``, ``accumulate``, and
+``reduceat`` all arguments may be passed by position. This means that when
+they were passed by position, they could previously have been asked to handle
+the ufunc call via ``__array_ufunc__``. Since this depended on the way the
+arguments were passed (by position or by keyword), NumPy will now only dispatch
+on the input and output array. For example, NumPy will never dispatch on the
+``where`` array in a reduction such as ``np.add.reduce``.
+
+(`gh-15271 <https://github.com/numpy/numpy/pull/15271>`__)
+
+Validate input values in ``Generator.uniform``
+----------------------------------------------
+Checked that ``high - low >= 0`` in ``np.random.Generator.uniform``. Raises
+``ValueError`` if ``low > high``. Previously out-of-order inputs were accepted
+and silently swapped, so that if ``low > high``, the value generated was
+``high + (low - high) * random()``.
+
+(`gh-17921 <https://github.com/numpy/numpy/pull/17921>`__)
+
+``/usr/include`` removed from default include paths
+---------------------------------------------------
+The default include paths when building a package with ``numpy.distutils`` no
+longer include ``/usr/include``. This path is normally added by the compiler,
+and hardcoding it can be problematic. In case this causes a problem, please
+open an issue. A workaround is documented in PR 18658.
+
+(`gh-18658 <https://github.com/numpy/numpy/pull/18658>`__)
+
+Changes to comparisons with ``dtype=...``
+-----------------------------------------
+When the ``dtype=`` (or ``signature``) arguments to comparison
+ufuncs (``equal``, ``less``, etc.) is used, this will denote
+the desired output dtype in the future.
+This means that:
+
+ np.equal(2, 3, dtype=object)
+
+will give a ``FutureWarning`` that it will return an ``object``
+array in the future, which currently happens for:
+
+ np.equal(None, None, dtype=object)
+
+due to the fact that ``np.array(None)`` is already an object
+array. (This also happens for some other dtypes.)
+
+Since comparisons normally only return boolean arrays, providing
+any other dtype will always raise an error in the future and
+give a ``DeprecationWarning`` now.
+
+(`gh-18718 <https://github.com/numpy/numpy/pull/18718>`__)
+
+Changes to ``dtype`` and ``signature`` arguments in ufuncs
+----------------------------------------------------------
+The universal function arguments ``dtype`` and ``signature``
+which are also valid for reduction such as ``np.add.reduce``
+(which is the implementation for ``np.sum``) will now issue
+a warning when the ``dtype`` provided is not a "basic" dtype.
+
+NumPy almost always ignored metadata, byteorder or time units
+on these inputs. NumPy will now always ignore it and raise an
+error if byteorder or time unit changed.
+The following are the most important examples of changes which
+will give the error. In some cases previously the information
+stored was not ignored, in all of these an error is now raised::
+
+ # Previously ignored the byte-order (affect if non-native)
+ np.add(3, 5, dtype=">i32")
+
+ # The biggest impact is for timedelta or datetimes:
+ arr = np.arange(10, dtype="m8[s]")
+ # The examples always ignored the time unit "ns":
+ np.add(arr, arr, dtype="m8[ns]")
+ np.maximum.reduce(arr, dtype="m8[ns]")
+
+ # The following previously did use "ns" (as opposed to `arr.dtype`)
+ np.add(3, 5, dtype="m8[ns]") # Now return generic time units
+ np.maximum(arr, arr, dtype="m8[ns]") # Now returns "s" (from `arr`)
+
+The same applies for functions like ``np.sum`` which use these internally.
+This change is necessary to achieve consistent handling within NumPy.
+
+If you run into these, in most cases pass for example ``dtype=np.timedelta64``
+which clearly denotes a general ``timedelta64`` without any unit or byte-order
+defined. If you need to specify the output dtype precisely, you may do so
+by either casting the inputs or providing an output array using `out=`.
+
+NumPy may choose to allow providing an exact output ``dtype`` here in the
+future, which would be preceded by a ``FutureWarning``.
+
+(`gh-18718 <https://github.com/numpy/numpy/pull/18718>`__)
+
+Ufunc ``signature=...`` and ``dtype=`` generalization and ``casting``
+---------------------------------------------------------------------
+The behaviour for ``np.ufunc(1.0, 1.0, signature=...)`` or
+``np.ufunc(1.0, 1.0, dtype=...)`` can now yield different loops in 1.21
+compared to 1.20 because of changes in promotion.
+When ``signature`` was previously used, the casting check on inputs
+was relaxed, which could lead to downcasting inputs unsafely especially
+if combined with ``casting="unsafe"``.
+
+Casting is now guaranteed to be safe. If a signature is only
+partially provided, for example using ``signature=("float64", None, None)``,
+this could lead to no loop being found (an error).
+In that case, it is necessary to provide the complete signature
+to enforce casting the inputs.
+If ``dtype="float64"`` is used or only outputs are set (e.g.
+``signature=(None, None, "float64")`` the is unchanged.
+We expect that very few users are affected by this change.
+
+Further, the meaning of ``dtype="float64"`` has been slightly modified and
+now strictly enforces only the correct output (and not input) DTypes.
+This means it is now always equivalent to::
+
+ signature=(None, None, "float64")
+
+(If the ufunc has two inputs and one output). Since this could lead
+to no loop being found in some cases, NumPy will normally also search
+for the loop::
+
+ signature=("float64", "float64", "float64")
+
+if the first search failed.
+In the future, this behaviour may be customized to achieve the expected
+results for more complex ufuncs. (For some universal functions such as
+``np.ldexp`` inputs can have different DTypes.)
+
+(`gh-18880 <https://github.com/numpy/numpy/pull/18880>`__)
+
+Distutils forces strict floating point model on clang
+-----------------------------------------------------
+NumPy distutils will now always add the ``-ffp-exception-behavior=strict``
+compiler flag when compiling with clang. Clang defaults to a non-strict
+version, which allows the compiler to generate code that does not set
+floating point warnings/errors correctly.
+
+(`gh-19049 <https://github.com/numpy/numpy/pull/19049>`__)
+
+
+C API changes
+=============
+
+Use of ``ufunc->type_resolver`` and "type tuple"
+------------------------------------------------
+NumPy now normalizes the "type tuple" argument to the type resolver functions
+before calling it. Note that in the use of this type resolver is legacy
+behaviour and NumPy will not do so when possible. Calling
+``ufunc->type_resolver`` or ``PyUFunc_DefaultTypeResolver`` is strongly
+discouraged and will now enforce a normalized type tuple if done. Note that
+this does not affect providing a type resolver, which is expected to keep
+working in most circumstances. If you have an unexpected use-case for calling
+the type resolver, please inform the NumPy developers so that a solution can be
+found.
+
+(`gh-18718 <https://github.com/numpy/numpy/pull/18718>`__)
+
+
+New Features
+============
+
+Added a mypy plugin for handling platform-specific ``numpy.number`` precisions
+------------------------------------------------------------------------------
+A mypy_ plugin is now available for automatically assigning the (platform-dependent)
+precisions of certain `~numpy.number` subclasses, including the likes of
+`~numpy.int_`, `~numpy.intp` and `~numpy.longlong`. See the documentation on
+:ref:`scalar types <arrays.scalars.built-in>` for a comprehensive overview
+of the affected classes.
+
+Note that while usage of the plugin is completely optional, without it the
+precision of above-mentioned classes will be inferred as `~typing.Any`.
+
+To enable the plugin, one must add it to their mypy `configuration file`_:
+
+.. code-block:: ini
+
+ [mypy]
+ plugins = numpy.typing.mypy_plugin
+
+
+.. _mypy: http://mypy-lang.org/
+.. _configuration file: https://mypy.readthedocs.io/en/stable/config_file.html
+
+(`gh-17843 <https://github.com/numpy/numpy/pull/17843>`__)
+
+Let the mypy plugin manage extended-precision ``numpy.number`` subclasses
+-------------------------------------------------------------------------
+The mypy_ plugin, introduced in `numpy/numpy#17843`_, has been expanded:
+the plugin now removes annotations for platform-specific extended-precision
+types that are not available to the platform in question.
+For example, it will remove `~numpy.float128` when not available.
+
+Without the plugin *all* extended-precision types will, as far as mypy is concerned,
+be available on all platforms.
+
+To enable the plugin, one must add it to their mypy `configuration file`_:
+
+.. code-block:: ini
+
+ [mypy]
+ plugins = numpy.typing.mypy_plugin
+
+
+.. _mypy: http://mypy-lang.org/
+.. _configuration file: https://mypy.readthedocs.io/en/stable/config_file.html
+.. _`numpy/numpy#17843`: https://github.com/numpy/numpy/pull/17843
+
+(`gh-18322 <https://github.com/numpy/numpy/pull/18322>`__)
+
+New ``min_digits`` argument for printing float values
+-----------------------------------------------------
+A new ``min_digits`` argument has been added to the dragon4 float printing
+functions `~numpy.format_float_positional` and `~numpy.format_float_scientific`
+. This kwd guarantees that at least the given number of digits will be printed
+when printing in unique=True mode, even if the extra digits are unnecessary to
+uniquely specify the value. It is the counterpart to the precision argument
+which sets the maximum number of digits to be printed. When unique=False in
+fixed precision mode, it has no effect and the precision argument fixes the
+number of digits.
+
+(`gh-18629 <https://github.com/numpy/numpy/pull/18629>`__)
+
+f2py now recognizes Fortran abstract interface blocks
+-----------------------------------------------------
+`~numpy.f2py` can now parse abstract interface blocks.
+
+(`gh-18695 <https://github.com/numpy/numpy/pull/18695>`__)
+
+BLAS and LAPACK configuration via environment variables
+-------------------------------------------------------
+Autodetection of installed BLAS and LAPACK libraries can be bypassed by using
+the ``NPY_BLAS_LIBS`` and ``NPY_LAPACK_LIBS`` environment variables. Instead,
+the link flags in these environment variables will be used directly, and the
+language is assumed to be F77. This is especially useful in automated builds
+where the BLAS and LAPACK that are installed are known exactly. A use case is
+replacing the actual implementation at runtime via stub library links.
+
+If ``NPY_CBLAS_LIBS`` is set (optional in addition to ``NPY_BLAS_LIBS``), this
+will be used as well, by defining ``HAVE_CBLAS`` and appending the environment
+variable content to the link flags.
+
+(`gh-18737 <https://github.com/numpy/numpy/pull/18737>`__)
+
+A runtime-subcriptable alias has been added for ``ndarray``
+-----------------------------------------------------------
+``numpy.typing.NDArray`` has been added, a runtime-subscriptable alias for
+``np.ndarray[Any, np.dtype[~Scalar]]``. The new type alias can be used
+for annotating arrays with a given dtype and unspecified shape. :sup:`1`
+
+:sup:`1` NumPy does not support the annotating of array shapes as of 1.21,
+this is expected to change in the future though (see :pep:`646`).
+
+Examples
+~~~~~~~~
+
+.. code-block:: python
+
+ >>> import numpy as np
+ >>> import numpy.typing as npt
+
+ >>> print(npt.NDArray)
+ numpy.ndarray[typing.Any, numpy.dtype[~ScalarType]]
+
+ >>> print(npt.NDArray[np.float64])
+ numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]
+
+ >>> NDArrayInt = npt.NDArray[np.int_]
+ >>> a: NDArrayInt = np.arange(10)
+
+ >>> def func(a: npt.ArrayLike) -> npt.NDArray[Any]:
+ ... return np.array(a)
+
+(`gh-18935 <https://github.com/numpy/numpy/pull/18935>`__)
+
+
+Improvements
+============
+
+Arbitrary ``period`` option for ``numpy.unwrap``
+------------------------------------------------
+The size of the interval over which phases are unwrapped is no longer restricted to ``2 * pi``.
+This is especially useful for unwrapping degrees, but can also be used for other intervals.
+
+.. code:: python
+
+ >>> phase_deg = np.mod(np.linspace(0,720,19), 360) - 180
+ >>> phase_deg
+ array([-180., -140., -100., -60., -20., 20., 60., 100., 140.,
+ -180., -140., -100., -60., -20., 20., 60., 100., 140.,
+ -180.])
+
+ >>> unwrap(phase_deg, period=360)
+ array([-180., -140., -100., -60., -20., 20., 60., 100., 140.,
+ 180., 220., 260., 300., 340., 380., 420., 460., 500.,
+ 540.])
+
+(`gh-16987 <https://github.com/numpy/numpy/pull/16987>`__)
+
+``np.unique`` now returns single ``NaN``
+----------------------------------------
+When ``np.unique`` operated on an array with multiple ``NaN`` entries,
+its return included a ``NaN`` for each entry that was ``NaN`` in the original array.
+This is now improved such that the returned array contains just one ``NaN`` as the
+last element.
+
+Also for complex arrays all ``NaN`` values are considered equivalent
+(no matter whether the ``NaN`` is in the real or imaginary part). As the
+representant for the returned array the smallest one in the
+lexicographical order is chosen - see ``np.sort`` for how the lexicographical
+order is defined for complex arrays.
+
+(`gh-18070 <https://github.com/numpy/numpy/pull/18070>`__)
+
+``Generator.rayleigh`` and ``Generator.geometric`` performance improved
+-----------------------------------------------------------------------
+The performance of Rayleigh and geometric random variate generation
+in ``Generator`` has improved. These are both transformation of exponential
+random variables and the slow log-based inverse cdf transformation has
+been replaced with the Ziggurat-based exponential variate generator.
+
+This change breaks the stream of variates generated when variates from
+either of these distributions are produced.
+
+(`gh-18666 <https://github.com/numpy/numpy/pull/18666>`__)
+
+Placeholder annotations have been improved
+------------------------------------------
+All placeholder annotations, that were previously annotated as ``typing.Any``,
+have been improved. Where appropiate they have been replaced with explicit
+function definitions, classes or other miscellaneous objects.
+
+(`gh-18934 <https://github.com/numpy/numpy/pull/18934>`__)
+
+
+Performance improvements
+========================
+
+Improved performance in integer division of NumPy arrays
+--------------------------------------------------------
+Integer division of NumPy arrays now uses
+`libdivide <https://libdivide.com/>`__ when the divisor is a constant. With the
+usage of libdivide and other minor optimizations, there is a large speedup.
+The ``//`` operator and ``np.floor_divide`` makes use of the new changes.
+
+(`gh-17727 <https://github.com/numpy/numpy/pull/17727>`__)
+
+Improve performance of ``np.save`` and ``np.load`` for small arrays
+-------------------------------------------------------------------
+``np.save`` is now a lot faster for small arrays.
+
+``np.load`` is also faster for small arrays,
+but only when serializing with a version >= ``(3, 0)``.
+
+Both are done by removing checks that are only relevant for Python 2,
+while still maintaining compatibility with arrays
+which might have been created by Python 2.
+
+(`gh-18657 <https://github.com/numpy/numpy/pull/18657>`__)
+
+
+Changes
+=======
+
+`numpy.piecewise` output class now matches the input class
+----------------------------------------------------------
+When `~numpy.ndarray` subclasses are used on input to `~numpy.piecewise`,
+they are passed on to the functions. The output will now be of the
+same subclass as well.
+
+(`gh-18110 <https://github.com/numpy/numpy/pull/18110>`__)
+
+Enable Accelerate Framework
+----------------------------
+With the release of macOS 11.3, several different issues that numpy was
+encountering when using Accelerate Framework's implementation of BLAS and
+LAPACK should be resolved. This change enables the Accelerate Framework as an
+option on macOS. If additional issues are found, please file a bug report
+against Accelerate using the developer feedback assistant tool
+(https://developer.apple.com/bug-reporting/). We intend to address issues
+promptly and plan to continue supporting and updating our BLAS and LAPACK
+libraries.
+
+(`gh-18874 <https://github.com/numpy/numpy/pull/18874>`__)
diff --git a/doc/source/release/1.21.1-notes.rst b/doc/source/release/1.21.1-notes.rst
new file mode 100644
index 000000000..0194327f8
--- /dev/null
+++ b/doc/source/release/1.21.1-notes.rst
@@ -0,0 +1,69 @@
+.. currentmodule:: numpy
+
+==========================
+NumPy 1.21.1 Release Notes
+==========================
+The NumPy 1.21.1 is maintenance release that fixes bugs discovered after the
+1.21.0 release and updates OpenBLAS to v0.3.17 to deal with problems on arm64.
+
+The Python versions supported for this release are 3.7-3.9. The 1.21.x series
+is compatible with development Python 3.10. Python 3.10 will be officially
+supported after it is released.
+
+.. warning::
+ There are unresolved problems compiling NumPy 1.20.0 with gcc-11.1.
+
+ * Optimization level `-O3` results in many incorrect warnings when
+ running the tests.
+ * On some hardware NumPY will hang in an infinite loop.
+
+Contributors
+============
+
+A total of 11 people contributed to this release. People with a "+" by their
+names contributed a patch for the first time.
+
+* Bas van Beek
+* Charles Harris
+* Ganesh Kathiresan
+* Gregory R. Lee
+* Hugo Defois +
+* Kevin Sheppard
+* Matti Picus
+* Ralf Gommers
+* Sayed Adel
+* Sebastian Berg
+* Thomas J. Fan
+
+Pull requests merged
+====================
+
+A total of 26 pull requests were merged for this release.
+
+* `#19311 <https://github.com/numpy/numpy/pull/19311>`__: REV,BUG: Replace ``NotImplemented`` with ``typing.Any``
+* `#19324 <https://github.com/numpy/numpy/pull/19324>`__: MAINT: Fixed the return-dtype of ``ndarray.real`` and ``imag``
+* `#19330 <https://github.com/numpy/numpy/pull/19330>`__: MAINT: Replace ``"dtype[Any]"`` with ``dtype`` in the definiton of...
+* `#19342 <https://github.com/numpy/numpy/pull/19342>`__: DOC: Fix some docstrings that crash pdf generation.
+* `#19343 <https://github.com/numpy/numpy/pull/19343>`__: MAINT: bump scipy-mathjax
+* `#19347 <https://github.com/numpy/numpy/pull/19347>`__: BUG: Fix arr.flat.index for large arrays and big-endian machines
+* `#19348 <https://github.com/numpy/numpy/pull/19348>`__: ENH: add ``numpy.f2py.get_include`` function
+* `#19349 <https://github.com/numpy/numpy/pull/19349>`__: BUG: Fix reference count leak in ufunc dtype handling
+* `#19350 <https://github.com/numpy/numpy/pull/19350>`__: MAINT: Annotate missing attributes of ``np.number`` subclasses
+* `#19351 <https://github.com/numpy/numpy/pull/19351>`__: BUG: Fix cast safety and comparisons for zero sized voids
+* `#19352 <https://github.com/numpy/numpy/pull/19352>`__: BUG: Correct Cython declaration in random
+* `#19353 <https://github.com/numpy/numpy/pull/19353>`__: BUG: protect against accessing base attribute of a NULL subarray
+* `#19365 <https://github.com/numpy/numpy/pull/19365>`__: BUG, SIMD: Fix detecting AVX512 features on Darwin
+* `#19366 <https://github.com/numpy/numpy/pull/19366>`__: MAINT: remove ``print()``'s in distutils template handling
+* `#19390 <https://github.com/numpy/numpy/pull/19390>`__: ENH: SIMD architectures to show_config
+* `#19391 <https://github.com/numpy/numpy/pull/19391>`__: BUG: Do not raise deprecation warning for all nans in unique...
+* `#19392 <https://github.com/numpy/numpy/pull/19392>`__: BUG: Fix NULL special case in object-to-any cast code
+* `#19430 <https://github.com/numpy/numpy/pull/19430>`__: MAINT: Use arm64-graviton2 for testing on travis
+* `#19495 <https://github.com/numpy/numpy/pull/19495>`__: BUILD: update OpenBLAS to v0.3.17
+* `#19496 <https://github.com/numpy/numpy/pull/19496>`__: MAINT: Avoid unicode characters in division SIMD code comments
+* `#19499 <https://github.com/numpy/numpy/pull/19499>`__: BUG, SIMD: Fix infinite loop during count non-zero on GCC-11
+* `#19500 <https://github.com/numpy/numpy/pull/19500>`__: BUG: fix a numpy.npiter leak in npyiter_multi_index_set
+* `#19501 <https://github.com/numpy/numpy/pull/19501>`__: TST: Fix a ``GenericAlias`` test failure for python 3.9.0
+* `#19502 <https://github.com/numpy/numpy/pull/19502>`__: MAINT: Start testing with Python 3.10.0b3.
+* `#19503 <https://github.com/numpy/numpy/pull/19503>`__: MAINT: Add missing dtype overloads for object- and ctypes-based...
+* `#19510 <https://github.com/numpy/numpy/pull/19510>`__: REL: Prepare for NumPy 1.21.1 release.
+
diff --git a/doc/source/release/1.22.0-notes.rst b/doc/source/release/1.22.0-notes.rst
new file mode 100644
index 000000000..0760a3dd7
--- /dev/null
+++ b/doc/source/release/1.22.0-notes.rst
@@ -0,0 +1,45 @@
+.. currentmodule:: numpy
+
+==========================
+NumPy 1.22.0 Release Notes
+==========================
+
+
+Highlights
+==========
+
+
+New functions
+=============
+
+
+Deprecations
+============
+
+
+Future Changes
+==============
+
+
+Expired deprecations
+====================
+
+
+Compatibility notes
+===================
+
+
+C API changes
+=============
+
+
+New Features
+============
+
+
+Improvements
+============
+
+
+Changes
+=======
diff --git a/doc/source/user/absolute_beginners.rst b/doc/source/user/absolute_beginners.rst
index 126f5f2a3..499e9ec5c 100644
--- a/doc/source/user/absolute_beginners.rst
+++ b/doc/source/user/absolute_beginners.rst
@@ -6,7 +6,8 @@ NumPy: the absolute basics for beginners
.. currentmodule:: numpy
Welcome to the absolute beginner's guide to NumPy! If you have comments or
-suggestions, please don’t hesitate to reach out!
+suggestions, please don’t hesitate to `reach out
+<https://numpy.org/community/>`_!
Welcome to NumPy!
@@ -37,8 +38,7 @@ Installing NumPy
To install NumPy, we strongly recommend using a scientific Python distribution.
If you're looking for the full instructions for installing NumPy on your
-operating system, you can `find all of the details here
-<https://www.scipy.org/install.html>`_.
+operating system, see `Installing NumPy <https://numpy.org/install/>`_.
@@ -56,24 +56,16 @@ thing about getting this distribution is the fact that you don’t need to worry
too much about separately installing NumPy or any of the major packages that
you’ll be using for your data analyses, like pandas, Scikit-Learn, etc.
-You can find all of the installation details in the
-`Installation <https://www.scipy.org/install.html>`_ section
-at `SciPy <https://www.scipy.org>`_.
-
How to import NumPy
-------------------
-Any time you want to use a package or library in your code, you first need to
-make it accessible.
-
-In order to start using NumPy and all of the functions available in NumPy,
-you'll need to import it. This can be easily done with this import statement::
+To access NumPy and its functions import it in your Python code like this::
import numpy as np
-(We shorten ``numpy`` to ``np`` in order to save time and also to keep code
-standardized so that anyone working with your code can easily understand and
-run it.)
+We shorten the imported name to ``np`` for better readability of code using
+NumPy. This is a widely adopted convention that you should follow so that
+anyone working with your code can easily understand it.
Reading the example code
------------------------
@@ -93,6 +85,7 @@ you would enter. Everything that doesn't have ``>>>`` in front of it
is **output**, or the results of running your code. This is the style
you see when you run ``python`` on the command line, but if you're using IPython, you might see a different style.
+For more information, see :ref:`documentation_conventions`.
What’s the difference between a Python list and a NumPy array?
--------------------------------------------------------------
@@ -775,12 +768,12 @@ If you start with this array::
>>> b = np.array([[1, 1], [2, 2]])
-You can sum the rows with::
+You can sum over the axis of rows with::
>>> b.sum(axis=0)
array([3, 3])
-You can sum the columns with::
+You can sum over the axis of columns with::
>>> b.sum(axis=1)
array([2, 4])
@@ -871,10 +864,11 @@ Creating matrices
You can pass Python lists of lists to create a 2-D array (or "matrix") to
represent them in NumPy. ::
- >>> data = np.array([[1, 2], [3, 4]])
+ >>> data = np.array([[1, 2], [3, 4], [5, 6]])
>>> data
array([[1, 2],
- [3, 4]])
+ [3, 4],
+ [5, 6]])
.. image:: images/np_create_matrix.png
@@ -883,7 +877,8 @@ Indexing and slicing operations are useful when you're manipulating matrices::
>>> data[0, 1]
2
>>> data[1:3]
- array([[3, 4]])
+ array([[3, 4],
+ [5, 6]])
>>> data[0:2, 0]
array([1, 3])
@@ -892,11 +887,11 @@ Indexing and slicing operations are useful when you're manipulating matrices::
You can aggregate matrices the same way you aggregated vectors::
>>> data.max()
- 4
+ 6
>>> data.min()
1
>>> data.sum()
- 10
+ 21
.. image:: images/np_matrix_aggregation.png
@@ -904,9 +899,9 @@ You can aggregate all the values in a matrix and you can aggregate them across
columns or rows using the ``axis`` parameter::
>>> data.max(axis=0)
- array([3, 4])
+ array([5, 6])
>>> data.max(axis=1)
- array([2, 4])
+ array([2, 4, 6])
.. image:: images/np_matrix_aggregation_row.png
@@ -1672,9 +1667,8 @@ For example, you can plot a 1D array like this::
With Matplotlib, you have access to an enormous number of visualization options. ::
- >>> from mpl_toolkits.mplot3d import Axes3D
>>> fig = plt.figure()
- >>> ax = Axes3D(fig)
+ >>> ax = fig.add_subplot(projection='3d')
>>> X = np.arange(-5, 5, 0.15)
>>> Y = np.arange(-5, 5, 0.15)
>>> X, Y = np.meshgrid(X, Y)
diff --git a/doc/source/user/basics.broadcasting.rst b/doc/source/user/basics.broadcasting.rst
index 5eae3eb32..c31fc98bd 100644
--- a/doc/source/user/basics.broadcasting.rst
+++ b/doc/source/user/basics.broadcasting.rst
@@ -1,22 +1,15 @@
.. _basics.broadcasting:
+.. _array-broadcasting-in-numpy:
************
Broadcasting
************
.. seealso::
- :class:`numpy.broadcast`
+ :class:`numpy.broadcast`
- :ref:`array-broadcasting-in-numpy`
- An introduction to the concepts discussed here
-.. note::
- See `this article
- <https://numpy.org/devdocs/user/theory.broadcasting.html>`_
- for illustrations of broadcasting concepts.
-
-
-The term broadcasting describes how numpy treats arrays with different
+The term broadcasting describes how NumPy treats arrays with different
shapes during arithmetic operations. Subject to certain constraints,
the smaller array is "broadcast" across the larger array so that they
have compatible shapes. Broadcasting provides a means of vectorizing
@@ -47,11 +40,23 @@ array([ 2., 4., 6.])
The result is equivalent to the previous example where ``b`` was an array.
We can think of the scalar ``b`` being *stretched* during the arithmetic
operation into an array with the same shape as ``a``. The new elements in
-``b`` are simply copies of the original scalar. The stretching analogy is
+``b``, as shown in :ref:`broadcasting.figure-1`, are simply copies of the
+original scalar. The stretching analogy is
only conceptual. NumPy is smart enough to use the original scalar value
without actually making copies so that broadcasting operations are as
memory and computationally efficient as possible.
+.. figure:: broadcasting_1.svg
+ :alt: A scalar is broadcast to match the shape of the 1-d array it
+ is being multiplied to.
+ :name: broadcasting.figure-1
+
+ *Figure 1*
+
+ *In the simplest example of broadcasting, the scalar* ``b`` *is
+ stretched to become an array of same shape as* ``a`` *so the shapes
+ are compatible for element-by-element multiplication.*
+
The code in the second example is more efficient than that in the first
because broadcasting moves less memory around during the multiplication
(``b`` is a scalar rather than an array).
@@ -123,50 +128,49 @@ Here are examples of shapes that do not broadcast::
A (2d array): 2 x 1
B (3d array): 8 x 4 x 3 # second from last dimensions mismatched
-An example of broadcasting in practice::
-
- >>> x = np.arange(4)
- >>> xx = x.reshape(4,1)
- >>> y = np.ones(5)
- >>> z = np.ones((3,4))
-
- >>> x.shape
- (4,)
+An example of broadcasting when a 1-d array is added to a 2-d array::
- >>> y.shape
- (5,)
-
- >>> x + y
- ValueError: operands could not be broadcast together with shapes (4,) (5,)
-
- >>> xx.shape
- (4, 1)
+ >>> a = array([[ 0.0, 0.0, 0.0],
+ ... [10.0, 10.0, 10.0],
+ ... [20.0, 20.0, 20.0],
+ ... [30.0, 30.0, 30.0]])
+ >>> b = array([1.0, 2.0, 3.0])
+ >>> a + b
+ array([[ 1., 2., 3.],
+ [ 11., 12., 13.],
+ [ 21., 22., 23.],
+ [ 31., 32., 33.]])
+ >>> b = array([1.0, 2.0, 3.0, 4.0])
+ >>> a + b
+ ValueError: operands could not be broadcast together with shapes (4,3) (4,)
- >>> y.shape
- (5,)
+As shown in :ref:`broadcasting.figure-2`, ``b`` is added to each row of ``a``.
+In :ref:`broadcasting.figure-3`, an exception is raised because of the
+incompatible shapes.
- >>> (xx + y).shape
- (4, 5)
+.. figure:: broadcasting_2.svg
+ :alt: A 1-d array with shape (3) is strectched to match the 2-d array of
+ shape (4, 3) it is being added to, and the result is a 2-d array of shape
+ (4, 3).
+ :name: broadcasting.figure-2
- >>> xx + y
- array([[ 1., 1., 1., 1., 1.],
- [ 2., 2., 2., 2., 2.],
- [ 3., 3., 3., 3., 3.],
- [ 4., 4., 4., 4., 4.]])
+ *Figure 2*
- >>> x.shape
- (4,)
+ *A one dimensional array added to a two dimensional array results in
+ broadcasting if number of 1-d array elements matches the number of 2-d
+ array columns.*
- >>> z.shape
- (3, 4)
+.. figure:: broadcasting_3.svg
+ :alt: A huge cross over the 2-d array of shape (4, 3) and the 1-d array
+ of shape (4) shows that they can not be broadcast due to mismatch
+ of shapes and thus produce no result.
+ :name: broadcasting.figure-3
- >>> (x + z).shape
- (3, 4)
+ *Figure 3*
- >>> x + z
- array([[ 1., 2., 3., 4.],
- [ 1., 2., 3., 4.],
- [ 1., 2., 3., 4.]])
+ *When the trailing dimensions of the arrays are unequal, broadcasting fails
+ because it is impossible to align the values in the rows of the 1st array
+ with the elements of the 2nd arrays for element-by-element addition.*
Broadcasting provides a convenient way of taking the outer product (or
any other outer operation) of two arrays. The following example shows an
@@ -180,8 +184,94 @@ outer addition operation of two 1-d arrays::
[ 21., 22., 23.],
[ 31., 32., 33.]])
+.. figure:: broadcasting_4.svg
+ :alt: A 2-d array of shape (4, 1) and a 1-d array of shape (3) are
+ stretched to match their shapes and produce a resultant array
+ of shape (4, 3).
+ :name: broadcasting.figure-4
+
+ *Figure 4*
+
+ *In some cases, broadcasting stretches both arrays to form an output array
+ larger than either of the initial arrays.*
+
Here the ``newaxis`` index operator inserts a new axis into ``a``,
making it a two-dimensional ``4x1`` array. Combining the ``4x1`` array
with ``b``, which has shape ``(3,)``, yields a ``4x3`` array.
-
+A Practical Example: Vector Quantization
+========================================
+
+Broadcasting comes up quite often in real world problems. A typical example
+occurs in the vector quantization (VQ) algorithm used in information theory,
+classification, and other related areas. The basic operation in VQ finds
+the closest point in a set of points, called ``codes`` in VQ jargon, to a given
+point, called the ``observation``. In the very simple, two-dimensional case
+shown below, the values in ``observation`` describe the weight and height of an
+athlete to be classified. The ``codes`` represent different classes of
+athletes. [#f1]_ Finding the closest point requires calculating the distance
+between observation and each of the codes. The shortest distance provides the
+best match. In this example, ``codes[0]`` is the closest class indicating that
+the athlete is likely a basketball player.
+
+ >>> from numpy import array, argmin, sqrt, sum
+ >>> observation = array([111.0, 188.0])
+ >>> codes = array([[102.0, 203.0],
+ ... [132.0, 193.0],
+ ... [45.0, 155.0],
+ ... [57.0, 173.0]])
+ >>> diff = codes - observation # the broadcast happens here
+ >>> dist = sqrt(sum(diff**2,axis=-1))
+ >>> argmin(dist)
+ 0
+
+In this example, the ``observation`` array is stretched to match
+the shape of the ``codes`` array::
+
+ Observation (1d array): 2
+ Codes (2d array): 4 x 2
+ Diff (2d array): 4 x 2
+
+.. figure:: broadcasting_5.svg
+ :alt: A height versus weight graph that shows data of a female
+ gymnast, marathon runner, basketball player, football
+ lineman and the athlete to be classified. Shortest distance
+ is found between the basketball player and the athlete
+ to be classified.
+ :name: broadcasting.figure-5
+
+ *Figure 5*
+
+ *The basic operation of vector quantization calculates the distance between
+ an object to be classified, the dark square, and multiple known codes, the
+ gray circles. In this simple case, the codes represent individual classes.
+ More complex cases use multiple codes per class.*
+
+Typically, a large number of ``observations``, perhaps read from a database,
+are compared to a set of ``codes``. Consider this scenario::
+
+ Observation (2d array): 10 x 3
+ Codes (2d array): 5 x 3
+ Diff (3d array): 5 x 10 x 3
+
+The three-dimensional array, ``diff``, is a consequence of broadcasting, not a
+necessity for the calculation. Large data sets will generate a large
+intermediate array that is computationally inefficient. Instead, if each
+observation is calculated individually using a Python loop around the code
+in the two-dimensional example above, a much smaller array is used.
+
+Broadcasting is a powerful tool for writing short and usually intuitive code
+that does its computations very efficiently in C. However, there are cases
+when broadcasting uses unnecessarily large amounts of memory for a particular
+algorithm. In these cases, it is better to write the algorithm's outer loop in
+Python. This may also produce more readable code, as algorithms that use
+broadcasting tend to become more difficult to interpret as the number of
+dimensions in the broadcast increases.
+
+.. rubric:: Footnotes
+
+.. [#f1]
+ In this example, weight has more impact on the distance calculation
+ than height because of the larger values. In practice, it is important to
+ normalize the height and weight, often by their standard deviation across the
+ data set, so that both have equal influence on the distance calculation.
diff --git a/doc/source/user/basics.creation.rst b/doc/source/user/basics.creation.rst
index 671a8ec59..ccd6de184 100644
--- a/doc/source/user/basics.creation.rst
+++ b/doc/source/user/basics.creation.rst
@@ -9,55 +9,102 @@ Array creation
Introduction
============
-There are 5 general mechanisms for creating arrays:
+There are 6 general mechanisms for creating arrays:
-1) Conversion from other Python structures (e.g., lists, tuples)
-2) Intrinsic numpy array creation objects (e.g., arange, ones, zeros,
+1) Conversion from other Python structures (i.e. lists and tuples)
+2) Intrinsic NumPy array creation functions (e.g. arange, ones, zeros,
etc.)
-3) Reading arrays from disk, either from standard or custom formats
-4) Creating arrays from raw bytes through the use of strings or buffers
-5) Use of special library functions (e.g., random)
+3) Replicating, joining, or mutating existing arrays
+4) Reading arrays from disk, either from standard or custom formats
+5) Creating arrays from raw bytes through the use of strings or buffers
+6) Use of special library functions (e.g., random)
-This section will not cover means of replicating, joining, or otherwise
-expanding or mutating existing arrays. Nor will it cover creating object
-arrays or structured arrays. Both of those are covered in their own sections.
+You can use these methods to create ndarrays or :ref:`structured_arrays`.
+This document will cover general methods for ndarray creation.
-Converting Python array_like Objects to NumPy Arrays
-====================================================
-
-In general, numerical data arranged in an array-like structure in Python can
-be converted to arrays through the use of the array() function. The most
-obvious examples are lists and tuples. See the documentation for array() for
-details for its use. Some objects may support the array-protocol and allow
-conversion to arrays this way. A simple way to find out if the object can be
-converted to a numpy array using array() is simply to try it interactively and
-see if it works! (The Python Way).
+1) Converting Python sequences to NumPy Arrays
+==============================================
-Examples: ::
+NumPy arrays can be defined using Python sequences such as lists and
+tuples. Lists and tuples are defined using ``[...]`` and ``(...)``,
+respectively. Lists and tuples can define ndarray creation:
- >>> x = np.array([2,3,1,0])
- >>> x = np.array([2, 3, 1, 0])
- >>> x = np.array([[1,2.0],[0,0],(1+1j,3.)]) # note mix of tuple and lists,
- and types
- >>> x = np.array([[ 1.+0.j, 2.+0.j], [ 0.+0.j, 0.+0.j], [ 1.+1.j, 3.+0.j]])
+* a list of numbers will create a 1D array,
+* a list of lists will create a 2D array,
+* further nested lists will create higher-dimensional arrays. In general, any array object is called an **ndarray** in NumPy.
-Intrinsic NumPy Array Creation
-==============================
-
-NumPy has built-in functions for creating arrays from scratch:
+::
-zeros(shape) will create an array filled with 0 values with the specified
-shape. The default dtype is float64. ::
+ >>> a1D = np.array([1, 2, 3, 4])
+ >>> a2D = np.array([[1, 2], [3, 4]])
+ >>> a3D = np.array([[[1, 2], [3, 4]],
+ [[5, 6], [7, 8]]])
- >>> np.zeros((2, 3))
- array([[ 0., 0., 0.], [ 0., 0., 0.]])
+When you use :func:`numpy.array` to define a new array, you should
+consider the :doc:`dtype <basics.types>` of the elements in the array,
+which can be specified explicitly. This feature gives you
+more control over the underlying data structures and how the elements
+are handled in C/C++ functions. If you are not careful with ``dtype``
+assignments, you can get unwanted overflow, as such
-ones(shape) will create an array filled with 1 values. It is identical to
-zeros in all other respects.
+::
-arange() will create arrays with regularly incrementing values. Check the
-docstring for complete information on the various ways it can be used. A few
-examples will be given here: ::
+ >>> a = np.array([127, 128, 129], dtype=np.int8)
+ >>> a
+ array([ 127, -128, -127], dtype=int8)
+
+An 8-bit signed integer represents integers from -128 to 127.
+Assigning the ``int8`` array to integers outside of this range results
+in overflow. This feature can often be misunderstood. If you
+perform calculations with mismatching ``dtypes``, you can get unwanted
+results, for example::
+
+ >>> a = array([2, 3, 4], dtype = np.uint32)
+ >>> b = array([5, 6, 7], dtype = np.uint32)
+ >>> c_unsigned32 = a - b
+ >>> print('unsigned c:', c_unsigned32, c_unsigned32.dtype)
+ unsigned c: [4294967293 4294967293 4294967293] uint32
+ >>> c_signed32 = a - b.astype(np.int32)
+ >>> print('signed c:', c_signed32, c_signed32.dtype)
+ signed c: [-3 -3 -3] int64
+
+Notice when you perform operations with two arrays of the same
+``dtype``: ``uint32``, the resulting array is the same type. When you
+perform operations with different ``dtype``, NumPy will
+assign a new type that satisfies all of the array elements involved in
+the computation, here ``uint32`` and ``int32`` can both be represented in
+as ``int64``.
+
+The default NumPy behavior is to create arrays in either 64-bit signed
+integers or double precision floating point numbers, ``int64`` and
+``float``, respectively. If you expect your arrays to be a certain type,
+then you need to specify the ``dtype`` while you create the array.
+
+2) Intrinsic NumPy array creation functions
+===========================================
+..
+ 40 functions seems like a small number, but the routies.array-creation
+ has ~47. I'm sure there are more.
+
+NumPy has over 40 built-in functions for creating arrays as laid
+out in the :ref:`Array creation routines <routines.array-creation>`.
+These functions can be split into roughly three categories, based on the
+dimension of the array they create:
+
+1) 1D arrays
+2) 2D arrays
+3) ndarrays
+
+1 - 1D array creation functions
+-------------------------------
+
+The 1D array creation functions e.g. :func:`numpy.linspace` and
+:func:`numpy.arange` generally need at least two inputs, ``start`` and
+``stop``.
+
+:func:`numpy.arange` creates arrays with regularly incrementing values.
+Check the documentation for complete information and examples. A few
+examples are shown::
>>> np.arange(10)
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
@@ -66,43 +113,216 @@ examples will be given here: ::
>>> np.arange(2, 3, 0.1)
array([ 2. , 2.1, 2.2, 2.3, 2.4, 2.5, 2.6, 2.7, 2.8, 2.9])
-Note that there are some subtleties regarding the last usage that the user
-should be aware of that are described in the arange docstring.
+Note: best practice for :func:`numpy.arange` is to use integer start, end, and
+step values. There are some subtleties regarding ``dtype``. In the second
+example, the ``dtype`` is defined. In the third example, the array is
+``dtype=float`` to accomodate the step size of ``0.1``. Due to roundoff error,
+the ``stop`` value is sometimes included.
-linspace() will create arrays with a specified number of elements, and
+:func:`numpy.linspace` will create arrays with a specified number of elements, and
spaced equally between the specified beginning and end values. For
example: ::
>>> np.linspace(1., 4., 6)
array([ 1. , 1.6, 2.2, 2.8, 3.4, 4. ])
-The advantage of this creation function is that one can guarantee the
-number of elements and the starting and end point, which arange()
-generally will not do for arbitrary start, stop, and step values.
+The advantage of this creation function is that you guarantee the
+number of elements and the starting and end point. The previous
+``arange(start, stop, step)`` will not include the value ``stop``.
+
+2 - 2D array creation functions
+-------------------------------
+
+The 2D array creation functions e.g. :func:`numpy.eye`, :func:`numpy.diag`, and :func:`numpy.vander`
+define properties of special matrices represented as 2D arrays.
+
+``np.eye(n, m)`` defines a 2D identity matrix. The elements where i=j (row index and column index are equal) are 1
+and the rest are 0, as such::
+
+ >>> np.eye(3)
+ array([[1., 0., 0.],
+ [0., 1., 0.],
+ [0., 0., 1.]])
+ >>> np.eye(3, 5)
+ array([[1., 0., 0., 0., 0.],
+ [0., 1., 0., 0., 0.],
+ [0., 0., 1., 0., 0.]])
+
+:func:`numpy.diag` can define either a square 2D array with given values along
+the diagonal *or* if given a 2D array returns a 1D array that is
+only the diagonal elements. The two array creation functions can be helpful while
+doing linear algebra, as such::
+
+ >>> np.diag([1, 2, 3])
+ array([[1, 0, 0],
+ [0, 2, 0],
+ [0, 0, 3]])
+ >>> np.diag([1, 2, 3], 1)
+ array([[0, 1, 0, 0],
+ [0, 0, 2, 0],
+ [0, 0, 0, 3],
+ [0, 0, 0, 0]])
+ >>> a = np.array([[1, 2], [3, 4]])
+ >>> np.diag(a)
+ array([1, 4])
+
+``vander(x, n)`` defines a Vandermonde matrix as a 2D NumPy array. Each column
+of the Vandermonde matrix is a decreasing power of the input 1D array or
+list or tuple,
+``x`` where the highest polynomial order is ``n-1``. This array creation
+routine is helpful in generating linear least squares models, as such::
+
+ >>> np.vander(np.linspace(0, 2, 5), 2)
+ array([[0. , 0. , 1. ],
+ [0.25, 0.5 , 1. ],
+ [1. , 1. , 1. ],
+ [2.25, 1.5 , 1. ],
+ [4. , 2. , 1. ]])
+ >>> np.vander([1, 2, 3, 4], 2)
+ array([[1, 1],
+ [2, 1],
+ [3, 1],
+ [4, 1]])
+ >>> np.vander((1, 2, 3, 4), 4)
+ array([[ 1, 1, 1, 1],
+ [ 8, 4, 2, 1],
+ [27, 9, 3, 1],
+ [64, 16, 4, 1]])
+
+3 - general ndarray creation functions
+--------------------------------------
+
+The ndarray creation functions e.g. :func:`numpy.ones`,
+:func:`numpy.zeros`, and :meth:`~numpy.random.Generator.random` define
+arrays based upon the desired shape. The ndarray creation functions
+can create arrays with any dimension by specifying how many dimensions
+and length along that dimension in a tuple or list.
+
+:func:`numpy.zeros` will create an array filled with 0 values with the
+specified shape. The default dtype is ``float64``::
-indices() will create a set of arrays (stacked as a one-higher dimensioned
-array), one per dimension with each representing variation in that dimension.
-An example illustrates much better than a verbal description: ::
+ >>> np.zeros((2, 3))
+ array([[0., 0., 0.],
+ [0., 0., 0.]])
+ >>> np.zeros((2, 3, 2))
+ array([[[0., 0.],
+ [0., 0.],
+ [0., 0.]],
+
+ [[0., 0.],
+ [0., 0.],
+ [0., 0.]]])
+
+:func:`numpy.ones` will create an array filled with 1 values. It is identical to
+``zeros`` in all other respects as such::
+
+ >>> np.ones((2, 3))
+ array([[ 1., 1., 1.],
+ [ 1., 1., 1.]])
+ >>> np.ones((2, 3, 2))
+ array([[[1., 1.],
+ [1., 1.],
+ [1., 1.]],
+
+ [[1., 1.],
+ [1., 1.],
+ [1., 1.]]])
+
+The :meth:`~numpy.random.Generator.random` method of the result of
+``default_rng`` will create an array filled with random
+values between 0 and 1. It is included with the :func:`numpy.random`
+library. Below, two arrays are created with shapes (2,3) and (2,3,2),
+respectively. The seed is set to 42 so you can reproduce these
+pseudorandom numbers::
+
+ >>> import numpy.random.default_rng
+ >>> default_rng(42).random((2,3))
+ array([[0.77395605, 0.43887844, 0.85859792],
+ [0.69736803, 0.09417735, 0.97562235]])
+ >>> default_rng(42).random((2,3,2))
+ array([[[0.77395605, 0.43887844],
+ [0.85859792, 0.69736803],
+ [0.09417735, 0.97562235]],
+ [[0.7611397 , 0.78606431],
+ [0.12811363, 0.45038594],
+ [0.37079802, 0.92676499]]])
+
+:func:`numpy.indices` will create a set of arrays (stacked as a one-higher
+dimensioned array), one per dimension with each representing variation in that
+dimension: ::
>>> np.indices((3,3))
- array([[[0, 0, 0], [1, 1, 1], [2, 2, 2]], [[0, 1, 2], [0, 1, 2], [0, 1, 2]]])
+ array([[[0, 0, 0],
+ [1, 1, 1],
+ [2, 2, 2]],
+ [[0, 1, 2],
+ [0, 1, 2],
+ [0, 1, 2]]])
This is particularly useful for evaluating functions of multiple dimensions on
a regular grid.
-Reading Arrays From Disk
-========================
+3) Replicating, joining, or mutating existing arrays
+====================================================
-This is presumably the most common case of large array creation. The details,
-of course, depend greatly on the format of data on disk and so this section
-can only give general pointers on how to handle various formats.
+Once you have created arrays, you can replicate, join, or mutate those
+existing arrays to create new arrays. When you assign an array or its
+elements to a new variable, you have to explicitly :func:`numpy.copy` the array,
+otherwise the variable is a view into the original array. Consider the
+following example::
+
+ >>> a = np.array([1, 2, 3, 4, 5, 6])
+ >>> b = a[:2]
+ >>> b += 1
+ >>> print('a =', a, '; b =', b)
+ a = [2 3 3 4 5 6]; b = [2 3]
+
+In this example, you did not create a new array. You created a variable,
+``b`` that viewed the first 2 elements of ``a``. When you added 1 to ``b`` you
+would get the same result by adding 1 to ``a[:2]``. If you want to create a
+*new* array, use the :func:`numpy.copy` array creation routine as such::
+
+ >>> a = np.array([1, 2, 3, 4])
+ >>> b = a[:2].copy()
+ >>> b += 1
+ >>> print('a = ', a, 'b = ', b)
+ a = [1 2 3 4 5 6] b = [2 3]
+
+For more information and examples look at :ref:`Copies and Views
+<quickstart.copies-and-views>`.
+
+There are a number of routines to join existing arrays e.g. :func:`numpy.vstack`,
+:func:`numpy.hstack`, and :func:`numpy.block`. Here is an example of joining four 2-by-2
+arrays into a 4-by-4 array using ``block``::
+
+ >>> A = np.ones((2, 2))
+ >>> B = np.eye((2, 2))
+ >>> C = np.zeros((2, 2))
+ >>> D = np.diag((-3, -4))
+ >>> np.block([[A, B],
+ [C, D]])
+ array([[ 1., 1., 1., 0. ],
+ [ 1., 1., 0., 1. ],
+ [ 0., 0., -3., 0. ],
+ [ 0., 0., 0., -4. ]])
+
+Other routines use similar syntax to join ndarrays. Check the
+routine's documentation for further examples and syntax.
+
+4) Reading arrays from disk, either from standard or custom formats
+===================================================================
+
+This is the most common case of large array creation. The details depend
+greatly on the format of data on disk. This section gives general pointers on
+how to handle various formats. For more detailed examples of IO look at
+:ref:`How to Read and Write files <how-to-io>`.
Standard Binary Formats
-----------------------
Various fields have standard formats for array data. The following lists the
-ones with known python libraries to read them and return numpy arrays (there
-may be others for which it is possible to read and convert to numpy arrays so
+ones with known Python libraries to read them and return NumPy arrays (there
+may be others for which it is possible to read and convert to NumPy arrays so
check the last section as well)
::
@@ -114,33 +334,51 @@ convert are those formats supported by libraries like PIL (able to read and
write many image formats such as jpg, png, etc).
Common ASCII Formats
-------------------------
+--------------------
-Comma Separated Value files (CSV) are widely used (and an export and import
-option for programs like Excel). There are a number of ways of reading these
-files in Python. There are CSV functions in Python and functions in pylab
-(part of matplotlib).
+Delimited files such as comma separated value (csv) and tab separated
+value (tsv) files are used for programs like Excel and LabView. Python
+functions can read and parse these files line-by-line. NumPy has two
+standard routines for importing a file with delimited data :func:`numpy.loadtxt`
+and :func:`numpy.genfromtxt`. These functions have more involved use cases in
+:doc:`how-to-io`. A simple example given a ``simple.csv``:
-More generic ascii files can be read using the io package in scipy.
+.. code-block:: bash
-Custom Binary Formats
----------------------
+ $ cat simple.csv
+ x, y
+ 0, 0
+ 1, 1
+ 2, 4
+ 3, 9
+
+Importing ``simple.csv`` is accomplished using :func:`loadtxt`::
+
+ >>> np.loadtxt('simple.csv', delimiter = ',', skiprows = 1) # doctest: +SKIP
+ array([[0., 0.],
+ [1., 1.],
+ [2., 4.],
+ [3., 9.]])
+
+
+More generic ASCII files can be read using `scipy.io` and `Pandas
+<https://pandas.pydata.org/>`_.
+
+5) Creating arrays from raw bytes through the use of strings or buffers
+=======================================================================
There are a variety of approaches one can use. If the file has a relatively
-simple format then one can write a simple I/O library and use the numpy
-fromfile() function and .tofile() method to read and write numpy arrays
+simple format then one can write a simple I/O library and use the NumPy
+``fromfile()`` function and ``.tofile()`` method to read and write NumPy arrays
directly (mind your byteorder though!) If a good C or C++ library exists that
read the data, one can wrap that library with a variety of techniques though
that certainly is much more work and requires significantly more advanced
knowledge to interface with C or C++.
-Use of Special Libraries
-------------------------
-
-There are libraries that can be used to generate arrays for special purposes
-and it isn't possible to enumerate all of them. The most common uses are use
-of the many array generation functions in random that can generate arrays of
-random values, and some utility functions to generate special matrices (e.g.
-diagonal).
-
+6) Use of special library functions (e.g., SciPy, Pandas, and OpenCV)
+=====================================================================
+NumPy is the fundamental library for array containers in the Python Scientific Computing
+stack. Many Python libraries, including SciPy, Pandas, and OpenCV, use NumPy ndarrays
+as the common format for data exchange, These libraries can create,
+operate on, and work with NumPy arrays.
diff --git a/doc/source/user/basics.dispatch.rst b/doc/source/user/basics.dispatch.rst
index c0e1cf9ba..089a7df17 100644
--- a/doc/source/user/basics.dispatch.rst
+++ b/doc/source/user/basics.dispatch.rst
@@ -22,8 +22,8 @@ example that has rather narrow utility but illustrates the concepts involved.
... self._i = value
... def __repr__(self):
... return f"{self.__class__.__name__}(N={self._N}, value={self._i})"
-... def __array__(self):
-... return self._i * np.eye(self._N)
+... def __array__(self, dtype=None):
+... return self._i * np.eye(self._N, dtype=dtype)
Our custom array can be instantiated like:
@@ -56,7 +56,7 @@ array([[2., 0., 0., 0., 0.],
Notice that the return type is a standard ``numpy.ndarray``.
->>> type(arr)
+>>> type(np.multiply(arr, 2))
numpy.ndarray
How can we pass our custom array type through this function? Numpy allows a
@@ -84,8 +84,8 @@ For this example we will only handle the method ``__call__``
... self._i = value
... def __repr__(self):
... return f"{self.__class__.__name__}(N={self._N}, value={self._i})"
-... def __array__(self):
-... return self._i * np.eye(self._N)
+... def __array__(self, dtype=None):
+... return self._i * np.eye(self._N, dtype=dtype)
... def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
... if method == '__call__':
... N = None
@@ -133,8 +133,8 @@ conveniently by inheriting from the mixin
... self._i = value
... def __repr__(self):
... return f"{self.__class__.__name__}(N={self._N}, value={self._i})"
-... def __array__(self):
-... return self._i * np.eye(self._N)
+... def __array__(self, dtype=None):
+... return self._i * np.eye(self._N, dtype=dtype)
... def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
... if method == '__call__':
... N = None
@@ -171,8 +171,8 @@ functions to our custom variants.
... self._i = value
... def __repr__(self):
... return f"{self.__class__.__name__}(N={self._N}, value={self._i})"
-... def __array__(self):
-... return self._i * np.eye(self._N)
+... def __array__(self, dtype=None):
+... return self._i * np.eye(self._N, dtype=dtype)
... def __array_ufunc__(self, ufunc, method, *inputs, **kwargs):
... if method == '__call__':
... N = None
diff --git a/doc/source/user/basics.indexing.rst b/doc/source/user/basics.indexing.rst
index 9545bb78c..7ee61b130 100644
--- a/doc/source/user/basics.indexing.rst
+++ b/doc/source/user/basics.indexing.rst
@@ -11,7 +11,7 @@ Indexing
:ref:`Indexing routines <routines.indexing>`
Array indexing refers to any use of the square brackets ([]) to index
-array values. There are many options to indexing, which give numpy
+array values. There are many options to indexing, which give NumPy
indexing great power, but with power comes some complexity and the
potential for confusion. This section is just an overview of the
various options and issues related to indexing. Aside from single
@@ -39,7 +39,7 @@ and accepts negative indices for indexing from the end of the array. ::
>>> x[-2]
8
-Unlike lists and tuples, numpy arrays support multidimensional indexing
+Unlike lists and tuples, NumPy arrays support multidimensional indexing
for multidimensional arrays. That means that it is not necessary to
separate each dimension's index into its own set of square brackets. ::
@@ -285,7 +285,7 @@ with four True elements to select rows from a 3-D array of shape
[20, 21, 22, 23, 24],
[25, 26, 27, 28, 29]])
-For further details, consult the numpy reference documentation on array indexing.
+For further details, consult the NumPy reference documentation on array indexing.
Combining index arrays with slices
==================================
diff --git a/doc/source/user/basics.rst b/doc/source/user/basics.rst
index e0fc0ece3..66f3f9ee9 100644
--- a/doc/source/user/basics.rst
+++ b/doc/source/user/basics.rst
@@ -1,14 +1,18 @@
-************
-NumPy basics
-************
+******************
+NumPy fundamentals
+******************
+
+These documents clarify concepts, design decisions, and technical
+constraints in NumPy. This is a great place to understand the
+fundamental NumPy ideas and philosophy.
.. toctree::
:maxdepth: 1
- basics.types
basics.creation
- basics.io
basics.indexing
+ basics.io
+ basics.types
basics.broadcasting
basics.byteswapping
basics.rec
diff --git a/doc/source/user/basics.subclassing.rst b/doc/source/user/basics.subclassing.rst
index 8ffa31688..1b7880986 100644
--- a/doc/source/user/basics.subclassing.rst
+++ b/doc/source/user/basics.subclassing.rst
@@ -223,8 +223,8 @@ where our object creation housekeeping usually goes.
new ndarray instance of its own class. In practice this means that
we, the authors of the code, will need to make a call to
``ndarray.__new__(MySubClass,...)``, a class-hierarchy prepared call to
- ``super(MySubClass, cls).__new__(cls, ...)``, or do view casting of an
- existing array (see below)
+ ``super().__new__(cls, ...)``, or do view casting of an existing array
+ (see below)
* For view casting and new-from-template, the equivalent of
``ndarray.__new__(MySubClass,...`` is called, at the C level.
@@ -240,7 +240,7 @@ The following code allows us to look at the call sequences and arguments:
class C(np.ndarray):
def __new__(cls, *args, **kwargs):
print('In __new__ with class %s' % cls)
- return super(C, cls).__new__(cls, *args, **kwargs)
+ return super().__new__(cls, *args, **kwargs)
def __init__(self, *args, **kwargs):
# in practice you probably will not need or want an __init__
@@ -312,9 +312,8 @@ Simple example - adding an extra attribute to ndarray
# ndarray input arguments. This will call the standard
# ndarray constructor, but return an object of our type.
# It also triggers a call to InfoArray.__array_finalize__
- obj = super(InfoArray, subtype).__new__(subtype, shape, dtype,
- buffer, offset, strides,
- order)
+ obj = super().__new__(subtype, shape, dtype,
+ buffer, offset, strides, order)
# set the new 'info' attribute to the value passed
obj.info = info
# Finally, we must return the newly created object:
@@ -486,8 +485,7 @@ following.
if out_no:
info['outputs'] = out_no
- results = super(A, self).__array_ufunc__(ufunc, method,
- *args, **kwargs)
+ results = super().__array_ufunc__(ufunc, method, *args, **kwargs)
if results is NotImplemented:
return NotImplemented
@@ -600,7 +598,7 @@ some print statements:
print(' self is %s' % repr(self))
print(' arr is %s' % repr(out_arr))
# then just call the parent
- return super(MySubClass, self).__array_wrap__(self, out_arr, context)
+ return super().__array_wrap__(self, out_arr, context)
We run a ufunc on an instance of our new array:
diff --git a/doc/source/user/basics.types.rst b/doc/source/user/basics.types.rst
index ec2af409a..354f003fb 100644
--- a/doc/source/user/basics.types.rst
+++ b/doc/source/user/basics.types.rst
@@ -1,3 +1,5 @@
+.. _basics.types:
+
**********
Data types
**********
@@ -96,70 +98,8 @@ The primitive types supported are tied closely to those in C:
Since many of these have platform-dependent definitions, a set of fixed-size
-aliases are provided:
-
-.. list-table::
- :header-rows: 1
-
- * - Numpy type
- - C type
- - Description
-
- * - `numpy.int8`
- - ``int8_t``
- - Byte (-128 to 127)
-
- * - `numpy.int16`
- - ``int16_t``
- - Integer (-32768 to 32767)
-
- * - `numpy.int32`
- - ``int32_t``
- - Integer (-2147483648 to 2147483647)
-
- * - `numpy.int64`
- - ``int64_t``
- - Integer (-9223372036854775808 to 9223372036854775807)
-
- * - `numpy.uint8`
- - ``uint8_t``
- - Unsigned integer (0 to 255)
-
- * - `numpy.uint16`
- - ``uint16_t``
- - Unsigned integer (0 to 65535)
+aliases are provided (See :ref:`sized-aliases`).
- * - `numpy.uint32`
- - ``uint32_t``
- - Unsigned integer (0 to 4294967295)
-
- * - `numpy.uint64`
- - ``uint64_t``
- - Unsigned integer (0 to 18446744073709551615)
-
- * - `numpy.intp`
- - ``intptr_t``
- - Integer used for indexing, typically the same as ``ssize_t``
-
- * - `numpy.uintp`
- - ``uintptr_t``
- - Integer large enough to hold a pointer
-
- * - `numpy.float32`
- - ``float``
- -
-
- * - `numpy.float64` / `numpy.float_`
- - ``double``
- - Note that this matches the precision of the builtin python `float`.
-
- * - `numpy.complex64`
- - ``float complex``
- - Complex number, represented by two 32-bit floats (real and imaginary components)
-
- * - `numpy.complex128` / `numpy.complex_`
- - ``double complex``
- - Note that this matches the precision of the builtin python `complex`.
NumPy numerical types are instances of ``dtype`` (data-type) objects, each
@@ -171,7 +111,7 @@ having unique characteristics. Once you have imported NumPy using
the dtypes are available as ``np.bool_``, ``np.float32``, etc.
-Advanced types, not listed in the table above, are explored in
+Advanced types, not listed above, are explored in
section :ref:`structured_arrays`.
There are 5 basic numerical types representing booleans (bool), integers (int),
@@ -261,12 +201,14 @@ identical behaviour between arrays and scalars, irrespective of whether the
value is inside an array or not. NumPy scalars also have many of the same
methods arrays do.
+.. _overflow-errors:
+
Overflow Errors
===============
The fixed size of NumPy numeric types may cause overflow errors when a value
requires more memory than available in the data type. For example,
-`numpy.power` evaluates ``100 * 10 ** 8`` correctly for 64-bit integers,
+`numpy.power` evaluates ``100 ** 8`` correctly for 64-bit integers,
but gives 1874919424 (incorrect) for a 32-bit integer.
>>> np.power(100, 8, dtype=np.int64)
diff --git a/doc/source/user/broadcasting_1.svg b/doc/source/user/broadcasting_1.svg
new file mode 100644
index 000000000..4031c3af4
--- /dev/null
+++ b/doc/source/user/broadcasting_1.svg
@@ -0,0 +1,669 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="137.50784mm"
+ height="50.70256mm"
+ viewBox="0 0 137.50784 50.70256"
+ version="1.1"
+ id="svg5"
+ sodipodi:docname="theory.broadcasting_1.svg"
+ inkscape:version="1.1 (c68e22c387, 2021-05-23)"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <sodipodi:namedview
+ id="namedview7"
+ pagecolor="#505050"
+ bordercolor="#eeeeee"
+ borderopacity="1"
+ inkscape:pageshadow="0"
+ inkscape:pageopacity="0"
+ inkscape:pagecheckerboard="0"
+ inkscape:document-units="mm"
+ showgrid="false"
+ showguides="true"
+ inkscape:zoom="1.3289991"
+ inkscape:cx="-66.591468"
+ inkscape:cy="32.731399"
+ inkscape:window-width="1920"
+ inkscape:window-height="1001"
+ inkscape:window-x="-9"
+ inkscape:window-y="-9"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="layer1"
+ fit-margin-top="5"
+ fit-margin-left="5"
+ fit-margin-right="5"
+ fit-margin-bottom="5">
+ <inkscape:grid
+ type="xygrid"
+ id="grid47998"
+ originx="-26.434583"
+ originy="-13.532259" />
+ </sodipodi:namedview>
+ <defs
+ id="defs2">
+ <marker
+ style="overflow:visible"
+ id="Arrow1Lend"
+ refX="0"
+ refY="0"
+ orient="auto"
+ inkscape:stockid="Arrow1Lend"
+ inkscape:isstock="true">
+ <path
+ transform="matrix(-0.8,0,0,-0.8,-10,0)"
+ style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
+ d="M 0,0 5,-5 -12.5,0 5,5 Z"
+ id="path96534" />
+ </marker>
+ </defs>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-26.434582,-13.53226)">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 31.508555,33.859917 4.704047,-5.931184"
+ id="path5205"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 58.319717,33.859917 4.704047,-5.931184"
+ id="path6922"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 49.382665,33.859917 4.704048,-5.931184"
+ id="path6924"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 40.445607,33.859917 4.704048,-5.931184"
+ id="path6926"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 58.319717,47.091968 4.704047,-5.931184"
+ id="path6961"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 36.212602,27.928733 h 8.937053 8.937058 8.937051"
+ id="path6996"
+ sodipodi:nodetypes="cccc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="M 63.023764,27.928733 V 41.160784"
+ id="path7224"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 31.508555,33.859917 4.704047,-5.931184"
+ id="path9982"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 58.319717,33.859917 4.704047,-5.931184"
+ id="path9988"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 49.382665,33.859917 4.704048,-5.931184"
+ id="path9990"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 40.445607,33.859917 4.704048,-5.931184"
+ id="path9992"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 58.319717,47.091968 4.704047,-5.931184"
+ id="path9994"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 36.212602,27.928733 h 8.937053 8.937058 8.937051"
+ id="path9996"
+ sodipodi:nodetypes="cccc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="M 63.023764,27.928733 V 41.160784"
+ id="path9998"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.147946px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 79.344654,34.069936 4.704047,-5.931184"
+ id="path48002"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.147946px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 106.15582,34.069936 4.70405,-5.931184"
+ id="path48008"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.147946px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 97.21876,34.069936 4.70405,-5.931184"
+ id="path48010"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.147946px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 88.281704,34.069936 4.704049,-5.931184"
+ id="path48012"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.147946px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 106.15582,47.301981 4.70405,-5.931184"
+ id="path48014"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.147946px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 110.85987,28.138752 V 41.370797"
+ id="path48018"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.147946px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 79.344654,34.069936 4.704047,-5.931184"
+ id="path48030"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.147946px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 106.15582,34.069936 4.70405,-5.931184"
+ id="path48036"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.147946px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 97.21876,34.069936 4.70405,-5.931184"
+ id="path48038"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.147946px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 88.281704,34.069936 4.704049,-5.931184"
+ id="path48040"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.147946px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 106.15582,47.301981 4.70405,-5.931184"
+ id="path48042"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.147946px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 84.048701,28.138752 h 8.937052 8.937057 8.93706"
+ id="path48044"
+ sodipodi:nodetypes="cccc" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.147946px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 110.85987,28.138752 V 41.370797"
+ id="path48046"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.147946px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 79.344654,34.069936 h 8.93705 8.937056 8.93706 v 13.232045"
+ id="path52709"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.147946px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 106.15582,47.301981 H 97.218767 88.28171 79.344654 V 34.069936"
+ id="path53128"
+ sodipodi:nodetypes="ccccc" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.147946px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 88.281704,34.069936 V 47.301981"
+ id="path53650"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.147946px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 97.21876,34.069936 V 47.301981"
+ id="path53935"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:#fcffff;fill-opacity:1;stroke:#000000;stroke-width:0.248;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 79.597689,33.925906 c 0.0217,-0.0352 1.048179,-1.335017 2.281023,-2.888597 l 2.241541,-2.824686 h 4.341296 4.341292 l -2.286401,2.886538 -2.286409,2.886544 -4.335912,0.0019 c -3.456122,0.0019 -4.327906,-0.01087 -4.29643,-0.06183 z"
+ id="path53974"
+ sodipodi:nodetypes="cscccccccc" />
+ <path
+ style="fill:#fcffff;fill-opacity:1;stroke:#c2c0c0;stroke-width:0.128684;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 88.519647,33.947332 c 0.0095,-0.02368 1.029425,-1.322348 2.26667,-2.885914 l 2.249527,-2.842843 4.332898,-0.0026 c 2.383092,-0.0019 4.332888,0.0078 4.332888,0.02098 0,0.01319 -1.01863,1.307278 -2.263631,2.875812 l -2.263628,2.851889 -4.335929,0.01306 c -2.384764,0.0072 -4.328222,-0.0064 -4.318795,-0.02998 z"
+ id="path54013"
+ sodipodi:nodetypes="csccsscccc" />
+ <path
+ style="fill:#fcffff;fill-opacity:1;stroke:#c2c0c0;stroke-width:0.128684;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 97.845189,33.440213 c 0.240884,-0.30228 0.711251,-0.894698 1.045271,-1.316486 0.793854,-1.002451 1.595,-2.012218 2.36656,-2.982813 0.34296,-0.431421 0.6492,-0.816914 0.68053,-0.856639 0.0485,-0.06138 0.70602,-0.07027 4.38287,-0.05913 l 4.32589,0.01306 -2.28034,2.875812 -2.28033,2.875818 h -4.33921 -4.339205 z"
+ id="path54052"
+ sodipodi:nodetypes="ssscccccccs" />
+ <path
+ style="fill:#fcffff;fill-opacity:1;stroke:#c2c0c0;stroke-width:0.128684;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 97.304831,40.661714 v -6.518518 h 4.371249 4.37124 v 6.518518 6.518518 h -4.37124 -4.371249 z"
+ id="path54091"
+ sodipodi:nodetypes="ccccccccc" />
+ <path
+ style="fill:#fcffff;fill-opacity:1;stroke:#c2c0c0;stroke-width:0.128684;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 88.357846,40.661714 v -6.518518 h 4.37124 4.37124 v 6.518518 6.518518 h -4.37124 -4.37124 z"
+ id="path54130"
+ sodipodi:nodetypes="ccccccccc" />
+ <path
+ style="fill:#fcffff;fill-opacity:1;stroke:#000000;stroke-width:0.248;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 79.461984,40.661714 v -6.518518 h 4.371248 4.37124 v 6.518518 6.518518 h -4.37124 -4.371248 z"
+ id="path54169"
+ sodipodi:nodetypes="ccccccccc" />
+ <path
+ style="fill:#fcffff;fill-opacity:1;stroke:#c2c0c0;stroke-width:0.128684;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 106.25221,40.556901 4.4e-4,-6.439275 2.22941,-2.811907 c 1.22617,-1.546548 2.23829,-2.821501 2.24913,-2.833211 0.0109,-0.01171 0.0198,2.878057 0.0198,6.421722 v 6.443019 l -2.20348,2.780901 c -1.21193,1.529484 -2.22422,2.802751 -2.24953,2.82946 -0.0273,0.02882 -0.0459,-2.570193 -0.0456,-6.390709 z"
+ id="path54208"
+ sodipodi:nodetypes="ccscsccscc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 31.508555,33.859917 h 8.937052 8.937058 8.937052"
+ id="path55000"
+ sodipodi:nodetypes="cccc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="M 58.319717,47.091968 V 33.859917"
+ id="path55035"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="M 31.508555,47.091968 V 33.859917"
+ id="path55070"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="M 40.445607,47.091968 V 33.859917"
+ id="path55072"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="M 49.382665,47.091968 V 33.859917"
+ id="path55074"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;stroke-miterlimit:4;stroke-dasharray:none"
+ d="m 31.508555,47.091968 h 8.937052 8.937058 8.937052"
+ id="path55189"
+ sodipodi:nodetypes="cccc" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.147946"
+ x="81.888199"
+ y="42.102463"
+ id="text62163"><tspan
+ sodipodi:role="line"
+ id="tspan62161"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.147946"
+ x="81.888199"
+ y="42.102463">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#c0c0c0;fill-opacity:1;stroke:none;stroke-width:0.147946"
+ x="90.934624"
+ y="42.102463"
+ id="text66863"><tspan
+ sodipodi:role="line"
+ id="tspan66861"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#c0c0c0;fill-opacity:1;stroke-width:0.147946"
+ x="90.934624"
+ y="42.102463">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#c0c0c0;fill-opacity:1;stroke:none;stroke-width:0.147946"
+ x="99.941132"
+ y="42.102463"
+ id="text77828"><tspan
+ sodipodi:role="line"
+ id="tspan77826"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#c0c0c0;fill-opacity:1;stroke-width:0.147946"
+ x="99.941132"
+ y="42.102463">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.147946"
+ x="69.630562"
+ y="41.596489"
+ id="text85828"><tspan
+ sodipodi:role="line"
+ id="tspan85826"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.147946"
+ x="69.630562"
+ y="41.596489">*</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.147946"
+ x="117.43818"
+ y="40.412045"
+ id="text87726"><tspan
+ sodipodi:role="line"
+ id="tspan87724"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.147946"
+ x="117.43818"
+ y="40.412045">=</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.91785px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.147946"
+ x="44.636856"
+ y="23.010897"
+ id="text89497"><tspan
+ sodipodi:role="line"
+ id="tspan89495"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.91785px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.147946"
+ x="44.636856"
+ y="23.010897"><tspan
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal"
+ id="tspan5460">a</tspan> (3)</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.91785px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.147946"
+ x="93.357834"
+ y="23.034334"
+ id="text90809"><tspan
+ sodipodi:role="line"
+ id="tspan90807"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.91785px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.147946"
+ x="93.357834"
+ y="23.034334"><tspan
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal"
+ id="tspan2930">b</tspan> (1)</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.91785px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.147946"
+ x="136.34079"
+ y="22.840616"
+ id="text91329"><tspan
+ sodipodi:role="line"
+ id="tspan91327"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.91785px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.147946"
+ x="136.34079"
+ y="22.840616"><tspan
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal"
+ id="tspan3730">result</tspan> (3)</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.91785px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.147946"
+ x="85.080841"
+ y="59.16547"
+ id="text93193"><tspan
+ sodipodi:role="line"
+ id="tspan93191"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.91785px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.147946"
+ x="85.080841"
+ y="59.16547">stretch</tspan></text>
+ <path
+ style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.165526;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
+ d="m 81.41288,52.445886 h 23.74344"
+ id="path96373"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:#ffffff;stroke:#000000;stroke-width:0.433145;stroke-miterlimit:5.30435;stroke-dasharray:none"
+ d="m 21.652887,74.977138 c 0.50651,-0.698939 4.230051,-5.429777 8.274534,-10.512973 l 7.353605,-9.242174 16.031996,-0.121532 16.031995,-0.121531 -5.423208,6.822108 c -2.982765,3.752159 -6.772069,8.537686 -8.420677,10.634504 l -2.997469,3.812397 H 36.61781 20.731958 Z"
+ id="path12997"
+ transform="matrix(0.26458333,0,0,0.26458333,26.434582,13.53226)" />
+ <path
+ style="fill:#ffffff;stroke:#000000;stroke-width:0.433145;stroke-miterlimit:5.30435;stroke-dasharray:none"
+ d="m 55.08026,75.409135 c 0.332112,-0.461342 4.101427,-5.244167 8.376257,-10.6285 l 7.772417,-9.789699 h 15.949964 15.949962 l -1.93952,2.426071 c -1.06673,1.334339 -4.858939,6.117164 -8.427127,10.6285 l -6.487614,8.20243 H 70.37551 c -15.273126,0 -15.875315,-0.03302 -15.29525,-0.838802 z"
+ id="path13036"
+ transform="matrix(0.26458333,0,0,0.26458333,26.434582,13.53226)" />
+ <path
+ style="fill:#ffffff;stroke:#000000;stroke-width:0.433145;stroke-miterlimit:5.30435;stroke-dasharray:none"
+ d="m 89.730475,74.283975 c 0.868474,-1.080179 4.664812,-5.863004 8.436305,-10.6285 l 6.85726,-8.664539 h 15.93574 15.93573 l -1.57904,1.963962 c -0.86848,1.08018 -4.66482,5.863005 -8.43631,10.628501 l -6.85726,8.664538 H 104.08717 88.15143 Z"
+ id="path13075"
+ transform="matrix(0.26458333,0,0,0.26458333,26.434582,13.53226)" />
+ <path
+ style="fill:#ffffff;stroke:#000000;stroke-width:0.433145;stroke-miterlimit:5.30435;stroke-dasharray:none"
+ d="M 87.338546,101.89497 V 77.634263 h 16.173804 16.17381 v 24.260707 24.26071 H 103.51235 87.338546 Z"
+ id="path13114"
+ transform="matrix(0.26458333,0,0,0.26458333,26.434582,13.53226)" />
+ <path
+ style="fill:#ffffff;stroke:#000000;stroke-width:0.433145;stroke-miterlimit:5.30435;stroke-dasharray:none"
+ d="M 53.60461,101.89497 V 77.634263 H 69.778415 85.95222 v 24.260707 24.26071 H 69.778415 53.60461 Z"
+ id="path13153"
+ transform="matrix(0.26458333,0,0,0.26458333,26.434582,13.53226)" />
+ <path
+ style="fill:#ffffff;stroke:#000000;stroke-width:0.433145;stroke-miterlimit:5.30435;stroke-dasharray:none"
+ d="M 19.870674,101.89497 V 77.634263 h 16.173805 16.173805 v 24.260707 24.26071 H 36.044479 19.870674 Z"
+ id="path13192"
+ transform="matrix(0.26458333,0,0,0.26458333,26.434582,13.53226)" />
+ <path
+ style="fill:#ffffff;stroke:#000000;stroke-width:0.433145;stroke-miterlimit:5.30435;stroke-dasharray:none"
+ d="M 121.07248,101.12036 V 77.327368 l 8.20243,-10.336784 8.20243,-10.336785 0.11972,23.659407 0.11973,23.659404 -8.32216,10.47037 -8.32215,10.47037 z"
+ id="path13231"
+ transform="matrix(0.26458333,0,0,0.26458333,26.434582,13.53226)" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.147946"
+ x="34.390987"
+ y="41.801289"
+ id="text11724"><tspan
+ sodipodi:role="line"
+ id="tspan11722"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.147946"
+ x="34.390987"
+ y="41.801289">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.147946"
+ x="43.594547"
+ y="41.801289"
+ id="text11728"><tspan
+ sodipodi:role="line"
+ id="tspan11726"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.147946"
+ x="43.594547"
+ y="41.801289">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.147946"
+ x="52.389057"
+ y="41.801289"
+ id="text11732"><tspan
+ sodipodi:role="line"
+ id="tspan11730"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.147946"
+ x="52.389057"
+ y="41.801289">3</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.147946"
+ x="34.390987"
+ y="41.801289"
+ id="text11736"><tspan
+ sodipodi:role="line"
+ id="tspan11734"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.147946"
+ x="34.390987"
+ y="41.801289">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.147946"
+ x="43.594547"
+ y="41.801289"
+ id="text11740"><tspan
+ sodipodi:role="line"
+ id="tspan11738"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.147946"
+ x="43.594547"
+ y="41.801289">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.147946"
+ x="52.389057"
+ y="41.801289"
+ id="text11744"><tspan
+ sodipodi:role="line"
+ id="tspan11742"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.147946"
+ x="52.389057"
+ y="41.801289">3</tspan></text>
+ <g
+ id="g14529"
+ transform="translate(-29.470708,43.570713)">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 156.53372,-9.7396236 4.70405,-5.9311844"
+ id="path14293"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 183.34488,-9.7396236 4.70405,-5.9311844"
+ id="path14295"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 174.40783,-9.7396236 4.70405,-5.9311844"
+ id="path14297"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 165.47077,-9.7396236 4.70405,-5.9311844"
+ id="path14299"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 183.34488,3.4924274 4.70405,-5.931184"
+ id="path14301"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 161.23777,-15.670808 h 8.93705 8.93706 8.93705"
+ id="path14303"
+ sodipodi:nodetypes="cccc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 188.04893,-15.670808 V -2.4387566"
+ id="path14305"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 156.53372,-9.7396236 4.70405,-5.9311844"
+ id="path14307"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 183.34488,-9.7396236 4.70405,-5.9311844"
+ id="path14309"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 174.40783,-9.7396236 4.70405,-5.9311844"
+ id="path14311"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 165.47077,-9.7396236 4.70405,-5.9311844"
+ id="path14313"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 183.34488,3.4924274 4.70405,-5.931184"
+ id="path14315"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 161.23777,-15.670808 h 8.93705 8.93706 8.93705"
+ id="path14317"
+ sodipodi:nodetypes="cccc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 188.04893,-15.670808 V -2.4387566"
+ id="path14319"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 156.53372,-9.7396236 h 8.93705 8.93706 8.93705"
+ id="path14321"
+ sodipodi:nodetypes="cccc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 183.34488,3.4924274 V -9.7396236"
+ id="path14323"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 156.53372,3.4924274 V -9.7396236"
+ id="path14325"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 165.47077,3.4924274 V -9.7396236"
+ id="path14327"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 174.40783,3.4924274 V -9.7396236"
+ id="path14329"
+ sodipodi:nodetypes="cc" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.248;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 156.53372,3.4924274 h 8.93705 8.93706 8.93705"
+ id="path14331"
+ sodipodi:nodetypes="cccc" />
+ <path
+ style="fill:#ffffff;stroke:#000000;stroke-width:0.114603;stroke-miterlimit:5.30435;stroke-dasharray:none"
+ d="m 157.18874,-10.22958 c 0.13402,-0.184927 1.1192,-1.436628 2.18931,-2.781557 l 1.94564,-2.445325 4.2418,-0.03216 4.24179,-0.03215 -1.43489,1.805016 c -0.78919,0.992759 -1.79177,2.25893 -2.22797,2.813713 l -0.79308,1.0086964 h -4.20313 -4.20313 z"
+ id="path14333" />
+ <path
+ style="fill:#ffffff;stroke:#000000;stroke-width:0.114603;stroke-miterlimit:5.30435;stroke-dasharray:none"
+ d="m 166.03307,-10.115281 c 0.0879,-0.122063 1.08517,-1.387519 2.21622,-2.812124 l 2.05645,-2.590191 h 4.22009 4.2201 l -0.51317,0.641898 c -0.28224,0.353044 -1.28559,1.6185 -2.22968,2.812124 l -1.71651,2.1702264 h -4.20663 c -4.04102,0 -4.20035,-0.00874 -4.04687,-0.2219334 z"
+ id="path14335" />
+ <path
+ style="fill:#ffffff;stroke:#000000;stroke-width:0.114603;stroke-miterlimit:5.30435;stroke-dasharray:none"
+ d="m 175.20094,-10.412979 c 0.22978,-0.285798 1.23423,-1.551253 2.2321,-2.812124 l 1.81432,-2.292493 h 4.21633 4.21633 l -0.41779,0.519632 c -0.22978,0.285798 -1.23423,1.551253 -2.23211,2.812124 l -1.81431,2.2924924 h -4.21633 -4.21633 z"
+ id="path14337" />
+ <path
+ style="fill:#ffffff;stroke:#000000;stroke-width:0.114603;stroke-miterlimit:5.30435;stroke-dasharray:none"
+ d="m 174.56807,-3.1075702 v -6.4189786 h 4.27932 4.27932 v 6.4189786 6.4189795 h -4.27932 -4.27932 z"
+ id="path14339" />
+ <path
+ style="fill:#ffffff;stroke:#000000;stroke-width:0.114603;stroke-miterlimit:5.30435;stroke-dasharray:none"
+ d="m 165.64264,-3.1075702 v -6.4189786 h 4.27931 4.27932 v 6.4189786 6.4189795 h -4.27932 -4.27931 z"
+ id="path14341" />
+ <path
+ style="fill:#ffffff;stroke:#000000;stroke-width:0.114603;stroke-miterlimit:5.30435;stroke-dasharray:none"
+ d="m 156.7172,-3.1075702 v -6.4189786 h 4.27932 4.27932 v 6.4189786 6.4189795 h -4.27932 -4.27932 z"
+ id="path14343" />
+ <path
+ style="fill:#ffffff;stroke:#000000;stroke-width:0.114603;stroke-miterlimit:5.30435;stroke-dasharray:none"
+ d="m 183.49351,-3.3125191 v -6.295229 l 2.17022,-2.7349409 2.17023,-2.734941 0.0317,6.2598848 0.0317,6.2598839 -2.20191,2.7702854 -2.2019,2.7702854 z"
+ id="path14345" />
+ <g
+ id="g14377"
+ transform="translate(29.265446,-43.59954)">
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.147946"
+ x="130.58751"
+ y="42.458767"
+ id="text77832"><tspan
+ sodipodi:role="line"
+ id="tspan77830"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;stroke-width:0.147946"
+ x="130.58751"
+ y="42.458767">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.147946"
+ x="139.3645"
+ y="42.501537"
+ id="text79640"><tspan
+ sodipodi:role="line"
+ id="tspan79638"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;stroke-width:0.147946"
+ x="139.3645"
+ y="42.501537">4</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.147946"
+ x="148.36816"
+ y="42.501537"
+ id="text81564"><tspan
+ sodipodi:role="line"
+ id="tspan81562"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.91785px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;stroke-width:0.147946"
+ x="148.36816"
+ y="42.501537">6</tspan></text>
+ </g>
+ </g>
+ </g>
+</svg>
diff --git a/doc/source/user/broadcasting_2.svg b/doc/source/user/broadcasting_2.svg
new file mode 100644
index 000000000..6985dad89
--- /dev/null
+++ b/doc/source/user/broadcasting_2.svg
@@ -0,0 +1,1308 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="136.12085mm"
+ height="55.258423mm"
+ viewBox="0 0 136.12085 55.258424"
+ version="1.1"
+ id="svg2361"
+ inkscape:version="1.1 (c68e22c387, 2021-05-23)"
+ sodipodi:docname="theory.broadcasting_2.svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <sodipodi:namedview
+ id="namedview2363"
+ pagecolor="#004100"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0"
+ inkscape:pagecheckerboard="0"
+ inkscape:document-units="mm"
+ showgrid="true"
+ inkscape:zoom="1.7469907"
+ inkscape:cx="30.051677"
+ inkscape:cy="75.844708"
+ inkscape:window-width="1920"
+ inkscape:window-height="1001"
+ inkscape:window-x="-9"
+ inkscape:window-y="-9"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="layer1"
+ lock-margins="false"
+ fit-margin-top="5"
+ fit-margin-left="5"
+ fit-margin-right="5"
+ fit-margin-bottom="5"
+ showguides="true"
+ inkscape:guide-bbox="true">
+ <inkscape:grid
+ type="xygrid"
+ id="grid44453"
+ originx="-1.3010658"
+ originy="-2.8566359" />
+ </sodipodi:namedview>
+ <defs
+ id="defs2358">
+ <marker
+ style="overflow:visible"
+ id="Arrow1Lend"
+ refX="0"
+ refY="0"
+ orient="auto"
+ inkscape:stockid="Arrow1Lend"
+ inkscape:isstock="true">
+ <path
+ transform="matrix(-0.8,0,0,-0.8,-10,0)"
+ style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
+ d="M 0,0 5,-5 -12.5,0 5,5 Z"
+ id="path96534" />
+ </marker>
+ </defs>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(142.99324,-67.354454)">
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.57899px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.114475"
+ x="90.957649"
+ y="63.798756"
+ id="text93193"
+ transform="rotate(90)"><tspan
+ sodipodi:role="line"
+ id="tspan93191"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.57899px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.114475"
+ x="90.957649"
+ y="63.798756">stretch</tspan></text>
+ <path
+ style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.236131;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
+ d="M -64.919305,88.215985 V 106.5877"
+ id="path96373" />
+ <g
+ id="g46002"
+ transform="matrix(1.0057054,0,0,1.0057054,-82.208516,-72.64114)">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -47.512773,165.23404 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21691" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -47.512773,157.41086 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21910" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -55.335963,165.23404 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21912" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -55.335963,157.41086 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21914" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -47.512773,173.05722 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21916" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -39.689583,173.05722 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21918" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -47.512773,180.8804 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21920" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -55.335963,180.8804 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21922" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -39.689583,165.23404 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21924" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -55.335963,173.05722 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21926" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -39.689583,157.41086 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21928" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -39.689583,180.8804 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21930" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -55.335963,157.41086 4.34622,-6.08471"
+ id="path22112" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M -31.866393,157.58471 -27.520173,151.5"
+ id="path22147" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M -39.689583,157.58471 -35.343363,151.5"
+ id="path22149" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M -47.512773,157.58471 -43.166553,151.5"
+ id="path22151" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -27.520173,151.5 v 31.29272"
+ id="path22266" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -50.989743,151.32615 7.82319,0.17385 h 7.82319 7.82319"
+ id="path22381" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -31.866393,188.87743 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22496" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -31.866393,165.40789 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22644" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -31.866393,173.23107 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22646" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -31.866393,181.05425 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22648" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -47.512773,165.23404 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22650" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -47.512773,157.41086 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22652" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -55.335963,165.23404 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22654" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -55.335963,157.41086 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22656" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -47.512773,173.05722 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22658" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -39.689583,173.05722 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22660" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -47.512773,180.8804 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22662" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -55.335963,180.8804 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22664" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -39.689583,165.23404 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22666" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -55.335963,173.05722 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22668" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -39.689583,157.41086 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22670" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -39.689583,180.8804 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22672" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -55.335963,157.41086 4.34622,-6.08471"
+ id="path22674" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M -31.866393,157.58471 -27.520173,151.5"
+ id="path22676" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M -39.689583,157.58471 -35.343363,151.5"
+ id="path22678" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M -47.512773,157.58471 -43.166553,151.5"
+ id="path22680" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -27.520173,151.5 v 31.29272"
+ id="path22682" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -50.989743,151.32615 7.82319,0.17385 h 7.82319 7.82319"
+ id="path22684" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -31.866393,188.87743 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22686" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -31.866393,165.40789 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22688" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -31.866393,173.23107 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22690" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -31.866393,181.05425 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22692" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -55.142483,161.45304 v -3.71055 h 3.71055 3.71054 v 3.71055 3.71055 h -3.71054 -3.71055 z"
+ id="path13541" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -47.267033,161.45304 v -3.71055 h 3.71054 3.71055 v 3.71055 3.71055 h -3.71055 -3.71054 z"
+ id="path13580" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -39.543043,161.45304 v -3.71055 h 3.71055 3.71055 v 3.71055 3.71055 h -3.71055 -3.71055 z"
+ id="path13619" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -39.543043,169.32849 v -3.71055 h 3.71055 3.71055 v 3.71055 3.71054 h -3.71055 -3.71055 z"
+ id="path13658" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -47.267033,169.32849 v -3.71055 h 3.71054 3.71055 v 3.71055 3.71054 h -3.71055 -3.71054 z"
+ id="path13697" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -55.142483,169.32849 v -3.71055 h 3.71055 3.71054 v 3.71055 3.71054 h -3.71054 -3.71055 z"
+ id="path13736" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -55.142483,177.20393 v -3.71054 h 3.71055 3.71054 v 3.71054 3.71055 h -3.71054 -3.71055 z"
+ id="path13775" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -47.267033,177.20393 v -3.71054 h 3.71054 3.71055 v 3.71054 3.71055 h -3.71055 -3.71054 z"
+ id="path13814" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -39.543043,177.20393 v -3.71054 h 3.71055 3.71055 v 3.71054 3.71055 h -3.71055 -3.71055 z"
+ id="path13853" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -39.543043,184.92793 v -3.71055 h 3.71055 3.71055 v 3.71055 3.71055 h -3.71055 -3.71055 z"
+ id="path13892" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -47.267033,184.92793 v -3.71055 h 3.71054 3.71055 v 3.71055 3.71055 h -3.71055 -3.71054 z"
+ id="path13931" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -55.142483,184.92793 v -3.71055 h 3.71055 3.71054 v 3.71055 3.71055 h -3.71054 -3.71055 z"
+ id="path13970" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -54.899273,157.25299 c 0.0622,-0.10561 0.9991,-1.43582 2.08211,-2.95601 l 1.96911,-2.76398 1.44974,0.019 c 0.79736,0.0105 2.42287,0.0616 3.61225,0.11359 l 2.1625,0.0945 -2.01181,2.80185 -2.0118,2.80184 -3.68255,0.0406 c -2.94083,0.0324 -3.65979,0.002 -3.56955,-0.15145 z"
+ id="path14009" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -46.783393,156.94737 c 0.20247,-0.27071 1.13436,-1.56562 2.07086,-2.87756 l 1.70272,-2.38535 h 3.62228 3.62228 l -2.05577,2.87756 -2.05578,2.87757 h -3.63737 -3.63736 z"
+ id="path14048" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -39.134073,157.23722 c 0.0666,-0.11131 0.97302,-1.40328 2.01425,-2.87104 l 1.89313,-2.66867 3.60958,-0.007 c 1.98527,-0.004 3.58686,0.0493 3.5591,0.11756 -0.0278,0.0683 -0.93452,1.36316 -2.015,2.87757 l -1.96451,2.75347 h -3.60883 c -2.97073,0 -3.58742,-0.0358 -3.48772,-0.20237 z"
+ id="path14087" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -31.667593,161.15934 v -3.45903 l 1.83964,-2.59144 c 1.01181,-1.42529 1.89779,-2.65618 1.96886,-2.73531 0.0718,-0.0799 0.12922,1.40769 0.12922,3.34472 v 3.4886 l -1.82587,2.56186 c -1.00422,1.40903 -1.89021,2.62661 -1.96886,2.70574 -0.0897,0.0903 -0.14299,-1.14491 -0.14299,-3.31514 z"
+ id="path14126" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -31.667593,169.01521 v -3.47859 l 1.83457,-2.57187 c 1.00901,-1.41453 1.895,-2.63661 1.96886,-2.71575 0.0784,-0.084 0.13429,1.30477 0.13429,3.33472 v 3.4786 l -1.83457,2.57187 c -1.00901,1.41452 -1.895,2.63661 -1.96886,2.71574 -0.0784,0.084 -0.13429,-1.30476 -0.13429,-3.33472 z"
+ id="path14165" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -31.667593,176.85105 v -3.49847 l 1.96886,-2.75406 1.96886,-2.75406 v 3.51758 3.51757 l -1.69335,2.37377 c -0.93135,1.30557 -1.81734,2.5363 -1.96886,2.73496 -0.26885,0.35246 -0.27551,0.27663 -0.27551,-3.13729 z"
+ id="path14204" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -31.667593,184.63423 v -3.45903 l 1.83964,-2.59143 c 1.01181,-1.4253 1.89779,-2.65619 1.96886,-2.73532 0.0718,-0.0799 0.12922,1.40768 0.12922,3.34472 v 3.4886 l -1.82587,2.56186 c -1.00422,1.40903 -1.89021,2.62661 -1.96886,2.70575 -0.0897,0.0903 -0.14299,-1.14492 -0.14299,-3.31515 z"
+ id="path14243" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-36.608471"
+ y="162.74039"
+ id="text17645"><tspan
+ sodipodi:role="line"
+ id="tspan17643"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-36.608471"
+ y="162.74039">0</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-37.600399"
+ y="170.6588"
+ id="text21689"><tspan
+ sodipodi:role="line"
+ id="tspan21687"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-37.600399"
+ y="170.6588">10</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-37.477116"
+ y="178.57722"
+ id="text22617"><tspan
+ sodipodi:role="line"
+ id="tspan22615"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-37.477116"
+ y="178.57722">20</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-37.494289"
+ y="186.49469"
+ id="text23721"><tspan
+ sodipodi:role="line"
+ id="tspan23719"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-37.494289"
+ y="186.49469">30</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-44.447037"
+ y="162.74039"
+ id="text25685"><tspan
+ sodipodi:role="line"
+ id="tspan25683"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-44.447037"
+ y="162.74039">0</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-45.438965"
+ y="170.6588"
+ id="text25689"><tspan
+ sodipodi:role="line"
+ id="tspan25687"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-45.438965"
+ y="170.6588">10</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-45.315681"
+ y="178.57722"
+ id="text25693"><tspan
+ sodipodi:role="line"
+ id="tspan25691"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-45.315681"
+ y="178.57722">20</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-45.332859"
+ y="186.49469"
+ id="text25697"><tspan
+ sodipodi:role="line"
+ id="tspan25695"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-45.332859"
+ y="186.49469">30</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-52.285603"
+ y="162.74039"
+ id="text25701"><tspan
+ sodipodi:role="line"
+ id="tspan25699"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-52.285603"
+ y="162.74039">0</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-53.277534"
+ y="170.6588"
+ id="text25705"><tspan
+ sodipodi:role="line"
+ id="tspan25703"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-53.277534"
+ y="170.6588">10</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-53.154247"
+ y="178.57722"
+ id="text25709"><tspan
+ sodipodi:role="line"
+ id="tspan25707"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-53.154247"
+ y="178.57722">20</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-53.171425"
+ y="186.49469"
+ id="text25713"><tspan
+ sodipodi:role="line"
+ id="tspan25711"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-53.171425"
+ y="186.49469">30</tspan></text>
+ </g>
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -88.477569,93.701364 v 8.042716 h 7.867883 v -7.867871 h -7.867883 z"
+ id="path22942" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -88.477569,85.833492 v 8.042717 h 7.867883 v -7.867873 h -7.867883 z"
+ id="path22944" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -96.345452,93.701364 v 8.042716 h 7.867883 v -7.867871 h -7.867883 z"
+ id="path22946" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -96.345452,85.833492 v 8.042717 h 7.867883 v -7.867873 h -7.867883 z"
+ id="path22948" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -88.477569,101.56924 v 8.04271 h 7.867883 v -7.86787 h -7.867883 z"
+ id="path22950" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -80.609686,101.56924 v 8.04271 h 7.867885 v -7.86787 h -7.867885 z"
+ id="path22952" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -88.477569,109.43711 v 8.04272 h 7.867883 v -7.86788 h -7.867883 z"
+ id="path22954" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -96.345452,109.43711 v 8.04272 h 7.867883 v -7.86788 h -7.867883 z"
+ id="path22956" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -80.609686,93.701364 v 8.042716 h 7.867885 v -7.867871 h -7.867885 z"
+ id="path22958" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -96.345452,101.56924 v 8.04271 h 7.867883 v -7.86787 h -7.867883 z"
+ id="path22960" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -80.609686,85.833492 v 8.042717 h 7.867885 v -7.867873 h -7.867885 z"
+ id="path22962" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -80.609686,109.43711 v 8.04272 h 7.867885 v -7.86788 h -7.867885 z"
+ id="path22964" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -96.345452,85.833492 4.37105,-6.119472"
+ id="path22966" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -72.741801,86.008336 4.371049,-6.119471"
+ id="path22968" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -80.609686,86.008336 4.371051,-6.119471"
+ id="path22970" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -88.477569,86.008336 4.37105,-6.119471"
+ id="path22972" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -91.974402,79.71402 7.867883,0.174845 h 7.867884 7.867883"
+ id="path22976" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -72.741801,117.47983 c 4.371049,-6.11948 4.371049,-6.11948 4.371049,-6.11948"
+ id="path22978" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -72.741801,93.876209 c 4.371049,-6.119471 4.371049,-6.119471 4.371049,-6.119471"
+ id="path22980" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -72.741801,101.74408 c 4.371049,-6.119469 4.371049,-6.119469 4.371049,-6.119469"
+ id="path22982" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -72.741801,109.61195 c 4.371049,-6.11947 4.371049,-6.11947 4.371049,-6.11947"
+ id="path22984" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -88.477569,93.701364 v 8.042716 h 7.867883 v -7.867871 h -7.867883 z"
+ id="path22986" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -88.477569,85.833492 v 8.042717 h 7.867883 v -7.867873 h -7.867883 z"
+ id="path22988" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -96.345452,93.701364 v 8.042716 h 7.867883 v -7.867871 h -7.867883 z"
+ id="path22990" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -96.345452,85.833492 v 8.042717 h 7.867883 v -7.867873 h -7.867883 z"
+ id="path22992" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -88.477569,101.56924 v 8.04271 h 7.867883 v -7.86787 h -7.867883 z"
+ id="path22994" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -80.609686,101.56924 v 8.04271 h 7.867885 v -7.86787 h -7.867885 z"
+ id="path22996" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -88.477569,109.43711 v 8.04272 h 7.867883 v -7.86788 h -7.867883 z"
+ id="path22998" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -96.345452,109.43711 v 8.04272 h 7.867883 v -7.86788 h -7.867883 z"
+ id="path23000" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -80.609686,93.701364 v 8.042716 h 7.867885 v -7.867871 h -7.867885 z"
+ id="path23002" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -96.345452,101.56924 v 8.04271 h 7.867883 v -7.86787 h -7.867883 z"
+ id="path23004" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -80.609686,85.833492 v 8.042717 h 7.867885 v -7.867873 h -7.867885 z"
+ id="path23006" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -80.609686,109.43711 v 8.04272 h 7.867885 v -7.86788 h -7.867885 z"
+ id="path23008" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -96.345452,85.833492 4.37105,-6.119472"
+ id="path23010" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -72.741801,86.008336 4.371049,-6.119471"
+ id="path23012" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -80.609686,86.008336 4.371051,-6.119471"
+ id="path23014" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -88.477569,86.008336 4.37105,-6.119471"
+ id="path23016" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -91.974402,79.71402 7.867883,0.174845 h 7.867884 7.867883"
+ id="path23020" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -72.741801,117.47983 c 4.371049,-6.11948 4.371049,-6.11948 4.371049,-6.11948"
+ id="path23022" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -72.741801,93.876209 c 4.371049,-6.119471 4.371049,-6.119471 4.371049,-6.119471"
+ id="path23024" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -72.741801,101.74408 c 4.371049,-6.119469 4.371049,-6.119469 4.371049,-6.119469"
+ id="path23026" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -72.741801,109.61195 c 4.371049,-6.11947 4.371049,-6.11947 4.371049,-6.11947"
+ id="path23028" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -68.370751,79.888865 v 7.867873"
+ id="path25266" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.266095px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -68.370751,111.36035 v -7.86787 -7.867869 -7.867873"
+ id="path25301" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.115137"
+ d="m -95.976457,85.797112 c 0,-0.04012 0.932308,-1.377881 2.071787,-2.972874 l 2.071791,-2.899975 1.469565,0.01909 c 0.808261,0.01077 2.441725,0.062 3.629919,0.114237 l 2.160351,0.0951 -2.014757,2.817848 -2.014754,2.817847 -3.686948,0.04076 c -2.027823,0.02243 -3.686954,0.0075 -3.686954,-0.03214 z"
+ id="path14282" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.115137"
+ d="m -87.460034,84.98877 c 0.338488,-0.481696 1.254857,-1.766862 2.036376,-2.855931 l 1.420944,-1.980112 3.609047,-0.04087 c 1.984978,-0.02243 3.60905,-0.001 3.60905,0.04733 0,0.04852 -0.903225,1.352058 -2.007167,2.896751 l -2.007163,2.808543 h -3.638261 -3.638259 z"
+ id="path14321" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.115137"
+ d="m -80.028905,85.650787 c 0.06699,-0.117601 0.978585,-1.418412 2.02576,-2.890703 l 1.903952,-2.676902 3.625075,-0.0033 c 3.068717,-0.0033 3.606384,0.02943 3.503272,0.210491 -0.06699,0.117602 -0.978583,1.418422 -2.025756,2.890714 l -1.903953,2.676891 -3.625077,0.0033 c -3.068716,0.0033 -3.606384,-0.02943 -3.503273,-0.210502 z"
+ id="path14360" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.115137"
+ d="m -80.440204,89.900966 v -3.731748 h 3.731745 3.731744 v 3.731748 3.731748 h -3.731744 -3.731745 z"
+ id="path14399" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.115137"
+ d="m -88.208328,89.900966 v -3.731748 h 3.731747 3.731746 v 3.731748 3.731748 h -3.731746 -3.731747 z"
+ id="path14438" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.115137"
+ d="m -96.128772,89.900966 v -3.731748 h 3.731751 3.731746 v 3.731748 3.731748 h -3.731746 -3.731751 z"
+ id="path14477" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.115137"
+ d="m -96.128772,97.821402 v -3.731737 h 3.731751 3.731746 v 3.731737 3.731748 h -3.731746 -3.731751 z"
+ id="path14516" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.115137"
+ d="m -88.208328,97.821402 v -3.731737 h 3.731747 3.731746 v 3.731737 3.731748 h -3.731746 -3.731747 z"
+ id="path14555" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.115137"
+ d="m -80.440204,97.821402 v -3.731737 h 3.731745 3.731744 v 3.731737 3.731748 h -3.731744 -3.731745 z"
+ id="path14594" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.115137"
+ d="m -80.440204,105.74185 v -3.73175 h 3.731745 3.731744 v 3.73175 3.73173 h -3.731744 -3.731745 z"
+ id="path14633" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.115137"
+ d="m -88.208328,105.74185 v -3.73175 h 3.731747 3.731746 v 3.73175 3.73173 h -3.731746 -3.731747 z"
+ id="path14672" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.115137"
+ d="m -96.128772,105.74185 v -3.73175 h 3.731751 3.731746 v 3.73175 3.73173 h -3.731746 -3.731751 z"
+ id="path14711" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.115137"
+ d="m -96.128772,113.50997 v -3.73176 h 3.731751 3.731746 v 3.73176 3.73174 h -3.731746 -3.731751 z"
+ id="path14750" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.115137"
+ d="m -88.208328,113.50997 v -3.73176 h 3.731747 3.731746 v 3.73176 3.73174 h -3.731746 -3.731747 z"
+ id="path14789" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.115137"
+ d="m -80.440204,113.50997 v -3.73176 h 3.731745 3.731744 v 3.73176 3.73174 h -3.731744 -3.731745 z"
+ id="path14828" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.115137"
+ d="m -72.519765,113.19491 v -3.49848 l 1.845051,-2.58657 c 1.014778,-1.42259 1.905828,-2.65167 1.980111,-2.73125 0.07881,-0.0845 0.135058,1.31643 0.135058,3.36384 v 3.50852 l -1.836301,2.57651 c -1.009966,1.41707 -1.901013,2.6416 -1.980109,2.72119 -0.09024,0.0908 -0.14381,-1.15878 -0.14381,-3.35376 z"
+ id="path14867" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.115137"
+ d="m -72.519765,105.36597 v -3.54385 l 1.94203,-2.730248 1.942033,-2.730242 0.04087,3.500405 0.04087,3.500415 -1.982893,2.77368 -1.982894,2.77369 z"
+ id="path14906" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.115137"
+ d="M -72.519765,97.476426 V 93.94804 l 1.980111,-2.769791 1.980109,-2.76978 v 3.547233 3.547221 l -1.850154,2.606246 c -1.017584,1.433432 -1.908633,2.671361 -1.980111,2.750941 -0.07215,0.0803 -0.129955,-1.42462 -0.129955,-3.383684 z"
+ id="path14945" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.115137"
+ d="m -72.519765,89.585909 v -3.498475 l 1.845051,-2.586568 c 1.014778,-1.422596 1.905828,-2.651672 1.980111,-2.731245 0.07882,-0.08453 0.135058,1.312207 0.135058,3.353767 v 3.498463 l -1.84505,2.586558 c -1.014779,1.422618 -1.905827,2.651673 -1.980111,2.731267 -0.07882,0.08453 -0.135059,-1.312218 -0.135059,-3.353767 z"
+ id="path14984" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.266095"
+ x="-93.463249"
+ y="114.9286"
+ id="text28985"><tspan
+ sodipodi:role="line"
+ id="tspan28983"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.266095"
+ x="-93.463249"
+ y="114.9286">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.266095"
+ x="-85.398956"
+ y="114.95239"
+ id="text29583"><tspan
+ sodipodi:role="line"
+ id="tspan29581"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.266095"
+ x="-85.398956"
+ y="114.95239">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.266095"
+ x="-77.531754"
+ y="114.95239"
+ id="text30291"><tspan
+ sodipodi:role="line"
+ id="tspan30289"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.266095"
+ x="-77.531754"
+ y="114.95239">3</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.266095"
+ x="-93.463249"
+ y="99.005096"
+ id="text33579"><tspan
+ sodipodi:role="line"
+ id="tspan33577"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.266095"
+ x="-93.463249"
+ y="99.005096">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.266095"
+ x="-85.398956"
+ y="106.99065"
+ id="text33583"><tspan
+ sodipodi:role="line"
+ id="tspan33581"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.266095"
+ x="-85.398956"
+ y="106.99065">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.266095"
+ x="-77.531754"
+ y="106.99065"
+ id="text33587"><tspan
+ sodipodi:role="line"
+ id="tspan33585"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.266095"
+ x="-77.531754"
+ y="106.99065">3</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.266095"
+ x="-93.463249"
+ y="106.96684"
+ id="text33591"><tspan
+ sodipodi:role="line"
+ id="tspan33589"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.266095"
+ x="-93.463249"
+ y="106.96684">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.266095"
+ x="-85.398956"
+ y="99.028893"
+ id="text33595"><tspan
+ sodipodi:role="line"
+ id="tspan33593"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.266095"
+ x="-85.398956"
+ y="99.028893">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.266095"
+ x="-77.531754"
+ y="99.028893"
+ id="text33599"><tspan
+ sodipodi:role="line"
+ id="tspan33597"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.266095"
+ x="-77.531754"
+ y="99.028893">3</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.266095"
+ x="-93.463249"
+ y="91.04332"
+ id="text33603"><tspan
+ sodipodi:role="line"
+ id="tspan33601"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.266095"
+ x="-93.463249"
+ y="91.04332">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.266095"
+ x="-85.398956"
+ y="91.067154"
+ id="text33607"><tspan
+ sodipodi:role="line"
+ id="tspan33605"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.266095"
+ x="-85.398956"
+ y="91.067154">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.266095"
+ x="-77.531754"
+ y="91.067154"
+ id="text33611"><tspan
+ sodipodi:role="line"
+ id="tspan33609"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.90273px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.266095"
+ x="-77.531754"
+ y="91.067154">3</tspan></text>
+ <g
+ id="g45824"
+ transform="matrix(1.005713,0,0,1.005713,99.471735,-72.501863)">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -130.83652,165.09427 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22694" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -130.83652,157.27109 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22696" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -138.65971,165.09427 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22698" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -138.65971,157.27109 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22700" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -130.83652,172.91745 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22702" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -123.01333,172.91745 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22704" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -130.83652,180.74063 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22706" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -138.65971,180.74063 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22708" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -123.01333,165.09427 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22710" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -138.65971,172.91745 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22712" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -123.01333,157.27109 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22714" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -123.01333,180.74063 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22716" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -138.65971,157.27109 4.34622,-6.08471"
+ id="path22718" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -115.19014,157.44494 4.34622,-6.08471"
+ id="path22720" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -123.01333,157.44494 4.34622,-6.08471"
+ id="path22722" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -130.83652,157.44494 4.34622,-6.08471"
+ id="path22724" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -110.84392,151.36023 v 31.29272"
+ id="path22726" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -134.31349,151.18638 7.82319,0.17385 h 7.82319 7.82319"
+ id="path22728" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -115.19014,188.73766 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22730" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -115.19014,165.26812 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22732" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -115.19014,173.0913 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22734" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -115.19014,180.91448 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22736" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -130.83652,165.09427 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22898" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -130.83652,157.27109 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22900" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -138.65971,165.09427 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22902" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -138.65971,157.27109 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22904" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -130.83652,172.91745 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22906" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -123.01333,172.91745 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22908" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -130.83652,180.74063 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22910" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -138.65971,180.74063 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22912" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -123.01333,165.09427 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22914" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -138.65971,172.91745 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22916" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -123.01333,157.27109 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22918" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -123.01333,180.74063 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22920" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -138.65971,157.27109 4.34622,-6.08471"
+ id="path22922" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -115.19014,157.44494 4.34622,-6.08471"
+ id="path22924" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -123.01333,157.44494 4.34622,-6.08471"
+ id="path22926" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -130.83652,157.44494 4.34622,-6.08471"
+ id="path22928" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -110.84392,151.36023 v 31.29272"
+ id="path22930" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -134.31349,151.18638 7.82319,0.17385 h 7.82319 7.82319"
+ id="path22932" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -115.19014,188.73766 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22934" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -115.19014,165.26812 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22936" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -115.19014,173.0913 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22938" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -115.19014,180.91448 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22940" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -137.98301,156.72127 c 0.20248,-0.27072 1.13436,-1.56562 2.07086,-2.87757 l 1.70273,-2.38535 3.05858,0.009 c 1.68221,0.005 3.30585,0.0559 3.60807,0.11359 l 0.54949,0.10486 -1.97753,2.76398 -1.97753,2.76398 h -3.70141 -3.7014 z"
+ id="path15023" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -130.26306,157.08883 c 0.0278,-0.0686 0.90239,-1.32645 1.94362,-2.79531 l 1.89313,-2.67066 3.60958,-0.007 c 1.98527,-0.004 3.58687,0.0496 3.5591,0.11813 -0.0278,0.0686 -0.90239,1.32645 -1.94362,2.79532 l -1.89313,2.67066 -3.60959,0.007 c -1.98526,0.004 -3.58686,-0.0496 -3.55909,-0.11813 z"
+ id="path15062" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -120.55489,154.41164 1.99954,-2.80184 h 3.60814 c 2.84723,0 3.58375,0.0399 3.49249,0.18932 -0.0636,0.10412 -0.95734,1.36495 -1.98606,2.80184 l -1.87041,2.61253 h -3.62162 -3.62162 z"
+ id="path15101" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -122.86721,161.37839 v -3.71055 h 3.71055 3.71055 v 3.71055 3.71054 h -3.71055 -3.71055 z"
+ id="path15140" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -130.59121,161.37839 v -3.71055 h 3.71055 3.71055 v 3.71055 3.71054 h -3.71055 -3.71055 z"
+ id="path15179" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -138.46665,161.37839 v -3.71055 h 3.71055 3.71054 v 3.71055 3.71054 h -3.71054 -3.71055 z"
+ id="path15218" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -138.46665,169.17811 v -3.63482 h 3.71055 3.71054 v 3.63482 3.63482 h -3.71054 -3.71055 z"
+ id="path15257" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -130.59121,169.17811 v -3.63482 h 3.71055 3.71055 v 3.63482 3.63482 h -3.71055 -3.71055 z"
+ id="path15296" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -122.86721,169.17811 v -3.63482 h 3.71055 3.71055 v 3.63482 3.63482 h -3.71055 -3.71055 z"
+ id="path15335" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -122.86721,176.97783 v -3.71055 h 3.71055 3.71055 v 3.71055 3.71055 h -3.71055 -3.71055 z"
+ id="path15374" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -130.59121,176.97783 v -3.71055 h 3.71055 3.71055 v 3.71055 3.71055 h -3.71055 -3.71055 z"
+ id="path15413" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -138.46665,176.97783 v -3.71055 h 3.71055 3.71054 v 3.71055 3.71055 h -3.71054 -3.71055 z"
+ id="path15452" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -138.46665,184.85328 v -3.71055 h 3.71055 3.71054 v 3.71055 3.71055 h -3.71054 -3.71055 z"
+ id="path15491" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -130.59121,184.85328 v -3.71055 h 3.71055 3.71055 v 3.71055 3.71055 h -3.71055 -3.71055 z"
+ id="path15530" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -122.86721,184.85328 v -3.71055 h 3.71055 3.71055 v 3.71055 3.71055 h -3.71055 -3.71055 z"
+ id="path15569" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -114.99176,184.53043 v -3.48817 l 1.931,-2.71 1.93099,-2.70999 0.0408,3.4588 0.0408,3.45881 -1.84253,2.59548 c -1.01339,1.42752 -1.90067,2.66023 -1.97174,2.73936 -0.0717,0.0799 -0.12922,-1.40749 -0.12922,-3.34429 z"
+ id="path15645" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -114.99176,176.68413 v -3.45903 l 1.83964,-2.59144 c 1.01181,-1.42528 1.89779,-2.65618 1.96886,-2.73531 0.0717,-0.0799 0.12922,1.40769 0.12922,3.34472 v 3.4886 l -1.82587,2.56186 c -1.00423,1.40903 -1.89021,2.62661 -1.96886,2.70575 -0.0897,0.0903 -0.14299,-1.14492 -0.14299,-3.31515 z"
+ id="path15684" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -114.99176,168.88852 v -3.5153 l 1.931,-2.7021 1.93099,-2.70211 0.0406,3.45947 0.0406,3.45948 -1.97163,2.75793 -1.97163,2.75793 z"
+ id="path15723" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -114.99176,161.03537 v -3.50834 l 1.96886,-2.75406 1.96886,-2.75405 v 3.54665 3.54665 l -1.83457,2.57187 c -1.00901,1.41452 -1.895,2.63661 -1.96886,2.71574 -0.0784,0.084 -0.13429,-1.31721 -0.13429,-3.36446 z"
+ id="path15918" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-135.50368"
+ y="162.51427"
+ id="text42017"><tspan
+ sodipodi:role="line"
+ id="tspan42015"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-135.50368"
+ y="162.51427">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-136.49561"
+ y="170.43268"
+ id="text42021"><tspan
+ sodipodi:role="line"
+ id="tspan42019"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-136.49561"
+ y="170.43268">11</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-136.37231"
+ y="178.3511"
+ id="text42025"><tspan
+ sodipodi:role="line"
+ id="tspan42023"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-136.37231"
+ y="178.3511">21</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-136.3895"
+ y="186.26857"
+ id="text42029"><tspan
+ id="tspan42027"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-136.3895"
+ y="186.26857"
+ sodipodi:role="line">31</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-129.09538"
+ y="170.45638"
+ id="text35953"><tspan
+ sodipodi:role="line"
+ id="tspan35951"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-129.09538"
+ y="170.45638">12 </tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-128.79399"
+ y="178.37479"
+ id="text36807"><tspan
+ sodipodi:role="line"
+ id="tspan36805"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-128.79399"
+ y="178.37479">22</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-128.81117"
+ y="186.26857"
+ id="text37913"><tspan
+ sodipodi:role="line"
+ id="tspan37911"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-128.81117"
+ y="186.26857">32</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-128.03241"
+ y="162.53795"
+ id="text42033"><tspan
+ sodipodi:role="line"
+ id="tspan42031"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-128.03241"
+ y="162.53795">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-121.76529"
+ y="170.45638"
+ id="text36473"><tspan
+ sodipodi:role="line"
+ id="tspan36471"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-121.76529"
+ y="170.45638">13</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-121.642"
+ y="178.37479"
+ id="text37579"><tspan
+ sodipodi:role="line"
+ id="tspan37577"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-121.642"
+ y="178.37479">23</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-121.65918"
+ y="186.26857"
+ id="text38469"><tspan
+ sodipodi:role="line"
+ id="tspan38467"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-121.65918"
+ y="186.26857">33</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-120.75713"
+ y="162.53795"
+ id="text42037"><tspan
+ sodipodi:role="line"
+ id="tspan42035"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-120.75713"
+ y="162.53795">3</tspan></text>
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:6.08596px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Bold Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.285279"
+ x="-105.52939"
+ y="99.007248"
+ id="text42921"><tspan
+ sodipodi:role="line"
+ id="tspan42919"
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:6.08596px;font-family:Arial;-inkscape-font-specification:'Arial, Bold Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.285279"
+ x="-105.52939"
+ y="99.007248">+</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:6.08596px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Bold Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.285279"
+ x="-51.477856"
+ y="98.843964"
+ id="text43309"><tspan
+ sodipodi:role="line"
+ id="tspan43307"
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:6.08596px;font-family:Arial;-inkscape-font-specification:'Arial, Bold Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.285279"
+ x="-51.477856"
+ y="98.843964">=</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.56447px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.206978"
+ x="-129.02751"
+ y="75.677513"
+ id="text47037"><tspan
+ sodipodi:role="line"
+ id="tspan47035"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.56447px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.206978"
+ x="-129.02751"
+ y="75.677513"><tspan
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.56447px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.206978"
+ id="tspan52971">a </tspan>(4 x 3)</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.56447px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.285279"
+ x="-84.158951"
+ y="75.75811"
+ id="text48337"><tspan
+ sodipodi:role="line"
+ id="tspan48335"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.56447px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.285279"
+ x="-84.158951"
+ y="75.75811"><tspan
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.56447px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.285279"
+ id="tspan57051">b</tspan> (3)</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.56447px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.285279"
+ x="-35.944736"
+ y="76.127975"
+ id="text49033"><tspan
+ sodipodi:role="line"
+ id="tspan49031"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.56447px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.285279"
+ x="-35.944736"
+ y="76.127975"><tspan
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:4.56447px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.285279"
+ id="tspan58435">result</tspan> (4 x 3)</tspan></text>
+ </g>
+</svg>
diff --git a/doc/source/user/broadcasting_3.svg b/doc/source/user/broadcasting_3.svg
new file mode 100644
index 000000000..a12030d9c
--- /dev/null
+++ b/doc/source/user/broadcasting_3.svg
@@ -0,0 +1,708 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="124.43386mm"
+ height="91.324844mm"
+ viewBox="0 0 124.43386 91.324844"
+ version="1.1"
+ id="svg60162"
+ inkscape:version="1.1 (c68e22c387, 2021-05-23)"
+ sodipodi:docname="theory.broadcasting_3.svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <sodipodi:namedview
+ id="namedview60164"
+ pagecolor="#005d00"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0"
+ inkscape:pagecheckerboard="0"
+ inkscape:document-units="mm"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ fit-margin-top="5"
+ fit-margin-left="5"
+ fit-margin-bottom="5"
+ fit-margin-right="5"
+ inkscape:zoom="0.99674932"
+ inkscape:cx="-75.746227"
+ inkscape:cy="366.692"
+ inkscape:window-width="1920"
+ inkscape:window-height="1001"
+ inkscape:window-x="-9"
+ inkscape:window-y="-9"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="g69631" />
+ <defs
+ id="defs60159">
+ <marker
+ style="overflow:visible"
+ id="Arrow2Lstart"
+ refX="0"
+ refY="0"
+ orient="auto"
+ inkscape:stockid="Arrow2Lstart"
+ inkscape:isstock="true">
+ <path
+ transform="matrix(1.1,0,0,1.1,1.1,0)"
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ style="fill:context-stroke;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+ id="path78024" />
+ </marker>
+ <marker
+ style="overflow:visible"
+ id="Arrow2Lend"
+ refX="0"
+ refY="0"
+ orient="auto"
+ inkscape:stockid="Arrow2Lend"
+ inkscape:isstock="true">
+ <path
+ transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
+ d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
+ style="fill:context-stroke;fill-rule:evenodd;stroke-width:0.625;stroke-linejoin:round"
+ id="path78027" />
+ </marker>
+ <marker
+ style="overflow:visible"
+ id="Arrow1Lend"
+ refX="0"
+ refY="0"
+ orient="auto"
+ inkscape:stockid="Arrow1Lend"
+ inkscape:isstock="true">
+ <path
+ transform="matrix(-0.8,0,0,-0.8,-10,0)"
+ style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
+ d="M 0,0 5,-5 -12.5,0 5,5 Z"
+ id="path96534" />
+ </marker>
+ </defs>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-32.1299,-4.5183083)">
+ <g
+ id="g46002"
+ transform="matrix(1.2203364,0,0,1.2203364,104.81983,-147.93224)">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -47.512773,165.23404 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21691" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -47.512773,157.41086 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21910" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -55.335963,165.23404 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21912" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -55.335963,157.41086 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21914" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -47.512773,173.05722 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21916" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -39.689583,173.05722 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21918" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -47.512773,180.8804 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21920" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -55.335963,180.8804 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21922" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -39.689583,165.23404 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21924" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -55.335963,173.05722 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21926" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -39.689583,157.41086 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21928" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -39.689583,180.8804 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path21930" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -55.335963,157.41086 4.34622,-6.08471"
+ id="path22112" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M -31.866393,157.58471 -27.520173,151.5"
+ id="path22147" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M -39.689583,157.58471 -35.343363,151.5"
+ id="path22149" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M -47.512773,157.58471 -43.166553,151.5"
+ id="path22151" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -27.520173,151.5 v 31.29272"
+ id="path22266" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -50.989743,151.32615 7.82319,0.17385 h 7.82319 7.82319"
+ id="path22381" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -31.866393,188.87743 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22496" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -31.866393,165.40789 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22644" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -31.866393,173.23107 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22646" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -31.866393,181.05425 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22648" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -47.512773,165.23404 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22650" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -47.512773,157.41086 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22652" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -55.335963,165.23404 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22654" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -55.335963,157.41086 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22656" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -47.512773,173.05722 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22658" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -39.689583,173.05722 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22660" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -47.512773,180.8804 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22662" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -55.335963,180.8804 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22664" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -39.689583,165.23404 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22666" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -55.335963,173.05722 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22668" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -39.689583,157.41086 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22670" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -39.689583,180.8804 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22672" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -55.335963,157.41086 4.34622,-6.08471"
+ id="path22674" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M -31.866393,157.58471 -27.520173,151.5"
+ id="path22676" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M -39.689583,157.58471 -35.343363,151.5"
+ id="path22678" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M -47.512773,157.58471 -43.166553,151.5"
+ id="path22680" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -27.520173,151.5 v 31.29272"
+ id="path22682" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -50.989743,151.32615 7.82319,0.17385 h 7.82319 7.82319"
+ id="path22684" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -31.866393,188.87743 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22686" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -31.866393,165.40789 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22688" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -31.866393,173.23107 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22690" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -31.866393,181.05425 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22692" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -55.142483,161.45304 v -3.71055 h 3.71055 3.71054 v 3.71055 3.71055 h -3.71054 -3.71055 z"
+ id="path13541" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -47.267033,161.45304 v -3.71055 h 3.71054 3.71055 v 3.71055 3.71055 h -3.71055 -3.71054 z"
+ id="path13580" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -39.543043,161.45304 v -3.71055 h 3.71055 3.71055 v 3.71055 3.71055 h -3.71055 -3.71055 z"
+ id="path13619" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -39.543043,169.32849 v -3.71055 h 3.71055 3.71055 v 3.71055 3.71054 h -3.71055 -3.71055 z"
+ id="path13658" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -47.267033,169.32849 v -3.71055 h 3.71054 3.71055 v 3.71055 3.71054 h -3.71055 -3.71054 z"
+ id="path13697" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -55.142483,169.32849 v -3.71055 h 3.71055 3.71054 v 3.71055 3.71054 h -3.71054 -3.71055 z"
+ id="path13736" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -55.142483,177.20393 v -3.71054 h 3.71055 3.71054 v 3.71054 3.71055 h -3.71054 -3.71055 z"
+ id="path13775" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -47.267033,177.20393 v -3.71054 h 3.71054 3.71055 v 3.71054 3.71055 h -3.71055 -3.71054 z"
+ id="path13814" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -39.543043,177.20393 v -3.71054 h 3.71055 3.71055 v 3.71054 3.71055 h -3.71055 -3.71055 z"
+ id="path13853" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -39.543043,184.92793 v -3.71055 h 3.71055 3.71055 v 3.71055 3.71055 h -3.71055 -3.71055 z"
+ id="path13892" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -47.267033,184.92793 v -3.71055 h 3.71054 3.71055 v 3.71055 3.71055 h -3.71055 -3.71054 z"
+ id="path13931" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -55.142483,184.92793 v -3.71055 h 3.71055 3.71054 v 3.71055 3.71055 h -3.71054 -3.71055 z"
+ id="path13970" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -54.899273,157.25299 c 0.0622,-0.10561 0.9991,-1.43582 2.08211,-2.95601 l 1.96911,-2.76398 1.44974,0.019 c 0.79736,0.0105 2.42287,0.0616 3.61225,0.11359 l 2.1625,0.0945 -2.01181,2.80185 -2.0118,2.80184 -3.68255,0.0406 c -2.94083,0.0324 -3.65979,0.002 -3.56955,-0.15145 z"
+ id="path14009" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -46.783393,156.94737 c 0.20247,-0.27071 1.13436,-1.56562 2.07086,-2.87756 l 1.70272,-2.38535 h 3.62228 3.62228 l -2.05577,2.87756 -2.05578,2.87757 h -3.63737 -3.63736 z"
+ id="path14048" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -39.134073,157.23722 c 0.0666,-0.11131 0.97302,-1.40328 2.01425,-2.87104 l 1.89313,-2.66867 3.60958,-0.007 c 1.98527,-0.004 3.58686,0.0493 3.5591,0.11756 -0.0278,0.0683 -0.93452,1.36316 -2.015,2.87757 l -1.96451,2.75347 h -3.60883 c -2.97073,0 -3.58742,-0.0358 -3.48772,-0.20237 z"
+ id="path14087" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -31.667593,161.15934 v -3.45903 l 1.83964,-2.59144 c 1.01181,-1.42529 1.89779,-2.65618 1.96886,-2.73531 0.0718,-0.0799 0.12922,1.40769 0.12922,3.34472 v 3.4886 l -1.82587,2.56186 c -1.00422,1.40903 -1.89021,2.62661 -1.96886,2.70574 -0.0897,0.0903 -0.14299,-1.14491 -0.14299,-3.31514 z"
+ id="path14126" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -31.667593,169.01521 v -3.47859 l 1.83457,-2.57187 c 1.00901,-1.41453 1.895,-2.63661 1.96886,-2.71575 0.0784,-0.084 0.13429,1.30477 0.13429,3.33472 v 3.4786 l -1.83457,2.57187 c -1.00901,1.41452 -1.895,2.63661 -1.96886,2.71574 -0.0784,0.084 -0.13429,-1.30476 -0.13429,-3.33472 z"
+ id="path14165" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -31.667593,176.85105 v -3.49847 l 1.96886,-2.75406 1.96886,-2.75406 v 3.51758 3.51757 l -1.69335,2.37377 c -0.93135,1.30557 -1.81734,2.5363 -1.96886,2.73496 -0.26885,0.35246 -0.27551,0.27663 -0.27551,-3.13729 z"
+ id="path14204" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -31.667593,184.63423 v -3.45903 l 1.83964,-2.59143 c 1.01181,-1.4253 1.89779,-2.65619 1.96886,-2.73532 0.0718,-0.0799 0.12922,1.40768 0.12922,3.34472 v 3.4886 l -1.82587,2.56186 c -1.00422,1.40903 -1.89021,2.62661 -1.96886,2.70575 -0.0897,0.0903 -0.14299,-1.14492 -0.14299,-3.31515 z"
+ id="path14243" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-36.608471"
+ y="162.74039"
+ id="text17645"><tspan
+ sodipodi:role="line"
+ id="tspan17643"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-36.608471"
+ y="162.74039">0</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-37.600399"
+ y="170.6588"
+ id="text21689"><tspan
+ sodipodi:role="line"
+ id="tspan21687"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-37.600399"
+ y="170.6588">10</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-37.477116"
+ y="178.57722"
+ id="text22617"><tspan
+ sodipodi:role="line"
+ id="tspan22615"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-37.477116"
+ y="178.57722">20</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-37.494289"
+ y="186.49469"
+ id="text23721"><tspan
+ sodipodi:role="line"
+ id="tspan23719"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-37.494289"
+ y="186.49469">30</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-44.447037"
+ y="162.74039"
+ id="text25685"><tspan
+ sodipodi:role="line"
+ id="tspan25683"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-44.447037"
+ y="162.74039">0</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-45.438965"
+ y="170.6588"
+ id="text25689"><tspan
+ sodipodi:role="line"
+ id="tspan25687"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-45.438965"
+ y="170.6588">10</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-45.315681"
+ y="178.57722"
+ id="text25693"><tspan
+ sodipodi:role="line"
+ id="tspan25691"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-45.315681"
+ y="178.57722">20</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-45.332859"
+ y="186.49469"
+ id="text25697"><tspan
+ sodipodi:role="line"
+ id="tspan25695"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-45.332859"
+ y="186.49469">30</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-52.285603"
+ y="162.74039"
+ id="text25701"><tspan
+ sodipodi:role="line"
+ id="tspan25699"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-52.285603"
+ y="162.74039">0</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-53.277534"
+ y="170.6588"
+ id="text25705"><tspan
+ sodipodi:role="line"
+ id="tspan25703"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-53.277534"
+ y="170.6588">10</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-53.154247"
+ y="178.57722"
+ id="text25709"><tspan
+ sodipodi:role="line"
+ id="tspan25707"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-53.154247"
+ y="178.57722">20</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-53.171425"
+ y="186.49469"
+ id="text25713"><tspan
+ sodipodi:role="line"
+ id="tspan25711"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-53.171425"
+ y="186.49469">30</tspan></text>
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:7.38479px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Bold Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.346162"
+ x="84.700111"
+ y="61.040264"
+ id="text42921"><tspan
+ sodipodi:role="line"
+ id="tspan42919"
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:7.38479px;font-family:Arial;-inkscape-font-specification:'Arial, Bold Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.346162"
+ x="84.700111"
+ y="61.040264">+</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.53859px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.251149"
+ x="46.541679"
+ y="32.299259"
+ id="text47037"><tspan
+ sodipodi:role="line"
+ id="tspan47035"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.53859px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.251149"
+ x="46.541679"
+ y="32.299259"><tspan
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.53859px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.251149"
+ id="tspan52971">a </tspan>(4 x 3)</tspan></text>
+ <g
+ id="g69631"
+ transform="matrix(0.79500238,0,0,0.79500238,35.940237,-68.109727)">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.406141px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 96.995629,141.48877 v 12.27561 H 109.0044 V 141.75563 H 96.995629 Z"
+ id="path22696" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.406141px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 84.986869,141.48877 v 12.27561 h 12.00876 v -12.00875 h -12.00876 z"
+ id="path22700" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.406141px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 109.0044,141.48877 v 12.27561 h 12.00876 V 141.75563 H 109.0044 Z"
+ id="path22714" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.406141px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 84.986869,141.48877 6.67154,-9.34016"
+ id="path22718" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.406141px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 121.01316,141.75563 6.67154,-9.34016"
+ id="path22720" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.406141px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 109.0044,141.75563 6.67154,-9.34016"
+ id="path22722" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.406141px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 96.995629,141.75563 6.671541,-9.34016"
+ id="path22724" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.406141px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 91.658409,132.14861 12.008761,0.26686 h 12.00877 12.00876"
+ id="path22728" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.406141px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 96.995629,141.48877 v 12.27561 H 109.0044 V 141.75563 H 96.995629 Z"
+ id="path22900" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.406141px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 84.986869,141.48877 v 12.27561 h 12.00876 v -12.00875 h -12.00876 z"
+ id="path22904" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.406141px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 109.0044,141.48877 v 12.27561 h 12.00876 V 141.75563 H 109.0044 Z"
+ id="path22918" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.406141px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 84.986869,141.48877 6.67154,-9.34016"
+ id="path22922" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.406141px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 121.01316,141.75563 6.67154,-9.34016"
+ id="path22924" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.406141px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 109.0044,141.75563 6.67154,-9.34016"
+ id="path22926" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.406141px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 96.995629,141.75563 6.671541,-9.34016"
+ id="path22928" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.175734"
+ d="m 86.025619,140.64478 c 0.31081,-0.41556 1.74126,-2.40326 3.17881,-4.41713 l 2.61373,-3.66156 4.69498,0.0138 c 2.58223,0.008 5.074551,0.0858 5.538471,0.17437 l 0.84348,0.16096 -3.035551,4.24277 -3.03555,4.24277 h -5.68175 -5.68173 z"
+ id="path15023" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.175734"
+ d="m 97.875909,141.209 c 0.0427,-0.10531 1.38518,-2.03613 2.983491,-4.29086 l 2.906,-4.09953 5.54078,-0.0107 c 3.04743,-0.006 5.50592,0.0761 5.4633,0.18133 -0.0427,0.1053 -1.38519,2.03613 -2.9835,4.29088 l -2.906,4.09952 -5.5408,0.0107 c -3.04741,0.006 -5.505901,-0.0761 -5.463271,-0.18133 z"
+ id="path15062" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.175734"
+ d="m 109.22869,147.79356 v -5.69577 h 5.69578 5.69577 v 5.69577 5.69576 h -5.69577 -5.69578 z"
+ id="path15140" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.175734"
+ d="m 97.372189,147.79356 v -5.69577 h 5.695771 5.69578 v 5.69577 5.69576 h -5.69578 -5.695771 z"
+ id="path15179" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.175734"
+ d="m 85.283219,147.79356 v -5.69577 h 5.69577 5.69576 v 5.69577 5.69576 h -5.69576 -5.69577 z"
+ id="path15218" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.95674px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.406141"
+ x="89.831451"
+ y="149.49193"
+ id="text42017"><tspan
+ sodipodi:role="line"
+ id="tspan42015"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.95674px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.406141"
+ x="89.831451"
+ y="149.49193">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.95674px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.406141"
+ x="102.09368"
+ y="149.52827"
+ id="text42033"><tspan
+ sodipodi:role="line"
+ id="tspan42031"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.95674px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.406141"
+ x="102.09368"
+ y="149.52827">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.95674px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.406141"
+ x="114.05506"
+ y="149.52827"
+ id="text42037"><tspan
+ sodipodi:role="line"
+ id="tspan42035"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.95674px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.406141"
+ x="114.05506"
+ y="149.52827">3</tspan></text>
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.406141px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 121.01316,141.48877 v 12.27561 h 12.00876 v -12.00875 h -12.00876 z"
+ id="path63486" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.406141px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 133.02192,141.75563 6.67154,-9.34016"
+ id="path63490" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.406;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 127.6847,132.41547 h 12.00876"
+ id="path64980" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.406;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 133.02192,153.76438 6.67154,-9.34016"
+ id="path65130" />
+ <path
+ style="fill:#ffffff;stroke:#000000;stroke-width:0.406;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 139.69346,132.41547 v 12.00875"
+ id="path65358" />
+ <path
+ style="fill:#ffffff;stroke:none;stroke-width:0.662837;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 414.24937,534.52703 c 0,-0.1315 5.26846,-7.6152 11.70769,-16.63044 l 11.70768,-16.39136 h 21.37323 c 11.75528,0 21.30844,0.16273 21.22924,0.36162 -0.0792,0.19889 -5.37721,7.68259 -11.77337,16.63045 l -11.62938,16.26883 h -21.30755 c -11.71915,0 -21.30754,-0.10759 -21.30754,-0.2391 z"
+ id="path65514"
+ transform="scale(0.26458333)" />
+ <path
+ style="fill:#ffffff;stroke:none;stroke-width:0.662837;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 459.67713,534.40451 c 0.0792,-0.19889 5.37721,-7.68259 11.77338,-16.63045 l 11.62938,-16.26883 h 21.30754 c 11.71915,0 21.30755,0.1076 21.30755,0.2391 0,0.1315 -5.26846,7.6152 -11.70769,16.63045 l -11.70769,16.39135 h -21.37322 c -11.75528,0 -21.30844,-0.16273 -21.22925,-0.36162 z"
+ id="path65553"
+ transform="scale(0.26458333)" />
+ <path
+ style="fill:#ffffff;stroke:none;stroke-width:0.662837;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 458.30926,558.52392 v -21.59799 h 21.81397 21.81396 v 21.59799 21.59798 h -21.81396 -21.81397 z"
+ id="path65592"
+ transform="scale(0.26458333)" />
+ <path
+ style="fill:#ffffff;stroke:none;stroke-width:0.662837;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="m 503.66503,557.16612 v -20.96876 l 11.66291,-16.33384 11.66292,-16.33384 v 21.04447 21.04447 l -11.29511,15.84777 c -6.21231,8.71627 -11.46062,16.03244 -11.66291,16.25814 -0.20302,0.2265 -0.36781,-8.98423 -0.36781,-20.55841 z"
+ id="path65631"
+ transform="scale(0.26458333)" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.95672px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="125.8052"
+ y="149.49046"
+ id="text66434"><tspan
+ sodipodi:role="line"
+ id="tspan66432"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.95672px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="125.8052"
+ y="149.49046">4</tspan></text>
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.53859px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.210344"
+ x="122.50475"
+ y="32.375103"
+ id="text72815"><tspan
+ sodipodi:role="line"
+ id="tspan72813"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.53859px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.210344"
+ x="122.50475"
+ y="32.375103"><tspan
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.53859px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.210344"
+ id="tspan76229">b</tspan> (4)</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.53859px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.210344"
+ x="86.699333"
+ y="15.341067"
+ id="text74733"><tspan
+ sodipodi:role="line"
+ id="tspan74731"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.53859px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.210344"
+ x="86.699333"
+ y="15.341067">mismatch</tspan></text>
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.322771;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 37.765217,27.055961 151.48494,90.702321"
+ id="path82219" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.322771;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ d="M 37.581798,90.702321 150.93468,27.055961"
+ id="path82340" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 61.594429,19.914188 h 68.219681 l 0,5.308925"
+ id="path1246" />
+ </g>
+</svg>
diff --git a/doc/source/user/broadcasting_4.svg b/doc/source/user/broadcasting_4.svg
new file mode 100644
index 000000000..40f946613
--- /dev/null
+++ b/doc/source/user/broadcasting_4.svg
@@ -0,0 +1,1330 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="150.64636mm"
+ height="69.054741mm"
+ viewBox="0 0 150.64636 69.054741"
+ version="1.1"
+ id="svg83310"
+ inkscape:version="1.1 (c68e22c387, 2021-05-23)"
+ sodipodi:docname="theory.broadcasting_4.svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <sodipodi:namedview
+ id="namedview83312"
+ pagecolor="#005200"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0"
+ inkscape:pagecheckerboard="0"
+ inkscape:document-units="mm"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ fit-margin-top="5"
+ lock-margins="true"
+ fit-margin-left="5"
+ fit-margin-right="5"
+ fit-margin-bottom="5"
+ inkscape:zoom="1.2432572"
+ inkscape:cx="197.46517"
+ inkscape:cy="157.24823"
+ inkscape:window-width="1920"
+ inkscape:window-height="1001"
+ inkscape:window-x="-9"
+ inkscape:window-y="-9"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="layer1" />
+ <defs
+ id="defs83307">
+ <marker
+ style="overflow:visible"
+ id="Arrow1Lend"
+ refX="0"
+ refY="0"
+ orient="auto"
+ inkscape:stockid="Arrow1Lend"
+ inkscape:isstock="true">
+ <path
+ transform="matrix(-0.8,0,0,-0.8,-10,0)"
+ style="fill:context-stroke;fill-rule:evenodd;stroke:context-stroke;stroke-width:1pt"
+ d="M 0,0 5,-5 -12.5,0 5,5 Z"
+ id="path96534" />
+ </marker>
+ </defs>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(-35.165196,-11.993335)">
+ <g
+ id="g91916"
+ transform="matrix(0.77839728,0,0,0.77839728,27.454002,-34.500382)">
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:6.56009px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.164003"
+ x="92.805412"
+ y="-122.62473"
+ id="text93193"
+ transform="rotate(90)"><tspan
+ sodipodi:role="line"
+ id="tspan93191"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:6.56009px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.164003"
+ x="92.805412"
+ y="-122.62473">stretch</tspan></text>
+ <path
+ style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.338293;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
+ d="M 121.01938,88.877548 V 115.1978"
+ id="path96373" />
+ </g>
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 49.087539,40.613975 v 8.968943 h 8.773973 v -8.773964 h -8.773973 z"
+ id="path21691" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 49.087539,31.840013 v 8.968941 h 8.773973 v -8.773962 h -8.773973 z"
+ id="path21910" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 40.313566,40.613975 v 8.968943 h 8.773973 v -8.773964 h -8.773973 z"
+ id="path21912" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 40.313566,31.840013 v 8.968941 h 8.773973 v -8.773962 h -8.773973 z"
+ id="path21914" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 49.087539,49.387937 v 8.968942 h 8.773973 v -8.773961 h -8.773973 z"
+ id="path21916" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 57.861512,49.387937 v 8.968942 h 8.773973 v -8.773961 h -8.773973 z"
+ id="path21918" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 49.087539,58.161899 v 8.96894 h 8.773973 v -8.77396 h -8.773973 z"
+ id="path21920" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 40.313566,58.161899 v 8.96894 h 8.773973 v -8.77396 h -8.773973 z"
+ id="path21922" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 57.861512,40.613975 v 8.968943 h 8.773973 v -8.773964 h -8.773973 z"
+ id="path21924" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 40.313566,49.387937 v 8.968942 h 8.773973 v -8.773961 h -8.773973 z"
+ id="path21926" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 57.861512,31.840013 v 8.968941 h 8.773973 v -8.773962 h -8.773973 z"
+ id="path21928" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 57.861512,58.161899 v 8.96894 h 8.773973 v -8.77396 h -8.773973 z"
+ id="path21930" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 40.313566,31.840013 4.874433,-6.824209"
+ id="path22112" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 66.635485,32.034992 4.874434,-6.824209"
+ id="path22147" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 57.861512,32.034992 4.874433,-6.824209"
+ id="path22149" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 49.087539,31.840013 4.874434,-6.824209"
+ id="path22151" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 71.509919,25.210783 V 60.306629"
+ id="path22266" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 66.635485,67.130839 c 4.874434,-6.82421 4.874434,-6.82421 4.874434,-6.82421"
+ id="path22496" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 66.635485,40.808954 c 4.874434,-6.824209 4.874434,-6.824209 4.874434,-6.824209"
+ id="path22644" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 66.635485,49.582918 c 4.874434,-6.824212 4.874434,-6.824212 4.874434,-6.824212"
+ id="path22646" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 66.635485,58.356879 c 4.874434,-6.82421 4.874434,-6.82421 4.874434,-6.82421"
+ id="path22648" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 49.087539,40.613975 v 8.968943 h 8.773973 v -8.773964 h -8.773973 z"
+ id="path22650" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 49.087539,31.840013 v 8.968941 h 8.773973 v -8.773962 h -8.773973 z"
+ id="path22652" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 40.313566,40.613975 v 8.968943 h 8.773973 v -8.773964 h -8.773973 z"
+ id="path22654" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 40.313566,31.840013 v 8.968941 h 8.773973 v -8.773962 h -8.773973 z"
+ id="path22656" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 49.087539,49.387937 v 8.968942 h 8.773973 v -8.773961 h -8.773973 z"
+ id="path22658" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 57.861512,49.387937 v 8.968942 h 8.773973 v -8.773961 h -8.773973 z"
+ id="path22660" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 49.087539,58.161899 v 8.96894 h 8.773973 v -8.77396 h -8.773973 z"
+ id="path22662" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 40.313566,58.161899 v 8.96894 h 8.773973 v -8.77396 h -8.773973 z"
+ id="path22664" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 57.861512,40.613975 v 8.968943 h 8.773973 v -8.773964 h -8.773973 z"
+ id="path22666" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 40.313566,49.387937 v 8.968942 h 8.773973 v -8.773961 h -8.773973 z"
+ id="path22668" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 57.861512,31.840013 v 8.968941 h 8.773973 v -8.773962 h -8.773973 z"
+ id="path22670" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 57.861512,58.161899 v 8.96894 h 8.773973 v -8.77396 h -8.773973 z"
+ id="path22672" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 40.313566,31.840013 4.874433,-6.824209"
+ id="path22674" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 66.635485,32.034992 4.874434,-6.824209"
+ id="path22676" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 57.861512,32.034992 4.874433,-6.824209"
+ id="path22678" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 71.509919,25.210783 V 60.306629"
+ id="path22682" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 66.635485,67.130839 c 4.874434,-6.82421 4.874434,-6.82421 4.874434,-6.82421"
+ id="path22686" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 66.635485,40.808954 c 4.874434,-6.824209 4.874434,-6.824209 4.874434,-6.824209"
+ id="path22688" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 66.635485,49.582918 c 4.874434,-6.824212 4.874434,-6.824212 4.874434,-6.824212"
+ id="path22690" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296739px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 66.635485,58.356879 c 4.874434,-6.82421 4.874434,-6.82421 4.874434,-6.82421"
+ id="path22692" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128397"
+ d="m 40.53056,36.373455 v -4.161508 h 4.161508 4.161496 v 4.161508 4.161507 H 44.692068 40.53056 Z"
+ id="path13541" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128397"
+ d="m 40.53056,45.206036 v -4.161504 h 4.161508 4.161496 v 4.161504 4.161499 H 44.692068 40.53056 Z"
+ id="path13736" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128397"
+ d="m 40.53056,54.038609 v -4.161496 h 4.161508 4.161496 v 4.161496 4.16151 H 44.692068 40.53056 Z"
+ id="path13775" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128397;stroke-opacity:1"
+ d="m 58.025862,54.038609 v -4.161496 h 4.161508 4.161507 v 4.161496 4.16151 H 62.18737 58.025862 Z"
+ id="path13853" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128397;stroke-opacity:1"
+ d="m 58.025862,62.701339 v -4.16151 h 4.161508 4.161507 v 4.16151 4.16151 H 62.18737 58.025862 Z"
+ id="path13892" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128397"
+ d="m 40.53056,62.701339 v -4.16151 h 4.161508 4.161496 v 4.16151 4.16151 H 44.692068 40.53056 Z"
+ id="path13970" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 95.383653,40.798804 v 8.969014 h 8.774037 v -8.774041 h -8.774037 z"
+ id="path22942" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 95.383653,32.024772 v 8.969005 h 8.774037 v -8.774024 h -8.774037 z"
+ id="path22944" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 86.60962,40.798804 v 8.969014 h 8.774033 V 40.993777 H 86.60962 Z"
+ id="path22946" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 86.60962,32.024772 v 8.969005 h 8.774033 V 32.219753 H 86.60962 Z"
+ id="path22948" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 95.383653,49.57283 v 8.968999 h 8.774037 v -8.774011 h -8.774037 z"
+ id="path22950" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 104.15769,49.57283 v 8.968999 h 8.77405 v -8.774011 h -8.77405 z"
+ id="path22952" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 95.383653,58.346849 v 8.96902 h 8.774037 v -8.77404 h -8.774037 z"
+ id="path22954" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 86.60962,58.346849 v 8.96902 h 8.774033 v -8.77404 H 86.60962 Z"
+ id="path22956" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 104.15769,40.798804 v 8.969014 h 8.77405 v -8.774041 h -8.77405 z"
+ id="path22958" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 86.60962,49.57283 v 8.968999 h 8.774033 V 49.767818 H 86.60962 Z"
+ id="path22960" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 104.15769,32.024772 v 8.969005 h 8.77405 v -8.774024 h -8.77405 z"
+ id="path22962" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 104.15769,58.346849 v 8.96902 h 8.77405 v -8.77404 h -8.77405 z"
+ id="path22964" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 86.60962,32.024772 4.874473,-6.824256"
+ id="path22966" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 112.93174,32.219753 4.87446,-6.824256"
+ id="path22968" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 104.15769,32.219753 4.87447,-6.824256"
+ id="path22970" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 95.383653,32.219753 4.874477,-6.824256"
+ id="path22972" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 91.484093,25.200516 8.774037,0.194981 h 8.77403 8.77404"
+ id="path22976" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 112.93174,67.315869 c 4.87446,-6.82427 4.87446,-6.82427 4.87446,-6.82427"
+ id="path22978" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 112.93174,40.993777 c 4.87446,-6.824256 4.87446,-6.824256 4.87446,-6.824256"
+ id="path22980" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 112.93174,49.767818 c 4.87446,-6.824273 4.87446,-6.824273 4.87446,-6.824273"
+ id="path22982" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 112.93174,58.541829 c 4.87446,-6.82426 4.87446,-6.82426 4.87446,-6.82426"
+ id="path22984" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 95.383653,40.798804 v 8.969014 h 8.774037 v -8.774041 h -8.774037 z"
+ id="path22986" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 95.383653,32.024772 v 8.969005 h 8.774037 v -8.774024 h -8.774037 z"
+ id="path22988" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 86.60962,40.798804 v 8.969014 h 8.774033 V 40.993777 H 86.60962 Z"
+ id="path22990" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 86.60962,32.024772 v 8.969005 h 8.774033 V 32.219753 H 86.60962 Z"
+ id="path22992" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 95.383653,49.57283 v 8.968999 h 8.774037 v -8.774011 h -8.774037 z"
+ id="path22994" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 104.15769,49.57283 v 8.968999 h 8.77405 v -8.774011 h -8.77405 z"
+ id="path22996" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 95.383653,58.346849 v 8.96902 h 8.774037 v -8.77404 h -8.774037 z"
+ id="path22998" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 86.60962,58.346849 v 8.96902 h 8.774033 v -8.77404 H 86.60962 Z"
+ id="path23000" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 104.15769,40.798804 v 8.969014 h 8.77405 v -8.774041 h -8.77405 z"
+ id="path23002" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 86.60962,49.57283 v 8.968999 h 8.774033 V 49.767818 H 86.60962 Z"
+ id="path23004" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 104.15769,32.024772 v 8.969005 h 8.77405 v -8.774024 h -8.77405 z"
+ id="path23006" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 104.15769,58.346849 v 8.96902 h 8.77405 v -8.77404 h -8.77405 z"
+ id="path23008" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 86.60962,32.024772 4.874473,-6.824256"
+ id="path23010" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 112.93174,32.219753 4.87446,-6.824256"
+ id="path23012" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 104.15769,32.219753 4.87447,-6.824256"
+ id="path23014" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 95.383653,32.219753 4.874477,-6.824256"
+ id="path23016" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 91.484093,25.200516 8.774037,0.194981 h 8.77403 8.77404"
+ id="path23020" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 112.93174,67.315869 c 4.87446,-6.82427 4.87446,-6.82427 4.87446,-6.82427"
+ id="path23022" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 112.93174,40.993777 c 4.87446,-6.824256 4.87446,-6.824256 4.87446,-6.824256"
+ id="path23024" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 112.93174,49.767818 c 4.87446,-6.824273 4.87446,-6.824273 4.87446,-6.824273"
+ id="path23026" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 112.93174,58.541829 c 4.87446,-6.82426 4.87446,-6.82426 4.87446,-6.82426"
+ id="path23028" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 117.8062,25.395497 v 8.774024"
+ id="path25266" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.296741px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 117.8062,60.491599 v -8.77403 -8.774024 -8.774024"
+ id="path25301" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128398"
+ d="m 87.021112,31.984202 c 0,-0.04476 1.039683,-1.536572 2.310393,-3.315264 l 2.310408,-3.233968 1.638806,0.02125 c 0.901361,0.01253 2.722951,0.0692 4.047985,0.1274 l 2.409163,0.106111 -2.246797,3.14239 -2.246789,3.142374 -4.11158,0.04546 c -2.261377,0.02506 -4.111589,0.0088 -4.111589,-0.03581 z"
+ id="path14282" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128398"
+ d="m 96.518385,31.082756 c 0.377468,-0.537164 1.399379,-1.97035 2.270904,-3.184844 l 1.584601,-2.208157 4.0247,-0.04554 c 2.21359,-0.02506 4.02471,-7.78e-4 4.02471,0.05278 0,0.05402 -1.00725,1.507771 -2.23833,3.230372 l -2.23833,3.131998 h -4.057281 -4.057287 z"
+ id="path14321" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128398"
+ d="m 104.80537,31.821027 c 0.0747,-0.131137 1.09129,-1.581774 2.25907,-3.223624 l 2.12323,-2.985208 4.04258,-0.0039 c 3.42215,-0.0039 4.02173,0.03277 3.90674,0.234726 -0.0747,0.131152 -1.09128,1.581789 -2.25906,3.223647 l -2.12323,2.9852 -4.04258,0.0039 c -3.42215,0.0039 -4.02174,-0.03277 -3.90675,-0.234757 z"
+ id="path14360" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128398"
+ d="m 104.3467,36.560703 v -4.16153 h 4.16152 4.16155 v 4.16153 4.161546 h -4.16155 -4.16152 z"
+ id="path14399" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128398"
+ d="m 95.683904,36.560703 v -4.16153 h 4.161546 4.16153 v 4.16153 4.161546 h -4.16153 -4.161546 z"
+ id="path14438" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128398"
+ d="m 86.851254,36.560703 v -4.16153 h 4.161543 4.161537 v 4.16153 4.161546 h -4.161537 -4.161543 z"
+ id="path14477" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128398"
+ d="m 86.851254,45.393358 v -4.161539 h 4.161543 4.161537 v 4.161539 4.16153 h -4.161537 -4.161543 z"
+ id="path14516" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128398"
+ d="m 95.683904,45.393358 v -4.161539 h 4.161546 4.16153 v 4.161539 4.16153 h -4.16153 -4.161546 z"
+ id="path14555" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128398"
+ d="m 104.3467,45.393358 v -4.161539 h 4.16152 4.16155 v 4.161539 4.16153 h -4.16155 -4.16152 z"
+ id="path14594" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128398"
+ d="m 104.3467,54.225999 v -4.161526 h 4.16152 4.16155 v 4.161526 4.16153 h -4.16155 -4.16152 z"
+ id="path14633" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128398"
+ d="m 95.683904,54.225999 v -4.161526 h 4.161546 4.16153 v 4.161526 4.16153 h -4.16153 -4.161546 z"
+ id="path14672" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128398"
+ d="m 86.851254,54.225999 v -4.161526 h 4.161543 4.161537 v 4.161526 4.16153 h -4.161537 -4.161543 z"
+ id="path14711" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128398"
+ d="m 86.851254,62.888789 v -4.16155 h 4.161543 4.161537 v 4.16155 4.16153 h -4.161537 -4.161543 z"
+ id="path14750" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128398"
+ d="m 95.683904,62.888789 v -4.16155 h 4.161546 4.16153 v 4.16155 4.16153 h -4.16153 -4.161546 z"
+ id="path14789" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128398"
+ d="m 104.3467,62.888789 v -4.16155 h 4.16152 4.16155 v 4.16155 4.16153 h -4.16155 -4.16152 z"
+ id="path14828" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128398"
+ d="m 113.17935,62.537449 v -3.90141 l 2.05754,-2.88447 c 1.13165,-1.58643 2.12532,-2.95706 2.20816,-3.04581 0.0878,-0.0942 0.15061,1.46804 0.15061,3.75126 v 3.9126 l -2.04778,2.87324 c -1.12629,1.58029 -2.11996,2.94585 -2.20816,3.0346 -0.10062,0.10124 -0.16037,-1.29223 -0.16037,-3.74001 z"
+ id="path14867" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128398"
+ d="m 113.17935,53.806829 v -3.951978 l 2.16569,-3.044709 2.16569,-3.044685 0.0455,3.903553 0.0455,3.903559 -2.21128,3.09312 -2.21126,3.09315 z"
+ id="path14906" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128398"
+ d="M 113.17935,45.008643 V 41.07389 l 2.20815,-3.08879 2.20816,-3.088781 v 3.955776 3.95576 l -2.06323,2.906405 c -1.13478,1.598524 -2.12846,2.979027 -2.20817,3.067772 -0.0805,0.08959 -0.14491,-1.588693 -0.14491,-3.773389 z"
+ id="path14945" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.128398"
+ d="m 113.17935,36.209366 v -3.901405 l 2.05754,-2.88446 c 1.13165,-1.586444 2.12532,-2.957077 2.20816,-3.045807 0.0878,-0.09422 0.15061,1.463333 0.15061,3.740013 v 3.901397 l -2.05754,2.88446 c -1.13166,1.586451 -2.12532,2.957061 -2.20816,3.04583 -0.0879,0.09422 -0.15061,-1.463356 -0.15061,-3.740028 z"
+ id="path14984" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.296741"
+ x="89.823761"
+ y="64.470802"
+ id="text28985"><tspan
+ sodipodi:role="line"
+ id="tspan28983"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.296741"
+ x="89.823761"
+ y="64.470802">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.296741"
+ x="98.816841"
+ y="64.49736"
+ id="text29583"><tspan
+ sodipodi:role="line"
+ id="tspan29581"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.296741"
+ x="98.816841"
+ y="64.49736">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.296741"
+ x="107.59012"
+ y="64.49736"
+ id="text30291"><tspan
+ sodipodi:role="line"
+ id="tspan30289"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.296741"
+ x="107.59012"
+ y="64.49736">3</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.296741"
+ x="89.823761"
+ y="46.71336"
+ id="text33579"><tspan
+ sodipodi:role="line"
+ id="tspan33577"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.296741"
+ x="89.823761"
+ y="46.71336">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.296741"
+ x="98.816841"
+ y="55.61861"
+ id="text33583"><tspan
+ sodipodi:role="line"
+ id="tspan33581"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.296741"
+ x="98.816841"
+ y="55.61861">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.296741"
+ x="107.59012"
+ y="55.61861"
+ id="text33587"><tspan
+ sodipodi:role="line"
+ id="tspan33585"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.296741"
+ x="107.59012"
+ y="55.61861">3</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.296741"
+ x="89.823761"
+ y="55.592068"
+ id="text33591"><tspan
+ sodipodi:role="line"
+ id="tspan33589"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.296741"
+ x="89.823761"
+ y="55.592068">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.296741"
+ x="98.816841"
+ y="46.739918"
+ id="text33595"><tspan
+ sodipodi:role="line"
+ id="tspan33593"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.296741"
+ x="98.816841"
+ y="46.739918">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.296741"
+ x="107.59012"
+ y="46.739918"
+ id="text33599"><tspan
+ sodipodi:role="line"
+ id="tspan33597"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.296741"
+ x="107.59012"
+ y="46.739918">3</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.296741"
+ x="89.823761"
+ y="37.834614"
+ id="text33603"><tspan
+ sodipodi:role="line"
+ id="tspan33601"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.296741"
+ x="89.823761"
+ y="37.834614">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.296741"
+ x="98.816841"
+ y="37.861195"
+ id="text33607"><tspan
+ sodipodi:role="line"
+ id="tspan33605"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.296741"
+ x="98.816841"
+ y="37.861195">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.296741"
+ x="107.59012"
+ y="37.861195"
+ id="text33611"><tspan
+ sodipodi:role="line"
+ id="tspan33609"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:4.35221px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.296741"
+ x="107.59012"
+ y="37.861195">3</tspan></text>
+ <g
+ id="g45824"
+ transform="matrix(1.1215424,0,0,1.1215424,304.97935,-144.54629)">
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -130.83652,165.09427 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22694" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -130.83652,157.27109 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22696" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -138.65971,165.09427 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22698" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -138.65971,157.27109 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22700" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -130.83652,172.91745 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22702" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -123.01333,172.91745 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22704" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -130.83652,180.74063 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22706" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -138.65971,180.74063 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22708" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -123.01333,165.09427 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22710" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -138.65971,172.91745 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22712" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -123.01333,157.27109 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22714" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -123.01333,180.74063 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22716" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -138.65971,157.27109 4.34622,-6.08471"
+ id="path22718" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -115.19014,157.44494 4.34622,-6.08471"
+ id="path22720" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -123.01333,157.44494 4.34622,-6.08471"
+ id="path22722" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -130.83652,157.44494 4.34622,-6.08471"
+ id="path22724" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -110.84392,151.36023 v 31.29272"
+ id="path22726" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -134.31349,151.18638 7.82319,0.17385 h 7.82319 7.82319"
+ id="path22728" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -115.19014,188.73766 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22730" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -115.19014,165.26812 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22732" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -115.19014,173.0913 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22734" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -115.19014,180.91448 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22736" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -130.83652,165.09427 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22898" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -130.83652,157.27109 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22900" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -138.65971,165.09427 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22902" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -138.65971,157.27109 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22904" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -130.83652,172.91745 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22906" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -123.01333,172.91745 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22908" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -130.83652,180.74063 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22910" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -138.65971,180.74063 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22912" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -123.01333,165.09427 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22914" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -138.65971,172.91745 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22916" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -123.01333,157.27109 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22918" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -123.01333,180.74063 v 7.99703 h 7.82319 v -7.82318 h -7.82319 z"
+ id="path22920" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -138.65971,157.27109 4.34622,-6.08471"
+ id="path22922" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -115.19014,157.44494 4.34622,-6.08471"
+ id="path22924" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -123.01333,157.44494 4.34622,-6.08471"
+ id="path22926" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -130.83652,157.44494 4.34622,-6.08471"
+ id="path22928" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -110.84392,151.36023 v 31.29272"
+ id="path22930" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -134.31349,151.18638 7.82319,0.17385 h 7.82319 7.82319"
+ id="path22932" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -115.19014,188.73766 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22934" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -115.19014,165.26812 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22936" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -115.19014,173.0913 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22938" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m -115.19014,180.91448 c 4.34622,-6.08471 4.34622,-6.08471 4.34622,-6.08471"
+ id="path22940" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -137.98301,156.72127 c 0.20248,-0.27072 1.13436,-1.56562 2.07086,-2.87757 l 1.70273,-2.38535 3.05858,0.009 c 1.68221,0.005 3.30585,0.0559 3.60807,0.11359 l 0.54949,0.10486 -1.97753,2.76398 -1.97753,2.76398 h -3.70141 -3.7014 z"
+ id="path15023" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -130.26306,157.08883 c 0.0278,-0.0686 0.90239,-1.32645 1.94362,-2.79531 l 1.89313,-2.67066 3.60958,-0.007 c 1.98527,-0.004 3.58687,0.0496 3.5591,0.11813 -0.0278,0.0686 -0.90239,1.32645 -1.94362,2.79532 l -1.89313,2.67066 -3.60959,0.007 c -1.98526,0.004 -3.58686,-0.0496 -3.55909,-0.11813 z"
+ id="path15062" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -120.55489,154.41164 1.99954,-2.80184 h 3.60814 c 2.84723,0 3.58375,0.0399 3.49249,0.18932 -0.0636,0.10412 -0.95734,1.36495 -1.98606,2.80184 l -1.87041,2.61253 h -3.62162 -3.62162 z"
+ id="path15101" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -122.86721,161.37839 v -3.71055 h 3.71055 3.71055 v 3.71055 3.71054 h -3.71055 -3.71055 z"
+ id="path15140" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -130.59121,161.37839 v -3.71055 h 3.71055 3.71055 v 3.71055 3.71054 h -3.71055 -3.71055 z"
+ id="path15179" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -138.46665,161.37839 v -3.71055 h 3.71055 3.71054 v 3.71055 3.71054 h -3.71054 -3.71055 z"
+ id="path15218" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -138.46665,169.17811 v -3.63482 h 3.71055 3.71054 v 3.63482 3.63482 h -3.71054 -3.71055 z"
+ id="path15257" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -130.59121,169.17811 v -3.63482 h 3.71055 3.71055 v 3.63482 3.63482 h -3.71055 -3.71055 z"
+ id="path15296" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -122.86721,169.17811 v -3.63482 h 3.71055 3.71055 v 3.63482 3.63482 h -3.71055 -3.71055 z"
+ id="path15335" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -122.86721,176.97783 v -3.71055 h 3.71055 3.71055 v 3.71055 3.71055 h -3.71055 -3.71055 z"
+ id="path15374" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -130.59121,176.97783 v -3.71055 h 3.71055 3.71055 v 3.71055 3.71055 h -3.71055 -3.71055 z"
+ id="path15413" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -138.46665,176.97783 v -3.71055 h 3.71055 3.71054 v 3.71055 3.71055 h -3.71054 -3.71055 z"
+ id="path15452" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -138.46665,184.85328 v -3.71055 h 3.71055 3.71054 v 3.71055 3.71055 h -3.71054 -3.71055 z"
+ id="path15491" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -130.59121,184.85328 v -3.71055 h 3.71055 3.71055 v 3.71055 3.71055 h -3.71055 -3.71055 z"
+ id="path15530" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -122.86721,184.85328 v -3.71055 h 3.71055 3.71055 v 3.71055 3.71055 h -3.71055 -3.71055 z"
+ id="path15569" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -114.99176,184.53043 v -3.48817 l 1.931,-2.71 1.93099,-2.70999 0.0408,3.4588 0.0408,3.45881 -1.84253,2.59548 c -1.01339,1.42752 -1.90067,2.66023 -1.97174,2.73936 -0.0717,0.0799 -0.12922,-1.40749 -0.12922,-3.34429 z"
+ id="path15645" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -114.99176,176.68413 v -3.45903 l 1.83964,-2.59144 c 1.01181,-1.42528 1.89779,-2.65618 1.96886,-2.73531 0.0717,-0.0799 0.12922,1.40769 0.12922,3.34472 v 3.4886 l -1.82587,2.56186 c -1.00423,1.40903 -1.89021,2.62661 -1.96886,2.70575 -0.0897,0.0903 -0.14299,-1.14492 -0.14299,-3.31515 z"
+ id="path15684" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -114.99176,168.88852 v -3.5153 l 1.931,-2.7021 1.93099,-2.70211 0.0406,3.45947 0.0406,3.45948 -1.97163,2.75793 -1.97163,2.75793 z"
+ id="path15723" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.114483"
+ d="m -114.99176,161.03537 v -3.50834 l 1.96886,-2.75406 1.96886,-2.75405 v 3.54665 3.54665 l -1.83457,2.57187 c -1.00901,1.41452 -1.895,2.63661 -1.96886,2.71574 -0.0784,0.084 -0.13429,-1.31721 -0.13429,-3.36446 z"
+ id="path15918" />
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-135.50368"
+ y="162.51427"
+ id="text42017"><tspan
+ sodipodi:role="line"
+ id="tspan42015"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-135.50368"
+ y="162.51427">1</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-136.49561"
+ y="170.43268"
+ id="text42021"><tspan
+ sodipodi:role="line"
+ id="tspan42019"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-136.49561"
+ y="170.43268">11</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-136.37231"
+ y="178.3511"
+ id="text42025"><tspan
+ sodipodi:role="line"
+ id="tspan42023"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-136.37231"
+ y="178.3511">21</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-136.3895"
+ y="186.26857"
+ id="text42029"><tspan
+ id="tspan42027"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-136.3895"
+ y="186.26857"
+ sodipodi:role="line">31</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-129.09538"
+ y="170.45638"
+ id="text35953"><tspan
+ sodipodi:role="line"
+ id="tspan35951"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-129.09538"
+ y="170.45638">12 </tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-128.79399"
+ y="178.37479"
+ id="text36807"><tspan
+ sodipodi:role="line"
+ id="tspan36805"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-128.79399"
+ y="178.37479">22</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-128.81117"
+ y="186.26857"
+ id="text37913"><tspan
+ sodipodi:role="line"
+ id="tspan37911"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-128.81117"
+ y="186.26857">32</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-128.03241"
+ y="162.53795"
+ id="text42033"><tspan
+ sodipodi:role="line"
+ id="tspan42031"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-128.03241"
+ y="162.53795">2</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-121.76529"
+ y="170.45638"
+ id="text36473"><tspan
+ sodipodi:role="line"
+ id="tspan36471"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-121.76529"
+ y="170.45638">13</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-121.642"
+ y="178.37479"
+ id="text37579"><tspan
+ sodipodi:role="line"
+ id="tspan37577"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-121.642"
+ y="178.37479">23</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-121.65918"
+ y="186.26857"
+ id="text38469"><tspan
+ sodipodi:role="line"
+ id="tspan38467"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-121.65918"
+ y="186.26857">33</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-120.75713"
+ y="162.53795"
+ id="text42037"><tspan
+ sodipodi:role="line"
+ id="tspan42035"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:3.88056px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.264583"
+ x="-120.75713"
+ y="162.53795">3</tspan></text>
+ </g>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:6.78689px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Bold Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.318136"
+ x="76.367958"
+ y="46.715771"
+ id="text42921"><tspan
+ sodipodi:role="line"
+ id="tspan42919"
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:6.78689px;font-family:Arial;-inkscape-font-specification:'Arial, Bold Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.318136"
+ x="76.367958"
+ y="46.715771">+</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:6.78689px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Bold Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.318136"
+ x="136.64468"
+ y="46.533672"
+ id="text43309"><tspan
+ sodipodi:role="line"
+ id="tspan43307"
+ style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:condensed;font-size:6.78689px;font-family:Arial;-inkscape-font-specification:'Arial, Bold Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.318136"
+ x="136.64468"
+ y="46.533672">=</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.09017px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.230815"
+ x="50.163528"
+ y="20.699118"
+ id="text47037"><tspan
+ sodipodi:role="line"
+ id="tspan47035"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.09017px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.230815"
+ x="50.163528"
+ y="20.699118"><tspan
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.09017px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.230815"
+ id="tspan52971">a </tspan>(4 x 1)</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.09017px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.318136"
+ x="100.19966"
+ y="20.788992"
+ id="text48337"><tspan
+ sodipodi:role="line"
+ id="tspan48335"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.09017px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.318136"
+ x="100.19966"
+ y="20.788992"><tspan
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.09017px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.318136"
+ id="tspan57051">b</tspan> (3)</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.09017px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.318136"
+ x="153.96677"
+ y="21.201468"
+ id="text49033"><tspan
+ sodipodi:role="line"
+ id="tspan49031"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.09017px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.318136"
+ x="153.96677"
+ y="21.201468"><tspan
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:5.09017px;font-family:Arial;-inkscape-font-specification:'Arial, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.318136"
+ id="tspan58435">result</tspan> (4 x 3)</tspan></text>
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.205951px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 45.187999,25.015804 c 8.773974,-2e-6 8.773974,-2e-6 8.773974,-2e-6"
+ id="path89538" />
+ <path
+ style="fill:none;stroke:#c2c0c0;stroke-width:0.205951px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="m 71.509918,25.210782 h -8.773973 l -8.773972,-0.19498"
+ id="path89540" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.254195;stroke-opacity:1"
+ d="m 41.237019,30.974494 c 0.308962,-0.432773 1.372792,-1.923662 2.364068,-3.313087 l 1.802319,-2.52623 h 4.107724 4.107722 l -2.356307,3.308862 -2.356308,3.308859 -4.115483,0.0042 -4.115484,0.0042 z"
+ id="path90170" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.254195;stroke-opacity:1"
+ d="m 49.486028,31.719487 c 0,-0.02302 1.035081,-1.491126 2.300178,-3.262446 l 2.300178,-3.220583 4.036101,0.04651 c 2.219854,0.02558 4.062159,0.07234 4.09401,0.103902 0.03185,0.03157 -0.959707,1.47874 -2.203461,3.21594 l -2.261368,3.158544 h -4.13282 c -2.27305,0 -4.132818,-0.01884 -4.132818,-0.04186 z"
+ id="path90209" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.254195;stroke-opacity:1"
+ d="m 58.547372,31.540001 c 0.07286,-0.121744 1.064278,-1.534877 2.203152,-3.140293 l 2.070678,-2.918941 4.095305,-0.0071 4.095306,-0.0071 -2.24857,3.147433 -2.248571,3.147431 h -4.049887 c -3.334947,0 -4.026499,-0.03907 -3.917413,-0.22135 z"
+ id="path90248" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.254195;stroke-opacity:1"
+ d="m 49.320374,36.399673 v -4.141359 h 4.141358 4.141359 v 4.141359 4.141358 h -4.141359 -4.141358 z"
+ id="path90287" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.254195;stroke-opacity:1"
+ d="m 58.100054,36.399673 v -4.141359 h 4.141359 4.141356 v 4.141359 4.141358 h -4.141356 -4.141359 z"
+ id="path90326" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.254195;stroke-opacity:1"
+ d="m 49.320374,45.179353 v -4.141358 h 4.141358 4.141359 v 4.141358 4.141359 h -4.141359 -4.141358 z"
+ id="path90365" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.254195;stroke-opacity:1"
+ d="m 58.100054,45.179353 v -4.141358 h 4.141359 4.141356 v 4.141358 4.141359 h -4.141356 -4.141359 z"
+ id="path90404" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.254195;stroke-opacity:1"
+ d="m 66.879733,36.045756 v -3.898917 l 2.19492,-3.077617 2.19492,-3.077618 0.04443,3.887202 0.04443,3.887203 -2.09267,2.931961 c -1.150967,1.612579 -2.158675,3.002779 -2.23935,3.089334 -0.08544,0.09167 -0.146684,-1.470387 -0.146684,-3.741548 z"
+ id="path90443" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.254195;stroke-opacity:1"
+ d="m 66.879733,44.805915 v -3.918442 l 2.19492,-3.075862 2.19492,-3.075865 0.04443,3.904972 0.04443,3.904972 -2.09267,2.93196 c -1.150967,1.61258 -2.158675,3.00278 -2.23935,3.089333 -0.08544,0.09167 -0.146684,-1.478578 -0.146684,-3.761068 z"
+ id="path90482" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.254195;stroke-opacity:1"
+ d="m 66.879733,53.585599 v -3.918445 l 2.19492,-3.075865 2.19492,-3.075863 0.04443,3.904972 0.04443,3.904971 -2.09267,2.93196 c -1.150967,1.61258 -2.158675,3.00278 -2.23935,3.08933 -0.08544,0.0917 -0.146684,-1.47857 -0.146684,-3.76106 z"
+ id="path90521" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.254195;stroke-opacity:1"
+ d="m 66.879733,62.365269 v -3.91843 l 2.19492,-3.07587 2.19492,-3.07586 0.04443,3.90497 0.04443,3.90497 -2.09267,2.93196 c -1.150967,1.61258 -2.158675,3.00278 -2.23935,3.08933 -0.08544,0.0917 -0.146684,-1.47857 -0.146684,-3.76107 z"
+ id="path90560" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.254195;stroke-opacity:1"
+ d="m 49.320374,62.738709 v -4.14136 h 4.141358 4.141359 v 4.14136 4.14136 h -4.141359 -4.141358 z"
+ id="path90599" />
+ <path
+ style="fill:#ffffff;stroke:#c2c0c0;stroke-width:0.254195;stroke-opacity:1"
+ d="m 49.320374,53.959029 v -4.141356 h 4.141358 4.141359 v 4.141356 4.14136 h -4.141359 -4.141358 z"
+ id="path90638" />
+ <g
+ id="g86032"
+ transform="matrix(0.7308395,0,0,0.7308395,29.446816,-29.293766)">
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.381218"
+ x="43.503597"
+ y="92.905823"
+ id="text17645"><tspan
+ sodipodi:role="line"
+ id="tspan17643"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.381218"
+ x="43.503597"
+ y="92.905823">0</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.381218"
+ x="42.074402"
+ y="104.31487"
+ id="text21689"><tspan
+ sodipodi:role="line"
+ id="tspan21687"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.381218"
+ x="42.074402"
+ y="104.31487">10</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.381218"
+ x="42.252033"
+ y="115.72393"
+ id="text22617"><tspan
+ sodipodi:role="line"
+ id="tspan22615"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.381218"
+ x="42.252033"
+ y="115.72393">20</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.381218"
+ x="42.227287"
+ y="127.13161"
+ id="text23721"><tspan
+ sodipodi:role="line"
+ id="tspan23719"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.381218"
+ x="42.227287"
+ y="127.13161">30</tspan></text>
+ </g>
+ <g
+ id="g86042"
+ transform="matrix(0.7308395,0,0,0.7308395,29.12217,-29.444835)">
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.381218"
+ x="32.209599"
+ y="92.905823"
+ id="text25685"><tspan
+ sodipodi:role="line"
+ id="tspan25683"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.381218"
+ x="32.209599"
+ y="92.905823">0</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.381218"
+ x="30.780405"
+ y="104.31487"
+ id="text25689"><tspan
+ sodipodi:role="line"
+ id="tspan25687"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.381218"
+ x="30.780405"
+ y="104.31487">10</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.381218"
+ x="30.958035"
+ y="115.72393"
+ id="text25693"><tspan
+ sodipodi:role="line"
+ id="tspan25691"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.381218"
+ x="30.958035"
+ y="115.72393">20</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.381218"
+ x="30.933285"
+ y="127.13161"
+ id="text25697"><tspan
+ sodipodi:role="line"
+ id="tspan25695"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#999999;stroke-width:0.381218"
+ x="30.933285"
+ y="127.13161">30</tspan></text>
+ </g>
+ <g
+ id="g90765"
+ transform="matrix(0.7308395,0,0,0.7308395,28.395655,-29.444835)">
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.381218"
+ x="20.9156"
+ y="92.905823"
+ id="text25701"><tspan
+ sodipodi:role="line"
+ id="tspan25699"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.381218"
+ x="20.9156"
+ y="92.905823">0</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.381218"
+ x="19.486401"
+ y="104.31487"
+ id="text25705"><tspan
+ sodipodi:role="line"
+ id="tspan25703"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.381218"
+ x="19.486401"
+ y="104.31487">10</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.381218"
+ x="19.664036"
+ y="115.72393"
+ id="text25709"><tspan
+ sodipodi:role="line"
+ id="tspan25707"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.381218"
+ x="19.664036"
+ y="115.72393">20</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.381218"
+ x="19.639286"
+ y="127.13161"
+ id="text25713"><tspan
+ sodipodi:role="line"
+ id="tspan25711"
+ style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:5.59121px;font-family:Arial;-inkscape-font-specification:'Arial, Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.381218"
+ x="19.639286"
+ y="127.13161">30</tspan></text>
+ </g>
+ <g
+ id="g91924"
+ transform="matrix(0,-0.77839728,0.77839728,0,-25.887022,168.912)">
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:6.56009px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.164003"
+ x="92.805412"
+ y="-122.62473"
+ id="text91920"
+ transform="rotate(90)"><tspan
+ sodipodi:role="line"
+ id="tspan91918"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:6.56009px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;stroke-width:0.164003"
+ x="92.805412"
+ y="-122.62473">stretch</tspan></text>
+ <path
+ style="fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.338293;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
+ d="M 121.01938,88.877548 V 115.1978"
+ id="path91922" />
+ </g>
+ </g>
+</svg>
diff --git a/doc/source/user/broadcasting_5.svg b/doc/source/user/broadcasting_5.svg
new file mode 100644
index 000000000..7d372e909
--- /dev/null
+++ b/doc/source/user/broadcasting_5.svg
@@ -0,0 +1,344 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="215.56395mm"
+ height="140.59219mm"
+ viewBox="0 0 215.56395 140.59219"
+ version="1.1"
+ id="svg92220"
+ inkscape:version="1.1 (c68e22c387, 2021-05-23)"
+ sodipodi:docname="broadcasting-figure-5.svg"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <sodipodi:namedview
+ id="namedview92222"
+ pagecolor="#005400"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ inkscape:pageshadow="2"
+ inkscape:pageopacity="0"
+ inkscape:pagecheckerboard="0"
+ inkscape:document-units="mm"
+ showgrid="false"
+ showguides="true"
+ inkscape:guide-bbox="true"
+ inkscape:zoom="1.1209083"
+ inkscape:cx="592.8228"
+ inkscape:cy="219.91094"
+ inkscape:window-width="1920"
+ inkscape:window-height="1001"
+ inkscape:window-x="-9"
+ inkscape:window-y="-9"
+ inkscape:window-maximized="1"
+ inkscape:current-layer="g112380"
+ fit-margin-top="5"
+ lock-margins="true"
+ fit-margin-left="5"
+ fit-margin-right="5"
+ fit-margin-bottom="5" />
+ <defs
+ id="defs92217">
+ <rect
+ x="-230.06293"
+ y="897.24542"
+ width="189.16286"
+ height="182.77222"
+ id="rect97145" />
+ </defs>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1"
+ transform="translate(1.916979,2.2534185)">
+ <text
+ xml:space="preserve"
+ transform="scale(0.26458333)"
+ id="text97143"
+ style="font-style:italic;font-stretch:condensed;font-size:39.9999px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';white-space:pre;shape-inside:url(#rect97145)" />
+ <g
+ style="fill:none;stroke:none;stroke-linecap:square;stroke-miterlimit:10"
+ id="g112380"
+ transform="matrix(0.34260659,0,0,0.35200053,2.6364747,2.279811)">
+ <path
+ fill="#ffffff"
+ d="M 1.3033791,1.3260505 H 601.30337 V 372.32605 H 1.3033791 Z"
+ fill-rule="nonzero"
+ id="path112290" />
+ <path
+ stroke="#cccccc"
+ stroke-width="1"
+ stroke-linecap="butt"
+ d="m 77.5,61.5 v 239"
+ fill-rule="nonzero"
+ id="path112292" />
+ <path
+ stroke="#cccccc"
+ stroke-width="1"
+ stroke-linecap="butt"
+ d="m 203.5,61.5 v 239"
+ fill-rule="nonzero"
+ id="path112294" />
+ <path
+ stroke="#cccccc"
+ stroke-width="1"
+ stroke-linecap="butt"
+ d="m 329.5,61.5 v 239"
+ fill-rule="nonzero"
+ id="path112296" />
+ <path
+ stroke="#cccccc"
+ stroke-width="1"
+ stroke-linecap="butt"
+ d="m 455.5,61.5 v 239"
+ fill-rule="nonzero"
+ id="path112298" />
+ <path
+ stroke="#cccccc"
+ stroke-width="1"
+ stroke-linecap="butt"
+ d="m 581.5,61.5 v 239"
+ fill-rule="nonzero"
+ id="path112300" />
+ <path
+ stroke="#cccccc"
+ stroke-width="1"
+ stroke-linecap="butt"
+ d="m 77.5,300.5 h 504"
+ fill-rule="nonzero"
+ id="path112302" />
+ <path
+ stroke="#cccccc"
+ stroke-width="1"
+ stroke-linecap="butt"
+ d="m 77.5,220.5 h 504"
+ fill-rule="nonzero"
+ id="path112304" />
+ <path
+ stroke="#cccccc"
+ stroke-width="1"
+ stroke-linecap="butt"
+ d="m 77.5,141.5 h 504"
+ fill-rule="nonzero"
+ id="path112306" />
+ <path
+ stroke="#cccccc"
+ stroke-width="1"
+ stroke-linecap="butt"
+ d="m 77.5,61.5 h 504"
+ fill-rule="nonzero"
+ id="path112308" />
+ <path
+ fill="#4285f4"
+ clip-path="url(#id_0)"
+ d="m 394.468,100.082 c 0,2.48528 -2.01472,4.5 -4.5,4.5 -2.48527,0 -4.5,-2.01472 -4.5,-4.5 0,-2.48528 2.01473,-4.5 4.5,-4.5 2.48528,0 4.5,2.01472 4.5,4.5 z"
+ fill-rule="nonzero"
+ id="path112313"
+ style="fill:#000000" />
+ <path
+ fill="#4285f4"
+ clip-path="url(#id_0)"
+ d="m 545.638,131.88644 c 0,2.48528 -2.0147,4.5 -4.5,4.5 -2.4853,0 -4.5,-2.01472 -4.5,-4.5 0,-2.48527 2.0147,-4.5 4.5,-4.5 2.4853,0 4.5,2.01473 4.5,4.5 z"
+ fill-rule="nonzero"
+ id="path112315"
+ style="fill:#000000" />
+ <path
+ fill="#4285f4"
+ clip-path="url(#id_0)"
+ d="m 107.245,252.74333 c 0,2.48527 -2.01472,4.50002 -4.5,4.50002 -2.48528,0 -4.5,-2.01475 -4.5,-4.50002 0,-2.48527 2.01472,-4.5 4.5,-4.5 2.48528,0 4.5,2.01473 4.5,4.5 z"
+ fill-rule="nonzero"
+ id="path112317"
+ style="fill:#000000" />
+ <path
+ fill="#4285f4"
+ clip-path="url(#id_0)"
+ d="m 167.713,195.49533 c 0,2.48529 -2.01471,4.5 -4.5,4.5 -2.48528,0 -4.5,-2.01471 -4.5,-4.5 0,-2.48527 2.01472,-4.5 4.5,-4.5 2.48529,0 4.5,2.01473 4.5,4.5 z"
+ fill-rule="nonzero"
+ id="path112319"
+ style="fill:#000000" />
+ <path
+ fill="#000000"
+ d="m 312.92188,349.45 -2.28126,-8.59374 h 1.17188 l 1.3125,5.64064 q 0.20312,0.875 0.35938,1.75 0.32812,-1.375 0.39062,-1.59376 l 1.625,-5.79688 h 1.375 l 1.23438,4.34374 q 0.45312,1.625 0.67187,3.0469 0.15625,-0.8125 0.42187,-1.875 l 1.34376,-5.51564 h 1.14062 l -2.34375,8.59374 h -1.10937 l -1.79688,-6.54686 q -0.23438,-0.8125 -0.28125,-1 -0.125,0.57812 -0.25,1 l -1.8125,6.54686 z m 13.625,-2 1.09374,0.125 q -0.25,0.95314 -0.95312,1.4844 -0.70312,0.53124 -1.78125,0.53124 -1.35937,0 -2.17187,-0.84374 -0.79688,-0.84376 -0.79688,-2.3594 0,-1.5625 0.8125,-2.42186 0.8125,-0.875 2.09375,-0.875 1.25,0 2.03125,0.84376 0.79688,0.84374 0.79688,2.3906 0,0.0938 0,0.28126 h -4.64063 q 0.0625,1.03124 0.57813,1.57814 0.51562,0.53124 1.29687,0.53124 0.57813,0 0.98437,-0.29688 0.42188,-0.3125 0.65626,-0.96876 z m -3.45313,-1.7031 h 3.46875 q -0.0625,-0.7969 -0.39062,-1.1875 -0.51563,-0.6094 -1.3125,-0.6094 -0.73438,0 -1.23438,0.4844 -0.48438,0.48436 -0.53125,1.3125 z m 6.20313,-3.6719 v -1.21874 h 1.0625 v 1.21874 z m 0,7.375 v -6.21874 h 1.0625 V 349.45 Z m 2.79687,0.51564 1.03125,0.15626 q 0.0625,0.46874 0.35938,0.6875 0.39062,0.29686 1.0625,0.29686 0.73437,0 1.125,-0.29686 0.40624,-0.2969 0.54687,-0.8125 0.0937,-0.32814 0.0781,-1.3594 -0.6875,0.8125 -1.71876,0.8125 -1.28124,0 -1.98437,-0.92186 -0.70313,-0.9375 -0.70313,-2.21874 0,-0.89064 0.3125,-1.64064 0.32813,-0.76562 0.9375,-1.17186 0.60938,-0.40626 1.4375,-0.40626 1.10938,0 1.82813,0.89062 v -0.75 h 0.96875 v 5.375 q 0,1.45314 -0.29688,2.0625 -0.29687,0.60938 -0.9375,0.95314 -0.64062,0.35936 -1.57812,0.35936 -1.10938,0 -1.79688,-0.5 -0.6875,-0.5 -0.67187,-1.51562 z m 0.875,-3.73438 q 0,1.21874 0.48437,1.78124 0.48438,0.5625 1.21876,0.5625 0.73437,0 1.21874,-0.5625 0.5,-0.5625 0.5,-1.75 0,-1.1406 -0.51562,-1.71874 -0.5,-0.57812 -1.21875,-0.57812 -0.70313,0 -1.20313,0.57812 -0.48437,0.5625 -0.48437,1.6875 z m 6.32813,3.21874 v -8.59374 h 1.04687 v 3.07814 q 0.73437,-0.84376 1.85937,-0.84376 0.70313,0 1.20313,0.28126 0.51563,0.2656 0.73437,0.75 0.21876,0.46874 0.21876,1.3906 v 3.9375 h -1.04688 v -3.9375 q 0,-0.79686 -0.34375,-1.15624 Q 342.625,343.9969 342,343.9969 q -0.46875,0 -0.89062,0.25 -0.40626,0.23436 -0.59376,0.65624 -0.17187,0.40626 -0.17187,1.14062 V 349.45 Z m 9.29687,-0.9375 0.15625,0.9219 q -0.45312,0.0937 -0.79688,0.0937 -0.57812,0 -0.89062,-0.17188 -0.3125,-0.1875 -0.45312,-0.48436 -0.125,-0.2969 -0.125,-1.25 v -3.57814 h -0.76563 v -0.8125 h 0.76563 v -1.54686 l 1.04687,-0.625 v 2.17186 h 1.0625 v 0.8125 h -1.0625 v 3.64064 q 0,0.4531 0.0469,0.5781 0.0625,0.125 0.1875,0.20314 0.125,0.0781 0.35938,0.0781 0.1875,0 0.46875,-0.0313 z"
+ fill-rule="nonzero"
+ id="path112323" />
+ <path
+ fill="#000000"
+ d="m 29.550013,204.71458 h -8.59375 v -1.125 h 3.53125 v -4.46875 h -3.53125 v -1.14062 h 8.59375 v 1.14062 h -4.046875 v 4.46875 h 4.046875 z m -2,-13.07812 0.125,-1.09375 q 0.953125,0.25 1.484375,0.95312 0.53125,0.70313 0.53125,1.78125 0,1.35938 -0.84375,2.17188 -0.84375,0.79687 -2.359375,0.79687 -1.5625,0 -2.421875,-0.8125 -0.875,-0.8125 -0.875,-2.09375 0,-1.25 0.84375,-2.03125 0.84375,-0.79687 2.390625,-0.79687 0.09375,0 0.28125,0 v 4.64062 q 1.03125,-0.0625 1.578125,-0.57812 0.53125,-0.51563 0.53125,-1.29688 0,-0.57812 -0.296875,-0.98437 -0.3125,-0.42188 -0.96875,-0.65625 z m -1.703125,3.45312 v -3.46875 q -0.796875,0.0625 -1.1875,0.39063 -0.609375,0.51562 -0.609375,1.3125 0,0.73437 0.484375,1.23437 0.484375,0.48438 1.3125,0.53125 z m -3.671875,-6.20312 h -1.21875 v -1.0625 h 1.21875 z m 7.375,0 h -6.21875 v -1.0625 h 6.21875 z m 0.515625,-2.79688 0.15625,-1.03125 q 0.46875,-0.0625 0.6875,-0.35937 0.296875,-0.39063 0.296875,-1.0625 0,-0.73438 -0.296875,-1.125 -0.296875,-0.40625 -0.8125,-0.54688 -0.328125,-0.0937 -1.359375,-0.0781 0.8125,0.6875 0.8125,1.71875 0,1.28125 -0.921875,1.98437 -0.9375,0.70313 -2.21875,0.70313 -0.890625,0 -1.640625,-0.3125 -0.765625,-0.32813 -1.171875,-0.9375 -0.40625,-0.60938 -0.40625,-1.4375 0,-1.10938 0.890625,-1.82813 h -0.75 v -0.96875 h 5.375 q 1.453125,0 2.0625,0.29688 0.609375,0.29687 0.953125,0.9375 0.359372,0.64062 0.359372,1.57812 0,1.10938 -0.499997,1.79688 -0.5,0.6875 -1.515625,0.67187 z m -3.734375,-0.875 q 1.21875,0 1.78125,-0.48437 0.5625,-0.48438 0.5625,-1.21875 0,-0.73438 -0.5625,-1.21875 -0.5625,-0.5 -1.75,-0.5 -1.140625,0 -1.71875,0.51562 -0.578125,0.5 -0.578125,1.21875 0,0.70313 0.578125,1.20313 0.5625,0.48437 1.6875,0.48437 z m 3.21875,-6.32812 h -8.59375 v -1.04688 h 3.078125 q -0.84375,-0.73437 -0.84375,-1.85937 0,-0.70313 0.28125,-1.20313 0.265625,-0.51562 0.75,-0.73437 0.46875,-0.21875 1.390625,-0.21875 h 3.9375 v 1.04687 h -3.9375 q -0.796875,0 -1.15625,0.34375 -0.359375,0.34375 -0.359375,0.96875 0,0.46875 0.25,0.89063 0.234375,0.40625 0.65625,0.59375 0.40625,0.17187 1.140625,0.17187 h 3.40625 z m -0.9375,-9.29688 0.921875,-0.15625 q 0.09375,0.45313 0.09375,0.79688 0,0.57812 -0.171875,0.89062 -0.1875,0.3125 -0.484375,0.45313 -0.296875,0.125 -1.25,0.125 h -3.578125 v 0.76562 h -0.8125 v -0.76562 h -1.546875 l -0.625,-1.04688 h 2.171875 v -1.0625 h 0.8125 v 1.0625 h 3.640625 q 0.453125,0 0.578125,-0.0469 0.125,-0.0625 0.203125,-0.1875 0.07813,-0.125 0.07813,-0.35938 0,-0.1875 -0.03125,-0.46875 z"
+ fill-rule="nonzero"
+ id="path112325" />
+ <path
+ fill="#000000"
+ d="m 55.01875,304.45 h -1.046876 v -6.71874 q -0.390624,0.35938 -1.015624,0.73438 -0.609376,0.35936 -1.09375,0.53126 v -1.01564 q 0.875,-0.42186 1.53125,-1 0.671874,-0.59376 0.953124,-1.15626 h 0.671876 z m 6.40625,0 v -2.0625 h -3.71875 v -0.96874 l 3.921874,-5.5625 H 62.4875 v 5.5625 h 1.15625 v 0.96874 H 62.4875 v 2.0625 z m 0,-3.03124 v -3.85936 l -2.6875,3.85936 z m 3.625,-1.20312 q 0,-1.53124 0.3125,-2.45314 0.3125,-0.9375 0.92188,-1.4375 0.625,-0.5 1.5625,-0.5 0.6875,0 1.20312,0.28126 0.53125,0.28124 0.875,0.8125 0.34375,0.51564 0.53125,1.26564 0.1875,0.75 0.1875,2.03124 0,1.51562 -0.3125,2.4375 -0.29687,0.92186 -0.92187,1.4375 -0.60938,0.5 -1.5625,0.5 -1.23438,0 -1.95313,-0.89064 Q 65.05,302.6375 65.05,300.21564 Z m 1.07813,0 q 0,2.10936 0.5,2.8125 0.5,0.70312 1.21875,0.70312 0.73437,0 1.21875,-0.70312 0.5,-0.70314 0.5,-2.8125 0,-2.125 -0.5,-2.8125 Q 68.58125,296.7 67.83125,296.7 q -0.71875,0 -1.15625,0.6094 -0.54687,0.78124 -0.54687,2.90624 z"
+ fill-rule="nonzero"
+ id="path112327" />
+ <path
+ fill="#000000"
+ d="m 55.01875,224.93889 h -1.046876 v -6.71875 q -0.390624,0.35937 -1.015624,0.73437 -0.609376,0.35938 -1.09375,0.53125 v -1.01562 q 0.875,-0.42188 1.53125,-1 0.671874,-0.59375 0.953124,-1.15625 h 0.671876 z m 8.5,-6.48438 -1.046876,0.0781 q -0.140624,-0.625 -0.390624,-0.90625 -0.4375,-0.45313 -1.0625,-0.45313 -0.5,0 -0.890626,0.28125 -0.484374,0.375 -0.78125,1.07813 -0.28125,0.6875 -0.296874,1.96875 0.375,-0.57813 0.921874,-0.85938 0.5625,-0.28125 1.171876,-0.28125 1.046874,0 1.78125,0.78125 0.75,0.78125 0.75,2 0,0.8125 -0.359376,1.51563 -0.34375,0.6875 -0.953124,1.0625 -0.609376,0.35937 -1.375,0.35937 -1.328126,0 -2.15625,-0.96875 -0.828126,-0.96875 -0.828126,-3.1875 0,-2.5 0.921876,-3.625 0.796874,-0.98437 2.15625,-0.98437 1.015624,0 1.65625,0.57812 0.65625,0.5625 0.78125,1.5625 z m -4.296876,3.70313 q 0,0.54687 0.21875,1.04687 0.234376,0.48438 0.640626,0.75 0.421874,0.26563 0.890624,0.26563 0.65625,0 1.140626,-0.53125 0.484374,-0.54688 0.484374,-1.46875 0,-0.89063 -0.484374,-1.40625 -0.46875,-0.51563 -1.1875,-0.51563 -0.71875,0 -1.21875,0.51563 -0.484376,0.51562 -0.484376,1.34375 z m 5.828126,0.53125 1.10938,-0.0937 q 0.125,0.8125 0.5625,1.21875 0.45312,0.40625 1.09375,0.40625 0.75,0 1.28125,-0.57813 0.53125,-0.57812 0.53125,-1.51562 0,-0.90625 -0.51563,-1.42188 -0.5,-0.53125 -1.32812,-0.53125 -0.5,0 -0.92188,0.23438 -0.40625,0.23437 -0.64062,0.59375 l -0.98438,-0.125 0.82813,-4.40625 h 4.28125 v 1 h -3.4375 l -0.45313,2.3125 q 0.76563,-0.54688 1.60938,-0.54688 1.125,0 1.89062,0.78125 0.78125,0.78125 0.78125,2.01563 0,1.15625 -0.67187,2.01562 -0.82813,1.03125 -2.25,1.03125 -1.17188,0 -1.92188,-0.65625 -0.73437,-0.65625 -0.84375,-1.73437 z"
+ fill-rule="nonzero"
+ id="path112329" />
+ <path
+ fill="#000000"
+ d="m 55.01875,145.42778 h -1.046876 v -6.71875 q -0.390624,0.35937 -1.015624,0.73437 -0.609376,0.35938 -1.09375,0.53126 v -1.01563 q 0.875,-0.42187 1.53125,-1 0.671874,-0.59375 0.953124,-1.15625 h 0.671876 z m 3.1875,-1.98438 1.015624,-0.0937 q 0.125,0.71874 0.484376,1.04687 0.375,0.3125 0.9375,0.3125 0.484374,0 0.84375,-0.21875 0.375,-0.23438 0.609374,-0.59375 0.234376,-0.375 0.390626,-1 0.15625,-0.64063 0.15625,-1.29687 0,-0.0781 0,-0.21876 -0.3125,0.5 -0.859376,0.82813 -0.546874,0.3125 -1.1875,0.3125 -1.078124,0 -1.8125,-0.76563 Q 58.05,140.97466 58.05,139.70903 q 0,-1.3125 0.765624,-2.10937 0.78125,-0.79688 1.9375,-0.79688 0.828126,0 1.515626,0.45312 0.703124,0.45313 1.0625,1.29688 0.359374,0.82812 0.359374,2.40625 0,1.64063 -0.359374,2.625 -0.34375,0.96875 -1.0625,1.48437 -0.703126,0.5 -1.640626,0.5 -1.015624,0 -1.65625,-0.54687 -0.640624,-0.5625 -0.765624,-1.57813 z m 4.3125,-3.79687 q 0,-0.90625 -0.484376,-1.4375 -0.46875,-0.53125 -1.15625,-0.53125 -0.703124,0 -1.234374,0.57812 -0.515626,0.5625 -0.515626,1.48438 0,0.8125 0.5,1.32812 0.5,0.51563 1.21875,0.51563 0.734376,0 1.203126,-0.51563 0.46875,-0.51562 0.46875,-1.42187 z M 65.05,141.1934 q 0,-1.53124 0.3125,-2.45312 0.3125,-0.9375 0.92188,-1.4375 0.625,-0.5 1.5625,-0.5 0.6875,0 1.20312,0.28125 0.53125,0.28125 0.875,0.8125 0.34375,0.51563 0.53125,1.26563 0.1875,0.75 0.1875,2.03124 0,1.51563 -0.3125,2.4375 -0.29687,0.92188 -0.92187,1.4375 -0.60938,0.5 -1.5625,0.5 -1.23438,0 -1.95313,-0.89062 Q 65.05,143.61528 65.05,141.1934 Z m 1.07813,0 q 0,2.10938 0.5,2.8125 0.5,0.70313 1.21875,0.70313 0.73437,0 1.21875,-0.70313 0.5,-0.70312 0.5,-2.8125 0,-2.125 -0.5,-2.8125 -0.48438,-0.70312 -1.23438,-0.70312 -0.71875,0 -1.15625,0.60938 -0.54687,0.78124 -0.54687,2.90624 z"
+ fill-rule="nonzero"
+ id="path112331" />
+ <path
+ fill="#000000"
+ d="m 56.596874,64.90104 v 1.015624 h -5.6875 q 0,-0.375 0.125,-0.734374 0.21875,-0.578126 0.6875,-1.140626 0.484376,-0.5625 1.390626,-1.296874 1.40625,-1.15625 1.890624,-1.828126 0.5,-0.671874 0.5,-1.265624 0,-0.625 -0.453124,-1.046876 -0.453126,-0.4375 -1.171876,-0.4375 -0.765624,0 -1.21875,0.453126 -0.453124,0.453124 -0.46875,1.265624 L 51.1125,59.77604 q 0.109374,-1.21875 0.828124,-1.84375 0.734376,-0.640626 1.96875,-0.640626 1.234376,0 1.953126,0.6875 0.71875,0.6875 0.71875,1.703126 0,0.515624 -0.21875,1.015624 -0.203126,0.484376 -0.703126,1.046876 -0.484374,0.546874 -1.609374,1.5 -0.953126,0.796874 -1.234376,1.09375 -0.265624,0.28125 -0.4375,0.5625 z m 5.421876,1.015624 h -1.046876 v -6.71875 Q 60.58125,59.55729 59.95625,59.93229 59.346874,60.291664 58.8625,60.46354 v -1.015626 q 0.875,-0.421874 1.53125,-1 0.671874,-0.59375 0.953124,-1.15625 h 0.671876 z m 3.03125,-2.25 1.10938,-0.09375 q 0.125,0.8125 0.5625,1.21875 0.45312,0.40625 1.09375,0.40625 0.75,0 1.28125,-0.578124 0.53125,-0.578126 0.53125,-1.515626 0,-0.90625 -0.51563,-1.421874 -0.5,-0.53125 -1.32812,-0.53125 -0.5,0 -0.92188,0.234374 -0.40625,0.234376 -0.64062,0.59375 l -0.98438,-0.125 0.82813,-4.40625 h 4.28125 v 1 h -3.4375 l -0.45313,2.3125 q 0.76563,-0.546874 1.60938,-0.546874 1.125,0 1.89062,0.78125 0.78125,0.78125 0.78125,2.015624 0,1.15625 -0.67187,2.015626 -0.82813,1.03125 -2.25,1.03125 -1.17188,0 -1.92188,-0.65625 Q 65.15938,64.74479 65.05,63.666664 Z"
+ fill-rule="nonzero"
+ id="path112333" />
+ <path
+ fill="#000000"
+ d="m 74.425,317.45 v -2.0625 h -3.71875 v -0.96874 l 3.92188,-5.5625 h 0.85937 v 5.5625 h 1.15625 v 0.96874 H 75.4875 v 2.0625 z m 0,-3.03124 v -3.85936 l -2.6875,3.85936 z m 3.625,-1.20312 q 0,-1.53124 0.3125,-2.45314 0.3125,-0.9375 0.92188,-1.4375 0.625,-0.5 1.5625,-0.5 0.6875,0 1.20312,0.28126 0.53125,0.28124 0.875,0.8125 0.34375,0.51564 0.53125,1.26564 0.1875,0.75 0.1875,2.03124 0,1.51562 -0.3125,2.4375 -0.29687,0.92186 -0.92187,1.4375 -0.60938,0.5 -1.5625,0.5 -1.23438,0 -1.95313,-0.89064 Q 78.05,315.6375 78.05,313.21564 Z m 1.07813,0 q 0,2.10936 0.5,2.8125 0.5,0.70312 1.21875,0.70312 0.73437,0 1.21875,-0.70312 0.5,-0.70314 0.5,-2.8125 0,-2.125 -0.5,-2.8125 Q 81.58125,309.7 80.83125,309.7 q -0.71875,0 -1.15625,0.6094 -0.54687,0.78124 -0.54687,2.90624 z"
+ fill-rule="nonzero"
+ id="path112335" />
+ <path
+ fill="#000000"
+ d="m 202.49374,310.96564 -1.04687,0.0781 q -0.14063,-0.625 -0.39063,-0.90626 -0.4375,-0.4531 -1.0625,-0.4531 -0.5,0 -0.89062,0.28124 -0.48438,0.375 -0.78125,1.07812 -0.28125,0.6875 -0.29687,1.96874 0.375,-0.5781 0.92187,-0.85936 0.5625,-0.28124 1.17187,-0.28124 1.04688,0 1.78126,0.78124 0.75,0.78126 0.75,2 0,0.8125 -0.35938,1.51562 -0.34375,0.6875 -0.95312,1.0625 -0.60938,0.35938 -1.375,0.35938 -1.32813,0 -2.15626,-0.96874 -0.82812,-0.96876 -0.82812,-3.1875 0,-2.5 0.92188,-3.625 0.79687,-0.9844 2.15624,-0.9844 1.01563,0 1.65626,0.57814 0.65624,0.5625 0.78124,1.5625 z m -4.29687,3.70312 q 0,0.54688 0.21875,1.04688 0.23438,0.48436 0.64062,0.75 0.42188,0.26562 0.89063,0.26562 0.65625,0 1.14063,-0.53126 0.48437,-0.54686 0.48437,-1.46874 0,-0.89062 -0.48437,-1.40626 -0.46876,-0.5156 -1.1875,-0.5156 -0.71876,0 -1.21876,0.5156 -0.48437,0.51564 -0.48437,1.34376 z m 5.82813,0.53124 1.10937,-0.0937 q 0.125,0.8125 0.5625,1.21874 0.45313,0.40626 1.09375,0.40626 0.75,0 1.28125,-0.57812 0.53125,-0.57814 0.53125,-1.51564 0,-0.90624 -0.51562,-1.42186 -0.5,-0.53124 -1.32813,-0.53124 -0.5,0 -0.92187,0.23436 -0.40626,0.23438 -0.64063,0.59374 l -0.98437,-0.125 0.82812,-4.40624 h 4.28125 v 1 h -3.4375 l -0.45313,2.3125 q 0.76563,-0.54686 1.60938,-0.54686 1.125,0 1.89062,0.78124 0.78126,0.78126 0.78126,2.01562 0,1.15624 -0.67188,2.01564 -0.82812,1.03124 -2.25,1.03124 -1.17188,0 -1.92188,-0.65624 -0.73437,-0.65626 -0.84374,-1.7344 z"
+ fill-rule="nonzero"
+ id="path112337" />
+ <path
+ fill="#000000"
+ d="m 323.15625,315.46564 1.01563,-0.0937 q 0.125,0.71874 0.48437,1.04686 0.375,0.3125 0.9375,0.3125 0.48437,0 0.84375,-0.21876 0.375,-0.23436 0.60938,-0.59374 0.23437,-0.375 0.39062,-1 0.15625,-0.64062 0.15625,-1.29686 0,-0.0781 0,-0.21876 -0.3125,0.5 -0.85937,0.82812 -0.54688,0.3125 -1.1875,0.3125 -1.07813,0 -1.8125,-0.76562 Q 323,312.9969 323,311.73126 q 0,-1.3125 0.76562,-2.10936 0.78126,-0.7969 1.9375,-0.7969 0.82813,0 1.51563,0.45314 0.70313,0.45312 1.0625,1.29686 0.35937,0.82814 0.35937,2.40626 0,1.64064 -0.35937,2.625 -0.34375,0.96874 -1.0625,1.48438 -0.70313,0.5 -1.64063,0.5 -1.01562,0 -1.65624,-0.54688 -0.64063,-0.5625 -0.76563,-1.57812 z m 4.3125,-3.79688 q 0,-0.90626 -0.48437,-1.4375 -0.46876,-0.53126 -1.15626,-0.53126 -0.70312,0 -1.23437,0.57814 -0.51563,0.5625 -0.51563,1.48436 0,0.8125 0.5,1.32814 0.5,0.51562 1.21876,0.51562 0.73437,0 1.20312,-0.51562 0.46875,-0.51564 0.46875,-1.42188 z M 330,313.21564 q 0,-1.53124 0.3125,-2.45314 0.3125,-0.9375 0.92188,-1.4375 0.625,-0.5 1.5625,-0.5 0.6875,0 1.20312,0.28126 0.53125,0.28124 0.875,0.8125 0.34375,0.51564 0.53125,1.26564 0.1875,0.75 0.1875,2.03124 0,1.51562 -0.3125,2.4375 -0.29687,0.92186 -0.92187,1.4375 -0.60938,0.5 -1.5625,0.5 -1.23438,0 -1.95313,-0.89064 Q 330,315.6375 330,313.21564 Z m 1.07812,0 q 0,2.10936 0.5,2.8125 0.5,0.70312 1.21876,0.70312 0.73437,0 1.21874,-0.70312 0.5,-0.70314 0.5,-2.8125 0,-2.125 -0.5,-2.8125 -0.48437,-0.70314 -1.23437,-0.70314 -0.71875,0 -1.15625,0.6094 -0.54688,0.78124 -0.54688,2.90624 z"
+ fill-rule="nonzero"
+ id="path112339" />
+ <path
+ fill="#000000"
+ d="m 449.44376,317.45 h -1.04688 v -6.71874 q -0.39062,0.35938 -1.01562,0.73438 -0.60938,0.35936 -1.09376,0.53126 v -1.01564 q 0.875,-0.42186 1.53126,-1 0.67187,-0.59376 0.95312,-1.15626 h 0.67188 z m 7,0 h -1.04688 v -6.71874 q -0.39062,0.35938 -1.01562,0.73438 -0.60938,0.35936 -1.09376,0.53126 v -1.01564 q 0.875,-0.42186 1.53126,-1 0.67187,-0.59376 0.95312,-1.15626 h 0.67188 z m 3.03124,-2.25 1.10938,-0.0937 q 0.125,0.8125 0.5625,1.21874 0.45312,0.40626 1.09375,0.40626 0.75,0 1.28125,-0.57812 0.53125,-0.57814 0.53125,-1.51564 0,-0.90624 -0.51563,-1.42186 -0.5,-0.53124 -1.32812,-0.53124 -0.5,0 -0.92188,0.23436 -0.40624,0.23438 -0.64062,0.59374 l -0.98438,-0.125 0.82813,-4.40624 h 4.28125 v 1 h -3.4375 l -0.45312,2.3125 q 0.76562,-0.54686 1.60937,-0.54686 1.125,0 1.89063,0.78124 0.78124,0.78126 0.78124,2.01562 0,1.15624 -0.67187,2.01564 -0.82813,1.03124 -2.25,1.03124 -1.17187,0 -1.92187,-0.65624 -0.73438,-0.65626 -0.84376,-1.7344 z"
+ fill-rule="nonzero"
+ id="path112341" />
+ <path
+ fill="#000000"
+ d="m 575.41876,317.45 h -1.04686 v -6.71874 q -0.39064,0.35938 -1.01564,0.73438 -0.60936,0.35936 -1.09376,0.53126 v -1.01564 q 0.875,-0.42186 1.53126,-1 0.67188,-0.59376 0.95314,-1.15626 h 0.67186 z m 6.40624,0 v -2.0625 h -3.71874 v -0.96874 l 3.92188,-5.5625 h 0.85936 v 5.5625 h 1.15626 v 0.96874 h -1.15626 v 2.0625 z m 0,-3.03124 v -3.85936 l -2.6875,3.85936 z m 3.625,-1.20312 q 0,-1.53124 0.3125,-2.45314 0.3125,-0.9375 0.9219,-1.4375 0.625,-0.5 1.5625,-0.5 0.6875,0 1.2031,0.28126 0.53126,0.28124 0.875,0.8125 0.34376,0.51564 0.53126,1.26564 0.1875,0.75 0.1875,2.03124 0,1.51562 -0.3125,2.4375 -0.29686,0.92186 -0.92186,1.4375 -0.6094,0.5 -1.5625,0.5 -1.2344,0 -1.95314,-0.89064 -0.84376,-1.0625 -0.84376,-3.48436 z m 1.07814,0 q 0,2.10936 0.5,2.8125 0.5,0.70312 1.21876,0.70312 0.73436,0 1.21874,-0.70312 0.5,-0.70314 0.5,-2.8125 0,-2.125 -0.5,-2.8125 -0.48438,-0.70314 -1.23438,-0.70314 -0.71876,0 -1.15626,0.6094 -0.54686,0.78124 -0.54686,2.90624 z"
+ fill-rule="nonzero"
+ id="path112343" />
+ <rect
+ style="fill:#000000;stroke:#000000;stroke-width:1.15183;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+ id="rect112598"
+ width="11.020167"
+ height="9.0759048"
+ x="428.62012"
+ y="143.09004"
+ ry="0" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.761891px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 434.5503,146.90838 162.4192,195.66656"
+ id="path113258" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.761891px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 434.5503,146.90838 539.95869,131.9254"
+ id="path113262" />
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:14.8083px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;stroke-width:0.761891"
+ x="328.28354"
+ y="78.15921"
+ id="text114292"
+ transform="scale(1.0136168,0.98656613)"><tspan
+ sodipodi:role="line"
+ id="tspan114290"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:14.8083px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;stroke-width:0.761891"
+ x="328.28354"
+ y="78.15921">basketball</tspan><tspan
+ sodipodi:role="line"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:14.8083px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;stroke-width:0.761891"
+ x="328.28354"
+ y="96.669586"
+ id="tspan114602">player</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:14.8083px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;stroke-width:0.761891"
+ x="415.56625"
+ y="109.67815"
+ id="text118086"
+ transform="scale(1.0136168,0.98656613)"><tspan
+ sodipodi:role="line"
+ id="tspan118084"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:14.8083px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;stroke-width:0.761891"
+ x="415.56625"
+ y="109.67815">shortest</tspan><tspan
+ sodipodi:role="line"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:14.8083px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;stroke-width:0.761891"
+ x="415.56625"
+ y="128.18852"
+ id="tspan118638">distance</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:14.8083px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;stroke-width:0.446669"
+ x="504.48294"
+ y="164.05591"
+ id="text119852"
+ transform="scale(1.0136168,0.98656613)"><tspan
+ sodipodi:role="line"
+ id="tspan119850"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:14.8083px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;stroke-width:0.446669"
+ x="504.48294"
+ y="164.05591">football</tspan><tspan
+ sodipodi:role="line"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:14.8083px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;stroke-width:0.446669"
+ x="504.48294"
+ y="182.56631"
+ id="tspan119876">lineman</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:14.8083px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;stroke-width:0.391862"
+ x="112.2299"
+ y="168.39136"
+ id="text121552"
+ transform="scale(1.0136168,0.98656613)"><tspan
+ sodipodi:role="line"
+ id="tspan121550"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:14.8083px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;stroke-width:0.391862"
+ x="112.2299"
+ y="168.39136">marathon</tspan><tspan
+ sodipodi:role="line"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:14.8083px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;stroke-width:0.391862"
+ x="112.2299"
+ y="186.90173"
+ id="tspan121554">runner</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-stretch:condensed;font-size:14.8083px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';fill:#000000;stroke-width:0.370208"
+ x="119.85936"
+ y="271.38208"
+ id="text124154"
+ transform="scale(1.0136168,0.98656613)"><tspan
+ sodipodi:role="line"
+ id="tspan124152"
+ style="fill:#000000;stroke-width:0.370208"
+ x="119.85936"
+ y="271.38208">female</tspan><tspan
+ sodipodi:role="line"
+ style="fill:#000000;stroke-width:0.370208"
+ x="119.85936"
+ y="289.89246"
+ id="tspan124156">gymnast</tspan></text>
+ <text
+ xml:space="preserve"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:14.8083px;line-height:1.25;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;stroke-width:0.761891"
+ x="383.78757"
+ y="182.4346"
+ id="text128880"
+ transform="scale(1.0136168,0.98656613)"><tspan
+ sodipodi:role="line"
+ id="tspan128878"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:14.8083px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;stroke-width:0.761891"
+ x="383.78757"
+ y="182.4346">athlete to be</tspan><tspan
+ sodipodi:role="line"
+ style="font-style:italic;font-variant:normal;font-weight:normal;font-stretch:condensed;font-size:14.8083px;font-family:Arial;-inkscape-font-specification:'Arial, Italic Condensed';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-east-asian:normal;fill:#000000;stroke-width:0.761891"
+ x="383.78757"
+ y="200.94498"
+ id="tspan128882">classified</tspan></text>
+ <path
+ style="fill:none;stroke:#000000;stroke-width:1.33901;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none;stroke-opacity:1"
+ d="M 434.5503,146.90838 389.37758,99.902324"
+ id="path132071" />
+ <path
+ style="fill:none;stroke:#000000;stroke-width:0.761891px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+ d="M 434.5503,146.90838 101.22492,252.57671"
+ id="path132073" />
+ </g>
+ </g>
+</svg>
diff --git a/doc/source/user/building.rst b/doc/source/user/building.rst
index 47399139e..10983ce8f 100644
--- a/doc/source/user/building.rst
+++ b/doc/source/user/building.rst
@@ -3,10 +3,32 @@
Building from source
====================
-A general overview of building NumPy from source is given here, with detailed
-instructions for specific platforms given separately.
+There are two options for building NumPy- building with Gitpod or locally from
+source. Your choice depends on your operating system and familiarity with the
+command line.
-..
+Gitpod
+------------
+
+Gitpod is an open-source platform that automatically creates
+the correct development environment right in your browser, reducing the need to
+install local development environments and deal with incompatible dependencies.
+
+If you are a Windows user, unfamiliar with using the command line or building
+NumPy for the first time, it is often faster to build with Gitpod. Here are the
+in-depth instructions for building NumPy with `building NumPy with Gitpod`_.
+
+.. _building NumPy with Gitpod: https://numpy.org/devdocs/dev/development_gitpod.html
+
+Building locally
+------------------
+
+Building locally on your machine gives you
+more granular control. If you are a MacOS or Linux user familiar with using the
+command line, you can continue with building NumPy locally by following the
+instructions below.
+
+..
This page is referenced from numpy/numpy/__init__.py. Please keep its
location in sync with the link there.
@@ -23,15 +45,16 @@ Building NumPy requires the following software installed:
2) Compilers
- To build any extension modules for Python, you'll need a C compiler.
- Various NumPy modules use FORTRAN 77 libraries, so you'll also need a
- FORTRAN 77 compiler installed.
+ While a FORTRAN 77 compiler is not necessary for building NumPy, it is
+ needed to run the ``numpy.f2py`` tests. These tests are skipped if the
+ compiler is not auto-detected.
Note that NumPy is developed mainly using GNU compilers and tested on
MSVC and Clang compilers. Compilers from other vendors such as Intel,
- Absoft, Sun, NAG, Compaq, Vast, Portland, Lahey, HP, IBM are only supported
- in the form of community feedback, and may not work out of the box.
- GCC 4.x (and later) compilers are recommended. On ARM64 (aarch64) GCC 8.x (and later) are recommended.
+ Absoft, Sun, NAG, Compaq, Vast, Portland, Lahey, HP, IBM are only
+ supported in the form of community feedback, and may not work out of the
+ box. GCC 4.x (and later) compilers are recommended. On ARM64 (aarch64)
+ GCC 8.x (and later) are recommended.
3) Linear Algebra libraries
@@ -67,7 +90,8 @@ To perform an in-place build that can be run from the source folder run::
Testing
-------
-Make sure to test your builds. To ensure everything stays in shape, see if all tests pass::
+Make sure to test your builds. To ensure everything stays in shape, see if
+all tests pass::
$ python runtests.py -v -m full
@@ -105,11 +129,12 @@ For more information see::
How to check the ABI of BLAS/LAPACK libraries
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-One relatively simple and reliable way to check for the compiler used to build
-a library is to use ldd on the library. If libg2c.so is a dependency, this
-means that g77 has been used (note: g77 is no longer supported for building NumPy).
-If libgfortran.so is a dependency, gfortran has been used. If both are dependencies,
-this means both have been used, which is almost always a very bad idea.
+One relatively simple and reliable way to check for the compiler used to
+build a library is to use ldd on the library. If libg2c.so is a dependency,
+this means that g77 has been used (note: g77 is no longer supported for
+building NumPy). If libgfortran.so is a dependency, gfortran has been used.
+If both are dependencies, this means both have been used, which is almost
+always a very bad idea.
.. _accelerated-blas-lapack-libraries:
@@ -123,6 +148,9 @@ in the ``site.cfg.example`` file.
BLAS
~~~~
+Note that both BLAS and CBLAS interfaces are needed for a properly
+optimized build of NumPy.
+
The default order for the libraries are:
1. MKL
@@ -131,6 +159,12 @@ The default order for the libraries are:
4. ATLAS
5. BLAS (NetLIB)
+The detection of BLAS libraries may be bypassed by defining the environment
+variable ``NPY_BLAS_LIBS`` , which should contain the exact linker flags you
+want to use (interface is assumed to be Fortran 77). Also define
+``NPY_CBLAS_LIBS`` (even empty if CBLAS is contained in your BLAS library) to
+trigger use of CBLAS and avoid slow fallback code for matrix calculations.
+
If you wish to build against OpenBLAS but you also have BLIS available one
may predefine the order of searching via the environment variable
``NPY_BLAS_ORDER`` which is a comma-separated list of the above names which
@@ -146,11 +180,11 @@ Alternatively one may use ``!`` or ``^`` to negate all items::
NPY_BLAS_ORDER='^blas,atlas' python setup.py build
-will allow using anything **but** NetLIB BLAS and ATLAS libraries, the order of the above
-list is retained.
+will allow using anything **but** NetLIB BLAS and ATLAS libraries, the order
+of the above list is retained.
-One cannot mix negation and positives, nor have multiple negations, such cases will
-raise an error.
+One cannot mix negation and positives, nor have multiple negations, such
+cases will raise an error.
LAPACK
~~~~~~
@@ -163,6 +197,9 @@ The default order for the libraries are:
4. ATLAS
5. LAPACK (NetLIB)
+The detection of LAPACK libraries may be bypassed by defining the environment
+variable ``NPY_LAPACK_LIBS``, which should contain the exact linker flags you
+want to use (language is assumed to be Fortran 77).
If you wish to build against OpenBLAS but you also have MKL available one
may predefine the order of searching via the environment variable
@@ -179,20 +216,19 @@ Alternatively one may use ``!`` or ``^`` to negate all items::
NPY_LAPACK_ORDER='^lapack' python setup.py build
-will allow using anything **but** the NetLIB LAPACK library, the order of the above
-list is retained.
-
-One cannot mix negation and positives, nor have multiple negations, such cases will
-raise an error.
+will allow using anything **but** the NetLIB LAPACK library, the order of
+the above list is retained.
+One cannot mix negation and positives, nor have multiple negations, such
+cases will raise an error.
.. deprecated:: 1.20
The native libraries on macOS, provided by Accelerate, are not fit for use
- in NumPy since they have bugs that cause wrong output under easily reproducible
- conditions. If the vendor fixes those bugs, the library could be reinstated,
- but until then users compiling for themselves should use another linear
- algebra library or use the built-in (but slower) default, see the next
- section.
+ in NumPy since they have bugs that cause wrong output under easily
+ reproducible conditions. If the vendor fixes those bugs, the library could
+ be reinstated, but until then users compiling for themselves should use
+ another linear algebra library or use the built-in (but slower) default,
+ see the next section.
Disabling ATLAS and other accelerated libraries
@@ -246,5 +282,6 @@ Supplying additional compiler flags
Additional compiler flags can be supplied by setting the ``OPT``,
``FOPT`` (for Fortran), and ``CC`` environment variables.
-When providing options that should improve the performance of the code ensure
-that you also set ``-DNDEBUG`` so that debugging code is not executed.
+When providing options that should improve the performance of the code
+ensure that you also set ``-DNDEBUG`` so that debugging code is not
+executed.
diff --git a/doc/source/user/c-info.beyond-basics.rst b/doc/source/user/c-info.beyond-basics.rst
index 124162d6c..121384d04 100644
--- a/doc/source/user/c-info.beyond-basics.rst
+++ b/doc/source/user/c-info.beyond-basics.rst
@@ -172,8 +172,8 @@ iterators so that all that needs to be done to advance to the next element in
each array is for PyArray_ITER_NEXT to be called for each of the inputs. This
incrementing is automatically performed by
:c:func:`PyArray_MultiIter_NEXT` ( ``obj`` ) macro (which can handle a
-multiterator ``obj`` as either a :c:type:`PyArrayMultiObject *` or a
-:c:type:`PyObject *<PyObject>`). The data from input number ``i`` is available using
+multiterator ``obj`` as either a :c:expr:`PyArrayMultiIterObject *` or a
+:c:expr:`PyObject *`). The data from input number ``i`` is available using
:c:func:`PyArray_MultiIter_DATA` ( ``obj``, ``i`` ) and the total (broadcasted)
size as :c:func:`PyArray_MultiIter_SIZE` ( ``obj``). An example of using this
feature follows.
@@ -330,7 +330,7 @@ function :c:func:`PyArray_RegisterCanCast` (from_descr, totype_number,
scalarkind) should be used to specify that the data-type object
from_descr can be cast to the data-type with type number
totype_number. If you are not trying to alter scalar coercion rules,
-then use :c:data:`NPY_NOSCALAR` for the scalarkind argument.
+then use :c:enumerator:`NPY_NOSCALAR` for the scalarkind argument.
If you want to allow your new data-type to also be able to share in
the scalar coercion rules, then you need to specify the scalarkind
@@ -340,7 +340,7 @@ available to that function). Then, you can register data-types that
can be cast to separately for each scalar kind that may be returned
from your user-defined data-type. If you don't register scalar
coercion handling, then all of your user-defined data-types will be
-seen as :c:data:`NPY_NOSCALAR`.
+seen as :c:enumerator:`NPY_NOSCALAR`.
Registering a ufunc loop
@@ -400,7 +400,7 @@ describe the desired behavior of the type. Typically, a new
C-structure is also created to contain the instance-specific
information needed for each object of the type as well. For example,
:c:data:`&PyArray_Type<PyArray_Type>` is a pointer to the type-object table for the ndarray
-while a :c:type:`PyArrayObject *` variable is a pointer to a particular instance
+while a :c:expr:`PyArrayObject *` variable is a pointer to a particular instance
of an ndarray (one of the members of the ndarray structure is, in
turn, a pointer to the type- object table :c:data:`&PyArray_Type<PyArray_Type>`). Finally
:c:func:`PyType_Ready` (<pointer_to_type_object>) must be called for
@@ -473,7 +473,7 @@ The __array_finalize\__ method
attribute is looked-up in the object dictionary. If it is present
and not None, then it can be either a CObject containing a pointer
to a :c:func:`PyArray_FinalizeFunc` or it can be a method taking a
- single argument (which could be None).
+ single argument (which could be None)
If the :obj:`~numpy.class.__array_finalize__` attribute is a CObject, then the pointer
must be a pointer to a function with the signature:
diff --git a/doc/source/user/c-info.how-to-extend.rst b/doc/source/user/c-info.how-to-extend.rst
index 845ce0a74..ebb4b7518 100644
--- a/doc/source/user/c-info.how-to-extend.rst
+++ b/doc/source/user/c-info.how-to-extend.rst
@@ -174,7 +174,7 @@ rule. There are several converter functions defined in the NumPy C-API
that may be of use. In particular, the :c:func:`PyArray_DescrConverter`
function is very useful to support arbitrary data-type specification.
This function transforms any valid data-type Python object into a
-:c:type:`PyArray_Descr *` object. Remember to pass in the address of the
+:c:expr:`PyArray_Descr *` object. Remember to pass in the address of the
C-variables that should be filled in.
There are lots of examples of how to use :c:func:`PyArg_ParseTuple`
@@ -192,7 +192,7 @@ It is important to keep in mind that you get a *borrowed* reference to
the object when using the "O" format string. However, the converter
functions usually require some form of memory handling. In this
example, if the conversion is successful, *dtype* will hold a new
-reference to a :c:type:`PyArray_Descr *` object, while *input* will hold a
+reference to a :c:expr:`PyArray_Descr *` object, while *input* will hold a
borrowed reference. Therefore, if this conversion were mixed with
another conversion (say to an integer) and the data-type conversion
was successful but the integer conversion failed, then you would need
@@ -213,9 +213,9 @@ The :c:func:`Py_BuildValue` (format_string, c_variables...) function makes
it easy to build tuples of Python objects from C variables. Pay
special attention to the difference between 'N' and 'O' in the format
string or you can easily create memory leaks. The 'O' format string
-increments the reference count of the :c:type:`PyObject *<PyObject>` C-variable it
+increments the reference count of the :c:expr:`PyObject *` C-variable it
corresponds to, while the 'N' format string steals a reference to the
-corresponding :c:type:`PyObject *<PyObject>` C-variable. You should use 'N' if you have
+corresponding :c:expr:`PyObject *` C-variable. You should use 'N' if you have
already created a reference for the object and just want to give that
reference to the tuple. You should use 'O' if you only have a borrowed
reference to an object and need to create one to provide for the
@@ -510,7 +510,7 @@ by providing default values for common use cases.
Getting at ndarray memory and accessing elements of the ndarray
---------------------------------------------------------------
-If obj is an ndarray (:c:type:`PyArrayObject *`), then the data-area of the
+If obj is an ndarray (:c:expr:`PyArrayObject *`), then the data-area of the
ndarray is pointed to by the void* pointer :c:func:`PyArray_DATA` (obj) or
the char* pointer :c:func:`PyArray_BYTES` (obj). Remember that (in general)
this data-area may not be aligned according to the data-type, it may
diff --git a/doc/source/user/depending_on_numpy.rst b/doc/source/user/depending_on_numpy.rst
new file mode 100644
index 000000000..d8e97ef1f
--- /dev/null
+++ b/doc/source/user/depending_on_numpy.rst
@@ -0,0 +1,147 @@
+.. _for-downstream-package-authors:
+
+For downstream package authors
+==============================
+
+This document aims to explain some best practices for authoring a package that
+depends on NumPy.
+
+
+Understanding NumPy's versioning and API/ABI stability
+------------------------------------------------------
+
+NumPy uses a standard, :pep:`440` compliant, versioning scheme:
+``major.minor.bugfix``. A *major* release is highly unusual (NumPy is still at
+version ``1.xx``) and if it happens it will likely indicate an ABI break.
+*Minor* versions are released regularly, typically every 6 months. Minor
+versions contain new features, deprecations, and removals of previously
+deprecated code. *Bugfix* releases are made even more frequently; they do not
+contain any new features or deprecations.
+
+It is important to know that NumPy, like Python itself and most other
+well known scientific Python projects, does **not** use semantic versioning.
+Instead, backwards incompatible API changes require deprecation warnings for at
+least two releases. For more details, see :ref:`NEP23`.
+
+NumPy has both a Python API and a C API. The C API can be used directly or via
+Cython, f2py, or other such tools. If your package uses the C API, then ABI
+(application binary interface) stability of NumPy is important. NumPy's ABI is
+forward but not backward compatible. This means: binaries compiled against a
+given version of NumPy will still run correctly with newer NumPy versions, but
+not with older versions.
+
+
+Testing against the NumPy main branch or pre-releases
+-----------------------------------------------------
+
+For large, actively maintained packages that depend on NumPy, we recommend
+testing against the development version of NumPy in CI. To make this easy,
+nightly builds are provided as wheels at
+https://anaconda.org/scipy-wheels-nightly/.
+This helps detect regressions in NumPy that need fixing before the next NumPy
+release. Furthermore, we recommend to raise errors on warnings in CI for this
+job, either all warnings or otherwise at least ``DeprecationWarning`` and
+``FutureWarning``. This gives you an early warning about changes in NumPy to
+adapt your code.
+
+
+Adding a dependency on NumPy
+----------------------------
+
+Build-time dependency
+`````````````````````
+
+If a package either uses the NumPy C API directly or it uses some other tool
+that depends on it like Cython or Pythran, NumPy is a *build-time* dependency
+of the package. Because the NumPy ABI is only forward compatible, you must
+build your own binaries (wheels or other package formats) against the lowest
+NumPy version that you support (or an even older version).
+
+Picking the correct NumPy version to build against for each Python version and
+platform can get complicated. There are a couple of ways to do this.
+Build-time dependencies are specified in ``pyproject.toml`` (see PEP 517),
+which is the file used to build wheels by PEP 517 compliant tools (e.g.,
+when using ``pip wheel``).
+
+You can specify everything manually in ``pyproject.toml``, or you can instead
+rely on the `oldest-supported-numpy <https://github.com/scipy/oldest-supported-numpy/>`__
+metapackage. ``oldest-supported-numpy`` will specify the correct NumPy version
+at build time for wheels, taking into account Python version, Python
+implementation (CPython or PyPy), operating system and hardware platform. It
+will specify the oldest NumPy version that supports that combination of
+characteristics. Note: for platforms for which NumPy provides wheels on PyPI,
+it will be the first version with wheels (even if some older NumPy version
+happens to build).
+
+For conda-forge it's a little less complicated: there's dedicated handling for
+NumPy in build-time and runtime dependencies, so typically this is enough
+(see `here <https://conda-forge.org/docs/maintainer/knowledge_base.html#building-against-numpy>`__ for docs)::
+
+ host:
+ - numpy
+ run:
+ - {{ pin_compatible('numpy') }}
+
+.. note::
+
+ ``pip`` has ``--no-use-pep517`` and ``--no-build-isolation`` flags that may
+ ignore ``pyproject.toml`` or treat it differently - if users use those
+ flags, they are responsible for installing the correct build dependencies
+ themselves.
+
+ ``conda`` will always use ``-no-build-isolation``; dependencies for conda
+ builds are given in the conda recipe (``meta.yaml``), the ones in
+ ``pyproject.toml`` have no effect.
+
+ Please do not use ``setup_requires`` (it is deprecated and may invoke
+ ``easy_install``).
+
+Because for NumPy you have to care about ABI compatibility, you
+specify the version with ``==`` to the lowest supported version. For your other
+build dependencies you can probably be looser, however it's still important to
+set lower and upper bounds for each dependency. It's fine to specify either a
+range or a specific version for a dependency like ``wheel`` or ``setuptools``.
+It's recommended to set the upper bound of the range to the latest already
+released version of ``wheel`` and ``setuptools`` - this prevents future
+releases from breaking your packages on PyPI.
+
+
+Runtime dependency & version ranges
+```````````````````````````````````
+
+NumPy itself and many core scientific Python packages have agreed on a schedule
+for dropping support for old Python and NumPy versions: :ref:`NEP29`. We
+recommend all packages depending on NumPy to follow the recommendations in NEP
+29.
+
+For *run-time dependencies*, you specify the range of versions in
+``install_requires`` in ``setup.py`` (assuming you use ``numpy.distutils`` or
+``setuptools`` to build). Getting the upper bound right for NumPy is slightly
+tricky. If we don't set any bound, a too-new version will be pulled in a few
+years down the line, and NumPy may have deprecated and removed some API that
+your package depended on by then. On the other hand if you set the upper bound
+to the newest already-released version, then as soon as a new NumPy version is
+released there will be no matching version of your package that works with it.
+
+What to do here depends on your release frequency. Given that NumPy releases
+come in a 6-monthly cadence and that features that get deprecated in NumPy
+should stay around for another two releases, a good upper bound is
+``<1.(xx+3).0`` - where ``xx`` is the minor version of the latest
+already-released NumPy. This is safe to do if you release at least once a year.
+If your own releases are much less frequent, you may set the upper bound a
+little further into the future - this is a trade-off between a future NumPy
+version _maybe_ removing something you rely on, and the upper bound being
+exceeded which _may_ lead to your package being hard to install in combination
+with other packages relying on the latest NumPy.
+
+
+.. note::
+
+
+ SciPy has more documentation on how it builds wheels and deals with its
+ build-time and runtime dependencies
+ `here <https://scipy.github.io/devdocs/dev/core-dev/index.html#distributing>`__.
+
+ NumPy and SciPy wheel build CI may also be useful as a reference, it can be
+ found `here for NumPy <https://github.com/MacPython/numpy-wheels>`__ and
+ `here for SciPy <https://github.com/MacPython/scipy-wheels>`__.
diff --git a/doc/source/user/explanations_index.rst b/doc/source/user/explanations_index.rst
deleted file mode 100644
index f515e36b1..000000000
--- a/doc/source/user/explanations_index.rst
+++ /dev/null
@@ -1,14 +0,0 @@
-.. _explanations:
-
-################
-Explanations
-################
-
-These documents are intended to explain in detail the concepts and techniques
-used in NumPy. For the reference documentation of the functions and classes
-contained in the package, see the :ref:`API reference <reference>`.
-
-.. toctree::
- :maxdepth: 1
-
- basics.broadcasting
diff --git a/doc/source/user/how-to-how-to.rst b/doc/source/user/how-to-how-to.rst
index de8afc28a..13d2b405f 100644
--- a/doc/source/user/how-to-how-to.rst
+++ b/doc/source/user/how-to-how-to.rst
@@ -1,118 +1,115 @@
-.. _how-to-how-to:
-
-##############################################################################
-How to write a NumPy how-to
-##############################################################################
-
-How-tos get straight to the point -- they
-
- - answer a focused question, or
- - narrow a broad question into focused questions that the user can
- choose among.
-
-******************************************************************************
-A stranger has asked for directions...
-******************************************************************************
-
-**"I need to refuel my car."**
-
-******************************************************************************
-Give a brief but explicit answer
-******************************************************************************
-
- - `"Three kilometers/miles, take a right at Hayseed Road, it's on your left."`
-
-Add helpful details for newcomers ("Hayseed Road", even though it's the only
-turnoff at three km/mi). But not irrelevant ones:
-
- - Don't also give directions from Route 7.
- - Don't explain why the town has only one filling station.
-
-If there's related background (tutorial, explanation, reference, alternative
-approach), bring it to the user's attention with a link ("Directions from Route 7,"
-"Why so few filling stations?").
-
-
-******************************************************************************
-Delegate
-******************************************************************************
-
- - `"Three km/mi, take a right at Hayseed Road, follow the signs."`
-
-If the information is already documented and succinct enough for a how-to,
-just link to it, possibly after an introduction ("Three km/mi, take a right").
-
-******************************************************************************
-If the question is broad, narrow and redirect it
-******************************************************************************
-
- **"I want to see the sights."**
-
-The `See the sights` how-to should link to a set of narrower how-tos:
-
-- Find historic buildings
-- Find scenic lookouts
-- Find the town center
-
-and these might in turn link to still narrower how-tos -- so the town center
-page might link to
-
- - Find the court house
- - Find city hall
-
-By organizing how-tos this way, you not only display the options for people
-who need to narrow their question, you also have provided answers for users
-who start with narrower questions ("I want to see historic buildings," "Which
-way to city hall?").
-
-******************************************************************************
-If there are many steps, break them up
-******************************************************************************
-
-If a how-to has many steps:
-
- - Consider breaking a step out into an individual how-to and linking to it.
- - Include subheadings. They help readers grasp what's coming and return
- where they left off.
-
-******************************************************************************
-Why write how-tos when there's Stack Overflow, Reddit, Gitter...?
-******************************************************************************
-
- - We have authoritative answers.
- - How-tos make the site less forbidding to non-experts.
- - How-tos bring people into the site and help them discover other information
- that's here .
- - Creating how-tos helps us see NumPy usability through new eyes.
-
-******************************************************************************
-Aren't how-tos and tutorials the same thing?
-******************************************************************************
-
-People use the terms "how-to" and "tutorial" interchangeably, but we draw a
-distinction, following Daniele Procida's `taxonomy of documentation`_.
-
- .. _`taxonomy of documentation`: https://documentation.divio.com/
-
-Documentation needs to meet users where they are. `How-tos` offer get-it-done
-information; the user wants steps to copy and doesn't necessarily want to
-understand NumPy. `Tutorials` are warm-fuzzy information; the user wants a
-feel for some aspect of NumPy (and again, may or may not care about deeper
-knowledge).
-
-We distinguish both tutorials and how-tos from `Explanations`, which are
-deep dives intended to give understanding rather than immediate assistance,
-and `References`, which give complete, autoritative data on some concrete
-part of NumPy (like its API) but aren't obligated to paint a broader picture.
-
-For more on tutorials, see the `tutorial how-to`_.
-
-.. _`tutorial how-to`: https://github.com/numpy/numpy-tutorials/blob/master/tutorial_style.ipynb
-
-
-******************************************************************************
-Is this page an example of a how-to?
-******************************************************************************
-
-Yes -- until the sections with question-mark headings; they explain rather
-than giving directions. In a how-to, those would be links. \ No newline at end of file
+.. _how-to-how-to:
+
+##############################################################################
+How to write a NumPy how-to
+##############################################################################
+
+How-tos get straight to the point -- they
+
+ - answer a focused question, or
+ - narrow a broad question into focused questions that the user can
+ choose among.
+
+******************************************************************************
+A stranger has asked for directions...
+******************************************************************************
+
+**"I need to refuel my car."**
+
+******************************************************************************
+Give a brief but explicit answer
+******************************************************************************
+
+ - `"Three kilometers/miles, take a right at Hayseed Road, it's on your left."`
+
+Add helpful details for newcomers ("Hayseed Road", even though it's the only
+turnoff at three km/mi). But not irrelevant ones:
+
+ - Don't also give directions from Route 7.
+ - Don't explain why the town has only one filling station.
+
+If there's related background (tutorial, explanation, reference, alternative
+approach), bring it to the user's attention with a link ("Directions from Route 7,"
+"Why so few filling stations?").
+
+
+******************************************************************************
+Delegate
+******************************************************************************
+
+ - `"Three km/mi, take a right at Hayseed Road, follow the signs."`
+
+If the information is already documented and succinct enough for a how-to,
+just link to it, possibly after an introduction ("Three km/mi, take a right").
+
+******************************************************************************
+If the question is broad, narrow and redirect it
+******************************************************************************
+
+ **"I want to see the sights."**
+
+The `See the sights` how-to should link to a set of narrower how-tos:
+
+- Find historic buildings
+- Find scenic lookouts
+- Find the town center
+
+and these might in turn link to still narrower how-tos -- so the town center
+page might link to
+
+ - Find the court house
+ - Find city hall
+
+By organizing how-tos this way, you not only display the options for people
+who need to narrow their question, you also have provided answers for users
+who start with narrower questions ("I want to see historic buildings," "Which
+way to city hall?").
+
+******************************************************************************
+If there are many steps, break them up
+******************************************************************************
+
+If a how-to has many steps:
+
+ - Consider breaking a step out into an individual how-to and linking to it.
+ - Include subheadings. They help readers grasp what's coming and return
+ where they left off.
+
+******************************************************************************
+Why write how-tos when there's Stack Overflow, Reddit, Gitter...?
+******************************************************************************
+
+ - We have authoritative answers.
+ - How-tos make the site less forbidding to non-experts.
+ - How-tos bring people into the site and help them discover other information
+ that's here .
+ - Creating how-tos helps us see NumPy usability through new eyes.
+
+******************************************************************************
+Aren't how-tos and tutorials the same thing?
+******************************************************************************
+
+People use the terms "how-to" and "tutorial" interchangeably, but we draw a
+distinction, following Daniele Procida's `taxonomy of documentation`_.
+
+ .. _`taxonomy of documentation`: https://documentation.divio.com/
+
+Documentation needs to meet users where they are. `How-tos` offer get-it-done
+information; the user wants steps to copy and doesn't necessarily want to
+understand NumPy. `Tutorials` are warm-fuzzy information; the user wants a
+feel for some aspect of NumPy (and again, may or may not care about deeper
+knowledge).
+
+We distinguish both tutorials and how-tos from `Explanations`, which are
+deep dives intended to give understanding rather than immediate assistance,
+and `References`, which give complete, autoritative data on some concrete
+part of NumPy (like its API) but aren't obligated to paint a broader picture.
+
+For more on tutorials, see :doc:`content/tutorial-style-guide`
+
+******************************************************************************
+Is this page an example of a how-to?
+******************************************************************************
+
+Yes -- until the sections with question-mark headings; they explain rather
+than giving directions. In a how-to, those would be links.
diff --git a/doc/source/user/how-to-io.rst b/doc/source/user/how-to-io.rst
index ca9fc41f0..d238ccbb6 100644
--- a/doc/source/user/how-to-io.rst
+++ b/doc/source/user/how-to-io.rst
@@ -1,328 +1,328 @@
-.. _how-to-io:
-
-##############################################################################
-Reading and writing files
-##############################################################################
-
-This page tackles common applications; for the full collection of I/O
-routines, see :ref:`routines.io`.
-
-
-******************************************************************************
-Reading text and CSV_ files
-******************************************************************************
-
-.. _CSV: https://en.wikipedia.org/wiki/Comma-separated_values
-
-With no missing values
-==============================================================================
-
-Use :func:`numpy.loadtxt`.
-
-With missing values
-==============================================================================
-
-Use :func:`numpy.genfromtxt`.
-
-:func:`numpy.genfromtxt` will either
-
- - return a :ref:`masked array<maskedarray.generic>`
- **masking out missing values** (if ``usemask=True``), or
-
- - **fill in the missing value** with the value specified in
- ``filling_values`` (default is ``np.nan`` for float, -1 for int).
-
-With non-whitespace delimiters
-------------------------------------------------------------------------------
-::
-
- >>> print(open("csv.txt").read()) # doctest: +SKIP
- 1, 2, 3
- 4,, 6
- 7, 8, 9
-
-
-Masked-array output
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-::
-
- >>> np.genfromtxt("csv.txt", delimiter=",", usemask=True) # doctest: +SKIP
- masked_array(
- data=[[1.0, 2.0, 3.0],
- [4.0, --, 6.0],
- [7.0, 8.0, 9.0]],
- mask=[[False, False, False],
- [False, True, False],
- [False, False, False]],
- fill_value=1e+20)
-
-Array output
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-::
-
- >>> np.genfromtxt("csv.txt", delimiter=",") # doctest: +SKIP
- array([[ 1., 2., 3.],
- [ 4., nan, 6.],
- [ 7., 8., 9.]])
-
-Array output, specified fill-in value
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-::
-
- >>> np.genfromtxt("csv.txt", delimiter=",", dtype=np.int8, filling_values=99) # doctest: +SKIP
- array([[ 1, 2, 3],
- [ 4, 99, 6],
- [ 7, 8, 9]], dtype=int8)
-
-Whitespace-delimited
--------------------------------------------------------------------------------
-
-:func:`numpy.genfromtxt` can also parse whitespace-delimited data files
-that have missing values if
-
-* **Each field has a fixed width**: Use the width as the `delimiter` argument.
- ::
-
- # File with width=4. The data does not have to be justified (for example,
- # the 2 in row 1), the last column can be less than width (for example, the 6
- # in row 2), and no delimiting character is required (for instance 8888 and 9
- # in row 3)
-
- >>> f = open("fixedwidth.txt").read() # doctest: +SKIP
- >>> print(f) # doctest: +SKIP
- 1 2 3
- 44 6
- 7 88889
-
- # Showing spaces as ^
- >>> print(f.replace(" ","^")) # doctest: +SKIP
- 1^^^2^^^^^^3
- 44^^^^^^6
- 7^^^88889
-
- >>> np.genfromtxt("fixedwidth.txt", delimiter=4) # doctest: +SKIP
- array([[1.000e+00, 2.000e+00, 3.000e+00],
- [4.400e+01, nan, 6.000e+00],
- [7.000e+00, 8.888e+03, 9.000e+00]])
-
-* **A special value (e.g. "x") indicates a missing field**: Use it as the
- `missing_values` argument.
- ::
-
- >>> print(open("nan.txt").read()) # doctest: +SKIP
- 1 2 3
- 44 x 6
- 7 8888 9
-
- >>> np.genfromtxt("nan.txt", missing_values="x") # doctest: +SKIP
- array([[1.000e+00, 2.000e+00, 3.000e+00],
- [4.400e+01, nan, 6.000e+00],
- [7.000e+00, 8.888e+03, 9.000e+00]])
-
-* **You want to skip the rows with missing values**: Set
- `invalid_raise=False`.
- ::
-
- >>> print(open("skip.txt").read()) # doctest: +SKIP
- 1 2 3
- 44 6
- 7 888 9
-
- >>> np.genfromtxt("skip.txt", invalid_raise=False) # doctest: +SKIP
- __main__:1: ConversionWarning: Some errors were detected !
- Line #2 (got 2 columns instead of 3)
- array([[ 1., 2., 3.],
- [ 7., 888., 9.]])
-
-
-* **The delimiter whitespace character is different from the whitespace that
- indicates missing data**. For instance, if columns are delimited by ``\t``,
- then missing data will be recognized if it consists of one
- or more spaces.
- ::
-
- >>> f = open("tabs.txt").read() # doctest: +SKIP
- >>> print(f) # doctest: +SKIP
- 1 2 3
- 44 6
- 7 888 9
-
- # Tabs vs. spaces
- >>> print(f.replace("\t","^")) # doctest: +SKIP
- 1^2^3
- 44^ ^6
- 7^888^9
-
- >>> np.genfromtxt("tabs.txt", delimiter="\t", missing_values=" +") # doctest: +SKIP
- array([[ 1., 2., 3.],
- [ 44., nan, 6.],
- [ 7., 888., 9.]])
-
-******************************************************************************
-Read a file in .npy or .npz format
-******************************************************************************
-
-Choices:
-
- - Use :func:`numpy.load`. It can read files generated by any of
- :func:`numpy.save`, :func:`numpy.savez`, or :func:`numpy.savez_compressed`.
-
- - Use memory mapping. See `numpy.lib.format.open_memmap`.
-
-******************************************************************************
-Write to a file to be read back by NumPy
-******************************************************************************
-
-Binary
-===============================================================================
-
-Use
-:func:`numpy.save`, or to store multiple arrays :func:`numpy.savez`
-or :func:`numpy.savez_compressed`.
-
-For :ref:`security and portability <how-to-io-pickle-file>`, set
-``allow_pickle=False`` unless the dtype contains Python objects, which
-requires pickling.
-
-Masked arrays :any:`can't currently be saved <MaskedArray.tofile>`,
-nor can other arbitrary array subclasses.
-
-Human-readable
-==============================================================================
-
-:func:`numpy.save` and :func:`numpy.savez` create binary files. To **write a
-human-readable file**, use :func:`numpy.savetxt`. The array can only be 1- or
-2-dimensional, and there's no ` savetxtz` for multiple files.
-
-Large arrays
-==============================================================================
-
-See :ref:`how-to-io-large-arrays`.
-
-******************************************************************************
-Read an arbitrarily formatted binary file ("binary blob")
-******************************************************************************
-
-Use a :doc:`structured array <basics.rec>`.
-
-**Example:**
-
-The ``.wav`` file header is a 44-byte block preceding ``data_size`` bytes of the
-actual sound data::
-
- chunk_id "RIFF"
- chunk_size 4-byte unsigned little-endian integer
- format "WAVE"
- fmt_id "fmt "
- fmt_size 4-byte unsigned little-endian integer
- audio_fmt 2-byte unsigned little-endian integer
- num_channels 2-byte unsigned little-endian integer
- sample_rate 4-byte unsigned little-endian integer
- byte_rate 4-byte unsigned little-endian integer
- block_align 2-byte unsigned little-endian integer
- bits_per_sample 2-byte unsigned little-endian integer
- data_id "data"
- data_size 4-byte unsigned little-endian integer
-
-The ``.wav`` file header as a NumPy structured dtype::
-
- wav_header_dtype = np.dtype([
- ("chunk_id", (bytes, 4)), # flexible-sized scalar type, item size 4
- ("chunk_size", "<u4"), # little-endian unsigned 32-bit integer
- ("format", "S4"), # 4-byte string, alternate spelling of (bytes, 4)
- ("fmt_id", "S4"),
- ("fmt_size", "<u4"),
- ("audio_fmt", "<u2"), #
- ("num_channels", "<u2"), # .. more of the same ...
- ("sample_rate", "<u4"), #
- ("byte_rate", "<u4"),
- ("block_align", "<u2"),
- ("bits_per_sample", "<u2"),
- ("data_id", "S4"),
- ("data_size", "<u4"),
- #
- # the sound data itself cannot be represented here:
- # it does not have a fixed size
- ])
-
- header = np.fromfile(f, dtype=wave_header_dtype, count=1)[0]
-
-This ``.wav`` example is for illustration; to read a ``.wav`` file in real
-life, use Python's built-in module :mod:`wave`.
-
-(Adapted from Pauli Virtanen, :ref:`advanced_numpy`, licensed
-under `CC BY 4.0 <https://creativecommons.org/licenses/by/4.0/>`_.)
-
-.. _how-to-io-large-arrays:
-
-******************************************************************************
-Write or read large arrays
-******************************************************************************
-
-**Arrays too large to fit in memory** can be treated like ordinary in-memory
-arrays using memory mapping.
-
-- Raw array data written with :func:`numpy.ndarray.tofile` or
- :func:`numpy.ndarray.tobytes` can be read with :func:`numpy.memmap`::
-
- array = numpy.memmap("mydata/myarray.arr", mode="r", dtype=np.int16, shape=(1024, 1024))
-
-- Files output by :func:`numpy.save` (that is, using the numpy format) can be read
- using :func:`numpy.load` with the ``mmap_mode`` keyword argument::
-
- large_array[some_slice] = np.load("path/to/small_array", mmap_mode="r")
-
-Memory mapping lacks features like data chunking and compression; more
-full-featured formats and libraries usable with NumPy include:
-
-* **HDF5**: `h5py <https://www.h5py.org/>`_ or `PyTables <https://www.pytables.org/>`_.
-* **Zarr**: `here <https://zarr.readthedocs.io/en/stable/tutorial.html#reading-and-writing-data>`_.
-* **NetCDF**: :class:`scipy.io.netcdf_file`.
-
-For tradeoffs among memmap, Zarr, and HDF5, see
-`pythonspeed.com <https://pythonspeed.com/articles/mmap-vs-zarr-hdf5/>`_.
-
-******************************************************************************
-Write files for reading by other (non-NumPy) tools
-******************************************************************************
-
-Formats for **exchanging data** with other tools include HDF5, Zarr, and
-NetCDF (see :ref:`how-to-io-large-arrays`).
-
-******************************************************************************
-Write or read a JSON file
-******************************************************************************
-
-NumPy arrays are **not** directly
-`JSON serializable <https://github.com/numpy/numpy/issues/12481>`_.
-
-
-.. _how-to-io-pickle-file:
-
-******************************************************************************
-Save/restore using a pickle file
-******************************************************************************
-
-Avoid when possible; :doc:`pickles <python:library/pickle>` are not secure
-against erroneous or maliciously constructed data.
-
-Use :func:`numpy.save` and :func:`numpy.load`. Set ``allow_pickle=False``,
-unless the array dtype includes Python objects, in which case pickling is
-required.
-
-******************************************************************************
-Convert from a pandas DataFrame to a NumPy array
-******************************************************************************
-
-See :meth:`pandas.DataFrame.to_numpy`.
-
-******************************************************************************
- Save/restore using `~numpy.ndarray.tofile` and `~numpy.fromfile`
-******************************************************************************
-
-In general, prefer :func:`numpy.save` and :func:`numpy.load`.
-
-:func:`numpy.ndarray.tofile` and :func:`numpy.fromfile` lose information on
-endianness and precision and so are unsuitable for anything but scratch
-storage.
-
+.. _how-to-io:
+
+##############################################################################
+Reading and writing files
+##############################################################################
+
+This page tackles common applications; for the full collection of I/O
+routines, see :ref:`routines.io`.
+
+
+******************************************************************************
+Reading text and CSV_ files
+******************************************************************************
+
+.. _CSV: https://en.wikipedia.org/wiki/Comma-separated_values
+
+With no missing values
+==============================================================================
+
+Use :func:`numpy.loadtxt`.
+
+With missing values
+==============================================================================
+
+Use :func:`numpy.genfromtxt`.
+
+:func:`numpy.genfromtxt` will either
+
+ - return a :ref:`masked array<maskedarray.generic>`
+ **masking out missing values** (if ``usemask=True``), or
+
+ - **fill in the missing value** with the value specified in
+ ``filling_values`` (default is ``np.nan`` for float, -1 for int).
+
+With non-whitespace delimiters
+------------------------------------------------------------------------------
+::
+
+ >>> print(open("csv.txt").read()) # doctest: +SKIP
+ 1, 2, 3
+ 4,, 6
+ 7, 8, 9
+
+
+Masked-array output
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+::
+
+ >>> np.genfromtxt("csv.txt", delimiter=",", usemask=True) # doctest: +SKIP
+ masked_array(
+ data=[[1.0, 2.0, 3.0],
+ [4.0, --, 6.0],
+ [7.0, 8.0, 9.0]],
+ mask=[[False, False, False],
+ [False, True, False],
+ [False, False, False]],
+ fill_value=1e+20)
+
+Array output
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+::
+
+ >>> np.genfromtxt("csv.txt", delimiter=",") # doctest: +SKIP
+ array([[ 1., 2., 3.],
+ [ 4., nan, 6.],
+ [ 7., 8., 9.]])
+
+Array output, specified fill-in value
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+::
+
+ >>> np.genfromtxt("csv.txt", delimiter=",", dtype=np.int8, filling_values=99) # doctest: +SKIP
+ array([[ 1, 2, 3],
+ [ 4, 99, 6],
+ [ 7, 8, 9]], dtype=int8)
+
+Whitespace-delimited
+-------------------------------------------------------------------------------
+
+:func:`numpy.genfromtxt` can also parse whitespace-delimited data files
+that have missing values if
+
+* **Each field has a fixed width**: Use the width as the `delimiter` argument.
+ ::
+
+ # File with width=4. The data does not have to be justified (for example,
+ # the 2 in row 1), the last column can be less than width (for example, the 6
+ # in row 2), and no delimiting character is required (for instance 8888 and 9
+ # in row 3)
+
+ >>> f = open("fixedwidth.txt").read() # doctest: +SKIP
+ >>> print(f) # doctest: +SKIP
+ 1 2 3
+ 44 6
+ 7 88889
+
+ # Showing spaces as ^
+ >>> print(f.replace(" ","^")) # doctest: +SKIP
+ 1^^^2^^^^^^3
+ 44^^^^^^6
+ 7^^^88889
+
+ >>> np.genfromtxt("fixedwidth.txt", delimiter=4) # doctest: +SKIP
+ array([[1.000e+00, 2.000e+00, 3.000e+00],
+ [4.400e+01, nan, 6.000e+00],
+ [7.000e+00, 8.888e+03, 9.000e+00]])
+
+* **A special value (e.g. "x") indicates a missing field**: Use it as the
+ `missing_values` argument.
+ ::
+
+ >>> print(open("nan.txt").read()) # doctest: +SKIP
+ 1 2 3
+ 44 x 6
+ 7 8888 9
+
+ >>> np.genfromtxt("nan.txt", missing_values="x") # doctest: +SKIP
+ array([[1.000e+00, 2.000e+00, 3.000e+00],
+ [4.400e+01, nan, 6.000e+00],
+ [7.000e+00, 8.888e+03, 9.000e+00]])
+
+* **You want to skip the rows with missing values**: Set
+ `invalid_raise=False`.
+ ::
+
+ >>> print(open("skip.txt").read()) # doctest: +SKIP
+ 1 2 3
+ 44 6
+ 7 888 9
+
+ >>> np.genfromtxt("skip.txt", invalid_raise=False) # doctest: +SKIP
+ __main__:1: ConversionWarning: Some errors were detected !
+ Line #2 (got 2 columns instead of 3)
+ array([[ 1., 2., 3.],
+ [ 7., 888., 9.]])
+
+
+* **The delimiter whitespace character is different from the whitespace that
+ indicates missing data**. For instance, if columns are delimited by ``\t``,
+ then missing data will be recognized if it consists of one
+ or more spaces.
+ ::
+
+ >>> f = open("tabs.txt").read() # doctest: +SKIP
+ >>> print(f) # doctest: +SKIP
+ 1 2 3
+ 44 6
+ 7 888 9
+
+ # Tabs vs. spaces
+ >>> print(f.replace("\t","^")) # doctest: +SKIP
+ 1^2^3
+ 44^ ^6
+ 7^888^9
+
+ >>> np.genfromtxt("tabs.txt", delimiter="\t", missing_values=" +") # doctest: +SKIP
+ array([[ 1., 2., 3.],
+ [ 44., nan, 6.],
+ [ 7., 888., 9.]])
+
+******************************************************************************
+Read a file in .npy or .npz format
+******************************************************************************
+
+Choices:
+
+ - Use :func:`numpy.load`. It can read files generated by any of
+ :func:`numpy.save`, :func:`numpy.savez`, or :func:`numpy.savez_compressed`.
+
+ - Use memory mapping. See `numpy.lib.format.open_memmap`.
+
+******************************************************************************
+Write to a file to be read back by NumPy
+******************************************************************************
+
+Binary
+===============================================================================
+
+Use
+:func:`numpy.save`, or to store multiple arrays :func:`numpy.savez`
+or :func:`numpy.savez_compressed`.
+
+For :ref:`security and portability <how-to-io-pickle-file>`, set
+``allow_pickle=False`` unless the dtype contains Python objects, which
+requires pickling.
+
+Masked arrays :any:`can't currently be saved <MaskedArray.tofile>`,
+nor can other arbitrary array subclasses.
+
+Human-readable
+==============================================================================
+
+:func:`numpy.save` and :func:`numpy.savez` create binary files. To **write a
+human-readable file**, use :func:`numpy.savetxt`. The array can only be 1- or
+2-dimensional, and there's no ` savetxtz` for multiple files.
+
+Large arrays
+==============================================================================
+
+See :ref:`how-to-io-large-arrays`.
+
+******************************************************************************
+Read an arbitrarily formatted binary file ("binary blob")
+******************************************************************************
+
+Use a :doc:`structured array <basics.rec>`.
+
+**Example:**
+
+The ``.wav`` file header is a 44-byte block preceding ``data_size`` bytes of the
+actual sound data::
+
+ chunk_id "RIFF"
+ chunk_size 4-byte unsigned little-endian integer
+ format "WAVE"
+ fmt_id "fmt "
+ fmt_size 4-byte unsigned little-endian integer
+ audio_fmt 2-byte unsigned little-endian integer
+ num_channels 2-byte unsigned little-endian integer
+ sample_rate 4-byte unsigned little-endian integer
+ byte_rate 4-byte unsigned little-endian integer
+ block_align 2-byte unsigned little-endian integer
+ bits_per_sample 2-byte unsigned little-endian integer
+ data_id "data"
+ data_size 4-byte unsigned little-endian integer
+
+The ``.wav`` file header as a NumPy structured dtype::
+
+ wav_header_dtype = np.dtype([
+ ("chunk_id", (bytes, 4)), # flexible-sized scalar type, item size 4
+ ("chunk_size", "<u4"), # little-endian unsigned 32-bit integer
+ ("format", "S4"), # 4-byte string, alternate spelling of (bytes, 4)
+ ("fmt_id", "S4"),
+ ("fmt_size", "<u4"),
+ ("audio_fmt", "<u2"), #
+ ("num_channels", "<u2"), # .. more of the same ...
+ ("sample_rate", "<u4"), #
+ ("byte_rate", "<u4"),
+ ("block_align", "<u2"),
+ ("bits_per_sample", "<u2"),
+ ("data_id", "S4"),
+ ("data_size", "<u4"),
+ #
+ # the sound data itself cannot be represented here:
+ # it does not have a fixed size
+ ])
+
+ header = np.fromfile(f, dtype=wave_header_dtype, count=1)[0]
+
+This ``.wav`` example is for illustration; to read a ``.wav`` file in real
+life, use Python's built-in module :mod:`wave`.
+
+(Adapted from Pauli Virtanen, :ref:`advanced_numpy`, licensed
+under `CC BY 4.0 <https://creativecommons.org/licenses/by/4.0/>`_.)
+
+.. _how-to-io-large-arrays:
+
+******************************************************************************
+Write or read large arrays
+******************************************************************************
+
+**Arrays too large to fit in memory** can be treated like ordinary in-memory
+arrays using memory mapping.
+
+- Raw array data written with :func:`numpy.ndarray.tofile` or
+ :func:`numpy.ndarray.tobytes` can be read with :func:`numpy.memmap`::
+
+ array = numpy.memmap("mydata/myarray.arr", mode="r", dtype=np.int16, shape=(1024, 1024))
+
+- Files output by :func:`numpy.save` (that is, using the numpy format) can be read
+ using :func:`numpy.load` with the ``mmap_mode`` keyword argument::
+
+ large_array[some_slice] = np.load("path/to/small_array", mmap_mode="r")
+
+Memory mapping lacks features like data chunking and compression; more
+full-featured formats and libraries usable with NumPy include:
+
+* **HDF5**: `h5py <https://www.h5py.org/>`_ or `PyTables <https://www.pytables.org/>`_.
+* **Zarr**: `here <https://zarr.readthedocs.io/en/stable/tutorial.html#reading-and-writing-data>`_.
+* **NetCDF**: :class:`scipy.io.netcdf_file`.
+
+For tradeoffs among memmap, Zarr, and HDF5, see
+`pythonspeed.com <https://pythonspeed.com/articles/mmap-vs-zarr-hdf5/>`_.
+
+******************************************************************************
+Write files for reading by other (non-NumPy) tools
+******************************************************************************
+
+Formats for **exchanging data** with other tools include HDF5, Zarr, and
+NetCDF (see :ref:`how-to-io-large-arrays`).
+
+******************************************************************************
+Write or read a JSON file
+******************************************************************************
+
+NumPy arrays are **not** directly
+`JSON serializable <https://github.com/numpy/numpy/issues/12481>`_.
+
+
+.. _how-to-io-pickle-file:
+
+******************************************************************************
+Save/restore using a pickle file
+******************************************************************************
+
+Avoid when possible; :doc:`pickles <python:library/pickle>` are not secure
+against erroneous or maliciously constructed data.
+
+Use :func:`numpy.save` and :func:`numpy.load`. Set ``allow_pickle=False``,
+unless the array dtype includes Python objects, in which case pickling is
+required.
+
+******************************************************************************
+Convert from a pandas DataFrame to a NumPy array
+******************************************************************************
+
+See :meth:`pandas.DataFrame.to_numpy`.
+
+******************************************************************************
+ Save/restore using `~numpy.ndarray.tofile` and `~numpy.fromfile`
+******************************************************************************
+
+In general, prefer :func:`numpy.save` and :func:`numpy.load`.
+
+:func:`numpy.ndarray.tofile` and :func:`numpy.fromfile` lose information on
+endianness and precision and so are unsuitable for anything but scratch
+storage.
+
diff --git a/doc/source/user/images/np_create_matrix.png b/doc/source/user/images/np_create_matrix.png
index cd685c4f5..65e4535e5 100644
--- a/doc/source/user/images/np_create_matrix.png
+++ b/doc/source/user/images/np_create_matrix.png
Binary files differ
diff --git a/doc/source/user/images/np_indexing.png b/doc/source/user/images/np_indexing.png
index 4303ec35b..863b2d46f 100644
--- a/doc/source/user/images/np_indexing.png
+++ b/doc/source/user/images/np_indexing.png
Binary files differ
diff --git a/doc/source/user/index.rst b/doc/source/user/index.rst
index 28297d9ea..b3ecc3a95 100644
--- a/doc/source/user/index.rst
+++ b/doc/source/user/index.rst
@@ -21,8 +21,9 @@ details are found in :ref:`reference`.
numpy-for-matlab-users
building
c-info
- tutorials_index
+ NumPy Tutorials <https://numpy.org/numpy-tutorials/features.html>
howtos_index
+ depending_on_numpy
.. Links to these files are placed directly in the top-level html
@@ -34,7 +35,6 @@ details are found in :ref:`reference`.
.. toctree::
:hidden:
- explanations_index
../f2py/index
../glossary
../dev/underthehood
diff --git a/doc/source/user/install.rst b/doc/source/user/install.rst
index e05cee2f1..b9425701f 100644
--- a/doc/source/user/install.rst
+++ b/doc/source/user/install.rst
@@ -1,7 +1,7 @@
-:orphan:
-
-****************
-Installing NumPy
-****************
-
+:orphan:
+
+****************
+Installing NumPy
+****************
+
See `Installing NumPy <https://numpy.org/install/>`_. \ No newline at end of file
diff --git a/doc/source/user/misc.rst b/doc/source/user/misc.rst
index 031ce4efa..f0a7f5e4c 100644
--- a/doc/source/user/misc.rst
+++ b/doc/source/user/misc.rst
@@ -149,11 +149,12 @@ Only a survey of the choices. Little detail on how each works.
- good numpy support: arrays have all these in their ctypes
attribute: ::
- a.ctypes.data a.ctypes.get_strides
- a.ctypes.data_as a.ctypes.shape
- a.ctypes.get_as_parameter a.ctypes.shape_as
- a.ctypes.get_data a.ctypes.strides
- a.ctypes.get_shape a.ctypes.strides_as
+ a.ctypes.data
+ a.ctypes.data_as
+ a.ctypes.shape
+ a.ctypes.shape_as
+ a.ctypes.strides
+ a.ctypes.strides_as
- Minuses:
diff --git a/doc/source/user/plots/matplotlib3.py b/doc/source/user/plots/matplotlib3.py
index 20a8c0767..7b56067ef 100644
--- a/doc/source/user/plots/matplotlib3.py
+++ b/doc/source/user/plots/matplotlib3.py
@@ -1,9 +1,8 @@
import numpy as np
import matplotlib.pyplot as plt
-from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
-ax = Axes3D(fig)
+ax = fig.add_subplot(projection='3d')
X = np.arange(-5, 5, 0.15)
Y = np.arange(-5, 5, 0.15)
X, Y = np.meshgrid(X, Y)
diff --git a/doc/source/user/quickstart.rst b/doc/source/user/quickstart.rst
index 8fdc6ec36..dd5773878 100644
--- a/doc/source/user/quickstart.rst
+++ b/doc/source/user/quickstart.rst
@@ -20,8 +20,7 @@ in addition to NumPy.
**Learner profile**
-This is a quick overview of
-algebra and arrays in NumPy. It demonstrates how n-dimensional
+This is a quick overview of arrays in NumPy. It demonstrates how n-dimensional
(:math:`n>=2`) arrays are represented and can be manipulated. In particular, if
you don't know how to apply common functions to n-dimensional arrays (without
using for-loops), or if you want to understand axis and shape properties for
@@ -53,8 +52,8 @@ axis has a length of 2, the second axis has a length of 3.
::
- [[ 1., 0., 0.],
- [ 0., 1., 2.]]
+ [[1., 0., 0.],
+ [0., 1., 2.]]
NumPy's array class is called ``ndarray``. It is also known by the alias
``array``. Note that ``numpy.array`` is not the same as the Standard
@@ -128,7 +127,7 @@ from the type of the elements in the sequences.
::
>>> import numpy as np
- >>> a = np.array([2,3,4])
+ >>> a = np.array([2, 3, 4])
>>> a
array([2, 3, 4])
>>> a.dtype
@@ -142,11 +141,11 @@ rather than providing a single sequence as an argument.
::
- >>> a = np.array(1,2,3,4) # WRONG
+ >>> a = np.array(1, 2, 3, 4) # WRONG
Traceback (most recent call last):
...
TypeError: array() takes from 1 to 2 positional arguments but 4 were given
- >>> a = np.array([1,2,3,4]) # RIGHT
+ >>> a = np.array([1, 2, 3, 4]) # RIGHT
``array`` transforms sequences of sequences into two-dimensional arrays,
sequences of sequences of sequences into three-dimensional arrays, and
@@ -154,7 +153,7 @@ so on.
::
- >>> b = np.array([(1.5,2,3), (4,5,6)])
+ >>> b = np.array([(1.5, 2, 3), (4, 5, 6)])
>>> b
array([[1.5, 2. , 3. ],
[4. , 5. , 6. ]])
@@ -163,7 +162,7 @@ The type of the array can also be explicitly specified at creation time:
::
- >>> c = np.array( [ [1,2], [3,4] ], dtype=complex )
+ >>> c = np.array([[1, 2], [3, 4]], dtype=complex)
>>> c
array([[1.+0.j, 2.+0.j],
[3.+0.j, 4.+0.j]])
@@ -177,7 +176,7 @@ The function ``zeros`` creates an array full of zeros, the function
``ones`` creates an array full of ones, and the function ``empty``
creates an array whose initial content is random and depends on the
state of the memory. By default, the dtype of the created array is
-``float64``.
+``float64``, but it can be specified via the key word argument ``dtype``.
::
@@ -185,7 +184,7 @@ state of the memory. By default, the dtype of the created array is
array([[0., 0., 0., 0.],
[0., 0., 0., 0.],
[0., 0., 0., 0.]])
- >>> np.ones( (2,3,4), dtype=np.int16 ) # dtype can also be specified
+ >>> np.ones((2, 3, 4), dtype=np.int16)
array([[[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]],
@@ -193,9 +192,9 @@ state of the memory. By default, the dtype of the created array is
[[1, 1, 1, 1],
[1, 1, 1, 1],
[1, 1, 1, 1]]], dtype=int16)
- >>> np.empty( (2,3) ) # uninitialized
- array([[ 3.73603959e-262, 6.02658058e-154, 6.55490914e-260], # may vary
- [ 5.30498948e-313, 3.14673309e-307, 1.00000000e+000]])
+ >>> np.empty((2, 3))
+ array([[3.73603959e-262, 6.02658058e-154, 6.55490914e-260], # may vary
+ [5.30498948e-313, 3.14673309e-307, 1.00000000e+000]])
To create sequences of numbers, NumPy provides the ``arange`` function
which is analogous to the Python built-in ``range``, but returns an
@@ -203,9 +202,9 @@ array.
::
- >>> np.arange( 10, 30, 5 )
+ >>> np.arange(10, 30, 5)
array([10, 15, 20, 25])
- >>> np.arange( 0, 2, 0.3 ) # it accepts float arguments
+ >>> np.arange(0, 2, 0.3) # it accepts float arguments
array([0. , 0.3, 0.6, 0.9, 1.2, 1.5, 1.8])
When ``arange`` is used with floating point arguments, it is generally
@@ -215,9 +214,9 @@ to use the function ``linspace`` that receives as an argument the number
of elements that we want, instead of the step::
>>> from numpy import pi
- >>> np.linspace( 0, 2, 9 ) # 9 numbers from 0 to 2
+ >>> np.linspace(0, 2, 9) # 9 numbers from 0 to 2
array([0. , 0.25, 0.5 , 0.75, 1. , 1.25, 1.5 , 1.75, 2. ])
- >>> x = np.linspace( 0, 2*pi, 100 ) # useful to evaluate function at lots of points
+ >>> x = np.linspace(0, 2 * pi, 100) # useful to evaluate function at lots of points
>>> f = np.sin(x)
.. seealso::
@@ -251,18 +250,18 @@ matrices and tridimensionals as lists of matrices.
::
- >>> a = np.arange(6) # 1d array
+ >>> a = np.arange(6) # 1d array
>>> print(a)
[0 1 2 3 4 5]
- >>>
- >>> b = np.arange(12).reshape(4,3) # 2d array
+ >>>
+ >>> b = np.arange(12).reshape(4, 3) # 2d array
>>> print(b)
[[ 0 1 2]
[ 3 4 5]
[ 6 7 8]
[ 9 10 11]]
- >>>
- >>> c = np.arange(24).reshape(2,3,4) # 3d array
+ >>>
+ >>> c = np.arange(24).reshape(2, 3, 4) # 3d array
>>> print(c)
[[[ 0 1 2 3]
[ 4 5 6 7]
@@ -280,8 +279,8 @@ central part of the array and only prints the corners::
>>> print(np.arange(10000))
[ 0 1 2 ... 9997 9998 9999]
- >>>
- >>> print(np.arange(10000).reshape(100,100))
+ >>>
+ >>> print(np.arange(10000).reshape(100, 100))
[[ 0 1 2 ... 97 98 99]
[ 100 101 102 ... 197 198 199]
[ 200 201 202 ... 297 298 299]
@@ -295,7 +294,7 @@ can change the printing options using ``set_printoptions``.
::
- >>> np.set_printoptions(threshold=sys.maxsize) # sys module should be imported
+ >>> np.set_printoptions(threshold=sys.maxsize) # sys module should be imported
.. _quickstart.basic-operations:
@@ -308,35 +307,35 @@ created and filled with the result.
::
- >>> a = np.array( [20,30,40,50] )
- >>> b = np.arange( 4 )
+ >>> a = np.array([20, 30, 40, 50])
+ >>> b = np.arange(4)
>>> b
array([0, 1, 2, 3])
- >>> c = a-b
+ >>> c = a - b
>>> c
array([20, 29, 38, 47])
>>> b**2
array([0, 1, 4, 9])
- >>> 10*np.sin(a)
+ >>> 10 * np.sin(a)
array([ 9.12945251, -9.88031624, 7.4511316 , -2.62374854])
- >>> a<35
+ >>> a < 35
array([ True, True, False, False])
Unlike in many matrix languages, the product operator ``*`` operates
elementwise in NumPy arrays. The matrix product can be performed using
the ``@`` operator (in python >=3.5) or the ``dot`` function or method::
- >>> A = np.array( [[1,1],
- ... [0,1]] )
- >>> B = np.array( [[2,0],
- ... [3,4]] )
- >>> A * B # elementwise product
+ >>> A = np.array([[1, 1],
+ ... [0, 1]])
+ >>> B = np.array([[2, 0],
+ ... [3, 4]])
+ >>> A * B # elementwise product
array([[2, 0],
[0, 4]])
- >>> A @ B # matrix product
+ >>> A @ B # matrix product
array([[5, 4],
[3, 4]])
- >>> A.dot(B) # another matrix product
+ >>> A.dot(B) # another matrix product
array([[5, 4],
[3, 4]])
@@ -345,9 +344,9 @@ existing array rather than create a new one.
::
- >>> rg = np.random.default_rng(1) # create instance of default random number generator
- >>> a = np.ones((2,3), dtype=int)
- >>> b = rg.random((2,3))
+ >>> rg = np.random.default_rng(1) # create instance of default random number generator
+ >>> a = np.ones((2, 3), dtype=int)
+ >>> b = rg.random((2, 3))
>>> a *= 3
>>> a
array([[3, 3, 3],
@@ -356,7 +355,7 @@ existing array rather than create a new one.
>>> b
array([[3.51182162, 3.9504637 , 3.14415961],
[3.94864945, 3.31183145, 3.42332645]])
- >>> a += b # b is not automatically converted to integer type
+ >>> a += b # b is not automatically converted to integer type
Traceback (most recent call last):
...
numpy.core._exceptions._UFuncOutputCastingError: Cannot cast ufunc 'add' output from dtype('float64') to dtype('int64') with casting rule 'same_kind'
@@ -368,15 +367,15 @@ as upcasting).
::
>>> a = np.ones(3, dtype=np.int32)
- >>> b = np.linspace(0,pi,3)
+ >>> b = np.linspace(0, pi, 3)
>>> b.dtype.name
'float64'
- >>> c = a+b
+ >>> c = a + b
>>> c
array([1. , 2.57079633, 4.14159265])
>>> c.dtype.name
'float64'
- >>> d = np.exp(c*1j)
+ >>> d = np.exp(c * 1j)
>>> d
array([ 0.54030231+0.84147098j, -0.84147098+0.54030231j,
-0.54030231-0.84147098j])
@@ -388,7 +387,7 @@ the array, are implemented as methods of the ``ndarray`` class.
::
- >>> a = rg.random((2,3))
+ >>> a = rg.random((2, 3))
>>> a
array([[0.82770259, 0.40919914, 0.54959369],
[0.02755911, 0.75351311, 0.53814331]])
@@ -404,19 +403,19 @@ of numbers, regardless of its shape. However, by specifying the ``axis``
parameter you can apply an operation along the specified axis of an
array::
- >>> b = np.arange(12).reshape(3,4)
+ >>> b = np.arange(12).reshape(3, 4)
>>> b
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
>>>
- >>> b.sum(axis=0) # sum of each column
+ >>> b.sum(axis=0) # sum of each column
array([12, 15, 18, 21])
>>>
- >>> b.min(axis=1) # min of each row
+ >>> b.min(axis=1) # min of each row
array([0, 4, 8])
>>>
- >>> b.cumsum(axis=1) # cumulative sum along each row
+ >>> b.cumsum(axis=1) # cumulative sum along each row
array([[ 0, 1, 3, 6],
[ 4, 9, 15, 22],
[ 8, 17, 27, 38]])
@@ -427,7 +426,7 @@ Universal Functions
NumPy provides familiar mathematical functions such as sin, cos, and
exp. In NumPy, these are called "universal
-functions"(\ ``ufunc``). Within NumPy, these functions
+functions" (\ ``ufunc``). Within NumPy, these functions
operate elementwise on an array, producing an array as output.
::
@@ -507,15 +506,15 @@ and other Python sequences.
8
>>> a[2:5]
array([ 8, 27, 64])
- # equivalent to a[0:6:2] = 1000;
- # from start to position 6, exclusive, set every 2nd element to 1000
+ >>> # equivalent to a[0:6:2] = 1000;
+ >>> # from start to position 6, exclusive, set every 2nd element to 1000
>>> a[:6:2] = 1000
>>> a
array([1000, 1, 1000, 27, 1000, 125, 216, 343, 512, 729])
- >>> a[ : :-1] # reversed a
+ >>> a[::-1] # reversed a
array([ 729, 512, 343, 216, 125, 1000, 27, 1000, 1, 1000])
>>> for i in a:
- ... print(i**(1/3.))
+ ... print(i**(1 / 3.))
...
9.999999999999998
1.0
@@ -532,23 +531,23 @@ and other Python sequences.
**Multidimensional** arrays can have one index per axis. These indices
are given in a tuple separated by commas::
- >>> def f(x,y):
- ... return 10*x+y
+ >>> def f(x, y):
+ ... return 10 * x + y
...
- >>> b = np.fromfunction(f,(5,4),dtype=int)
+ >>> b = np.fromfunction(f, (5, 4), dtype=int)
>>> b
array([[ 0, 1, 2, 3],
[10, 11, 12, 13],
[20, 21, 22, 23],
[30, 31, 32, 33],
[40, 41, 42, 43]])
- >>> b[2,3]
+ >>> b[2, 3]
23
- >>> b[0:5, 1] # each row in the second column of b
+ >>> b[0:5, 1] # each row in the second column of b
array([ 1, 11, 21, 31, 41])
- >>> b[ : ,1] # equivalent to the previous example
+ >>> b[:, 1] # equivalent to the previous example
array([ 1, 11, 21, 31, 41])
- >>> b[1:3, : ] # each column in the second and third row of b
+ >>> b[1:3, :] # each column in the second and third row of b
array([[10, 11, 12, 13],
[20, 21, 22, 23]])
@@ -557,34 +556,34 @@ indices are considered complete slices\ ``:``
::
- >>> b[-1] # the last row. Equivalent to b[-1,:]
+ >>> b[-1] # the last row. Equivalent to b[-1, :]
array([40, 41, 42, 43])
The expression within brackets in ``b[i]`` is treated as an ``i``
followed by as many instances of ``:`` as needed to represent the
remaining axes. NumPy also allows you to write this using dots as
-``b[i,...]``.
+``b[i, ...]``.
The **dots** (``...``) represent as many colons as needed to produce a
complete indexing tuple. For example, if ``x`` is an array with 5
axes, then
-- ``x[1,2,...]`` is equivalent to ``x[1,2,:,:,:]``,
-- ``x[...,3]`` to ``x[:,:,:,:,3]`` and
-- ``x[4,...,5,:]`` to ``x[4,:,:,5,:]``.
+- ``x[1, 2, ...]`` is equivalent to ``x[1, 2, :, :, :]``,
+- ``x[..., 3]`` to ``x[:, :, :, :, 3]`` and
+- ``x[4, ..., 5, :]`` to ``x[4, :, :, 5, :]``.
::
- >>> c = np.array( [[[ 0, 1, 2], # a 3D array (two stacked 2D arrays)
- ... [ 10, 12, 13]],
- ... [[100,101,102],
- ... [110,112,113]]])
+ >>> c = np.array([[[ 0, 1, 2], # a 3D array (two stacked 2D arrays)
+ ... [ 10, 12, 13]],
+ ... [[100, 101, 102],
+ ... [110, 112, 113]]])
>>> c.shape
(2, 2, 3)
- >>> c[1,...] # same as c[1,:,:] or c[1]
+ >>> c[1, ...] # same as c[1, :, :] or c[1]
array([[100, 101, 102],
[110, 112, 113]])
- >>> c[...,2] # same as c[:,:,2]
+ >>> c[..., 2] # same as c[:, :, 2]
array([[ 2, 13],
[102, 113]])
@@ -647,7 +646,7 @@ Changing the shape of an array
An array has a shape given by the number of elements along each axis::
- >>> a = np.floor(10*rg.random((3,4)))
+ >>> a = np.floor(10 * rg.random((3, 4)))
>>> a
array([[3., 7., 3., 4.],
[1., 4., 2., 2.],
@@ -661,7 +660,7 @@ the original array::
>>> a.ravel() # returns the array, flattened
array([3., 7., 3., 4., 1., 4., 2., 2., 7., 2., 4., 9.])
- >>> a.reshape(6,2) # returns the array with a modified shape
+ >>> a.reshape(6, 2) # returns the array with a modified shape
array([[3., 7.],
[3., 4.],
[1., 4.],
@@ -678,14 +677,14 @@ the original array::
>>> a.shape
(3, 4)
-The order of the elements in the array resulting from ravel() is
+The order of the elements in the array resulting from ``ravel`` is
normally "C-style", that is, the rightmost index "changes the fastest",
-so the element after a[0,0] is a[0,1]. If the array is reshaped to some
+so the element after ``a[0, 0]`` is ``a[0, 1]``. If the array is reshaped to some
other shape, again the array is treated as "C-style". NumPy normally
-creates arrays stored in this order, so ravel() will usually not need to
+creates arrays stored in this order, so ``ravel`` will usually not need to
copy its argument, but if the array was made by taking slices of another
array or created with unusual options, it may need to be copied. The
-functions ravel() and reshape() can also be instructed, using an
+functions ``ravel`` and ``reshape`` can also be instructed, using an
optional argument, to use FORTRAN-style arrays, in which the leftmost
index changes the fastest.
@@ -698,15 +697,15 @@ itself::
array([[3., 7., 3., 4.],
[1., 4., 2., 2.],
[7., 2., 4., 9.]])
- >>> a.resize((2,6))
+ >>> a.resize((2, 6))
>>> a
array([[3., 7., 3., 4., 1., 4.],
[2., 2., 7., 2., 4., 9.]])
-If a dimension is given as -1 in a reshaping operation, the other
+If a dimension is given as ``-1`` in a reshaping operation, the other
dimensions are automatically calculated::
- >>> a.reshape(3,-1)
+ >>> a.reshape(3, -1)
array([[3., 7., 3., 4.],
[1., 4., 2., 2.],
[7., 2., 4., 9.]])
@@ -726,45 +725,44 @@ Stacking together different arrays
Several arrays can be stacked together along different axes::
- >>> a = np.floor(10*rg.random((2,2)))
+ >>> a = np.floor(10 * rg.random((2, 2)))
>>> a
array([[9., 7.],
[5., 2.]])
- >>> b = np.floor(10*rg.random((2,2)))
+ >>> b = np.floor(10 * rg.random((2, 2)))
>>> b
array([[1., 9.],
[5., 1.]])
- >>> np.vstack((a,b))
+ >>> np.vstack((a, b))
array([[9., 7.],
[5., 2.],
[1., 9.],
[5., 1.]])
- >>> np.hstack((a,b))
+ >>> np.hstack((a, b))
array([[9., 7., 1., 9.],
[5., 2., 5., 1.]])
-The function `column_stack`
-stacks 1D arrays as columns into a 2D array. It is equivalent to
-`hstack` only for 2D arrays::
+The function `column_stack` stacks 1D arrays as columns into a 2D array.
+It is equivalent to `hstack` only for 2D arrays::
>>> from numpy import newaxis
- >>> np.column_stack((a,b)) # with 2D arrays
+ >>> np.column_stack((a, b)) # with 2D arrays
array([[9., 7., 1., 9.],
[5., 2., 5., 1.]])
- >>> a = np.array([4.,2.])
- >>> b = np.array([3.,8.])
- >>> np.column_stack((a,b)) # returns a 2D array
+ >>> a = np.array([4., 2.])
+ >>> b = np.array([3., 8.])
+ >>> np.column_stack((a, b)) # returns a 2D array
array([[4., 3.],
[2., 8.]])
- >>> np.hstack((a,b)) # the result is different
+ >>> np.hstack((a, b)) # the result is different
array([4., 2., 3., 8.])
- >>> a[:,newaxis] # view `a` as a 2D column vector
+ >>> a[:, newaxis] # view `a` as a 2D column vector
array([[4.],
[2.]])
- >>> np.column_stack((a[:,newaxis],b[:,newaxis]))
+ >>> np.column_stack((a[:, newaxis], b[:, newaxis]))
array([[4., 3.],
[2., 8.]])
- >>> np.hstack((a[:,newaxis],b[:,newaxis])) # the result is the same
+ >>> np.hstack((a[:, newaxis], b[:, newaxis])) # the result is the same
array([[4., 3.],
[2., 8.]])
@@ -785,12 +783,10 @@ which the concatenation should happen.
**Note**
-In complex cases, `r_` and
-`c_` are useful for creating arrays
-by stacking numbers along one axis. They allow the use of range literals
-(":") ::
+In complex cases, `r_` and `c_` are useful for creating arrays by stacking
+numbers along one axis. They allow the use of range literals ``:``. ::
- >>> np.r_[1:4,0,4]
+ >>> np.r_[1:4, 0, 4]
array([1, 2, 3, 0, 4])
When used with arrays as arguments,
@@ -818,18 +814,18 @@ array along its horizontal axis, either by specifying the number of
equally shaped arrays to return, or by specifying the columns after
which the division should occur::
- >>> a = np.floor(10*rg.random((2,12)))
+ >>> a = np.floor(10 * rg.random((2, 12)))
>>> a
array([[6., 7., 6., 9., 0., 5., 4., 0., 6., 8., 5., 2.],
[8., 5., 5., 7., 1., 8., 6., 7., 1., 8., 1., 0.]])
- # Split a into 3
- >>> np.hsplit(a,3)
+ >>> # Split `a` into 3
+ >>> np.hsplit(a, 3)
[array([[6., 7., 6., 9.],
[8., 5., 5., 7.]]), array([[0., 5., 4., 0.],
[1., 8., 6., 7.]]), array([[6., 8., 5., 2.],
[1., 8., 1., 0.]])]
- # Split a after the third and the fourth column
- >>> np.hsplit(a,(3,4))
+ >>> # Split `a` after the third and the fourth column
+ >>> np.hsplit(a, (3, 4))
[array([[6., 7., 6.],
[8., 5., 5.]]), array([[9.],
[7.]]), array([[0., 5., 4., 0., 6., 8., 5., 2.],
@@ -871,7 +867,7 @@ copy.
>>> def f(x):
... print(id(x))
...
- >>> id(a) # id is a unique identifier of an object
+ >>> id(a) # id is a unique identifier of an object
148293216 # may vary
>>> f(a)
148293216 # may vary
@@ -887,15 +883,15 @@ creates a new array object that looks at the same data.
>>> c = a.view()
>>> c is a
False
- >>> c.base is a # c is a view of the data owned by a
+ >>> c.base is a # c is a view of the data owned by a
True
>>> c.flags.owndata
False
>>>
- >>> c = c.reshape((2, 6)) # a's shape doesn't change
+ >>> c = c.reshape((2, 6)) # a's shape doesn't change
>>> a.shape
(3, 4)
- >>> c[0, 4] = 1234 # a's data changes
+ >>> c[0, 4] = 1234 # a's data changes
>>> a
array([[ 0, 1, 2, 3],
[1234, 5, 6, 7],
@@ -903,8 +899,8 @@ creates a new array object that looks at the same data.
Slicing an array returns a view of it::
- >>> s = a[ : , 1:3] # spaces added for clarity; could also be written "s = a[:, 1:3]"
- >>> s[:] = 10 # s[:] is a view of s. Note the difference between s = 10 and s[:] = 10
+ >>> s = a[:, 1:3]
+ >>> s[:] = 10 # s[:] is a view of s. Note the difference between s = 10 and s[:] = 10
>>> a
array([[ 0, 10, 10, 3],
[1234, 10, 10, 7],
@@ -917,12 +913,12 @@ The ``copy`` method makes a complete copy of the array and its data.
::
- >>> d = a.copy() # a new array object with new data is created
+ >>> d = a.copy() # a new array object with new data is created
>>> d is a
False
- >>> d.base is a # d doesn't share anything with a
+ >>> d.base is a # d doesn't share anything with a
False
- >>> d[0,0] = 9999
+ >>> d[0, 0] = 9999
>>> a
array([[ 0, 10, 10, 3],
[1234, 10, 10, 7],
@@ -1068,13 +1064,13 @@ Indexing with Arrays of Indices
::
- >>> a = np.arange(12)**2 # the first 12 square numbers
- >>> i = np.array([1, 1, 3, 8, 5]) # an array of indices
- >>> a[i] # the elements of a at the positions i
+ >>> a = np.arange(12)**2 # the first 12 square numbers
+ >>> i = np.array([1, 1, 3, 8, 5]) # an array of indices
+ >>> a[i] # the elements of `a` at the positions `i`
array([ 1, 1, 9, 64, 25])
- >>>
- >>> j = np.array([[3, 4], [9, 7]]) # a bidimensional array of indices
- >>> a[j] # the same shape as j
+ >>>
+ >>> j = np.array([[3, 4], [9, 7]]) # a bidimensional array of indices
+ >>> a[j] # the same shape as `j`
array([[ 9, 16],
[81, 49]])
@@ -1090,9 +1086,9 @@ using a palette.
... [0, 255, 0], # green
... [0, 0, 255], # blue
... [255, 255, 255]]) # white
- >>> image = np.array([[0, 1, 2, 0], # each value corresponds to a color in the palette
+ >>> image = np.array([[0, 1, 2, 0], # each value corresponds to a color in the palette
... [0, 3, 4, 0]])
- >>> palette[image] # the (2, 4, 3) color image
+ >>> palette[image] # the (2, 4, 3) color image
array([[[ 0, 0, 0],
[255, 0, 0],
[ 0, 255, 0],
@@ -1108,25 +1104,25 @@ indices for each dimension must have the same shape.
::
- >>> a = np.arange(12).reshape(3,4)
+ >>> a = np.arange(12).reshape(3, 4)
>>> a
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
- >>> i = np.array([[0, 1], # indices for the first dim of a
+ >>> i = np.array([[0, 1], # indices for the first dim of `a`
... [1, 2]])
- >>> j = np.array([[2, 1], # indices for the second dim
+ >>> j = np.array([[2, 1], # indices for the second dim
... [3, 3]])
- >>>
- >>> a[i, j] # i and j must have equal shape
+ >>>
+ >>> a[i, j] # i and j must have equal shape
array([[ 2, 5],
[ 7, 11]])
- >>>
+ >>>
>>> a[i, 2]
array([[ 2, 6],
[ 6, 10]])
- >>>
- >>> a[:, j] # i.e., a[ : , j]
+ >>>
+ >>> a[:, j]
array([[[ 2, 1],
[ 3, 3]],
<BLANKLINE>
@@ -1142,26 +1138,24 @@ put ``i`` and ``j`` in a ``tuple`` and then do the indexing with that.
::
>>> l = (i, j)
- # equivalent to a[i, j]
+ >>> # equivalent to a[i, j]
>>> a[l]
array([[ 2, 5],
[ 7, 11]])
However, we can not do this by putting ``i`` and ``j`` into an array,
because this array will be interpreted as indexing the first dimension
-of a.
+of ``a``.
::
>>> s = np.array([i, j])
-
- # not what we want
+ >>> # not what we want
>>> a[s]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: index 3 is out of bounds for axis 0 with size 3
-
- # same as a[i, j]
+ >>> # same as `a[i, j]`
>>> a[tuple(s)]
array([[ 2, 5],
[ 7, 11]])
@@ -1169,8 +1163,8 @@ of a.
Another common use of indexing with arrays is the search of the maximum
value of time-dependent series::
- >>> time = np.linspace(20, 145, 5) # time scale
- >>> data = np.sin(np.arange(20)).reshape(5,4) # 4 time-dependent series
+ >>> time = np.linspace(20, 145, 5) # time scale
+ >>> data = np.sin(np.arange(20)).reshape(5, 4) # 4 time-dependent series
>>> time
array([ 20. , 51.25, 82.5 , 113.75, 145. ])
>>> data
@@ -1179,22 +1173,18 @@ value of time-dependent series::
[ 0.98935825, 0.41211849, -0.54402111, -0.99999021],
[-0.53657292, 0.42016704, 0.99060736, 0.65028784],
[-0.28790332, -0.96139749, -0.75098725, 0.14987721]])
-
- # index of the maxima for each series
+ >>> # index of the maxima for each series
>>> ind = data.argmax(axis=0)
>>> ind
array([2, 0, 3, 1])
-
- # times corresponding to the maxima
+ >>> # times corresponding to the maxima
>>> time_max = time[ind]
- >>>
- >>> data_max = data[ind, range(data.shape[1])] # => data[ind[0],0], data[ind[1],1]...
-
+ >>>
+ >>> data_max = data[ind, range(data.shape[1])] # => data[ind[0], 0], data[ind[1], 1]...
>>> time_max
array([ 82.5 , 20. , 113.75, 51.25])
>>> data_max
array([0.98935825, 0.84147098, 0.99060736, 0.6569866 ])
-
>>> np.all(data_max == data.max(axis=0))
True
@@ -1203,7 +1193,7 @@ You can also use indexing with arrays as a target to assign to::
>>> a = np.arange(5)
>>> a
array([0, 1, 2, 3, 4])
- >>> a[[1,3,4]] = 0
+ >>> a[[1, 3, 4]] = 0
>>> a
array([0, 0, 2, 0, 0])
@@ -1211,7 +1201,7 @@ However, when the list of indices contains repetitions, the assignment
is done several times, leaving behind the last value::
>>> a = np.arange(5)
- >>> a[[0,0,2]]=[1,2,3]
+ >>> a[[0, 0, 2]] = [1, 2, 3]
>>> a
array([2, 1, 3, 3, 4])
@@ -1219,13 +1209,13 @@ This is reasonable enough, but watch out if you want to use Python's
``+=`` construct, as it may not do what you expect::
>>> a = np.arange(5)
- >>> a[[0,0,2]]+=1
+ >>> a[[0, 0, 2]] += 1
>>> a
array([1, 1, 3, 3, 4])
Even though 0 occurs twice in the list of indices, the 0th element is
-only incremented once. This is because Python requires "a+=1" to be
-equivalent to "a = a + 1".
+only incremented once. This is because Python requires ``a += 1`` to be
+equivalent to ``a = a + 1``.
Indexing with Boolean Arrays
----------------------------
@@ -1238,18 +1228,18 @@ which ones we don't.
The most natural way one can think of for boolean indexing is to use
boolean arrays that have *the same shape* as the original array::
- >>> a = np.arange(12).reshape(3,4)
+ >>> a = np.arange(12).reshape(3, 4)
>>> b = a > 4
- >>> b # b is a boolean with a's shape
+ >>> b # `b` is a boolean with `a`'s shape
array([[False, False, False, False],
[False, True, True, True],
[ True, True, True, True]])
- >>> a[b] # 1d array with the selected elements
+ >>> a[b] # 1d array with the selected elements
array([ 5, 6, 7, 8, 9, 10, 11])
This property can be very useful in assignments::
- >>> a[b] = 0 # All elements of 'a' higher than 4 become 0
+ >>> a[b] = 0 # All elements of `a` higher than 4 become 0
>>> a
array([[0, 1, 2, 3],
[4, 0, 0, 0],
@@ -1264,45 +1254,47 @@ set <https://en.wikipedia.org/wiki/Mandelbrot_set>`__:
>>> import numpy as np
>>> import matplotlib.pyplot as plt
- >>> def mandelbrot( h,w, maxit=20 ):
+ >>> def mandelbrot(h, w, maxit=20, r=2):
... """Returns an image of the Mandelbrot fractal of size (h,w)."""
- ... y,x = np.ogrid[ -1.4:1.4:h*1j, -2:0.8:w*1j ]
- ... c = x+y*1j
- ... z = c
+ ... x = np.linspace(-2.5, 1.5, 4*h+1)
+ ... y = np.linspace(-1.5, 1.5, 3*w+1)
+ ... A, B = np.meshgrid(x, y)
+ ... C = A + B*1j
+ ... z = np.zeros_like(C)
... divtime = maxit + np.zeros(z.shape, dtype=int)
...
... for i in range(maxit):
- ... z = z**2 + c
- ... diverge = z*np.conj(z) > 2**2 # who is diverging
- ... div_now = diverge & (divtime==maxit) # who is diverging now
- ... divtime[div_now] = i # note when
- ... z[diverge] = 2 # avoid diverging too much
+ ... z = z**2 + C
+ ... diverge = abs(z) > r # who is diverging
+ ... div_now = diverge & (divtime == maxit) # who is diverging now
+ ... divtime[div_now] = i # note when
+ ... z[diverge] = r # avoid diverging too much
...
... return divtime
- >>> plt.imshow(mandelbrot(400,400))
+ >>> plt.imshow(mandelbrot(400, 400))
The second way of indexing with booleans is more similar to integer
indexing; for each dimension of the array we give a 1D boolean array
selecting the slices we want::
- >>> a = np.arange(12).reshape(3,4)
- >>> b1 = np.array([False,True,True]) # first dim selection
- >>> b2 = np.array([True,False,True,False]) # second dim selection
- >>>
- >>> a[b1,:] # selecting rows
+ >>> a = np.arange(12).reshape(3, 4)
+ >>> b1 = np.array([False, True, True]) # first dim selection
+ >>> b2 = np.array([True, False, True, False]) # second dim selection
+ >>>
+ >>> a[b1, :] # selecting rows
array([[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
- >>>
- >>> a[b1] # same thing
+ >>>
+ >>> a[b1] # same thing
array([[ 4, 5, 6, 7],
[ 8, 9, 10, 11]])
- >>>
- >>> a[:,b2] # selecting columns
+ >>>
+ >>> a[:, b2] # selecting columns
array([[ 0, 2],
[ 4, 6],
[ 8, 10]])
- >>>
- >>> a[b1,b2] # a weird thing to do
+ >>>
+ >>> a[b1, b2] # a weird thing to do
array([ 4, 10])
Note that the length of the 1D boolean array must coincide with the
@@ -1319,10 +1311,10 @@ obtain the result for each n-uplet. For example, if you want to compute
all the a+b\*c for all the triplets taken from each of the vectors a, b
and c::
- >>> a = np.array([2,3,4,5])
- >>> b = np.array([8,5,4])
- >>> c = np.array([5,4,6,8,3])
- >>> ax,bx,cx = np.ix_(a,b,c)
+ >>> a = np.array([2, 3, 4, 5])
+ >>> b = np.array([8, 5, 4])
+ >>> c = np.array([5, 4, 6, 8, 3])
+ >>> ax, bx, cx = np.ix_(a, b, c)
>>> ax
array([[[2]],
<BLANKLINE>
@@ -1339,7 +1331,7 @@ and c::
array([[[5, 4, 6, 8, 3]]])
>>> ax.shape, bx.shape, cx.shape
((4, 1, 1), (1, 3, 1), (1, 1, 5))
- >>> result = ax+bx*cx
+ >>> result = ax + bx * cx
>>> result
array([[[42, 34, 50, 66, 26],
[27, 22, 32, 42, 17],
@@ -1356,9 +1348,9 @@ and c::
[[45, 37, 53, 69, 29],
[30, 25, 35, 45, 20],
[25, 21, 29, 37, 17]]])
- >>> result[3,2,4]
+ >>> result[3, 2, 4]
17
- >>> a[3]+b[2]*c[4]
+ >>> a[3] + b[2] * c[4]
17
You could also implement the reduce as follows::
@@ -1367,12 +1359,12 @@ You could also implement the reduce as follows::
... vs = np.ix_(*vectors)
... r = ufct.identity
... for v in vs:
- ... r = ufct(r,v)
+ ... r = ufct(r, v)
... return r
and then use it as::
- >>> ufunc_reduce(np.add,a,b,c)
+ >>> ufunc_reduce(np.add, a, b, c)
array([[[15, 14, 16, 18, 13],
[12, 11, 13, 15, 10],
[11, 10, 12, 14, 9]],
@@ -1400,64 +1392,6 @@ Indexing with strings
See :ref:`structured_arrays`.
-Linear Algebra
-==============
-
-Work in progress. Basic linear algebra to be included here.
-
-Simple Array Operations
------------------------
-
-See linalg.py in numpy folder for more.
-
-::
-
- >>> import numpy as np
- >>> a = np.array([[1.0, 2.0], [3.0, 4.0]])
- >>> print(a)
- [[1. 2.]
- [3. 4.]]
-
- >>> a.transpose()
- array([[1., 3.],
- [2., 4.]])
-
- >>> np.linalg.inv(a)
- array([[-2. , 1. ],
- [ 1.5, -0.5]])
-
- >>> u = np.eye(2) # unit 2x2 matrix; "eye" represents "I"
- >>> u
- array([[1., 0.],
- [0., 1.]])
- >>> j = np.array([[0.0, -1.0], [1.0, 0.0]])
-
- >>> j @ j # matrix product
- array([[-1., 0.],
- [ 0., -1.]])
-
- >>> np.trace(u) # trace
- 2.0
-
- >>> y = np.array([[5.], [7.]])
- >>> np.linalg.solve(a, y)
- array([[-3.],
- [ 4.]])
-
- >>> np.linalg.eig(j)
- (array([0.+1.j, 0.-1.j]), array([[0.70710678+0.j , 0.70710678-0.j ],
- [0. -0.70710678j, 0. +0.70710678j]]))
-
-::
-
- Parameters:
- square matrix
- Returns
- The eigenvalues, each repeated according to its multiplicity.
- The normalized (unit "length") eigenvectors, such that the
- column ``v[:,i]`` is the eigenvector corresponding to the
- eigenvalue ``w[i]`` .
-
Tricks and Tips
===============
@@ -1496,13 +1430,13 @@ functions ``column_stack``, ``dstack``, ``hstack`` and ``vstack``,
depending on the dimension in which the stacking is to be done. For
example::
- >>> x = np.arange(0,10,2)
+ >>> x = np.arange(0, 10, 2)
>>> y = np.arange(5)
- >>> m = np.vstack([x,y])
+ >>> m = np.vstack([x, y])
>>> m
array([[0, 2, 4, 6, 8],
[0, 1, 2, 3, 4]])
- >>> xy = np.hstack([x,y])
+ >>> xy = np.hstack([x, y])
>>> xy
array([0, 2, 4, 6, 8, 0, 1, 2, 3, 4])
@@ -1530,12 +1464,14 @@ that ``pylab.hist`` plots the histogram automatically, while
>>> import matplotlib.pyplot as plt
>>> # Build a vector of 10000 normal deviates with variance 0.5^2 and mean 2
>>> mu, sigma = 2, 0.5
- >>> v = rg.normal(mu,sigma,10000)
+ >>> v = rg.normal(mu, sigma, 10000)
>>> # Plot a normalized histogram with 50 bins
- >>> plt.hist(v, bins=50, density=1) # matplotlib version (plot)
+ >>> plt.hist(v, bins=50, density=True) # matplotlib version (plot)
>>> # Compute the histogram with numpy and then plot it
>>> (n, bins) = np.histogram(v, bins=50, density=True) # NumPy version (no plot)
- >>> plt.plot(.5*(bins[1:]+bins[:-1]), n)
+ >>> plt.plot(.5 * (bins[1:] + bins[:-1]), n)
+
+With Matplotlib >=3.4 you can also use ``plt.stairs(n, bins)``.
Further reading
@@ -1546,3 +1482,4 @@ Further reading
- `SciPy Tutorial <https://docs.scipy.org/doc/scipy/reference/tutorial/index.html>`__
- `SciPy Lecture Notes <https://scipy-lectures.org>`__
- A `matlab, R, IDL, NumPy/SciPy dictionary <http://mathesaurus.sf.net/>`__
+- :doc:`tutorial-svd <content/tutorial-svd>`
diff --git a/doc/source/user/theory.broadcast_1.gif b/doc/source/user/theory.broadcast_1.gif
deleted file mode 100644
index 541ec734b..000000000
--- a/doc/source/user/theory.broadcast_1.gif
+++ /dev/null
Binary files differ
diff --git a/doc/source/user/theory.broadcast_2.gif b/doc/source/user/theory.broadcast_2.gif
deleted file mode 100644
index 163a8473f..000000000
--- a/doc/source/user/theory.broadcast_2.gif
+++ /dev/null
Binary files differ
diff --git a/doc/source/user/theory.broadcast_3.gif b/doc/source/user/theory.broadcast_3.gif
deleted file mode 100644
index 83f61f2df..000000000
--- a/doc/source/user/theory.broadcast_3.gif
+++ /dev/null
Binary files differ
diff --git a/doc/source/user/theory.broadcast_4.gif b/doc/source/user/theory.broadcast_4.gif
deleted file mode 100644
index 9b21ff582..000000000
--- a/doc/source/user/theory.broadcast_4.gif
+++ /dev/null
Binary files differ
diff --git a/doc/source/user/theory.broadcast_5.png b/doc/source/user/theory.broadcast_5.png
deleted file mode 100644
index 3aa2f0536..000000000
--- a/doc/source/user/theory.broadcast_5.png
+++ /dev/null
Binary files differ
diff --git a/doc/source/user/theory.broadcasting.rst b/doc/source/user/theory.broadcasting.rst
index b37edeacc..a4973e4e6 100644
--- a/doc/source/user/theory.broadcasting.rst
+++ b/doc/source/user/theory.broadcasting.rst
@@ -1,7 +1,5 @@
:orphan:
-.. _array-broadcasting-in-numpy:
-
===========================
Array Broadcasting in Numpy
===========================
@@ -12,218 +10,6 @@ Array Broadcasting in Numpy
`github repo
<https://github.com/scipy/old-wiki/blob/gh-pages/pages/EricsBroadcastingDoc.html>`_
-Let's explore a more advanced concept in numpy called broadcasting. The
-term broadcasting describes how numpy treats arrays with different shapes
-during arithmetic operations. Subject to certain constraints, the smaller array
-is "broadcast" across the larger array so that they have compatible shapes.
-Broadcasting provides a means of vectorizing array operations so that looping
-occurs in C instead of Python. It does this without making needless copies of
-data and usually leads to efficient algorithm implementations. There are also
-cases where broadcasting is a bad idea because it leads to inefficient use of
-memory that slows computation. This article provides a gentle introduction to
-broadcasting with numerous examples ranging from simple to involved. It also
-provides hints on when and when not to use broadcasting.
-
-numpy operations are usually done element-by-element which requires two arrays
-to have exactly the same shape:
-
-.. code-block:: python
- :caption: Example 1
- :name: example-1
-
- >>> from numpy import array
- >>> a = array([1.0, 2.0, 3.0])
- >>> b = array([2.0, 2.0, 2.0])
- >>> a * b
- array([ 2., 4., 6.])
-
-numpy's broadcasting rule relaxes this constraint when the arrays' shapes meet
-certain constraints. The simplest broadcasting example occurs when an array and
-a scalar value are combined in an operation:
-
-.. code-block:: python
- :caption: Example 2
- :name: example-2
-
- >>> from numpy import array
- >>> a = array([1.0,2.0,3.0])
- >>> b = 2.0
- >>> a * b
- array([ 2., 4., 6.])
-
-The result is equivalent to the previous example where ``b`` was an array. We
-can think of the scalar ``b`` being stretched during the arithmetic operation
-into an array with the same shape as ``a``. The new elements in ``b``, as shown
-in :ref:`figure-1`, are simply copies of the original scalar. The stretching
-analogy is only conceptual. numpy is smart enough to use the original scalar
-value without actually making copies so that broadcasting operations are as
-memory and computationally efficient as possible. Because :ref:`example-2`
-moves less memory, (``b`` is a scalar, not an array) around during the
-multiplication, it is about 10% faster than :ref:`example-1` using the standard
-numpy on Windows 2000 with one million element arrays.
-
-.. figure:: theory.broadcast_1.gif
- :alt: Vector-Scalar multiplication
- :name: figure-1
-
- *Figure 1*
-
- *In the simplest example of broadcasting, the scalar ``b`` is
- stretched to become an array of with the same shape as ``a`` so the shapes
- are compatible for element-by-element multiplication.*
-
-
-The rule governing whether two arrays have compatible shapes for broadcasting
-can be expressed in a single sentence.
-
-.. admonition:: The Broadcasting Rule
-
- **In order to broadcast, the size of the trailing axes for both arrays in
- an operation must either be the same size or one of them must be one.**
-
-If this condition is not met, a ``ValueError('frames are not aligned')``
-exception is thrown indicating that the arrays have incompatible shapes. The
-size of the result array created by broadcast operations is the maximum size
-along each dimension from the input arrays. Note that the rule does not say
-anything about the two arrays needing to have the same number of dimensions.
-So, for example, if you have a 256 x 256 x 3 array of RGB values, and you want
-to scale each color in the image by a different value, you can multiply the
-image by a one-dimensional array with 3 values. Lining up the sizes of the
-trailing axes of these arrays according to the broadcast rule shows that they
-are compatible
-
-+-------+------------+-------+-------+---+
-|Image | (3d array) | 256 x | 256 x | 3 |
-+-------+------------+-------+-------+---+
-|Scale | (1d array) | | | 3 |
-+-------+------------+-------+-------+---+
-|Result | (3d array) | 256 x | 256 x | 3 |
-+-------+------------+-------+-------+---+
-
-In the following example, both the ``A`` and ``B`` arrays have axes with length
-one that are expanded to a larger size in a broadcast operation.
-
-+-------+------------+-----+-----+-----+---+
-|A | (4d array) | 8 x | 1 x | 6 x | 1 |
-+-------+------------+-----+-----+-----+---+
-|B | (3d array) | | 7 x | 1 x | 5 |
-+-------+------------+-----+-----+-----+---+
-|Result | (4d array) | 8 x | 7 x | 6 x | 5 |
-+-------+------------+-----+-----+-----+---+
-
-Below, are several code examples and graphical representations that help make
-the broadcast rule visually obvious. :ref:`example-3` adds a one-dimensional array
-to a two-dimensional array:
-
-.. code-block:: python
- :caption: Example 3
- :name: example-3
-
- >>> from numpy import array
- >>> a = array([[ 0.0, 0.0, 0.0],
- ... [10.0, 10.0, 10.0],
- ... [20.0, 20.0, 20.0],
- ... [30.0, 30.0, 30.0]])
- >>> b = array([1.0, 2.0, 3.0])
- >>> a + b
- array([[ 1., 2., 3.],
- [ 11., 12., 13.],
- [ 21., 22., 23.],
- [ 31., 32., 33.]])
-
-As shown in :ref:`figure-2`, ``b`` is added to each row of ``a``. When ``b`` is
-longer than the rows of ``a``, as in :ref:`figure-3`, an exception is raised
-because of the incompatible shapes.
-
-.. figure:: theory.broadcast_2.gif
- :alt: Matrix-Vector
- :name: figure-2
-
- *Figure 2*
-
- *A two dimensional array multiplied by a one dimensional array results in
- broadcasting if number of 1-d array elements matches the number of 2-d
- array columns.*
-
-.. figure:: theory.broadcast_3.gif
- :alt: Matrix-Vector-with-error
- :name: figure-3
-
- *Figure 3*
-
- *When the trailing dimensions of the arrays are unequal, broadcasting fails
- because it is impossible to align the values in the rows of the 1st array
- with the elements of the 2nd arrays for element-by-element addition.*
-
-Broadcasting provides a convenient way of taking the outer product (or any
-other outer operation) of two arrays. The following example shows an outer
-addition operation of two 1-d arrays that produces the same result as
-:ref:`example-3`
-
-.. code-block:: python
- :caption: Example 4
- :name: example-4
-
- >>> from numpy import array, newaxis
- >>> a = array([0.0, 10.0, 20.0, 30.0])
- >>> b = array([1.0, 2.0, 3.0])
- >>> a[:,newaxis] + b
- array([[ 1., 2., 3.],
- [ 11., 12., 13.],
- [ 21., 22., 23.],
- [ 31., 32., 33.]])
-
-Here the newaxis index operator inserts a new axis into ``a``, making it a
-two-dimensional 4x1 array. :ref:`figure-4` illustrates the stretching of both
-arrays to produce the desired 4x3 output array.
-
-.. figure:: theory.broadcast_4.gif
- :alt: vector-vector with newaxis
- :name: figure-4
-
- *Figure 4*
-
- In some cases, broadcasting stretches both arrays to form an output array
- larger than either of the initial arrays.*
-
-A Practical Example: Vector Quantization.
-=========================================
-
-Broadcasting comes up quite often in real world problems. A typical example
-occurs in the vector quantization (VQ) algorithm used in information theory,
-classification, and other related areas. The basic operation in VQ [#f0] finds
-the closest point in a set of points, called codes in VQ jargon, to a given
-point, called the observation. In the very simple, two-dimensional case shown
-in :ref:`figure-5`, the values in observation describe the weight and height of an
-athlete to be classified. The codes represent different classes of
-athletes. [#f1]_ Finding the closest point requires calculating the distance
-between observation and each of the codes. The shortest distance provides the
-best match. In this example, ``codes[0]`` is the closest class indicating that
-the athlete is likely a basketball player.
-
-.. figure:: theory.broadcast_5.png
- :alt: vector quantitization example
- :name: figure-5
-
- *Figure 5*
-
- *The basic operation of vector quantization calculates the distance between
- an object to be classified, the dark square, and multiple known codes, the
- gray circles. In this simple case, the codes represent individual classes.
- More complex cases use multiple codes per class.*
-
-
-.. rubric:: Footnotes
-
-.. [#f0] Vector Quantization J. Makhoul, S. Roucos, and H. Gish, "Vector Quantization in Speech Coding," Proc. IEEE, vol. 73, pp. 1551-1587, Nov. 1985.
-.. [#f1]
- In this example, weight has more impact on the distance calculation
- than height because of the larger values. In practice, it is important to
- normalize the height and weight, often by their standard deviation across the
- data set, so that both have equal influence on the distance calculation.
-
.. note::
-
- The code to produce the figures is part of the `AstroML book
- <http://www.astroml.org/book_figures/appendix/fig_broadcast_visual.html>`_
+ Please refer to the updated :doc:`basics.broadcasting` document.
diff --git a/doc/source/user/tutorial-ma.rst b/doc/source/user/tutorial-ma.rst
deleted file mode 100644
index 88bad3cbe..000000000
--- a/doc/source/user/tutorial-ma.rst
+++ /dev/null
@@ -1,386 +0,0 @@
-=======================
-Tutorial: Masked Arrays
-=======================
-
-.. currentmodule:: numpy
-
-.. testsetup::
-
- import numpy as np
- np.random.seed(1)
-
-Prerequisites
--------------
-
-Before reading this tutorial, you should know a bit of Python. If you
-would like to refresh your memory, take a look at the
-:doc:`Python tutorial <python:tutorial/index>`.
-
-If you want to be able to run the examples in this tutorial, you should also
-have `matplotlib <https://matplotlib.org/>`_ installed on your computer.
-
-Learner profile
----------------
-
-This tutorial is for people who have a basic understanding of NumPy and want to
-understand how masked arrays and the :mod:`numpy.ma` module can be used in
-practice.
-
-Learning Objectives
--------------------
-
-After this tutorial, you should be able to:
-
-- Understand what are masked arrays and how they can be created
-- Understand how to access and modify data for masked arrays
-- Decide when the use of masked arrays is appropriate in some of your
- applications
-
-What are masked arrays?
------------------------
-
-Consider the following problem. You have a dataset with missing or invalid
-entries. If you're doing any kind of processing on this data, and want to
-`skip` or flag these unwanted entries without just deleting them, you may have
-to use conditionals or filter your data somehow. The :mod:`numpy.ma` module
-provides some of the same funcionality of
-:class:`NumPy ndarrays <numpy.ndarray>` with added structure to ensure
-invalid entries are not used in computation.
-
-From the :mod:`Reference Guide <numpy.ma>`:
-
- A masked array is the combination of a standard :class:`numpy.ndarray` and
- a **mask**. A mask is either ``nomask``, indicating that no value of the
- associated array is invalid, or an array of booleans that determines for
- each element of the associated array whether the value is valid or not.
- When an element of the mask is ``False``, the corresponding element of the
- associated array is valid and is said to be unmasked. When an element of
- the mask is ``True``, the corresponding element of the associated array is
- said to be masked (invalid).
-
-
-We can think of a :class:`MaskedArray <numpy.ma.MaskedArray>` as a
-combination of:
-
-- Data, as a regular :class:`numpy.ndarray` of any shape or datatype;
-- A boolean mask with the same shape as the data;
-- A ``fill_value``, a value that may be used to replace the invalid entries
- in order to return a standard :class:`numpy.ndarray`.
-
-When can they be useful?
-------------------------
-
-There are a few situations where masked arrays can be more useful than just
-eliminating the invalid entries of an array:
-
-- When you want to preserve the values you masked for later processing, without
- copying the array;
-- When you have to handle many arrays, each with their own mask. If the mask is
- part of the array, you avoid bugs and the code is possibly more compact;
-- When you have different flags for missing or invalid values, and wish to
- preserve these flags without replacing them in the original dataset, but
- exclude them from computations;
-- If you can't avoid or eliminate missing values, but don't want to deal with
- :class:`NaN <numpy.nan>` (Not A Number) values in your operations.
-
-Masked arrays are also a good idea since the :mod:`numpy.ma` module also
-comes with a specific implementation of most :term:`NumPy universal functions
-(ufuncs) <ufunc>`, which means that you can still apply fast vectorized
-functions and operations on masked data. The output is then a masked array.
-We'll see some examples of how this works in practice below.
-
-Using masked arrays to see COVID-19 data
-----------------------------------------
-
-From `Kaggle <https://www.kaggle.com/atilamadai/covid19>`_ it is possible to
-download a dataset with initial data about the COVID-19 outbreak in the
-beginning of 2020. We are going to look at a small subset of this data,
-contained in the file ``who_covid_19_sit_rep_time_series.csv``.
-
-.. ipython:: python
-
- import numpy as np
- import os
- # The os.getcwd() function returns the current folder; you can change
- # the filepath variable to point to the folder where you saved the .csv file
- filepath = os.getcwd()
- @suppress
- filepath = os.path.join(filepath, "source", "user")
- filename = os.path.join(filepath, "who_covid_19_sit_rep_time_series.csv")
-
-The data file contains data of different types and is organized as follows:
-
-- The first row is a header line that (mostly) describes the data in each column
- that follow in the rows below, and beginning in the fourth column, the header
- is the date of the observation.
-- The second through seventh row contain summary data that is of a different
- type than that which we are going to examine, so we will need to exclude that
- from the data with which we will work.
-- The numerical data we wish to work with begins at column 4, row 8, and extends
- from there to the rightmost column and the lowermost row.
-
-Let's explore the data inside this file for the first 14 days of records. To
-gather data from the ``.csv`` file, we will use the :func:`numpy.genfromtxt`
-function, making sure we select only the columns with actual numbers instead of
-the first three columns which contain location data. We also skip the first 7
-rows of this file, since they contain other data we are not interested in.
-Separately, we will extract the information about dates and location for this
-data.
-
-.. ipython:: python
-
- # Note we are using skip_header and usecols to read only portions of the
- # data file into each variable.
- # Read just the dates for columns 3-7 from the first row
- dates = np.genfromtxt(filename, dtype=np.unicode_, delimiter=",",
- max_rows=1, usecols=range(3, 17),
- encoding="utf-8-sig")
- # Read the names of the geographic locations from the first two
- # columns, skipping the first seven rows
- locations = np.genfromtxt(filename, dtype=np.unicode_, delimiter=",",
- skip_header=7, usecols=(0, 1),
- encoding="utf-8-sig")
- # Read the numeric data from just the first 14 days
- nbcases = np.genfromtxt(filename, dtype=np.int_, delimiter=",",
- skip_header=7, usecols=range(3, 17),
- encoding="utf-8-sig")
-
-Included in the :func:`numpy.genfromtxt` function call, we have selected the
-:class:`numpy.dtype` for each subset of the data (either an integer -
-:class:`numpy.int_` - or a string of characters - :class:`numpy.unicode_`). We
-have also used the ``encoding`` argument to select ``utf-8-sig`` as the encoding
-for the file (read more about encoding in the `official Python documentation
-<https://docs.python.org/3/library/codecs.html#encodings-and-unicode>`__). You
-can read more about the :func:`numpy.genfromtxt` function from
-the :func:`Reference Documentation <numpy.genfromtxt>` or from the
-:doc:`Basic IO tutorial <basics.io.genfromtxt>`.
-
-Exploring the data
-------------------
-
-First of all, we can plot the whole set of data we have and see what it looks
-like. In order to get a readable plot, we select only a few of the dates to
-show in our :func:`x-axis ticks <matplotlib.pyplot.xticks>`. Note also that in
-our plot command, we use ``nbcases.T`` (the transpose of the ``nbcases`` array)
-since this means we will plot each row of the file as a separate line. We choose
-to plot a dashed line (using the ``'--'`` line style). See the
-`matplotlib <https://matplotlib.org/>`_ documentation for more info on this.
-
-.. ipython:: python
-
- import matplotlib.pyplot as plt
- selected_dates = [0, 3, 11, 13]
- plt.plot(dates, nbcases.T, '--');
- plt.xticks(selected_dates, dates[selected_dates]);
- @savefig plot_covid_1.png
- plt.title("COVID-19 cumulative cases from Jan 21 to Feb 3 2020");
-
-.. note::
-
- If you are executing the commands above in the IPython shell, it might be
- necessary to use the command ``plt.show()`` to show the image window. Note
- also that we use a semicolon at the end of a line to suppress its output, but
- this is optional.
-
-The graph has a strange shape from January 24th to February 1st. It would be
-interesing to know where this data comes from. If we look at the ``locations``
-array we extracted from the ``.csv`` file, we can see that we have two columns,
-where the first would contain regions and the second would contain the name of
-the country. However, only the first few rows contain data for the the first
-column (province names in China). Following that, we only have country names. So
-it would make sense to group all the data from China into a single row. For
-this, we'll select from the ``nbcases`` array only the rows for which the
-second entry of the ``locations`` array corresponds to China. Next, we'll use
-the :func:`numpy.sum` function to sum all the selected rows (``axis=0``):
-
-.. ipython:: python
-
- china_total = nbcases[locations[:, 1] == 'China'].sum(axis=0)
- china_total
-
-Something's wrong with this data - we are not supposed to have negative values
-in a cumulative data set. What's going on?
-
-Missing data
-------------
-
-Looking at the data, here's what we find: there is a period with
-**missing data**:
-
-.. ipython:: python
-
- nbcases
-
-All the ``-1`` values we are seeing come from :func:`numpy.genfromtxt`
-attempting to read missing data from the original ``.csv`` file. Obviously, we
-don't want to compute missing data as ``-1`` - we just want to skip this value
-so it doesn't interfere in our analysis. After importing the :mod:`numpy.ma`
-module, we'll create a new array, this time masking the invalid values:
-
-.. ipython:: python
-
- from numpy import ma
- nbcases_ma = ma.masked_values(nbcases, -1)
-
-If we look at the ``nbcases_ma`` masked array, this is what we have:
-
-.. ipython:: python
-
- nbcases_ma
-
-We can see that this is a different kind of array. As mentioned in the
-introduction, it has three attributes (``data``, ``mask`` and ``fill_value``).
-Keep in mind that the ``mask`` attribute has a ``True`` value for elements
-corresponding to **invalid** data (represented by two dashes in the ``data``
-attribute).
-
-.. note::
-
- Adding ``-1`` to missing data is not a problem with :func:`numpy.genfromtxt`;
- in this particular case, substituting the missing value with ``0`` might have
- been fine, but we'll see later that this is far from a general solution.
- Also, it is possible to call the :func:`numpy.genfromtxt` function using the
- ``usemask`` parameter. If ``usemask=True``, :func:`numpy.genfromtxt`
- automatically returns a masked array.
-
-Let's try and see what the data looks like excluding the first row
-(data from the Hubei province in China) so we can look at the missing data more
-closely:
-
-.. ipython:: python
-
- plt.plot(dates, nbcases_ma[1:].T, '--');
- plt.xticks(selected_dates, dates[selected_dates]);
- @savefig plot_covid_2.png
- plt.title("COVID-19 cumulative cases from Jan 21 to Feb 3 2020");
-
-Now that our data has been masked, let's try summing up all the cases in China:
-
-.. ipython:: python
-
- china_masked = nbcases_ma[locations[:, 1] == 'China'].sum(axis=0)
- china_masked
-
-Note that ``china_masked`` is a masked array, so it has a different data
-structure than a regular NumPy array. Now, we can access its data directly by
-using the ``.data`` attribute:
-
-.. ipython:: python
-
- china_total = china_masked.data
- china_total
-
-That is better: no more negative values. However, we can still see that for some
-days, the cumulative number of cases seems to go down (from 835 to 10, for
-example), which does not agree with the definition of "cumulative data". If we
-look more closely at the data, we can see that in the period where there was
-missing data in mainland China, there was valid data for Hong Kong, Taiwan,
-Macau and "Unspecified" regions of China. Maybe we can remove those from the
-total sum of cases in China, to get a better understanding of the data.
-
-First, we'll identify the indices of locations in mainland China:
-
-.. ipython:: python
-
- china_mask = ((locations[:, 1] == 'China') &
- (locations[:, 0] != 'Hong Kong') &
- (locations[:, 0] != 'Taiwan') &
- (locations[:, 0] != 'Macau') &
- (locations[:, 0] != 'Unspecified*'))
-
-Now, ``china_mask`` is an array of boolean values (``True`` or ``False``); we
-can check that the indices are what we wanted with the :func:`ma.nonzero` method
-for masked arrays:
-
-.. ipython:: python
-
- china_mask.nonzero()
-
-Now we can correctly sum entries for mainland China:
-
-.. ipython:: python
-
- china_total = nbcases_ma[china_mask].sum(axis=0)
- china_total
-
-We can replace the data with this information and plot a new graph, focusing on
-Mainland China:
-
-.. ipython:: python
-
- plt.plot(dates, china_total.T, '--');
- plt.xticks(selected_dates, dates[selected_dates]);
- @savefig plot_covid_3.png
- plt.title("COVID-19 cumulative cases from Jan 21 to Feb 3 2020 - Mainland China");
-
-It's clear that masked arrays are the right solution here. We cannot represent
-the missing data without mischaracterizing the evolution of the curve.
-
-Fitting Data
-------------
-
-One possibility we can think of is to interpolate the missing data to estimate
-the number of cases in late January. Observe that we can select the masked
-elements using the ``.mask`` attribute:
-
-.. ipython:: python
-
- china_total.mask
- invalid = china_total[china_total.mask]
- invalid
-
-We can also access the valid entries by using the logical negation for this
-mask:
-
-.. ipython:: python
-
- valid = china_total[~china_total.mask]
- valid
-
-Now, if we want to create a very simple approximation for this data, we should
-take into account the valid entries around the invalid ones. So first let's
-select the dates for which the data is valid. Note that we can use the mask
-from the ``china_total`` masked array to index the dates array:
-
-.. ipython:: python
-
- dates[~china_total.mask]
-
-Finally, we can use the :func:`numpy.polyfit` and :func:`numpy.polyval`
-functions to create a cubic polynomial that fits the data as best as possible:
-
-.. ipython:: python
-
- t = np.arange(len(china_total))
- params = np.polyfit(t[~china_total.mask], valid, 3)
- cubic_fit = np.polyval(params, t)
- plt.plot(t, china_total);
- @savefig plot_covid_4.png
- plt.plot(t, cubic_fit, '--');
-
-This plot is not so readable since the lines seem to be over each other, so
-let's summarize in a more elaborate plot. We'll plot the real data when
-available, and show the cubic fit for unavailable data, using this fit to
-compute an estimate to the observed number of cases on January 28th 2020, 7 days
-after the beginning of the records:
-
-.. ipython:: python
-
- plt.plot(t, china_total);
- plt.plot(t[china_total.mask], cubic_fit[china_total.mask], '--', color='orange');
- plt.plot(7, np.polyval(params, 7), 'r*');
- plt.xticks([0, 7, 13], dates[[0, 7, 13]]);
- plt.yticks([0, np.polyval(params, 7), 10000, 17500]);
- plt.legend(['Mainland China', 'Cubic estimate', '7 days after start']);
- @savefig plot_covid_5.png
- plt.title("COVID-19 cumulative cases from Jan 21 to Feb 3 2020 - Mainland China\n"
- "Cubic estimate for 7 days after start");
-
-More reading
-------------
-
-Topics not covered in this tutorial can be found in the documentation:
-
-- :func:`Hardmasks <numpy.ma.harden_mask>` vs. :func:`softmasks
- <numpy.ma.soften_mask>`
-- :ref:`The numpy.ma module <maskedarray.generic>`
diff --git a/doc/source/user/tutorial-svd.rst b/doc/source/user/tutorial-svd.rst
deleted file mode 100644
index fd9e366e0..000000000
--- a/doc/source/user/tutorial-svd.rst
+++ /dev/null
@@ -1,524 +0,0 @@
-================================================
-Tutorial: Linear algebra on n-dimensional arrays
-================================================
-
-.. currentmodule:: numpy
-
-.. testsetup::
-
- import numpy as np
- np.random.seed(1)
-
-Prerequisites
--------------
-
-Before reading this tutorial, you should know a bit of Python. If you
-would like to refresh your memory, take a look at the
-:doc:`Python tutorial <python:tutorial/index>`.
-
-If you want to be able to run the examples in this tutorial, you should also
-have `matplotlib <https://matplotlib.org/>`_ and `SciPy <https://scipy.org>`_
-installed on your computer.
-
-Learner profile
----------------
-
-This tutorial is for people who have a basic understanding of linear
-algebra and arrays in NumPy and want to understand how n-dimensional
-(:math:`n>=2`) arrays are represented and can be manipulated. In particular, if
-you don't know how to apply common functions to n-dimensional arrays (without
-using for-loops), or if you want to understand axis and shape properties for
-n-dimensional arrays, this tutorial might be of help.
-
-Learning Objectives
--------------------
-
-After this tutorial, you should be able to:
-
-- Understand the difference between one-, two- and n-dimensional arrays in
- NumPy;
-- Understand how to apply some linear algebra operations to n-dimensional
- arrays without using for-loops;
-- Understand axis and shape properties for n-dimensional arrays.
-
-Content
--------
-
-In this tutorial, we will use a `matrix decomposition
-<https://en.wikipedia.org/wiki/Matrix_decomposition>`_ from linear algebra, the
-Singular Value Decomposition, to generate a compressed approximation of an
-image. We'll use the ``face`` image from the `scipy.misc` module:
-
- >>> from scipy import misc
- >>> img = misc.face()
-
-.. note::
-
- If you prefer, you can use your own image as you work through this tutorial.
- In order to transform your image into a NumPy array that can be manipulated,
- you can use the ``imread`` function from the `matplotlib.pyplot` submodule.
- Alternatively, you can use the :func:`imageio.imread` function from the
- ``imageio`` library. Be aware that if you use your own image, you'll likely
- need to adapt the steps below. For more information on how images are treated
- when converted to NumPy arrays, see :std:doc:`user_guide/numpy_images` from
- the ``scikit-image`` documentation.
-
-Now, ``img`` is a NumPy array, as we can see when using the ``type`` function::
-
- >>> type(img)
- <class 'numpy.ndarray'>
-
-We can see the image using the `matplotlib.pyplot.imshow` function::
-
- >>> import matplotlib.pyplot as plt
- >>> plt.imshow(img)
-
-.. plot:: user/plot_face.py
- :align: center
- :include-source: 0
-
-.. note::
-
- If you are executing the commands above in the IPython shell, it might be
- necessary to use the command ``plt.show()`` to show the image window.
-
-Shape, axis and array properties
---------------------------------
-
-Note that, in linear algebra, the dimension of a vector refers to the number of
-entries in an array. In NumPy, it instead defines the number of axes. For
-example, a 1D array is a vector such as ``[1, 2, 3]``, a 2D array is a matrix,
-and so forth.
-
-First, let's check for the shape of the data in our array. Since this image is
-two-dimensional (the pixels in the image form a rectangle), we might expect a
-two-dimensional array to represent it (a matrix). However, using the ``shape``
-property of this NumPy array gives us a different result::
-
- >>> img.shape
- (768, 1024, 3)
-
-The output is a :ref:`tuple <python:tut-tuples>` with three elements, which means
-that this is a three-dimensional array. In fact, since this is a color image, and
-we have used the ``imread`` function to read it, the data is organized in three 2D
-arrays, representing color channels (in this case, red, green and blue - RGB). You
-can see this by looking at the shape above: it indicates that we have an array of
-3 matrices, each having shape 768x1024.
-
-Furthermore, using the ``ndim`` property of this array, we can see that
-
-::
-
- >>> img.ndim
- 3
-
-NumPy refers to each dimension as an `axis`. Because of how ``imread``
-works, the *first index in the 3rd axis* is the red pixel data for our image. We
-can access this by using the syntax
-
-::
-
- >>> img[:, :, 0]
- array([[121, 138, 153, ..., 119, 131, 139],
- [ 89, 110, 130, ..., 118, 134, 146],
- [ 73, 94, 115, ..., 117, 133, 144],
- ...,
- [ 87, 94, 107, ..., 120, 119, 119],
- [ 85, 95, 112, ..., 121, 120, 120],
- [ 85, 97, 111, ..., 120, 119, 118]], dtype=uint8)
-
-From the output above, we can see that every value in ``img[:,:,0]`` is an
-integer value between 0 and 255, representing the level of red in each
-corresponding image pixel (keep in mind that this might be different if you
-use your own image instead of `scipy.misc.face`).
-
-As expected, this is a 768x1024 matrix::
-
- >>> img[:, :, 0].shape
- (768, 1024)
-
-Since we are going to perform linear algebra operations on this data, it might
-be more interesting to have real numbers between 0 and 1 in each entry of the
-matrices to represent the RGB values. We can do that by setting
-
- >>> img_array = img / 255
-
-This operation, dividing an array by a scalar, works because of NumPy's
-:ref:`broadcasting rules <array-broadcasting-in-numpy>`). (Note that in
-real-world applications, it would be better to use, for example, the
-:func:`img_as_float <skimage.img_as_float>` utility function from
-``scikit-image``).
-
-You can check that the above works by doing some tests; for example, inquiring
-about maximum and minimum values for this array::
-
- >>> img_array.max(), img_array.min()
- (1.0, 0.0)
-
-or checking the type of data in the array::
-
- >>> img_array.dtype
- dtype('float64')
-
-Note that we can assign each color channel to a separate matrix using the slice
-syntax::
-
- >>> red_array = img_array[:, :, 0]
- >>> green_array = img_array[:, :, 1]
- >>> blue_array = img_array[:, :, 2]
-
-Operations on an axis
----------------------
-
-It is possible to use methods from linear algebra to approximate an existing set
-of data. Here, we will use the `SVD (Singular Value Decomposition)
-<https://en.wikipedia.org/wiki/Singular_value_decomposition>`_ to try to rebuild
-an image that uses less singular value information than the original one, while
-still retaining some of its features.
-
-.. note::
-
- We will use NumPy's linear algebra module, `numpy.linalg`, to
- perform the operations in this tutorial. Most of the linear algebra
- functions in this module can also be found in `scipy.linalg`, and
- users are encouraged to use the `scipy` module for real-world
- applications. However, it is currently not possible to apply linear
- algebra operations to n-dimensional arrays using the `scipy.linalg`
- module. For more information on this, check the
- :doc:`scipy.linalg Reference<scipy:tutorial/linalg>`.
-
-To proceed, import the linear algebra submodule from NumPy::
-
- >>> from numpy import linalg
-
-In order to extract information from a given matrix, we can use the SVD to obtain
-3 arrays which can be multiplied to obtain the original matrix. From the theory
-of linear algebra, given a matrix :math:`A`, the following product can be
-computed:
-
-.. math::
-
- U \Sigma V^T = A
-
-where :math:`U` and :math:`V^T` are square and :math:`\Sigma` is the same size
-as :math:`A`. :math:`\Sigma` is a diagonal matrix and contains the
-`singular values <https://en.wikipedia.org/wiki/Singular_value>`_ of :math:`A`,
-organized from largest to smallest. These values are always non-negative and can
-be used as an indicator of the "importance" of some features represented by the
-matrix :math:`A`.
-
-Let's see how this works in practice with just one matrix first. Note that
-according to `colorimetry <https://en.wikipedia.org/wiki/Grayscale#Colorimetric_(perceptual_luminance-preserving)_conversion_to_grayscale>`_,
-it is possible to obtain a fairly reasonable grayscale version of our color
-image if we apply the formula
-
-.. math::
-
- Y = 0.2126 R + 0.7152 G + 0.0722 B
-
-where :math:`Y` is the array representing the grayscale image, and :math:`R, G`
-and :math:`B` are the red, green and blue channel arrays we had originally.
-Notice we can use the ``@`` operator (the matrix multiplication operator for
-NumPy arrays, see `numpy.matmul`) for this:
-
-::
-
- >>> img_gray = img_array @ [0.2126, 0.7152, 0.0722]
-
-Now, ``img_gray`` has shape
-
-::
-
- >>> img_gray.shape
- (768, 1024)
-
-To see if this makes sense in our image, we should use a colormap from
-``matplotlib`` corresponding to the color we wish to see in out image
-(otherwise, ``matplotlib`` will default to a colormap that does not
-correspond to the real data).
-
-In our case, we are approximating the grayscale portion of the image, so we
-will use the colormap ``gray``::
-
- >>> plt.imshow(img_gray, cmap="gray")
-
-.. plot:: user/plot_gray.py
- :align: center
- :include-source: 0
-
-Now, applying the `linalg.svd` function to this matrix, we obtain the
-following decomposition:
-::
-
- >>> U, s, Vt = linalg.svd(img_gray)
-
-.. note::
-
- If you are using your own image, this command might take a while to run,
- depending on the size of your image and your hardware. Don't worry, this
- is normal! The SVD can be a pretty intensive computation.
-
-Let's check that this is what we expected::
-
- >>> U.shape, s.shape, Vt.shape
- ((768, 768), (768,), (1024, 1024))
-
-Note that ``s`` has a particular shape: it has only one dimension. This
-means that some linear algebra functions that expect 2d arrays might not work.
-For example, from the theory, one might expect ``s`` and ``Vt`` to be
-compatible for multiplication. However, this is not true as ``s`` does not
-have a second axis. Executing
-
-::
-
- >>> s @ Vt
- Traceback (most recent call last):
- ...
- ValueError: matmul: Input operand 1 has a mismatch in its core dimension 0,
- with gufunc signature (n?,k),(k,m?)->(n?,m?) (size 1024 is different from
- 768)
-
-results in a ``ValueError``. This happens because having a one-dimensional
-array for ``s``, in this case, is much more economic in practice than building a
-diagonal matrix with the same data. To reconstruct the original matrix, we can
-rebuild the diagonal matrix :math:`\Sigma` with the elements of ``s`` in its
-diagonal and with the appropriate dimensions for multiplying: in our case,
-:math:`\Sigma` should be 768x1024 since ``U`` is 768x768 and ``Vt`` is
-1024x1024.
-
-::
-
- >>> import numpy as np
- >>> Sigma = np.zeros((768, 1024))
- >>> for i in range(768):
- ... Sigma[i, i] = s[i]
-
-Now, we want to check if the reconstructed ``U @ Sigma @ Vt`` is
-close to the original ``img_gray`` matrix.
-
-Approximation
--------------
-
-The `linalg` module includes a ``norm`` function, which
-computes the norm of a vector or matrix represented in a NumPy array. For
-example, from the SVD explanation above, we would expect the norm of the
-difference between ``img_gray`` and the reconstructed SVD product to be small.
-As expected, you should see something like
-
-::
-
- >>> linalg.norm(img_gray - U @ Sigma @ Vt)
- 1.3926466851808837e-12
-
-(The actual result of this operation might be different depending on your
-architecture and linear algebra setup. Regardless, you should see a small
-number.)
-
-We could also have used the `numpy.allclose` function to make sure the
-reconstructed product is, in fact, *close* to our original matrix (the
-difference between the two arrays is small)::
-
- >>> np.allclose(img_gray, U @ Sigma @ Vt)
- True
-
-To see if an approximation is reasonable, we can check the values in ``s``::
-
- >>> plt.plot(s)
-
-.. plot:: user/plot_gray_svd.py
- :align: center
- :include-source: 0
-
-In the graph, we can see that although we have 768 singular values in
-``s``, most of those (after the 150th entry or so) are pretty small. So it
-might make sense to use only the information related to the first (say, 50)
-*singular values* to build a more economical approximation to our image.
-
-The idea is to consider all but the first ``k`` singular values in
-``Sigma`` (which are the same as in ``s``) as zeros, keeping
-``U`` and ``Vt`` intact, and computing the product of these matrices
-as the approximation.
-
-For example, if we choose
-
-::
-
- >>> k = 10
-
-we can build the approximation by doing
-
-::
-
- >>> approx = U @ Sigma[:, :k] @ Vt[:k, :]
-
-Note that we had to use only the first ``k`` rows of ``Vt``, since all
-other rows would be multiplied by the zeros corresponding to the singular
-values we eliminated from this approximation.
-
-::
-
- >>> plt.imshow(approx, cmap="gray")
-
-.. plot:: user/plot_approx.py
- :align: center
- :include-source: 0
-
-Now, you can go ahead and repeat this experiment with other values of `k`, and
-each of your experiments should give you a slightly better (or worse) image
-depending on the value you choose.
-
-Applying to all colors
-----------------------
-
-Now we want to do the same kind of operation, but to all three colors. Our
-first instinct might be to repeat the same operation we did above to each color
-matrix individually. However, NumPy's `broadcasting` takes care of this
-for us.
-
-If our array has more than two dimensions, then the SVD can be applied to all
-axes at once. However, the linear algebra functions in NumPy expect to see an
-array of the form ``(N, M, M)``, where the first axis represents the number
-of matrices.
-
-In our case,
-
-::
-
- >>> img_array.shape
- (768, 1024, 3)
-
-so we need to permutate the axis on this array to get a shape like
-``(3, 768, 1024)``. Fortunately, the `numpy.transpose` function can do that for
-us:
-
-::
-
- np.transpose(x, axes=(i, j, k))
-
-indicates that the axis will be reordered such that the final shape of the
-transposed array will be reordered according to the indices ``(i, j, k)``.
-
-Let's see how this goes for our array::
-
- >>> img_array_transposed = np.transpose(img_array, (2, 0, 1))
- >>> img_array_transposed.shape
- (3, 768, 1024)
-
-Now we are ready to apply the SVD::
-
- >>> U, s, Vt = linalg.svd(img_array_transposed)
-
-Finally, to obtain the full approximated image, we need to reassemble these
-matrices into the approximation. Now, note that
-
-::
-
- >>> U.shape, s.shape, Vt.shape
- ((3, 768, 768), (3, 768), (3, 1024, 1024))
-
-To build the final approximation matrix, we must understand how multiplication
-across different axes works.
-
-Products with n-dimensional arrays
-----------------------------------
-
-If you have worked before with only one- or two-dimensional arrays in NumPy,
-you might use `numpy.dot` and `numpy.matmul` (or the ``@`` operator)
-interchangeably. However, for n-dimensional arrays, they work in very different
-ways. For more details, check the documentation `numpy.matmul`.
-
-Now, to build our approximation, we first need to make sure that our singular
-values are ready for multiplication, so we build our ``Sigma`` matrix similarly
-to what we did before. The ``Sigma`` array must have dimensions
-``(3, 768, 1024)``. In order to add the singular values to the diagonal of
-``Sigma``, we will use the ``fill_diagonal`` function from NumPy, using each of
-the 3 rows in ``s`` as the diagonal for each of the 3 matrices in ``Sigma``:
-
-::
-
- >>> Sigma = np.zeros((3, 768, 1024))
- >>> for j in range(3):
- ... np.fill_diagonal(Sigma[j, :, :], s[j, :])
-
-Now, if we wish to rebuild the full SVD (with no approximation), we can do
-
-::
-
- >>> reconstructed = U @ Sigma @ Vt
-
-Note that
-
-::
-
- >>> reconstructed.shape
- (3, 768, 1024)
-
-and
-
-::
-
- >>> plt.imshow(np.transpose(reconstructed, (1, 2, 0)))
-
-.. plot:: user/plot_reconstructed.py
- :align: center
- :include-source: 0
-
-should give you an image indistinguishable from the original one (although we
-may introduce floating point errors for this reconstruction). In fact,
-you might see a warning message saying `"Clipping input data to the
-valid range for imshow with RGB data ([0..1] for floats or [0..255] for
-integers)."` This is expected from the manipulation we just did on the original
-image.
-
-Now, to do the approximation, we must choose only the first ``k`` singular
-values for each color channel. This can be done using the following syntax::
-
- >>> approx_img = U @ Sigma[..., :k] @ Vt[..., :k, :]
-
-You can see that we have selected only the first ``k`` components of the last
-axis for ``Sigma`` (this means that we have used only the first ``k`` columns
-of each of the three matrices in the stack), and that we have selected only the
-first ``k`` components in the second-to-last axis of ``Vt`` (this means we have
-selected only the first ``k`` rows from every matrix in the stack ``Vt`` and
-all columns). If you are unfamiliar with the ellipsis syntax, it is a
-placeholder for other axes. For more details, see the documentation on
-:ref:`Indexing <basics.indexing>`.
-
-Now,
-
-::
-
- >>> approx_img.shape
- (3, 768, 1024)
-
-which is not the right shape for showing the image. Finally, reordering the axes
-back to our original shape of ``(768, 1024, 3)``, we can see our approximation::
-
- >>> plt.imshow(np.transpose(approx_img, (1, 2, 0)))
-
-.. plot:: user/plot_final.py
- :align: center
- :include-source: 0
-
-Even though the image is not as sharp, using a small number of ``k`` singular
-values (compared to the original set of 768 values), we can recover many of the
-distinguishing features from this image.
-
-Final words
------------
-
-Of course, this is not the best method to *approximate* an image.
-However, there is, in fact, a result in linear algebra that says that the
-approximation we built above is the best we can get to the original matrix in
-terms of the norm of the difference. For more information, see *G. H. Golub and
-C. F. Van Loan, Matrix Computations, Baltimore, MD, Johns Hopkins University
-Press, 1985*.
-
-Further reading
----------------
-
-- :doc:`Python tutorial <python:tutorial/index>`
-- :ref:`reference`
-- :doc:`SciPy Tutorial <scipy:tutorial/index>`
-- `SciPy Lecture Notes <https://scipy-lectures.org>`__
-- `A matlab, R, IDL, NumPy/SciPy dictionary <http://mathesaurus.sf.net/>`__
diff --git a/doc/source/user/tutorials_index.rst b/doc/source/user/tutorials_index.rst
deleted file mode 100644
index 20e2c256c..000000000
--- a/doc/source/user/tutorials_index.rst
+++ /dev/null
@@ -1,16 +0,0 @@
-.. _tutorials:
-
-################
-NumPy Tutorials
-################
-
-These documents are intended as an introductory overview of NumPy and its
-features. For detailed reference documentation of the functions and
-classes contained in the package, see the :ref:`API reference <reference>`.
-
-.. toctree::
- :maxdepth: 1
-
- tutorial-svd
- tutorial-ma
-
diff --git a/doc/source/user/who_covid_19_sit_rep_time_series.csv b/doc/source/user/who_covid_19_sit_rep_time_series.csv
deleted file mode 100644
index ebf670b8c..000000000
--- a/doc/source/user/who_covid_19_sit_rep_time_series.csv
+++ /dev/null
@@ -1,115 +0,0 @@
-Province/States,Country/Region,WHO region,1/21/20,1/22/20,1/23/20,1/24/20,1/25/20,1/26/20,1/27/20,1/28/20,1/29/20,1/30/20,1/31/20,2/1/20,2/2/20,2/3/20,2/4/20,2/5/20,2/6/20,2/7/20,2/8/20,2/9/20,2/10/20,2/11/20,2/12/20,2/13/20,2/14/20,2/15/20,2/16/20,2/17/20,2/18/20,2/19/20,2/20/20,2/21/20,2/22/20,2/23/20,2/24/20,2/25/20,2/26/20,2/27/20,2/28/20,2/29/20,3/1/20,3/2/20,3/3/20
-Confirmed,Globally,,282,314,581,846,1320,2014,2798,4593,6065,7818,9826,11953,14557,17391,20630,24554,28276,31481,34886,37558,40554,43103,45171,46997,49053,50580,51857,71429,73332,75204,75748,76769,77794,78811,79331,80239,81109,82294,83652,85403,87137,88948,90870
-Confirmed,Mainland China,Western Pacific Region,278,309,571,830,1297,1985,2741,4537,5997,7736,9720,11821,14411,17238,20471,24363,28060,31211,34598,37251,40235,42708,44730,46550,48548,50054,51174,70635,72528,74280,74675,75569,76392,77042,77262,77780,78191,78630,78961,79394,79968,80174,80304
-Confirmed,Outside of China,,4,5,10,16,23,29,57,56,68,82,106,132,146,153,159,191,216,270,288,307,319,395,441,447,505,526,683,794,804,924,1073,1200,1402,1769,2069,2459,2918,3664,4691,6009,7169,8774,10566
-Suspected,Mainland China,Western Pacific Region,,,,,,,5794,6973,9239,12167,15238,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
-Severe,Mainland China,Western Pacific Region,,,,,,,461,976,1239,1370,1527,1795,2110,2296,2788,3219,3859,4821,6101,6188,6484,7333,8204,,,,,,,,,,,,,,,,,,,,
-Deaths,Mainland China,Western Pacific Region,,,,,,,80,106,132,170,213,259,304,361,425,491,564,637,723,812,909,1017,1114,1260,1381,1524,1666,1772,1870,2006,2121,2239,2348,2445,2595,2666,2718,2747,2791,2838,2873,2915,2946
-Hubei ,China,Western Pacific Region,258,270,375,375,,,,,,,,7153,9074,11177,13522,16678,19665,22112,24953,27100,29631,31728,33366,34874,51968,54406,56249,58182,59989,61682,62031,62662,63454,64084,64287,64786,65187,65596,65914,66337,66907,67103,67217
-Guangdong,China,Western Pacific Region,14,17,26,32,,,,,,,,520,604,683,797,870,944,1018,1075,1120,1151,1177,1219,1241,1261,1295,1316,1322,1328,1331,1332,1333,1339,1342,1345,1347,1347,1347,1348,1349,1349,1350,1350
-Henan,China,Western Pacific Region,,1,1,1,,,,,,,,422,493,566,675,764,851,914,981,1033,1073,1105,1135,1169,1184,1212,1231,1246,1257,1262,1265,1267,1270,1271,1271,1271,1271,1272,1272,1272,1272,1272,1272
-Zhejiang,China,Western Pacific Region,,5,5,5,,,,,,,,599,661,724,829,895,954,1006,1048,1075,1104,1117,1131,1145,1155,1162,1167,1171,1172,1173,1175,1203,1205,1205,1205,1205,1205,1205,1205,1205,1205,1206,1213
-Hunan,China,Western Pacific Region,,1,1,1,,,,,,,,389,463,521,593,661,711,772,803,838,879,912,946,968,988,1001,1004,1006,1007,1008,1010,1011,1013,1016,1016,1016,1016,1017,1017,1018,1018,1018,1018
-Anhui,China,Western Pacific Region,,,,,,,,,,,,297,340,408,480,530,591,665,733,779,830,860,889,910,934,950,962,973,982,986,987,988,989,989,989,989,989,989,990,990,990,990,990
-Jiangxi,China,Western Pacific Region,,1,2,2,,,,,,,,286,333,391,476,548,600,661,698,740,771,804,844,872,900,913,925,930,933,934,934,934,934,934,934,934,934,934,935,935,935,935,935
-Shandong,China,Western Pacific Region,,1,1,1,,,,,,,,202,225,246,270,298,343,379,407,435,459,486,497,506,519,530,537,541,543,544,546,748,750,754,755,755,756,756,756,756,756,758,758
-Jiangsu,China,Western Pacific Region,,,,,,,,,,,,202,231,271,308,341,373,408,439,468,492,515,543,570,593,604,617,626,629,631,631,631,631,631,631,631,631,631,631,631,631,631,631
-Chongqing,China,Western Pacific Region,,1,5,5,,,,,,,,238,262,300,337,366,389,411,426,446,468,486,505,518,529,537,544,551,553,555,560,567,572,573,575,576,576,576,576,576,576,576,576
-Sichuan,China,Western Pacific Region,,1,2,2,,,,,,,,207,236,254,282,301,321,344,363,386,405,417,436,451,463,470,481,495,508,514,520,525,526,526,527,529,531,534,538,538,538,538,538
-Heilongjiang,China,Western Pacific Region,,,,,,,,,,,,80,95,118,155,190,227,277,282,307,331,360,378,395,418,425,445,457,464,470,476,479,479,480,480,480,480,480,480,480,480,480,480
-Beijing,China,Western Pacific Region,5,5,10,10,,,,,,,,156,183,212,228,253,274,297,315,326,337,342,352,366,372,375,380,381,387,393,395,396,399,399,399,400,400,410,410,411,413,414,414
-Shanghai,China,Western Pacific Region,1,2,9,9,,,,,,,,153,177,193,208,233,254,269,281,292,295,302,306,313,318,326,328,331,333,333,333,334,334,335,335,335,336,337,337,337,337,337,338
-Hebei,China,Western Pacific Region,,,,,,,,,,,,96,104,113,126,135,157,171,195,206,218,239,251,265,283,291,300,301,302,306,307,308,309,311,311,311,312,317,318,318,318,318,318
-Fujian,China,Western Pacific Region,,,,,,,,,,,,144,159,179,194,205,215,224,239,250,261,267,272,279,281,285,287,290,292,293,293,293,293,293,293,294,294,296,296,296,296,296,296
-Guangxi,China,Western Pacific Region,,,,,,,,,,,,100,111,127,139,150,168,172,183,195,210,215,222,222,226,235,237,238,242,244,245,246,249,249,251,252,252,252,252,252,252,252,252
-Shaanxi,China,Western Pacific Region,,,,,,,,,,,,101,116,128,142,165,173,184,195,208,213,219,225,229,230,232,236,240,240,242,245,245,245,245,245,245,245,245,245,245,245,245,245
-Yunnan,China,Western Pacific Region,,1,1,1,,,,,,,,91,99,109,117,122,128,135,138,140,141,149,154,155,162,168,169,171,172,172,172,174,174,174,174,174,174,174,174,174,174,174,174
-Hainan,China,Western Pacific Region,,,,,,,,,,,,57,63,70,79,89,100,111,123,128,136,142,145,157,157,162,162,162,163,163,168,168,168,168,168,168,168,168,168,168,168,168,168
-Guizhou,China,Western Pacific Region,,,,,,,,,,,,29,38,46,56,64,69,77,89,96,109,118,131,135,140,143,144,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146,146
-Tianjin,China,Western Pacific Region,,2,2,2,,,,,,,,34,40,49,63,67,70,94,81,88,91,96,106,112,119,120,122,124,125,128,130,131,133,135,135,135,135,135,136,136,136,136,136
-Shanxi,China,Western Pacific Region,,,,,,,,,,,,47,56,66,74,81,90,96,104,115,119,122,124,126,126,127,128,129,130,131,131,132,132,132,132,133,133,133,133,133,133,133,133
-Liaoning,China,Western Pacific Region,,,,,,,,,,,,60,64,70,74,81,89,94,99,105,107,108,111,116,117,119,120,121,121,121,121,121,121,121,121,121,121,121,121,121,122,122,125
-Hong Kong,China,Western Pacific Region,,,1,2,5,5,8,8,8,10,12,13,14,15,15,18,21,24,26,26,36,42,49,50,53,56,56,57,60,62,65,68,68,70,74,81,85,91,93,94,95,98,101
-Jilin,China,Western Pacific Region,,,,,,,,,,,,17,21,31,42,54,59,65,69,78,80,81,83,84,86,88,88,89,89,90,91,91,91,91,93,93,93,93,93,93,93,93,93
-Gansu,China,Western Pacific Region,,,,,,,,,,,,35,45,51,56,57,62,70,71,81,85,86,86,87,90,90,90,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91,91
-Xinjiang,China,Western Pacific Region,,,,,,,,,,,,18,23,24,29,32,36,39,42,45,49,55,59,63,65,70,71,73,76,76,76,76,76,75,76,76,76,76,76,76,76,76,76
-Inner Mongolia,China,Western Pacific Region,,,,,,,,,,,,23,26,33,37,42,46,49,50,54,58,58,60,61,63,68,70,72,73,75,75,75,75,75,75,75,75,75,75,75,75,75,75
-Ningxia,China,Western Pacific Region,,,,,,,,,,,,26,28,31,34,34,40,43,45,45,49,53,58,64,67,70,70,70,70,71,71,71,71,71,71,71,71,72,72,73,73,74,74
-Taiwan,China,Western Pacific Region,,1,1,1,3,3,4,7,8,8,9,10,10,10,10,11,11,16,16,17,18,18,18,18,18,18,18,20,22,23,24,26,26,23,28,31,32,32,34,39,39,40,42
-Qinghai,China,Western Pacific Region,,,,,,,,,,,,8,9,13,15,17,18,18,18,18,18,18,18,18,18,18,18,18,18,12,18,18,18,18,18,18,18,18,18,18,18,18,18
-Macau,China,Western Pacific Region,,,1,2,2,2,5,7,7,7,7,7,7,8,8,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10,10
-Xizang,China,Western Pacific Region,,,,,,,,,,,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
-Unspecified*,China,Western Pacific Region,,,131,384,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
-,Japan,Western Pacific Region,1,1,1,1,3,3,4,6,7,11,14,17,20,20,20,33,25,25,25,26,26,26,28,29,33,41,53,59,65,73,85,93,105,132,144,157,164,186,210,230,239,254,268
-,Republic of Korea,Western Pacific Region,1,1,1,2,2,2,4,4,4,4,11,12,15,15,16,18,23,24,24,27,27,28,28,28,28,28,29,30,31,51,104,204,346,602,763,977,1261,1766,2337,3150,3736,4212,4812
-,Thailand,South-East Asia Region,2,2,2,4,4,5,5,14,14,14,14,19,19,19,19,25,25,25,32,32,32,33,33,33,33,34,34,35,35,35,35,35,35,35,35,37,40,40,40,42,42,42,43
-,United States of America,Region of the Americas,,,1,1,2,2,5,5,5,5,6,7,8,11,11,11,12,12,12,12,12,13,13,14,15,15,15,15,15,15,15,15,35,35,35,53,53,59,59,62,62,62,64
-,Vietnam,Western Pacific Region,,,,2,2,2,2,2,2,2,5,6,7,8,9,10,10,12,13,14,14,15,15,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16
-,Singapore,Western Pacific Region,,,,1,3,3,4,7,7,10,13,16,18,18,18,24,28,30,33,40,43,45,47,50,58,67,72,75,77,81,84,85,86,89,89,90,91,93,96,98,102,106,108
-,Italy,European Region,,,,,,,,,,,2,2,2,2,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,9,76,124,229,322,400,650,888,1128,1689,2036
-,Nepal,South-East Asia Region,,,,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
-,Australia,Western Pacific Region,,,,,3,3,4,5,7,7,9,12,12,12,12,13,14,15,15,15,15,15,15,15,15,15,15,15,15,15,15,17,21,21,21,22,23,23,23,24,25,27,33
-,Malaysia,Western Pacific Region,,,,,,3,4,4,4,7,8,8,8,8,10,10,12,14,15,17,18,18,18,18,19,21,22,22,22,22,22,22,22,22,22,22,22,22,24,24,24,24,29
-,Canada,Region of the Americas,,,,,,,1,2,3,3,3,4,4,4,4,5,5,7,7,7,7,7,7,7,7,7,7,7,8,8,8,8,8,9,9,10,10,11,11,14,19,19,27
-,Cambodia,Western Pacific Region,,,,,,,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
-,France,European Region,,,,,3,3,3,3,4,5,6,6,6,6,6,6,6,6,6,11,11,11,11,11,11,11,12,12,12,12,12,12,12,12,12,12,12,18,38,57,100,100,191
-,Sri Lanka,South-East Asia Region,,,,,,,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1
-,Iran,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,5,18,28,43,61,95,141,245,388,593,978,1501
-,India,South-East Asia Region,,,,,,,,,,1,1,1,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,5
-,Germany,European Region,,,,,,,,1,4,4,5,7,8,10,12,12,12,13,14,14,14,14,16,16,16,16,16,16,16,16,16,16,16,16,16,16,18,21,26,57,57,129,157
-,Philippines,Western Pacific Region,,,,,,,,,,1,1,1,2,2,2,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3
-,Spain,European Region,,,,,,,,,,,,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,12,25,32,45,45,114
-,United Kingdom,European Region,,,,,,,,,,,,2,2,2,2,2,2,3,3,3,4,8,8,9,9,9,9,9,9,9,9,9,9,9,9,13,13,13,16,20,23,36,39
-,Sweden,European Region,,,,,,,,,,,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,7,12,13,14,15
-,Switzerland,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,6,10,18,26,30
-,Austria,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,2,4,5,10,10,18
-,Norway,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,4,6,15,19,25
-,Kuwait,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,8,12,43,43,45,45,56,56
-,Bahrain,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,8,26,33,33,38,40,47,49
-,United Arab Emirates,Eastern Mediterranean Region,,,,,,,,,4,4,4,4,5,5,5,5,5,5,7,7,7,8,8,8,8,8,8,9,9,9,9,9,11,13,13,13,13,13,19,19,19,21,21
-,Israel,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,2,2,2,3,5,7,7,10
-,Iraq,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,5,6,7,8,13,19,26
-,Oman,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,4,4,6,6,6,6,6
-,Lebanon,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1,2,2,2,2,10,13
-,Pakistan,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,2,2,4,4,5
-,Egypt,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2
-,Croatia,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,3,3,5,7,7,9
-,Greece,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,3,3,3,7,7
-,Finland,European Region,,,,,,,,,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,6,7
-,Algeria,African Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1,1,5
-,Brazil,Region of the Americas,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,2,2,2
-,Russian,European Region,,,,,,,,,,,,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,3
-,Belgium,European Region,,,,,,,,,,,,,,,,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,8
-,Denmark,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,2,3,4,5
-,Estonia,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1,1
-,Georgia,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,2,3,3,3
-,North Macedonia,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1,1
-,Romania,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,3,3,3,3
-,Afghanistan,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1,1,1,1
-,New Zealand,Western Pacific Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,2
-,Belarus,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1
-,Lithuania,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1
-,Netherlands,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,2,7,13,18
-,Nigeria,African Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,1,1
-,Mexico,Region of the Americas,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,2,5,5
-,San Marino,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1,8
-,Azerbaijan,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,3,3
-,Ireland,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1
-,Monaco,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,1
-,Qatar,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,3,7
-,Ecuador,Region of the Americas,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1,6
-,Czechia,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,3,3
-,Iceland,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,9
-,Armenia,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1
-,Luxembourg,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1
-,Indonesia,South-East Asia Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2,2
-,Dominican Republic,Region of the Americas,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1,1
-,Portugal,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,2
-,Andorra,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1
-,Latvia,European Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1
-,Jordan,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1
-,Morocco,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1
-,Saudi Arabia,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1
-,Tunisia,Eastern Mediterranean Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1
-,Senegal,African Region,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,1
-Case on an international conveyance,Other,Other,,,,,,,,,,,,,,,,,20,61,64,64,70,135,175,174,218,218,355,454,454,542,621,634,634,634,695,691,691,705,705,705,706,706,706 \ No newline at end of file
diff --git a/doc_requirements.txt b/doc_requirements.txt
index f69cc5dcb..61ce7549b 100644
--- a/doc_requirements.txt
+++ b/doc_requirements.txt
@@ -1,7 +1,7 @@
-sphinx>=2.2.0,<3.0
+sphinx==4.1.2
numpydoc==1.1.0
ipython
scipy
matplotlib
pandas
-pydata-sphinx-theme==0.4.1
+pydata-sphinx-theme
diff --git a/environment.yml b/environment.yml
new file mode 100644
index 000000000..5fb7d292d
--- /dev/null
+++ b/environment.yml
@@ -0,0 +1,36 @@
+# To use:
+#
+# $ conda env create -f environment.yml # `mamba` works too for this command
+# $ conda activate numpy-dev
+#
+name: numpy-dev
+channels:
+ - conda-forge
+dependencies:
+ - python
+ - cython
+ - compilers
+ - openblas
+ - nomkl
+ # For testing
+ - pytest
+ - pytest-cov
+ - pytest-xdist
+ - hypothesis
+ # For type annotations
+ - mypy=0.902
+ - typing_extensions
+ # For building docs
+ - sphinx=4.1.1
+ - numpydoc=1.1.0
+ - ipython
+ - scipy
+ - pandas
+ - matplotlib
+ - pydata-sphinx-theme
+ # For linting
+ - pycodestyle=2.7.0
+ - gitpython
+ # Used in some tests
+ - cffi
+ - pytz
diff --git a/linter_requirements.txt b/linter_requirements.txt
new file mode 100644
index 000000000..51a769ee0
--- /dev/null
+++ b/linter_requirements.txt
@@ -0,0 +1,2 @@
+pycodestyle==2.7.0
+GitPython==3.1.13 \ No newline at end of file
diff --git a/numpy/__init__.cython-30.pxd b/numpy/__init__.cython-30.pxd
index a2c451bc1..42a46d0b8 100644
--- a/numpy/__init__.cython-30.pxd
+++ b/numpy/__init__.cython-30.pxd
@@ -910,8 +910,6 @@ cdef extern from "numpy/ufuncobject.h":
void **, char *, int, int, int, int, char *, char *, int)
int PyUFunc_RegisterLoopForType(ufunc, int,
PyUFuncGenericFunction, int *, void *)
- int PyUFunc_GenericFunction \
- (ufunc, PyObject *, PyObject *, PyArrayObject **)
void PyUFunc_f_f_As_d_d \
(char **, npy_intp *, npy_intp *, void *)
void PyUFunc_d_d \
diff --git a/numpy/__init__.pxd b/numpy/__init__.pxd
index fd704b7e3..97f3da2e5 100644
--- a/numpy/__init__.pxd
+++ b/numpy/__init__.pxd
@@ -868,8 +868,6 @@ cdef extern from "numpy/ufuncobject.h":
void **, char *, int, int, int, int, char *, char *, int)
int PyUFunc_RegisterLoopForType(ufunc, int,
PyUFuncGenericFunction, int *, void *)
- int PyUFunc_GenericFunction \
- (ufunc, PyObject *, PyObject *, PyArrayObject **)
void PyUFunc_f_f_As_d_d \
(char **, npy_intp *, npy_intp *, void *)
void PyUFunc_d_d \
diff --git a/numpy/__init__.py b/numpy/__init__.py
index 3e5277318..8546238ec 100644
--- a/numpy/__init__.py
+++ b/numpy/__init__.py
@@ -109,8 +109,9 @@ Exceptions to this rule are documented.
import sys
import warnings
-from ._globals import ModuleDeprecationWarning, VisibleDeprecationWarning
-from ._globals import _NoValue
+from ._globals import (
+ ModuleDeprecationWarning, VisibleDeprecationWarning, _NoValue
+)
# We first need to detect if we're being called as part of the numpy setup
# procedure itself in a reliable manner.
@@ -130,12 +131,16 @@ else:
your python interpreter from there."""
raise ImportError(msg) from e
- from .version import git_revision as __git_revision__
- from .version import version as __version__
-
__all__ = ['ModuleDeprecationWarning',
'VisibleDeprecationWarning']
+ # get the version using versioneer
+ from ._version import get_versions
+ vinfo = get_versions()
+ __version__ = vinfo.get("closest-tag", vinfo["version"])
+ __git_version__ = vinfo.get("full-revisionid")
+ del get_versions, vinfo
+
# mapping of {name: (value, deprecation_msg)}
__deprecated_attrs__ = {}
@@ -161,33 +166,62 @@ else:
# Deprecations introduced in NumPy 1.20.0, 2020-06-06
import builtins as _builtins
+
+ _msg = (
+ "`np.{n}` is a deprecated alias for the builtin `{n}`. "
+ "To silence this warning, use `{n}` by itself. Doing this will not "
+ "modify any behavior and is safe. {extended_msg}\n"
+ "Deprecated in NumPy 1.20; for more details and guidance: "
+ "https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations")
+
+ _specific_msg = (
+ "If you specifically wanted the numpy scalar type, use `np.{}` here.")
+
+ _int_extended_msg = (
+ "When replacing `np.{}`, you may wish to use e.g. `np.int64` "
+ "or `np.int32` to specify the precision. If you wish to review "
+ "your current use, check the release note link for "
+ "additional information.")
+
+ _type_info = [
+ ("object", ""), # The NumPy scalar only exists by name.
+ ("bool", _specific_msg.format("bool_")),
+ ("float", _specific_msg.format("float64")),
+ ("complex", _specific_msg.format("complex128")),
+ ("str", _specific_msg.format("str_")),
+ ("int", _int_extended_msg.format("int"))]
+
__deprecated_attrs__.update({
- n: (
- getattr(_builtins, n),
- "`np.{n}` is a deprecated alias for the builtin `{n}`. "
- "Use `{n}` by itself, which is identical in behavior, to silence "
- "this warning. "
- "If you specifically wanted the numpy scalar type, use `np.{n}_` "
- "here."
- .format(n=n)
- )
- for n in ["bool", "int", "float", "complex", "object", "str"]
- })
- __deprecated_attrs__.update({
- n: (
- getattr(compat, n),
- "`np.{n}` is a deprecated alias for `np.compat.{n}`. "
- "Use `np.compat.{n}` by itself, which is identical in behavior, "
- "to silence this warning. "
- "In the likely event your code does not need to work on Python 2 "
- "you can use the builtin ``{n2}`` for which ``np.compat.{n}`` is "
- "itself an alias. "
- "If you specifically wanted the numpy scalar type, use `np.{n2}_` "
- "here."
- .format(n=n, n2=n2)
- )
- for n, n2 in [("long", "int"), ("unicode", "str")]
+ n: (getattr(_builtins, n), _msg.format(n=n, extended_msg=extended_msg))
+ for n, extended_msg in _type_info
})
+ # Numpy 1.20.0, 2020-10-19
+ __deprecated_attrs__["typeDict"] = (
+ core.numerictypes.typeDict,
+ "`np.typeDict` is a deprecated alias for `np.sctypeDict`."
+ )
+
+ _msg = (
+ "`np.{n}` is a deprecated alias for `np.compat.{n}`. "
+ "To silence this warning, use `np.compat.{n}` by itself. "
+ "In the likely event your code does not need to work on Python 2 "
+ "you can use the builtin `{n2}` for which `np.compat.{n}` is itself "
+ "an alias. Doing this will not modify any behaviour and is safe. "
+ "{extended_msg}\n"
+ "Deprecated in NumPy 1.20; for more details and guidance: "
+ "https://numpy.org/devdocs/release/1.20.0-notes.html#deprecations")
+
+ __deprecated_attrs__["long"] = (
+ getattr(compat, "long"),
+ _msg.format(n="long", n2="int",
+ extended_msg=_int_extended_msg.format("long")))
+
+ __deprecated_attrs__["unicode"] = (
+ getattr(compat, "unicode"),
+ _msg.format(n="unicode", n2="str",
+ extended_msg=_specific_msg.format("str_")))
+
+ del _msg, _specific_msg, _int_extended_msg, _type_info, _builtins
from .core import round, abs, max, min
# now that numpy modules are imported, can initialize limits
@@ -349,10 +383,10 @@ else:
error_message = "{}: {}".format(w[-1].category.__name__, str(w[-1].message))
msg = (
"Polyfit sanity test emitted a warning, most likely due "
- "to using a buggy Accelerate backend. If you compiled "
- "yourself, more information is available at "
- "https://numpy.org/doc/stable/user/building.html#accelerated-blas-lapack-libraries "
- "Otherwise report this to the vendor "
+ "to using a buggy Accelerate backend."
+ "\nIf you compiled yourself, more information is available at:"
+ "\nhttps://numpy.org/doc/stable/user/building.html#accelerated-blas-lapack-libraries"
+ "\nOtherwise report this to the vendor "
"that provided NumPy.\n{}\n".format(error_message))
raise RuntimeError(msg)
del _mac_os_check
@@ -384,3 +418,12 @@ else:
# Note that this will currently only make a difference on Linux
core.multiarray._set_madvise_hugepage(use_hugepage)
+
+ # Give a warning if NumPy is reloaded or imported on a sub-interpreter
+ # We do this from python, since the C-module may not be reloaded and
+ # it is tidier organized.
+ core.multiarray._multiarray_umath._reload_guard()
+
+from ._version import get_versions
+__version__ = get_versions()['version']
+del get_versions
diff --git a/numpy/__init__.pyi b/numpy/__init__.pyi
index ad37979ed..0c6ac34f9 100644
--- a/numpy/__init__.pyi
+++ b/numpy/__init__.pyi
@@ -1,30 +1,126 @@
import builtins
+import os
import sys
+import mmap
+import ctypes as ct
+import array as _array
import datetime as dt
from abc import abstractmethod
-from types import TracebackType
+from types import TracebackType, MappingProxyType
from contextlib import ContextDecorator
+from numpy._pytesttester import PytestTester
+from numpy.core.multiarray import flagsobj
from numpy.core._internal import _ctypes
+from numpy.core.getlimits import MachArLike
+
from numpy.typing import (
+ # Arrays
ArrayLike,
+ NDArray,
+ _SupportsArray,
+ _NestedSequence,
+ _RecursiveSequence,
+ _SupportsArray,
+ _ArrayLikeBool_co,
+ _ArrayLikeUInt_co,
+ _ArrayLikeInt_co,
+ _ArrayLikeFloat_co,
+ _ArrayLikeComplex_co,
+ _ArrayLikeNumber_co,
+ _ArrayLikeTD64_co,
+ _ArrayLikeDT64_co,
+ _ArrayLikeObject_co,
+
+ # DTypes
DTypeLike,
- _Shape,
- _ShapeLike,
- _CharLike,
- _BoolLike,
- _IntLike,
- _FloatLike,
- _ComplexLike,
- _NumberLike,
_SupportsDType,
_VoidDTypeLike,
+
+ # Shapes
+ _Shape,
+ _ShapeLike,
+
+ # Scalars
+ _CharLike_co,
+ _BoolLike_co,
+ _IntLike_co,
+ _FloatLike_co,
+ _ComplexLike_co,
+ _TD64Like_co,
+ _NumberLike_co,
+ _ScalarLike_co,
+
+ # `number` precision
NBitBase,
+ _256Bit,
+ _128Bit,
+ _96Bit,
+ _80Bit,
_64Bit,
_32Bit,
_16Bit,
_8Bit,
+ _NBitByte,
+ _NBitShort,
+ _NBitIntC,
+ _NBitIntP,
+ _NBitInt,
+ _NBitLongLong,
+ _NBitHalf,
+ _NBitSingle,
+ _NBitDouble,
+ _NBitLongDouble,
+
+ # Character codes
+ _BoolCodes,
+ _UInt8Codes,
+ _UInt16Codes,
+ _UInt32Codes,
+ _UInt64Codes,
+ _Int8Codes,
+ _Int16Codes,
+ _Int32Codes,
+ _Int64Codes,
+ _Float16Codes,
+ _Float32Codes,
+ _Float64Codes,
+ _Complex64Codes,
+ _Complex128Codes,
+ _ByteCodes,
+ _ShortCodes,
+ _IntCCodes,
+ _IntPCodes,
+ _IntCodes,
+ _LongLongCodes,
+ _UByteCodes,
+ _UShortCodes,
+ _UIntCCodes,
+ _UIntPCodes,
+ _UIntCodes,
+ _ULongLongCodes,
+ _HalfCodes,
+ _SingleCodes,
+ _DoubleCodes,
+ _LongDoubleCodes,
+ _CSingleCodes,
+ _CDoubleCodes,
+ _CLongDoubleCodes,
+ _DT64Codes,
+ _TD64Codes,
+ _StrCodes,
+ _BytesCodes,
+ _VoidCodes,
+ _ObjectCodes,
+
+ # Ufuncs
+ _UFunc_Nin1_Nout1,
+ _UFunc_Nin2_Nout1,
+ _UFunc_Nin1_Nout2,
+ _UFunc_Nin2_Nout2,
+ _GUFunc_Nin2_Nout1,
)
+
from numpy.typing._callable import (
_BoolOp,
_BoolBitOp,
@@ -50,6 +146,23 @@ from numpy.typing._callable import (
_ComparisonOp,
)
+# NOTE: Numpy's mypy plugin is used for removing the types unavailable
+# to the specific platform
+from numpy.typing._extended_precision import (
+ uint128 as uint128,
+ uint256 as uint256,
+ int128 as int128,
+ int256 as int256,
+ float80 as float80,
+ float96 as float96,
+ float128 as float128,
+ float256 as float256,
+ complex160 as complex160,
+ complex192 as complex192,
+ complex256 as complex256,
+ complex512 as complex512,
+)
+
from typing import (
Any,
ByteString,
@@ -60,8 +173,10 @@ from typing import (
Generic,
IO,
Iterable,
+ Iterator,
List,
Mapping,
+ NoReturn,
Optional,
overload,
Sequence,
@@ -77,81 +192,74 @@ from typing import (
)
if sys.version_info >= (3, 8):
- from typing import Literal, Protocol, SupportsIndex, Final
+ from typing import Literal as L, Protocol, SupportsIndex, Final
else:
- from typing_extensions import Literal, Protocol, Final
- class SupportsIndex(Protocol):
- def __index__(self) -> int: ...
+ from typing_extensions import Literal as L, Protocol, SupportsIndex, Final
# Ensures that the stubs are picked up
from numpy import (
- char,
- ctypeslib,
- emath,
- fft,
- lib,
- linalg,
- ma,
- matrixlib,
- polynomial,
- random,
- rec,
- testing,
- version,
+ char as char,
+ ctypeslib as ctypeslib,
+ fft as fft,
+ lib as lib,
+ linalg as linalg,
+ ma as ma,
+ matrixlib as matrixlib,
+ polynomial as polynomial,
+ random as random,
+ rec as rec,
+ testing as testing,
+ version as version,
)
from numpy.core.function_base import (
- linspace,
- logspace,
- geomspace,
+ linspace as linspace,
+ logspace as logspace,
+ geomspace as geomspace,
)
from numpy.core.fromnumeric import (
- take,
- reshape,
- choose,
- repeat,
- put,
- swapaxes,
- transpose,
- partition,
- argpartition,
- sort,
- argsort,
- argmax,
- argmin,
- searchsorted,
- resize,
- squeeze,
- diagonal,
- trace,
- ravel,
- nonzero,
- shape,
- compress,
- clip,
- sum,
- all,
- any,
- cumsum,
- ptp,
- amax,
- amin,
- prod,
- cumprod,
- ndim,
- size,
- around,
- mean,
- std,
- var,
+ take as take,
+ reshape as reshape,
+ choose as choose,
+ repeat as repeat,
+ put as put,
+ swapaxes as swapaxes,
+ transpose as transpose,
+ partition as partition,
+ argpartition as argpartition,
+ sort as sort,
+ argsort as argsort,
+ argmax as argmax,
+ argmin as argmin,
+ searchsorted as searchsorted,
+ resize as resize,
+ squeeze as squeeze,
+ diagonal as diagonal,
+ trace as trace,
+ ravel as ravel,
+ nonzero as nonzero,
+ shape as shape,
+ compress as compress,
+ clip as clip,
+ sum as sum,
+ all as all,
+ any as any,
+ cumsum as cumsum,
+ ptp as ptp,
+ amax as amax,
+ amin as amin,
+ prod as prod,
+ cumprod as cumprod,
+ ndim as ndim,
+ size as size,
+ around as around,
+ mean as mean,
+ std as std,
+ var as var,
)
from numpy.core._asarray import (
- asarray as asarray,
- asanyarray as asanyarray,
- ascontiguousarray as ascontiguousarray,
- asfortranarray as asfortranarray,
require as require,
)
@@ -173,11 +281,78 @@ from numpy.core._ufunc_config import (
_ErrDictOptional,
)
+from numpy.core.arrayprint import (
+ set_printoptions as set_printoptions,
+ get_printoptions as get_printoptions,
+ array2string as array2string,
+ format_float_scientific as format_float_scientific,
+ format_float_positional as format_float_positional,
+ array_repr as array_repr,
+ array_str as array_str,
+ set_string_function as set_string_function,
+ printoptions as printoptions,
+)
+
+from numpy.core.einsumfunc import (
+ einsum as einsum,
+ einsum_path as einsum_path,
+)
+
+from numpy.core.multiarray import (
+ ALLOW_THREADS as ALLOW_THREADS,
+ BUFSIZE as BUFSIZE,
+ CLIP as CLIP,
+ MAXDIMS as MAXDIMS,
+ MAY_SHARE_BOUNDS as MAY_SHARE_BOUNDS,
+ MAY_SHARE_EXACT as MAY_SHARE_EXACT,
+ RAISE as RAISE,
+ WRAP as WRAP,
+ tracemalloc_domain as tracemalloc_domain,
+ array as array,
+ empty_like as empty_like,
+ empty as empty,
+ zeros as zeros,
+ concatenate as concatenate,
+ inner as inner,
+ where as where,
+ lexsort as lexsort,
+ can_cast as can_cast,
+ min_scalar_type as min_scalar_type,
+ result_type as result_type,
+ dot as dot,
+ vdot as vdot,
+ bincount as bincount,
+ copyto as copyto,
+ putmask as putmask,
+ packbits as packbits,
+ unpackbits as unpackbits,
+ shares_memory as shares_memory,
+ may_share_memory as may_share_memory,
+ asarray as asarray,
+ asanyarray as asanyarray,
+ ascontiguousarray as ascontiguousarray,
+ asfortranarray as asfortranarray,
+ arange as arange,
+ busday_count as busday_count,
+ busday_offset as busday_offset,
+ compare_chararrays as compare_chararrays,
+ datetime_as_string as datetime_as_string,
+ datetime_data as datetime_data,
+ frombuffer as frombuffer,
+ fromfile as fromfile,
+ fromiter as fromiter,
+ is_busday as is_busday,
+ promote_types as promote_types,
+ seterrobj as seterrobj,
+ geterrobj as geterrobj,
+ fromstring as fromstring,
+ frompyfunc as frompyfunc,
+)
+
from numpy.core.numeric import (
zeros_like as zeros_like,
ones as ones,
ones_like as ones_like,
- empty_like as empty_like,
full as full,
full_like as full_like,
count_nonzero as count_nonzero,
@@ -213,6 +388,10 @@ from numpy.core.numerictypes import (
issubdtype as issubdtype,
sctype2char as sctype2char,
find_common_type as find_common_type,
+ nbytes as nbytes,
+ cast as cast,
+ ScalarType as ScalarType,
+ typecodes as typecodes,
)
from numpy.core.shape_base import (
@@ -225,625 +404,659 @@ from numpy.core.shape_base import (
vstack as vstack,
)
-# Add an object to `__all__` if their stubs are defined in an external file;
-# their stubs will not be recognized otherwise.
-# NOTE: This is redundant for objects defined within this file.
-__all__ = [
- "linspace",
- "logspace",
- "geomspace",
- "take",
- "reshape",
- "choose",
- "repeat",
- "put",
- "swapaxes",
- "transpose",
- "partition",
- "argpartition",
- "sort",
- "argsort",
- "argmax",
- "argmin",
- "searchsorted",
- "resize",
- "squeeze",
- "diagonal",
- "trace",
- "ravel",
- "nonzero",
- "shape",
- "compress",
- "clip",
- "sum",
- "all",
- "any",
- "cumsum",
- "ptp",
- "amax",
- "amin",
- "prod",
- "cumprod",
- "ndim",
- "size",
- "around",
- "mean",
- "std",
- "var",
-]
+from numpy.lib import (
+ emath as emath,
+)
+
+from numpy.lib.arraypad import (
+ pad as pad,
+)
+
+from numpy.lib.arraysetops import (
+ ediff1d as ediff1d,
+ intersect1d as intersect1d,
+ setxor1d as setxor1d,
+ union1d as union1d,
+ setdiff1d as setdiff1d,
+ unique as unique,
+ in1d as in1d,
+ isin as isin,
+)
+
+from numpy.lib.arrayterator import (
+ Arrayterator as Arrayterator,
+)
+
+from numpy.lib.function_base import (
+ select as select,
+ piecewise as piecewise,
+ trim_zeros as trim_zeros,
+ copy as copy,
+ iterable as iterable,
+ percentile as percentile,
+ diff as diff,
+ gradient as gradient,
+ angle as angle,
+ unwrap as unwrap,
+ sort_complex as sort_complex,
+ disp as disp,
+ flip as flip,
+ rot90 as rot90,
+ extract as extract,
+ place as place,
+ asarray_chkfinite as asarray_chkfinite,
+ average as average,
+ bincount as bincount,
+ digitize as digitize,
+ cov as cov,
+ corrcoef as corrcoef,
+ msort as msort,
+ median as median,
+ sinc as sinc,
+ hamming as hamming,
+ hanning as hanning,
+ bartlett as bartlett,
+ blackman as blackman,
+ kaiser as kaiser,
+ trapz as trapz,
+ i0 as i0,
+ add_newdoc as add_newdoc,
+ add_docstring as add_docstring,
+ meshgrid as meshgrid,
+ delete as delete,
+ insert as insert,
+ append as append,
+ interp as interp,
+ add_newdoc_ufunc as add_newdoc_ufunc,
+ quantile as quantile,
+)
+
+from numpy.lib.histograms import (
+ histogram_bin_edges as histogram_bin_edges,
+ histogram as histogram,
+ histogramdd as histogramdd,
+)
+
+from numpy.lib.index_tricks import (
+ ravel_multi_index as ravel_multi_index,
+ unravel_index as unravel_index,
+ mgrid as mgrid,
+ ogrid as ogrid,
+ r_ as r_,
+ c_ as c_,
+ s_ as s_,
+ index_exp as index_exp,
+ ix_ as ix_,
+ fill_diagonal as fill_diagonal,
+ diag_indices as diag_indices,
+ diag_indices_from as diag_indices_from,
+)
+
+from numpy.lib.nanfunctions import (
+ nansum as nansum,
+ nanmax as nanmax,
+ nanmin as nanmin,
+ nanargmax as nanargmax,
+ nanargmin as nanargmin,
+ nanmean as nanmean,
+ nanmedian as nanmedian,
+ nanpercentile as nanpercentile,
+ nanvar as nanvar,
+ nanstd as nanstd,
+ nanprod as nanprod,
+ nancumsum as nancumsum,
+ nancumprod as nancumprod,
+ nanquantile as nanquantile,
+)
+
+from numpy.lib.npyio import (
+ savetxt as savetxt,
+ loadtxt as loadtxt,
+ genfromtxt as genfromtxt,
+ recfromtxt as recfromtxt,
+ recfromcsv as recfromcsv,
+ load as load,
+ loads as loads,
+ save as save,
+ savez as savez,
+ savez_compressed as savez_compressed,
+ packbits as packbits,
+ unpackbits as unpackbits,
+ fromregex as fromregex,
+)
+
+from numpy.lib.polynomial import (
+ poly as poly,
+ roots as roots,
+ polyint as polyint,
+ polyder as polyder,
+ polyadd as polyadd,
+ polysub as polysub,
+ polymul as polymul,
+ polydiv as polydiv,
+ polyval as polyval,
+ polyfit as polyfit,
+)
+
+from numpy.lib.shape_base import (
+ column_stack as column_stack,
+ row_stack as row_stack,
+ dstack as dstack,
+ array_split as array_split,
+ split as split,
+ hsplit as hsplit,
+ vsplit as vsplit,
+ dsplit as dsplit,
+ apply_over_axes as apply_over_axes,
+ expand_dims as expand_dims,
+ apply_along_axis as apply_along_axis,
+ kron as kron,
+ tile as tile,
+ get_array_wrap as get_array_wrap,
+ take_along_axis as take_along_axis,
+ put_along_axis as put_along_axis,
+)
+
+from numpy.lib.stride_tricks import (
+ broadcast_to as broadcast_to,
+ broadcast_arrays as broadcast_arrays,
+ broadcast_shapes as broadcast_shapes,
+)
+
+from numpy.lib.twodim_base import (
+ diag as diag,
+ diagflat as diagflat,
+ eye as eye,
+ fliplr as fliplr,
+ flipud as flipud,
+ tri as tri,
+ triu as triu,
+ tril as tril,
+ vander as vander,
+ histogram2d as histogram2d,
+ mask_indices as mask_indices,
+ tril_indices as tril_indices,
+ tril_indices_from as tril_indices_from,
+ triu_indices as triu_indices,
+ triu_indices_from as triu_indices_from,
+)
+
+from numpy.lib.type_check import (
+ mintypecode as mintypecode,
+ asfarray as asfarray,
+ real as real,
+ imag as imag,
+ iscomplex as iscomplex,
+ isreal as isreal,
+ iscomplexobj as iscomplexobj,
+ isrealobj as isrealobj,
+ nan_to_num as nan_to_num,
+ real_if_close as real_if_close,
+ typename as typename,
+ common_type as common_type,
+)
+
+from numpy.lib.ufunclike import (
+ fix as fix,
+ isposinf as isposinf,
+ isneginf as isneginf,
+)
+
+from numpy.lib.utils import (
+ issubclass_ as issubclass_,
+ issubsctype as issubsctype,
+ issubdtype as issubdtype,
+ deprecate as deprecate,
+ deprecate_with_doc as deprecate_with_doc,
+ get_include as get_include,
+ info as info,
+ source as source,
+ who as who,
+ lookfor as lookfor,
+ byte_bounds as byte_bounds,
+ safe_eval as safe_eval,
+)
+
+from numpy.matrixlib import (
+ asmatrix as asmatrix,
+ mat as mat,
+ bmat as bmat,
+)
+
+__all__: List[str]
+__path__: List[str]
+__version__: str
+__git_version__: str
+test: PytestTester
+
+# TODO: Move placeholders to their respective module once
+# their annotations are properly implemented
+#
+# Placeholders for classes
+# TODO: Remove `__getattr__` once the classes are stubbed out
+class MachAr:
+ def __init__(
+ self,
+ float_conv: Any = ...,
+ int_conv: Any = ...,
+ float_to_float: Any = ...,
+ float_to_str: Any = ...,
+ title: Any = ...,
+ ) -> None: ...
+ def __getattr__(self, key: str) -> Any: ...
+
+class chararray(ndarray[_ShapeType, _DType_co]):
+ def __new__(
+ subtype,
+ shape: Any,
+ itemsize: Any = ...,
+ unicode: Any = ...,
+ buffer: Any = ...,
+ offset: Any = ...,
+ strides: Any = ...,
+ order: Any = ...,
+ ) -> Any: ...
+ def __array_finalize__(self, obj): ...
+ def argsort(self, axis=..., kind=..., order=...): ...
+ def capitalize(self): ...
+ def center(self, width, fillchar=...): ...
+ def count(self, sub, start=..., end=...): ...
+ def decode(self, encoding=..., errors=...): ...
+ def encode(self, encoding=..., errors=...): ...
+ def endswith(self, suffix, start=..., end=...): ...
+ def expandtabs(self, tabsize=...): ...
+ def find(self, sub, start=..., end=...): ...
+ def index(self, sub, start=..., end=...): ...
+ def isalnum(self): ...
+ def isalpha(self): ...
+ def isdigit(self): ...
+ def islower(self): ...
+ def isspace(self): ...
+ def istitle(self): ...
+ def isupper(self): ...
+ def join(self, seq): ...
+ def ljust(self, width, fillchar=...): ...
+ def lower(self): ...
+ def lstrip(self, chars=...): ...
+ def partition(self, sep): ...
+ def replace(self, old, new, count=...): ...
+ def rfind(self, sub, start=..., end=...): ...
+ def rindex(self, sub, start=..., end=...): ...
+ def rjust(self, width, fillchar=...): ...
+ def rpartition(self, sep): ...
+ def rsplit(self, sep=..., maxsplit=...): ...
+ def rstrip(self, chars=...): ...
+ def split(self, sep=..., maxsplit=...): ...
+ def splitlines(self, keepends=...): ...
+ def startswith(self, prefix, start=..., end=...): ...
+ def strip(self, chars=...): ...
+ def swapcase(self): ...
+ def title(self): ...
+ def translate(self, table, deletechars=...): ...
+ def upper(self): ...
+ def zfill(self, width): ...
+ def isnumeric(self): ...
+ def isdecimal(self): ...
+
+class format_parser:
+ def __init__(
+ self,
+ formats: Any,
+ names: Any,
+ titles: Any,
+ aligned: Any = ...,
+ byteorder: Any = ...,
+ ) -> None: ...
-DataSource: Any
-MachAr: Any
-ScalarType: Any
-angle: Any
-append: Any
-apply_along_axis: Any
-apply_over_axes: Any
-arange: Any
-array2string: Any
-array_repr: Any
-array_split: Any
-array_str: Any
-asarray_chkfinite: Any
-asfarray: Any
-asmatrix: Any
-asscalar: Any
-average: Any
-bartlett: Any
-bincount: Any
-bitwise_not: Any
-blackman: Any
-bmat: Any
-bool8: Any
-broadcast: Any
-broadcast_arrays: Any
-broadcast_to: Any
-busday_count: Any
-busday_offset: Any
-busdaycalendar: Any
-byte: Any
-byte_bounds: Any
-bytes0: Any
-c_: Any
-can_cast: Any
-cast: Any
-cdouble: Any
-cfloat: Any
-chararray: Any
-clongdouble: Any
-clongfloat: Any
-column_stack: Any
-common_type: Any
-compare_chararrays: Any
-complex256: Any
-complex_: Any
-concatenate: Any
-conj: Any
-copy: Any
-copyto: Any
-corrcoef: Any
-cov: Any
-csingle: Any
-cumproduct: Any
-datetime_as_string: Any
-datetime_data: Any
-delete: Any
-deprecate: Any
-deprecate_with_doc: Any
-diag: Any
-diag_indices: Any
-diag_indices_from: Any
-diagflat: Any
-diff: Any
-digitize: Any
-disp: Any
-divide: Any
-dot: Any
-double: Any
-dsplit: Any
-dstack: Any
-ediff1d: Any
-einsum: Any
-einsum_path: Any
-expand_dims: Any
-extract: Any
-eye: Any
-fill_diagonal: Any
-finfo: Any
-fix: Any
-flip: Any
-fliplr: Any
-flipud: Any
-float128: Any
-float_: Any
-format_float_positional: Any
-format_float_scientific: Any
-format_parser: Any
-frombuffer: Any
-fromfile: Any
-fromiter: Any
-frompyfunc: Any
-fromregex: Any
-fromstring: Any
-genfromtxt: Any
-get_include: Any
-get_printoptions: Any
-geterrobj: Any
-gradient: Any
-half: Any
-hamming: Any
-hanning: Any
-histogram: Any
-histogram2d: Any
-histogram_bin_edges: Any
-histogramdd: Any
-hsplit: Any
-i0: Any
-iinfo: Any
-imag: Any
-in1d: Any
-index_exp: Any
-info: Any
-inner: Any
-insert: Any
-int0: Any
-int_: Any
-intc: Any
-interp: Any
-intersect1d: Any
-intp: Any
-is_busday: Any
-iscomplex: Any
-iscomplexobj: Any
-isin: Any
-isneginf: Any
-isposinf: Any
-isreal: Any
-isrealobj: Any
-iterable: Any
-ix_: Any
-kaiser: Any
-kron: Any
-lexsort: Any
-load: Any
-loads: Any
-loadtxt: Any
-longcomplex: Any
-longdouble: Any
-longfloat: Any
-longlong: Any
-lookfor: Any
-mafromtxt: Any
-mask_indices: Any
-mat: Any
-matrix: Any
-max: Any
-may_share_memory: Any
-median: Any
-memmap: Any
-meshgrid: Any
-mgrid: Any
-min: Any
-min_scalar_type: Any
-mintypecode: Any
-mod: Any
-msort: Any
-nan_to_num: Any
-nanargmax: Any
-nanargmin: Any
-nancumprod: Any
-nancumsum: Any
-nanmax: Any
-nanmean: Any
-nanmedian: Any
-nanmin: Any
-nanpercentile: Any
-nanprod: Any
-nanquantile: Any
-nanstd: Any
-nansum: Any
-nanvar: Any
-nbytes: Any
-ndenumerate: Any
-ndfromtxt: Any
-ndindex: Any
-nditer: Any
-nested_iters: Any
-newaxis: Any
-numarray: Any
-object0: Any
-ogrid: Any
-packbits: Any
-pad: Any
-percentile: Any
-piecewise: Any
-place: Any
-poly: Any
-poly1d: Any
-polyadd: Any
-polyder: Any
-polydiv: Any
-polyfit: Any
-polyint: Any
-polymul: Any
-polysub: Any
-polyval: Any
-printoptions: Any
-product: Any
-promote_types: Any
-put_along_axis: Any
-putmask: Any
-quantile: Any
-r_: Any
-ravel_multi_index: Any
-real: Any
-real_if_close: Any
-recarray: Any
-recfromcsv: Any
-recfromtxt: Any
-record: Any
-result_type: Any
-roots: Any
-rot90: Any
-round: Any
-round_: Any
-row_stack: Any
-s_: Any
-save: Any
-savetxt: Any
-savez: Any
-savez_compressed: Any
-select: Any
-set_printoptions: Any
-set_string_function: Any
-setdiff1d: Any
-seterrobj: Any
-setxor1d: Any
-shares_memory: Any
-short: Any
-show_config: Any
-sinc: Any
-single: Any
-singlecomplex: Any
-sort_complex: Any
-source: Any
-split: Any
-string_: Any
-take_along_axis: Any
-tile: Any
-trapz: Any
-tri: Any
-tril: Any
-tril_indices: Any
-tril_indices_from: Any
-trim_zeros: Any
-triu: Any
-triu_indices: Any
-triu_indices_from: Any
-typeDict: Any
-typecodes: Any
-typename: Any
-ubyte: Any
-uint: Any
-uint0: Any
-uintc: Any
-uintp: Any
-ulonglong: Any
-union1d: Any
-unique: Any
-unpackbits: Any
-unravel_index: Any
-unwrap: Any
-ushort: Any
-vander: Any
-vdot: Any
-vectorize: Any
-void0: Any
-vsplit: Any
-where: Any
-who: Any
+class matrix(ndarray[_ShapeType, _DType_co]):
+ def __new__(
+ subtype,
+ data: Any,
+ dtype: Any = ...,
+ copy: Any = ...,
+ ) -> Any: ...
+ def __array_finalize__(self, obj): ...
+ def __getitem__(self, index): ...
+ def __mul__(self, other): ...
+ def __rmul__(self, other): ...
+ def __imul__(self, other): ...
+ def __pow__(self, other): ...
+ def __ipow__(self, other): ...
+ def __rpow__(self, other): ...
+ def tolist(self): ...
+ def sum(self, axis=..., dtype=..., out=...): ...
+ def squeeze(self, axis=...): ...
+ def flatten(self, order=...): ...
+ def mean(self, axis=..., dtype=..., out=...): ...
+ def std(self, axis=..., dtype=..., out=..., ddof=...): ...
+ def var(self, axis=..., dtype=..., out=..., ddof=...): ...
+ def prod(self, axis=..., dtype=..., out=...): ...
+ def any(self, axis=..., out=...): ...
+ def all(self, axis=..., out=...): ...
+ def max(self, axis=..., out=...): ...
+ def argmax(self, axis=..., out=...): ...
+ def min(self, axis=..., out=...): ...
+ def argmin(self, axis=..., out=...): ...
+ def ptp(self, axis=..., out=...): ...
+ def ravel(self, order=...): ...
+ @property
+ def T(self): ...
+ @property
+ def I(self): ...
+ @property
+ def A(self): ...
+ @property
+ def A1(self): ...
+ @property
+ def H(self): ...
+ def getT(self): ...
+ def getA(self): ...
+ def getA1(self): ...
+ def getH(self): ...
+ def getI(self): ...
+
+class memmap(ndarray[_ShapeType, _DType_co]):
+ def __new__(
+ subtype,
+ filename: Any,
+ dtype: Any = ...,
+ mode: Any = ...,
+ offset: Any = ...,
+ shape: Any = ...,
+ order: Any = ...,
+ ) -> Any: ...
+ def __getattr__(self, key: str) -> Any: ...
+
+class nditer:
+ def __new__(
+ cls,
+ op: Any,
+ flags: Any = ...,
+ op_flags: Any = ...,
+ op_dtypes: Any = ...,
+ order: Any = ...,
+ casting: Any = ...,
+ op_axes: Any = ...,
+ itershape: Any = ...,
+ buffersize: Any = ...,
+ ) -> Any: ...
+ def __getattr__(self, key: str) -> Any: ...
+ def __enter__(self) -> nditer: ...
+ def __exit__(
+ self,
+ exc_type: None | Type[BaseException],
+ exc_value: None | BaseException,
+ traceback: None | TracebackType,
+ ) -> None: ...
+ def __iter__(self) -> Iterator[Any]: ...
+ def __next__(self) -> Any: ...
+ def __len__(self) -> int: ...
+ def __copy__(self) -> nditer: ...
+ def __getitem__(self, index: SupportsIndex | slice) -> Any: ...
+ def __setitem__(self, index: SupportsIndex | slice, value: Any) -> None: ...
+ def __delitem__(self, key: SupportsIndex | slice) -> None: ...
+
+
+class poly1d:
+ def __init__(
+ self,
+ c_or_r: Any,
+ r: Any = ...,
+ variable: Any = ...,
+ ) -> None: ...
+ def __call__(self, val: Any) -> Any: ...
+ __hash__: Any
+ @property
+ def coeffs(self): ...
+ @coeffs.setter
+ def coeffs(self, value): ...
+ @property
+ def c(self): ...
+ @c.setter
+ def c(self, value): ...
+ @property
+ def coef(self): ...
+ @coef.setter
+ def coef(self, value): ...
+ @property
+ def coefficients(self): ...
+ @coefficients.setter
+ def coefficients(self, value): ...
+ @property
+ def variable(self): ...
+ @property
+ def order(self): ...
+ @property
+ def o(self): ...
+ @property
+ def roots(self): ...
+ @property
+ def r(self): ...
+ def __array__(self, t=...): ...
+ def __len__(self): ...
+ def __neg__(self): ...
+ def __pos__(self): ...
+ def __mul__(self, other): ...
+ def __rmul__(self, other): ...
+ def __add__(self, other): ...
+ def __radd__(self, other): ...
+ def __pow__(self, val): ...
+ def __sub__(self, other): ...
+ def __rsub__(self, other): ...
+ def __div__(self, other): ...
+ def __truediv__(self, other): ...
+ def __rdiv__(self, other): ...
+ def __rtruediv__(self, other): ...
+ def __eq__(self, other): ...
+ def __ne__(self, other): ...
+ def __getitem__(self, val): ...
+ def __setitem__(self, key, val): ...
+ def __iter__(self): ...
+ def integ(self, m=..., k=...): ...
+ def deriv(self, m=...): ...
+
+class recarray(ndarray[_ShapeType, _DType_co]):
+ def __new__(
+ subtype,
+ shape: Any,
+ dtype: Any = ...,
+ buf: Any = ...,
+ offset: Any = ...,
+ strides: Any = ...,
+ formats: Any = ...,
+ names: Any = ...,
+ titles: Any = ...,
+ byteorder: Any = ...,
+ aligned: Any = ...,
+ order: Any = ...,
+ ) -> Any: ...
+ def __array_finalize__(self, obj): ...
+ def __getattribute__(self, attr): ...
+ def __setattr__(self, attr, val): ...
+ def __getitem__(self, indx): ...
+ def field(self, attr, val=...): ...
+
+class record(void):
+ def __getattribute__(self, attr): ...
+ def __setattr__(self, attr, val): ...
+ def __getitem__(self, indx): ...
+ def pprint(self): ...
+
+class vectorize:
+ pyfunc: Any
+ cache: Any
+ signature: Any
+ otypes: Any
+ excluded: Any
+ __doc__: Any
+ def __init__(
+ self,
+ pyfunc,
+ otypes: Any = ...,
+ doc: Any = ...,
+ excluded: Any = ...,
+ cache: Any = ...,
+ signature: Any = ...,
+ ) -> None: ...
+ def __call__(self, *args: Any, **kwargs: Any) -> Any: ...
+
+# Some of these are aliases; others are wrappers with an identical signature
+round = around
+round_ = around
+max = amax
+min = amin
+product = prod
+cumproduct = cumprod
+sometrue = any
+alltrue = all
+
+def show_config() -> None: ...
+
+# TODO: Sort out which parameters are positional-only
+def nested_iters(*args, **kwargs): ... # TODO: Sort out parameters
_NdArraySubClass = TypeVar("_NdArraySubClass", bound=ndarray)
-_DTypeScalar = TypeVar("_DTypeScalar", bound=generic)
-_ByteOrder = Literal["S", "<", ">", "=", "|", "L", "B", "N", "I"]
+_DTypeScalar_co = TypeVar("_DTypeScalar_co", covariant=True, bound=generic)
+_ByteOrder = L["S", "<", ">", "=", "|", "L", "B", "N", "I"]
-class dtype(Generic[_DTypeScalar]):
- names: Optional[Tuple[str, ...]]
+class dtype(Generic[_DTypeScalar_co]):
+ names: None | Tuple[str, ...]
# Overload for subclass of generic
@overload
def __new__(
cls,
- dtype: Type[_DTypeScalar],
+ dtype: Type[_DTypeScalar_co],
align: bool = ...,
copy: bool = ...,
- ) -> dtype[_DTypeScalar]: ...
+ ) -> dtype[_DTypeScalar_co]: ...
# Overloads for string aliases, Python types, and some assorted
# other special cases. Order is sometimes important because of the
# subtype relationships
#
- # bool < int < float < complex
+ # bool < int < float < complex < object
#
# so we have to make sure the overloads for the narrowest type is
# first.
+ # Builtin types
@overload
- def __new__(
- cls,
- dtype: Union[
- Type[bool],
- Literal[
- "?",
- "=?",
- "<?",
- ">?",
- "bool",
- "bool_",
- ],
- ],
- align: bool = ...,
- copy: bool = ...,
- ) -> dtype[bool_]: ...
+ def __new__(cls, dtype: Type[bool], align: bool = ..., copy: bool = ...) -> dtype[bool_]: ...
@overload
- def __new__(
- cls,
- dtype: Literal[
- "uint8",
- "u1",
- "=u1",
- "<u1",
- ">u1",
- ],
- align: bool = ...,
- copy: bool = ...,
- ) -> dtype[uint8]: ...
+ def __new__(cls, dtype: Type[int], align: bool = ..., copy: bool = ...) -> dtype[int_]: ...
@overload
- def __new__(
- cls,
- dtype: Literal[
- "uint16",
- "u2",
- "=u2",
- "<u2",
- ">u2",
- ],
- align: bool = ...,
- copy: bool = ...,
- ) -> dtype[uint16]: ...
+ def __new__(cls, dtype: None | Type[float], align: bool = ..., copy: bool = ...) -> dtype[float_]: ...
@overload
- def __new__(
- cls,
- dtype: Literal[
- "uint32",
- "u4",
- "=u4",
- "<u4",
- ">u4",
- ],
- align: bool = ...,
- copy: bool = ...,
- ) -> dtype[uint32]: ...
+ def __new__(cls, dtype: Type[complex], align: bool = ..., copy: bool = ...) -> dtype[complex_]: ...
@overload
- def __new__(
- cls,
- dtype: Literal[
- "uint64",
- "u8",
- "=u8",
- "<u8",
- ">u8",
- ],
- align: bool = ...,
- copy: bool = ...,
- ) -> dtype[uint64]: ...
+ def __new__(cls, dtype: Type[str], align: bool = ..., copy: bool = ...) -> dtype[str_]: ...
@overload
- def __new__(
- cls,
- dtype: Literal[
- "int8",
- "i1",
- "=i1",
- "<i1",
- ">i1",
- ],
- align: bool = ...,
- copy: bool = ...,
- ) -> dtype[int8]: ...
+ def __new__(cls, dtype: Type[bytes], align: bool = ..., copy: bool = ...) -> dtype[bytes_]: ...
+
+ # `unsignedinteger` string-based representations and ctypes
@overload
- def __new__(
- cls,
- dtype: Literal[
- "int16",
- "i2",
- "=i2",
- "<i2",
- ">i2",
- ],
- align: bool = ...,
- copy: bool = ...,
- ) -> dtype[int16]: ...
+ def __new__(cls, dtype: _UInt8Codes | Type[ct.c_uint8], align: bool = ..., copy: bool = ...) -> dtype[uint8]: ...
@overload
- def __new__(
- cls,
- dtype: Literal[
- "int32",
- "i4",
- "=i4",
- "<i4",
- ">i4",
- ],
- align: bool = ...,
- copy: bool = ...,
- ) -> dtype[int32]: ...
+ def __new__(cls, dtype: _UInt16Codes | Type[ct.c_uint16], align: bool = ..., copy: bool = ...) -> dtype[uint16]: ...
@overload
- def __new__(
- cls,
- dtype: Literal[
- "int64",
- "i8",
- "=i8",
- "<i8",
- ">i8",
- ],
- align: bool = ...,
- copy: bool = ...,
- ) -> dtype[int64]: ...
- # "int"/int resolve to int_, which is system dependent and as of
- # now untyped. Long-term we'll do something fancier here.
+ def __new__(cls, dtype: _UInt32Codes | Type[ct.c_uint32], align: bool = ..., copy: bool = ...) -> dtype[uint32]: ...
@overload
- def __new__(
- cls,
- dtype: Union[Type[int], Literal["int"]],
- align: bool = ...,
- copy: bool = ...,
- ) -> dtype: ...
+ def __new__(cls, dtype: _UInt64Codes | Type[ct.c_uint64], align: bool = ..., copy: bool = ...) -> dtype[uint64]: ...
@overload
- def __new__(
- cls,
- dtype: Literal[
- "float16",
- "f4",
- "=f4",
- "<f4",
- ">f4",
- "e",
- "=e",
- "<e",
- ">e",
- "half",
- ],
- align: bool = ...,
- copy: bool = ...,
- ) -> dtype[float16]: ...
+ def __new__(cls, dtype: _UByteCodes | Type[ct.c_ubyte], align: bool = ..., copy: bool = ...) -> dtype[ubyte]: ...
@overload
- def __new__(
- cls,
- dtype: Literal[
- "float32",
- "f4",
- "=f4",
- "<f4",
- ">f4",
- "f",
- "=f",
- "<f",
- ">f",
- "single",
- ],
- align: bool = ...,
- copy: bool = ...,
- ) -> dtype[float32]: ...
+ def __new__(cls, dtype: _UShortCodes | Type[ct.c_ushort], align: bool = ..., copy: bool = ...) -> dtype[ushort]: ...
@overload
- def __new__(
- cls,
- dtype: Union[
- None,
- Type[float],
- Literal[
- "float64",
- "f8",
- "=f8",
- "<f8",
- ">f8",
- "d",
- "<d",
- ">d",
- "float",
- "double",
- "float_",
- ],
- ],
- align: bool = ...,
- copy: bool = ...,
- ) -> dtype[float64]: ...
+ def __new__(cls, dtype: _UIntCCodes | Type[ct.c_uint], align: bool = ..., copy: bool = ...) -> dtype[uintc]: ...
+
+ # NOTE: We're assuming here that `uint_ptr_t == size_t`,
+ # an assumption that does not hold in rare cases (same for `ssize_t`)
@overload
- def __new__(
- cls,
- dtype: Literal[
- "complex64",
- "c8",
- "=c8",
- "<c8",
- ">c8",
- "F",
- "=F",
- "<F",
- ">F",
- ],
- align: bool = ...,
- copy: bool = ...,
- ) -> dtype[complex64]: ...
+ def __new__(cls, dtype: _UIntPCodes | Type[ct.c_void_p] | Type[ct.c_size_t], align: bool = ..., copy: bool = ...) -> dtype[uintp]: ...
@overload
- def __new__(
- cls,
- dtype: Union[
- Type[complex],
- Literal[
- "complex128",
- "c16",
- "=c16",
- "<c16",
- ">c16",
- "D",
- "=D",
- "<D",
- ">D",
- ],
- ],
- align: bool = ...,
- copy: bool = ...,
- ) -> dtype[complex128]: ...
+ def __new__(cls, dtype: _UIntCodes | Type[ct.c_ulong], align: bool = ..., copy: bool = ...) -> dtype[uint]: ...
@overload
- def __new__(
- cls,
- dtype: Union[
- Type[bytes],
- Literal[
- "S",
- "=S",
- "<S",
- ">S",
- "bytes",
- "bytes_",
- "bytes0",
- ],
- ],
- align: bool = ...,
- copy: bool = ...,
- ) -> dtype[bytes_]: ...
+ def __new__(cls, dtype: _ULongLongCodes | Type[ct.c_ulonglong], align: bool = ..., copy: bool = ...) -> dtype[ulonglong]: ...
+
+ # `signedinteger` string-based representations and ctypes
@overload
- def __new__(
- cls,
- dtype: Union[
- Type[str],
- Literal[
- "U",
- "=U",
- # <U and >U intentionally not included; they are not
- # the same dtype and which one dtype("U") translates
- # to is platform-dependent.
- "str",
- "str_",
- "str0",
- ],
- ],
- align: bool = ...,
- copy: bool = ...,
- ) -> dtype[str_]: ...
+ def __new__(cls, dtype: _Int8Codes | Type[ct.c_int8], align: bool = ..., copy: bool = ...) -> dtype[int8]: ...
+ @overload
+ def __new__(cls, dtype: _Int16Codes | Type[ct.c_int16], align: bool = ..., copy: bool = ...) -> dtype[int16]: ...
+ @overload
+ def __new__(cls, dtype: _Int32Codes | Type[ct.c_int32], align: bool = ..., copy: bool = ...) -> dtype[int32]: ...
+ @overload
+ def __new__(cls, dtype: _Int64Codes | Type[ct.c_int64], align: bool = ..., copy: bool = ...) -> dtype[int64]: ...
+ @overload
+ def __new__(cls, dtype: _ByteCodes | Type[ct.c_byte], align: bool = ..., copy: bool = ...) -> dtype[byte]: ...
+ @overload
+ def __new__(cls, dtype: _ShortCodes | Type[ct.c_short], align: bool = ..., copy: bool = ...) -> dtype[short]: ...
+ @overload
+ def __new__(cls, dtype: _IntCCodes | Type[ct.c_int], align: bool = ..., copy: bool = ...) -> dtype[intc]: ...
+ @overload
+ def __new__(cls, dtype: _IntPCodes | Type[ct.c_ssize_t], align: bool = ..., copy: bool = ...) -> dtype[intp]: ...
+ @overload
+ def __new__(cls, dtype: _IntCodes | Type[ct.c_long], align: bool = ..., copy: bool = ...) -> dtype[int_]: ...
+ @overload
+ def __new__(cls, dtype: _LongLongCodes | Type[ct.c_longlong], align: bool = ..., copy: bool = ...) -> dtype[longlong]: ...
+
+ # `floating` string-based representations and ctypes
+ @overload
+ def __new__(cls, dtype: _Float16Codes, align: bool = ..., copy: bool = ...) -> dtype[float16]: ...
+ @overload
+ def __new__(cls, dtype: _Float32Codes, align: bool = ..., copy: bool = ...) -> dtype[float32]: ...
+ @overload
+ def __new__(cls, dtype: _Float64Codes, align: bool = ..., copy: bool = ...) -> dtype[float64]: ...
+ @overload
+ def __new__(cls, dtype: _HalfCodes, align: bool = ..., copy: bool = ...) -> dtype[half]: ...
+ @overload
+ def __new__(cls, dtype: _SingleCodes | Type[ct.c_float], align: bool = ..., copy: bool = ...) -> dtype[single]: ...
+ @overload
+ def __new__(cls, dtype: _DoubleCodes | Type[ct.c_double], align: bool = ..., copy: bool = ...) -> dtype[double]: ...
+ @overload
+ def __new__(cls, dtype: _LongDoubleCodes | Type[ct.c_longdouble], align: bool = ..., copy: bool = ...) -> dtype[longdouble]: ...
+
+ # `complexfloating` string-based representations
+ @overload
+ def __new__(cls, dtype: _Complex64Codes, align: bool = ..., copy: bool = ...) -> dtype[complex64]: ...
+ @overload
+ def __new__(cls, dtype: _Complex128Codes, align: bool = ..., copy: bool = ...) -> dtype[complex128]: ...
+ @overload
+ def __new__(cls, dtype: _CSingleCodes, align: bool = ..., copy: bool = ...) -> dtype[csingle]: ...
+ @overload
+ def __new__(cls, dtype: _CDoubleCodes, align: bool = ..., copy: bool = ...) -> dtype[cdouble]: ...
+ @overload
+ def __new__(cls, dtype: _CLongDoubleCodes, align: bool = ..., copy: bool = ...) -> dtype[clongdouble]: ...
+
+ # Miscellaneous string-based representations and ctypes
+ @overload
+ def __new__(cls, dtype: _BoolCodes | Type[ct.c_bool], align: bool = ..., copy: bool = ...) -> dtype[bool_]: ...
+ @overload
+ def __new__(cls, dtype: _TD64Codes, align: bool = ..., copy: bool = ...) -> dtype[timedelta64]: ...
+ @overload
+ def __new__(cls, dtype: _DT64Codes, align: bool = ..., copy: bool = ...) -> dtype[datetime64]: ...
+ @overload
+ def __new__(cls, dtype: _StrCodes, align: bool = ..., copy: bool = ...) -> dtype[str_]: ...
+ @overload
+ def __new__(cls, dtype: _BytesCodes | Type[ct.c_char], align: bool = ..., copy: bool = ...) -> dtype[bytes_]: ...
+ @overload
+ def __new__(cls, dtype: _VoidCodes, align: bool = ..., copy: bool = ...) -> dtype[void]: ...
+ @overload
+ def __new__(cls, dtype: _ObjectCodes | Type[ct.py_object], align: bool = ..., copy: bool = ...) -> dtype[object_]: ...
+
# dtype of a dtype is the same dtype
@overload
def __new__(
cls,
- dtype: dtype[_DTypeScalar],
+ dtype: dtype[_DTypeScalar_co],
align: bool = ...,
copy: bool = ...,
- ) -> dtype[_DTypeScalar]: ...
- # TODO: handle _SupportsDType better
+ ) -> dtype[_DTypeScalar_co]: ...
@overload
def __new__(
cls,
- dtype: _SupportsDType,
+ dtype: _SupportsDType[dtype[_DTypeScalar_co]],
align: bool = ...,
copy: bool = ...,
- ) -> dtype[Any]: ...
+ ) -> dtype[_DTypeScalar_co]: ...
# Handle strings that can't be expressed as literals; i.e. s1, s2, ...
@overload
def __new__(
@@ -852,7 +1065,7 @@ class dtype(Generic[_DTypeScalar]):
align: bool = ...,
copy: bool = ...,
) -> dtype[Any]: ...
- # Catchall overload
+ # Catchall overload for void-likes
@overload
def __new__(
cls,
@@ -860,8 +1073,36 @@ class dtype(Generic[_DTypeScalar]):
align: bool = ...,
copy: bool = ...,
) -> dtype[void]: ...
- def __eq__(self, other: DTypeLike) -> bool: ...
- def __ne__(self, other: DTypeLike) -> bool: ...
+ # Catchall overload for object-likes
+ @overload
+ def __new__(
+ cls,
+ dtype: Type[object],
+ align: bool = ...,
+ copy: bool = ...,
+ ) -> dtype[object_]: ...
+
+ @overload
+ def __getitem__(self: dtype[void], key: List[str]) -> dtype[void]: ...
+ @overload
+ def __getitem__(self: dtype[void], key: str | SupportsIndex) -> dtype[Any]: ...
+
+ # NOTE: In the future 1-based multiplications will also yield `flexible` dtypes
+ @overload
+ def __mul__(self: _DType, value: L[1]) -> _DType: ...
+ @overload
+ def __mul__(self: _FlexDType, value: SupportsIndex) -> _FlexDType: ...
+ @overload
+ def __mul__(self, value: SupportsIndex) -> dtype[void]: ...
+
+ # NOTE: `__rmul__` seems to be broken when used in combination with
+ # literals as of mypy 0.902. Set the return-type to `dtype[Any]` for
+ # now for non-flexible dtypes.
+ @overload
+ def __rmul__(self: _FlexDType, value: SupportsIndex) -> _FlexDType: ...
+ @overload
+ def __rmul__(self, value: SupportsIndex) -> dtype[Any]: ...
+
def __gt__(self, other: DTypeLike) -> bool: ...
def __ge__(self, other: DTypeLike) -> bool: ...
def __lt__(self, other: DTypeLike) -> bool: ...
@@ -869,17 +1110,17 @@ class dtype(Generic[_DTypeScalar]):
@property
def alignment(self) -> int: ...
@property
- def base(self) -> dtype: ...
+ def base(self) -> dtype[Any]: ...
@property
def byteorder(self) -> str: ...
@property
def char(self) -> str: ...
@property
- def descr(self) -> List[Union[Tuple[str, str], Tuple[str, str, _Shape]]]: ...
+ def descr(self) -> List[Tuple[str, str] | Tuple[str, str, _Shape]]: ...
@property
def fields(
self,
- ) -> Optional[Mapping[str, Union[Tuple[dtype, int], Tuple[dtype, int, Any]]]]: ...
+ ) -> None | MappingProxyType[str, Tuple[dtype[Any], int] | Tuple[dtype[Any], int, Any]]: ...
@property
def flags(self) -> int: ...
@property
@@ -895,7 +1136,7 @@ class dtype(Generic[_DTypeScalar]):
@property
def kind(self) -> str: ...
@property
- def metadata(self) -> Optional[Mapping[str, Any]]: ...
+ def metadata(self) -> None | MappingProxyType[str, Any]: ...
@property
def name(self) -> str: ...
@property
@@ -905,46 +1146,14 @@ class dtype(Generic[_DTypeScalar]):
@property
def ndim(self) -> int: ...
@property
- def subdtype(self) -> Optional[Tuple[dtype, _Shape]]: ...
- def newbyteorder(self, __new_order: _ByteOrder = ...) -> dtype: ...
+ def subdtype(self) -> None | Tuple[dtype[Any], _Shape]: ...
+ def newbyteorder(self: _DType, __new_order: _ByteOrder = ...) -> _DType: ...
# Leave str and type for end to avoid having to use `builtins.str`
# everywhere. See https://github.com/python/mypy/issues/3775
@property
def str(self) -> builtins.str: ...
@property
- def type(self) -> Type[generic]: ...
-
-_DType = dtype # to avoid name conflicts with ndarray.dtype
-
-class _flagsobj:
- aligned: bool
- updateifcopy: bool
- writeable: bool
- writebackifcopy: bool
- @property
- def behaved(self) -> bool: ...
- @property
- def c_contiguous(self) -> bool: ...
- @property
- def carray(self) -> bool: ...
- @property
- def contiguous(self) -> bool: ...
- @property
- def f_contiguous(self) -> bool: ...
- @property
- def farray(self) -> bool: ...
- @property
- def fnc(self) -> bool: ...
- @property
- def forc(self) -> bool: ...
- @property
- def fortran(self) -> bool: ...
- @property
- def num(self) -> int: ...
- @property
- def owndata(self) -> bool: ...
- def __getitem__(self, key: str) -> bool: ...
- def __setitem__(self, key: str, value: bool) -> None: ...
+ def type(self) -> Type[_DTypeScalar_co]: ...
_ArrayLikeInt = Union[
int,
@@ -956,43 +1165,39 @@ _ArrayLikeInt = Union[
_FlatIterSelf = TypeVar("_FlatIterSelf", bound=flatiter)
-class flatiter(Generic[_ArraySelf]):
+class flatiter(Generic[_NdArraySubClass]):
@property
- def base(self) -> _ArraySelf: ...
+ def base(self) -> _NdArraySubClass: ...
@property
def coords(self) -> _Shape: ...
@property
def index(self) -> int: ...
- def copy(self) -> _ArraySelf: ...
+ def copy(self) -> _NdArraySubClass: ...
def __iter__(self: _FlatIterSelf) -> _FlatIterSelf: ...
- def __next__(self) -> generic: ...
+ def __next__(self: flatiter[ndarray[Any, dtype[_ScalarType]]]) -> _ScalarType: ...
def __len__(self) -> int: ...
@overload
- def __getitem__(self, key: Union[int, integer]) -> generic: ...
+ def __getitem__(
+ self: flatiter[ndarray[Any, dtype[_ScalarType]]],
+ key: Union[int, integer],
+ ) -> _ScalarType: ...
@overload
def __getitem__(
self, key: Union[_ArrayLikeInt, slice, ellipsis],
- ) -> _ArraySelf: ...
- def __array__(self, __dtype: DTypeLike = ...) -> ndarray: ...
-
-_OrderKACF = Optional[Literal["K", "A", "C", "F"]]
-_OrderACF = Optional[Literal["A", "C", "F"]]
-_OrderCF = Optional[Literal["C", "F"]]
-
-_ModeKind = Literal["raise", "wrap", "clip"]
-_PartitionKind = Literal["introselect"]
-_SortKind = Literal["quicksort", "mergesort", "heapsort", "stable"]
-_SortSide = Literal["left", "right"]
-
-_ArrayLikeBool = Union[_BoolLike, Sequence[_BoolLike], ndarray]
-_ArrayLikeIntOrBool = Union[
- _IntLike,
- _BoolLike,
- ndarray,
- Sequence[_IntLike],
- Sequence[_BoolLike],
- Sequence[Sequence[Any]], # TODO: wait for support for recursive types
-]
+ ) -> _NdArraySubClass: ...
+ @overload
+ def __array__(self: flatiter[ndarray[Any, _DType]], __dtype: None = ...) -> ndarray[Any, _DType]: ...
+ @overload
+ def __array__(self, __dtype: _DType) -> ndarray[Any, _DType]: ...
+
+_OrderKACF = Optional[L["K", "A", "C", "F"]]
+_OrderACF = Optional[L["A", "C", "F"]]
+_OrderCF = Optional[L["C", "F"]]
+
+_ModeKind = L["raise", "wrap", "clip"]
+_PartitionKind = L["introselect"]
+_SortKind = L["quicksort", "mergesort", "heapsort", "stable"]
+_SortSide = L["left", "right"]
_ArraySelf = TypeVar("_ArraySelf", bound=_ArrayOrScalarCommon)
@@ -1002,12 +1207,11 @@ class _ArrayOrScalarCommon:
@property
def data(self) -> memoryview: ...
@property
- def flags(self) -> _flagsobj: ...
+ def flags(self) -> flagsobj: ...
@property
def itemsize(self) -> int: ...
@property
def nbytes(self) -> int: ...
- def __array__(self, __dtype: DTypeLike = ...) -> ndarray: ...
def __bool__(self) -> bool: ...
def __bytes__(self) -> bytes: ...
def __str__(self) -> str: ...
@@ -1016,66 +1220,43 @@ class _ArrayOrScalarCommon:
def __deepcopy__(self: _ArraySelf, __memo: Optional[dict] = ...) -> _ArraySelf: ...
def __eq__(self, other): ...
def __ne__(self, other): ...
- def astype(
- self: _ArraySelf,
- dtype: DTypeLike,
- order: _OrderKACF = ...,
- casting: _Casting = ...,
- subok: bool = ...,
- copy: bool = ...,
- ) -> _ArraySelf: ...
def copy(self: _ArraySelf, order: _OrderKACF = ...) -> _ArraySelf: ...
def dump(self, file: str) -> None: ...
def dumps(self) -> bytes: ...
- def flatten(self, order: _OrderKACF = ...) -> ndarray: ...
- def getfield(
- self: _ArraySelf, dtype: DTypeLike, offset: int = ...
- ) -> _ArraySelf: ...
- def ravel(self, order: _OrderKACF = ...) -> ndarray: ...
- @overload
- def reshape(
- self, __shape: Sequence[int], *, order: _OrderACF = ...
- ) -> ndarray: ...
- @overload
- def reshape(
- self, *shape: int, order: _OrderACF = ...
- ) -> ndarray: ...
def tobytes(self, order: _OrderKACF = ...) -> bytes: ...
# NOTE: `tostring()` is deprecated and therefore excluded
# def tostring(self, order=...): ...
def tofile(
- self, fid: Union[IO[bytes], str], sep: str = ..., format: str = ...
+ self, fid: Union[IO[bytes], str, bytes, os.PathLike[Any]], sep: str = ..., format: str = ...
) -> None: ...
# generics and 0d arrays return builtin scalars
def tolist(self) -> Any: ...
- @overload
- def view(self, type: Type[_NdArraySubClass]) -> _NdArraySubClass: ...
- @overload
- def view(self: _ArraySelf, dtype: DTypeLike = ...) -> _ArraySelf: ...
- @overload
- def view(
- self, dtype: DTypeLike, type: Type[_NdArraySubClass]
- ) -> _NdArraySubClass: ...
# TODO: Add proper signatures
def __getitem__(self, key) -> Any: ...
@property
def __array_interface__(self): ...
@property
- def __array_priority__(self): ...
+ def __array_priority__(self) -> float: ...
@property
def __array_struct__(self): ...
- def __array_wrap__(array, context=...): ...
def __setstate__(self, __state): ...
# a `bool_` is returned when `keepdims=True` and `self` is a 0d array
+
@overload
def all(
- self, axis: None = ..., out: None = ..., keepdims: Literal[False] = ...
+ self,
+ axis: None = ...,
+ out: None = ...,
+ keepdims: L[False] = ...,
) -> bool_: ...
@overload
def all(
- self, axis: Optional[_ShapeLike] = ..., out: None = ..., keepdims: bool = ...
- ) -> Union[bool_, ndarray]: ...
+ self,
+ axis: Optional[_ShapeLike] = ...,
+ out: None = ...,
+ keepdims: bool = ...,
+ ) -> Any: ...
@overload
def all(
self,
@@ -1083,14 +1264,21 @@ class _ArrayOrScalarCommon:
out: _NdArraySubClass = ...,
keepdims: bool = ...,
) -> _NdArraySubClass: ...
+
@overload
def any(
- self, axis: None = ..., out: None = ..., keepdims: Literal[False] = ...
+ self,
+ axis: None = ...,
+ out: None = ...,
+ keepdims: L[False] = ...,
) -> bool_: ...
@overload
def any(
- self, axis: Optional[_ShapeLike] = ..., out: None = ..., keepdims: bool = ...
- ) -> Union[bool_, ndarray]: ...
+ self,
+ axis: Optional[_ShapeLike] = ...,
+ out: None = ...,
+ keepdims: bool = ...,
+ ) -> Any: ...
@overload
def any(
self,
@@ -1098,40 +1286,79 @@ class _ArrayOrScalarCommon:
out: _NdArraySubClass = ...,
keepdims: bool = ...,
) -> _NdArraySubClass: ...
+
@overload
- def argmax(self, axis: None = ..., out: None = ...) -> signedinteger: ...
+ def argmax(
+ self,
+ axis: None = ...,
+ out: None = ...,
+ *,
+ keepdims: L[False] = ...,
+ ) -> intp: ...
@overload
def argmax(
- self, axis: _ShapeLike = ..., out: None = ...
- ) -> Union[signedinteger, ndarray]: ...
+ self,
+ axis: _ShapeLike = ...,
+ out: None = ...,
+ *,
+ keepdims: bool = ...,
+ ) -> Any: ...
@overload
def argmax(
- self, axis: Optional[_ShapeLike] = ..., out: _NdArraySubClass = ...
+ self,
+ axis: Optional[_ShapeLike] = ...,
+ out: _NdArraySubClass = ...,
+ *,
+ keepdims: bool = ...,
) -> _NdArraySubClass: ...
+
@overload
- def argmin(self, axis: None = ..., out: None = ...) -> signedinteger: ...
+ def argmin(
+ self,
+ axis: None = ...,
+ out: None = ...,
+ *,
+ keepdims: L[False] = ...,
+ ) -> intp: ...
@overload
def argmin(
- self, axis: _ShapeLike = ..., out: None = ...
- ) -> Union[signedinteger, ndarray]: ...
+ self,
+ axis: _ShapeLike = ...,
+ out: None = ...,
+ *,
+ keepdims: bool = ...,
+ ) -> Any: ...
@overload
def argmin(
- self, axis: Optional[_ShapeLike] = ..., out: _NdArraySubClass = ...
+ self,
+ axis: Optional[_ShapeLike] = ...,
+ out: _NdArraySubClass = ...,
+ *,
+ keepdims: bool = ...,
) -> _NdArraySubClass: ...
+
def argsort(
self,
- axis: Optional[int] = ...,
+ axis: Optional[SupportsIndex] = ...,
kind: Optional[_SortKind] = ...,
order: Union[None, str, Sequence[str]] = ...,
) -> ndarray: ...
+
@overload
def choose(
- self, choices: ArrayLike, out: None = ..., mode: _ModeKind = ...,
+ self,
+ choices: ArrayLike,
+ out: None = ...,
+ mode: _ModeKind = ...,
) -> ndarray: ...
@overload
def choose(
- self, choices: ArrayLike, out: _NdArraySubClass = ..., mode: _ModeKind = ...,
+ self,
+ choices: ArrayLike,
+ out: _NdArraySubClass = ...,
+ mode: _ModeKind = ...,
) -> _NdArraySubClass: ...
+
@overload
def clip(
self,
@@ -1139,7 +1366,7 @@ class _ArrayOrScalarCommon:
max: Optional[ArrayLike] = ...,
out: None = ...,
**kwargs: Any,
- ) -> Union[number, ndarray]: ...
+ ) -> ndarray: ...
@overload
def clip(
self,
@@ -1147,7 +1374,7 @@ class _ArrayOrScalarCommon:
max: ArrayLike = ...,
out: None = ...,
**kwargs: Any,
- ) -> Union[number, ndarray]: ...
+ ) -> ndarray: ...
@overload
def clip(
self,
@@ -1164,73 +1391,75 @@ class _ArrayOrScalarCommon:
out: _NdArraySubClass = ...,
**kwargs: Any,
) -> _NdArraySubClass: ...
+
@overload
def compress(
- self, a: ArrayLike, axis: Optional[int] = ..., out: None = ...,
+ self,
+ a: ArrayLike,
+ axis: Optional[SupportsIndex] = ...,
+ out: None = ...,
) -> ndarray: ...
@overload
def compress(
- self, a: ArrayLike, axis: Optional[int] = ..., out: _NdArraySubClass = ...,
+ self,
+ a: ArrayLike,
+ axis: Optional[SupportsIndex] = ...,
+ out: _NdArraySubClass = ...,
) -> _NdArraySubClass: ...
+
def conj(self: _ArraySelf) -> _ArraySelf: ...
+
def conjugate(self: _ArraySelf) -> _ArraySelf: ...
+
@overload
def cumprod(
- self, axis: Optional[int] = ..., dtype: DTypeLike = ..., out: None = ...,
+ self,
+ axis: Optional[SupportsIndex] = ...,
+ dtype: DTypeLike = ...,
+ out: None = ...,
) -> ndarray: ...
@overload
def cumprod(
self,
- axis: Optional[int] = ...,
+ axis: Optional[SupportsIndex] = ...,
dtype: DTypeLike = ...,
out: _NdArraySubClass = ...,
) -> _NdArraySubClass: ...
+
@overload
def cumsum(
- self, axis: Optional[int] = ..., dtype: DTypeLike = ..., out: None = ...,
+ self,
+ axis: Optional[SupportsIndex] = ...,
+ dtype: DTypeLike = ...,
+ out: None = ...,
) -> ndarray: ...
@overload
def cumsum(
self,
- axis: Optional[int] = ...,
+ axis: Optional[SupportsIndex] = ...,
dtype: DTypeLike = ...,
out: _NdArraySubClass = ...,
) -> _NdArraySubClass: ...
- @overload
- def max(
- self,
- axis: None = ...,
- out: None = ...,
- keepdims: Literal[False] = ...,
- initial: _NumberLike = ...,
- where: _ArrayLikeBool = ...,
- ) -> number: ...
+
@overload
def max(
self,
axis: Optional[_ShapeLike] = ...,
out: None = ...,
keepdims: bool = ...,
- initial: _NumberLike = ...,
- where: _ArrayLikeBool = ...,
- ) -> Union[number, ndarray]: ...
+ initial: _NumberLike_co = ...,
+ where: _ArrayLikeBool_co = ...,
+ ) -> Any: ...
@overload
def max(
self,
axis: Optional[_ShapeLike] = ...,
out: _NdArraySubClass = ...,
keepdims: bool = ...,
- initial: _NumberLike = ...,
- where: _ArrayLikeBool = ...,
+ initial: _NumberLike_co = ...,
+ where: _ArrayLikeBool_co = ...,
) -> _NdArraySubClass: ...
- @overload
- def mean(
- self,
- axis: None = ...,
- dtype: DTypeLike = ...,
- out: None = ...,
- keepdims: Literal[False] = ...,
- ) -> number: ...
+
@overload
def mean(
self,
@@ -1238,7 +1467,7 @@ class _ArrayOrScalarCommon:
dtype: DTypeLike = ...,
out: None = ...,
keepdims: bool = ...,
- ) -> Union[number, ndarray]: ...
+ ) -> Any: ...
@overload
def mean(
self,
@@ -1247,44 +1476,31 @@ class _ArrayOrScalarCommon:
out: _NdArraySubClass = ...,
keepdims: bool = ...,
) -> _NdArraySubClass: ...
- @overload
- def min(
- self,
- axis: None = ...,
- out: None = ...,
- keepdims: Literal[False] = ...,
- initial: _NumberLike = ...,
- where: _ArrayLikeBool = ...,
- ) -> number: ...
+
@overload
def min(
self,
axis: Optional[_ShapeLike] = ...,
out: None = ...,
keepdims: bool = ...,
- initial: _NumberLike = ...,
- where: _ArrayLikeBool = ...,
- ) -> Union[number, ndarray]: ...
+ initial: _NumberLike_co = ...,
+ where: _ArrayLikeBool_co = ...,
+ ) -> Any: ...
@overload
def min(
self,
axis: Optional[_ShapeLike] = ...,
out: _NdArraySubClass = ...,
keepdims: bool = ...,
- initial: _NumberLike = ...,
- where: _ArrayLikeBool = ...,
+ initial: _NumberLike_co = ...,
+ where: _ArrayLikeBool_co = ...,
) -> _NdArraySubClass: ...
- def newbyteorder(self: _ArraySelf, __new_order: _ByteOrder = ...) -> _ArraySelf: ...
- @overload
- def prod(
- self,
- axis: None = ...,
- dtype: DTypeLike = ...,
- out: None = ...,
- keepdims: Literal[False] = ...,
- initial: _NumberLike = ...,
- where: _ArrayLikeBool = ...,
- ) -> number: ...
+
+ def newbyteorder(
+ self: _ArraySelf,
+ __new_order: _ByteOrder = ...,
+ ) -> _ArraySelf: ...
+
@overload
def prod(
self,
@@ -1292,9 +1508,9 @@ class _ArrayOrScalarCommon:
dtype: DTypeLike = ...,
out: None = ...,
keepdims: bool = ...,
- initial: _NumberLike = ...,
- where: _ArrayLikeBool = ...,
- ) -> Union[number, ndarray]: ...
+ initial: _NumberLike_co = ...,
+ where: _ArrayLikeBool_co = ...,
+ ) -> Any: ...
@overload
def prod(
self,
@@ -1302,17 +1518,17 @@ class _ArrayOrScalarCommon:
dtype: DTypeLike = ...,
out: _NdArraySubClass = ...,
keepdims: bool = ...,
- initial: _NumberLike = ...,
- where: _ArrayLikeBool = ...,
+ initial: _NumberLike_co = ...,
+ where: _ArrayLikeBool_co = ...,
) -> _NdArraySubClass: ...
+
@overload
def ptp(
- self, axis: None = ..., out: None = ..., keepdims: Literal[False] = ...,
- ) -> number: ...
- @overload
- def ptp(
- self, axis: Optional[_ShapeLike] = ..., out: None = ..., keepdims: bool = ...,
- ) -> Union[number, ndarray]: ...
+ self,
+ axis: Optional[_ShapeLike] = ...,
+ out: None = ...,
+ keepdims: bool = ...,
+ ) -> Any: ...
@overload
def ptp(
self,
@@ -1320,24 +1536,20 @@ class _ArrayOrScalarCommon:
out: _NdArraySubClass = ...,
keepdims: bool = ...,
) -> _NdArraySubClass: ...
- def repeat(
- self, repeats: _ArrayLikeIntOrBool, axis: Optional[int] = ...
- ) -> ndarray: ...
- @overload
- def round(self: _ArraySelf, decimals: int = ..., out: None = ...) -> _ArraySelf: ...
+
@overload
def round(
- self, decimals: int = ..., out: _NdArraySubClass = ...
- ) -> _NdArraySubClass: ...
+ self: _ArraySelf,
+ decimals: SupportsIndex = ...,
+ out: None = ...,
+ ) -> _ArraySelf: ...
@overload
- def std(
+ def round(
self,
- axis: None = ...,
- dtype: DTypeLike = ...,
- out: None = ...,
- ddof: int = ...,
- keepdims: Literal[False] = ...,
- ) -> number: ...
+ decimals: SupportsIndex = ...,
+ out: _NdArraySubClass = ...,
+ ) -> _NdArraySubClass: ...
+
@overload
def std(
self,
@@ -1346,7 +1558,7 @@ class _ArrayOrScalarCommon:
out: None = ...,
ddof: int = ...,
keepdims: bool = ...,
- ) -> Union[number, ndarray]: ...
+ ) -> Any: ...
@overload
def std(
self,
@@ -1356,16 +1568,7 @@ class _ArrayOrScalarCommon:
ddof: int = ...,
keepdims: bool = ...,
) -> _NdArraySubClass: ...
- @overload
- def sum(
- self,
- axis: None = ...,
- dtype: DTypeLike = ...,
- out: None = ...,
- keepdims: Literal[False] = ...,
- initial: _NumberLike = ...,
- where: _ArrayLikeBool = ...,
- ) -> number: ...
+
@overload
def sum(
self,
@@ -1373,9 +1576,9 @@ class _ArrayOrScalarCommon:
dtype: DTypeLike = ...,
out: None = ...,
keepdims: bool = ...,
- initial: _NumberLike = ...,
- where: _ArrayLikeBool = ...,
- ) -> Union[number, ndarray]: ...
+ initial: _NumberLike_co = ...,
+ where: _ArrayLikeBool_co = ...,
+ ) -> Any: ...
@overload
def sum(
self,
@@ -1383,42 +1586,10 @@ class _ArrayOrScalarCommon:
dtype: DTypeLike = ...,
out: _NdArraySubClass = ...,
keepdims: bool = ...,
- initial: _NumberLike = ...,
- where: _ArrayLikeBool = ...,
+ initial: _NumberLike_co = ...,
+ where: _ArrayLikeBool_co = ...,
) -> _NdArraySubClass: ...
- @overload
- def take(
- self,
- indices: Union[_IntLike, _BoolLike],
- axis: Optional[int] = ...,
- out: None = ...,
- mode: _ModeKind = ...,
- ) -> generic: ...
- @overload
- def take(
- self,
- indices: _ArrayLikeIntOrBool,
- axis: Optional[int] = ...,
- out: None = ...,
- mode: _ModeKind = ...,
- ) -> ndarray: ...
- @overload
- def take(
- self,
- indices: _ArrayLikeIntOrBool,
- axis: Optional[int] = ...,
- out: _NdArraySubClass = ...,
- mode: _ModeKind = ...,
- ) -> _NdArraySubClass: ...
- @overload
- def var(
- self,
- axis: None = ...,
- dtype: DTypeLike = ...,
- out: None = ...,
- ddof: int = ...,
- keepdims: Literal[False] = ...,
- ) -> number: ...
+
@overload
def var(
self,
@@ -1427,7 +1598,7 @@ class _ArrayOrScalarCommon:
out: None = ...,
ddof: int = ...,
keepdims: bool = ...,
- ) -> Union[number, ndarray]: ...
+ ) -> Any: ...
@overload
def var(
self,
@@ -1438,10 +1609,58 @@ class _ArrayOrScalarCommon:
keepdims: bool = ...,
) -> _NdArraySubClass: ...
-_BufferType = Union[ndarray, bytes, bytearray, memoryview]
-_Casting = Literal["no", "equiv", "safe", "same_kind", "unsafe"]
+_DType = TypeVar("_DType", bound=dtype[Any])
+_DType_co = TypeVar("_DType_co", covariant=True, bound=dtype[Any])
+_FlexDType = TypeVar("_FlexDType", bound=dtype[flexible])
+
+# TODO: Set the `bound` to something more suitable once we
+# have proper shape support
+_ShapeType = TypeVar("_ShapeType", bound=Any)
+_ShapeType2 = TypeVar("_ShapeType2", bound=Any)
+_NumberType = TypeVar("_NumberType", bound=number[Any])
+
+# There is currently no exhaustive way to type the buffer protocol,
+# as it is implemented exclusivelly in the C API (python/typing#593)
+_SupportsBuffer = Union[
+ bytes,
+ bytearray,
+ memoryview,
+ _array.array[Any],
+ mmap.mmap,
+ NDArray[Any],
+ generic,
+]
+
+_T = TypeVar("_T")
+_T_co = TypeVar("_T_co", covariant=True)
+_2Tuple = Tuple[_T, _T]
+_CastingKind = L["no", "equiv", "safe", "same_kind", "unsafe"]
+
+_DTypeLike = Union[
+ dtype[_ScalarType],
+ Type[_ScalarType],
+ _SupportsDType[dtype[_ScalarType]],
+]
+
+_ArrayUInt_co = NDArray[Union[bool_, unsignedinteger[Any]]]
+_ArrayInt_co = NDArray[Union[bool_, integer[Any]]]
+_ArrayFloat_co = NDArray[Union[bool_, integer[Any], floating[Any]]]
+_ArrayComplex_co = NDArray[Union[bool_, integer[Any], floating[Any], complexfloating[Any, Any]]]
+_ArrayNumber_co = NDArray[Union[bool_, number[Any]]]
+_ArrayTD64_co = NDArray[Union[bool_, integer[Any], timedelta64]]
+
+class _SupportsItem(Protocol[_T_co]):
+ def item(self, __args: Any) -> _T_co: ...
-class ndarray(_ArrayOrScalarCommon, Iterable, Sized, Container):
+class _SupportsReal(Protocol[_T_co]):
+ @property
+ def real(self) -> _T_co: ...
+
+class _SupportsImag(Protocol[_T_co]):
+ @property
+ def imag(self) -> _T_co: ...
+
+class ndarray(_ArrayOrScalarCommon, Generic[_ShapeType, _DType_co]):
@property
def base(self) -> Optional[ndarray]: ...
@property
@@ -1449,183 +1668,1224 @@ class ndarray(_ArrayOrScalarCommon, Iterable, Sized, Container):
@property
def size(self) -> int: ...
@property
- def real(self: _ArraySelf) -> _ArraySelf: ...
+ def real(
+ self: NDArray[_SupportsReal[_ScalarType]], # type: ignore[type-var]
+ ) -> ndarray[_ShapeType, dtype[_ScalarType]]: ...
@real.setter
def real(self, value: ArrayLike) -> None: ...
@property
- def imag(self: _ArraySelf) -> _ArraySelf: ...
+ def imag(
+ self: NDArray[_SupportsImag[_ScalarType]], # type: ignore[type-var]
+ ) -> ndarray[_ShapeType, dtype[_ScalarType]]: ...
@imag.setter
def imag(self, value: ArrayLike) -> None: ...
def __new__(
cls: Type[_ArraySelf],
- shape: Sequence[int],
+ shape: _ShapeLike,
dtype: DTypeLike = ...,
- buffer: _BufferType = ...,
+ buffer: _SupportsBuffer = ...,
offset: int = ...,
strides: _ShapeLike = ...,
order: _OrderKACF = ...,
) -> _ArraySelf: ...
+ @overload
+ def __array__(self, __dtype: None = ...) -> ndarray[Any, _DType_co]: ...
+ @overload
+ def __array__(self, __dtype: _DType) -> ndarray[Any, _DType]: ...
+
+ def __array_wrap__(
+ self,
+ __array: ndarray[_ShapeType2, _DType],
+ __context: None | Tuple[ufunc, Tuple[Any, ...], int] = ...,
+ ) -> ndarray[_ShapeType2, _DType]: ...
+
+ def __array_prepare__(
+ self,
+ __array: ndarray[_ShapeType2, _DType],
+ __context: None | Tuple[ufunc, Tuple[Any, ...], int] = ...,
+ ) -> ndarray[_ShapeType2, _DType]: ...
+
@property
- def dtype(self) -> _DType: ...
- @property
- def ctypes(self) -> _ctypes: ...
+ def ctypes(self) -> _ctypes[int]: ...
@property
def shape(self) -> _Shape: ...
@shape.setter
- def shape(self, value: _ShapeLike): ...
+ def shape(self, value: _ShapeLike) -> None: ...
@property
def strides(self) -> _Shape: ...
@strides.setter
- def strides(self, value: _ShapeLike): ...
+ def strides(self, value: _ShapeLike) -> None: ...
def byteswap(self: _ArraySelf, inplace: bool = ...) -> _ArraySelf: ...
def fill(self, value: Any) -> None: ...
@property
- def flat(self: _ArraySelf) -> flatiter[_ArraySelf]: ...
+ def flat(self: _NdArraySubClass) -> flatiter[_NdArraySubClass]: ...
+
+ # Use the same output type as that of the underlying `generic`
@overload
- def item(self, *args: int) -> Any: ...
+ def item(
+ self: ndarray[Any, dtype[_SupportsItem[_T]]], # type: ignore[type-var]
+ *args: SupportsIndex,
+ ) -> _T: ...
@overload
- def item(self, __args: Tuple[int, ...]) -> Any: ...
+ def item(
+ self: ndarray[Any, dtype[_SupportsItem[_T]]], # type: ignore[type-var]
+ __args: Tuple[SupportsIndex, ...],
+ ) -> _T: ...
+
@overload
def itemset(self, __value: Any) -> None: ...
@overload
def itemset(self, __item: _ShapeLike, __value: Any) -> None: ...
+
@overload
- def resize(self, __new_shape: Sequence[int], *, refcheck: bool = ...) -> None: ...
+ def resize(self, __new_shape: _ShapeLike, *, refcheck: bool = ...) -> None: ...
@overload
- def resize(self, *new_shape: int, refcheck: bool = ...) -> None: ...
+ def resize(self, *new_shape: SupportsIndex, refcheck: bool = ...) -> None: ...
+
def setflags(
self, write: bool = ..., align: bool = ..., uic: bool = ...
) -> None: ...
+
def squeeze(
- self: _ArraySelf, axis: Union[int, Tuple[int, ...]] = ...
- ) -> _ArraySelf: ...
- def swapaxes(self: _ArraySelf, axis1: int, axis2: int) -> _ArraySelf: ...
+ self,
+ axis: Union[SupportsIndex, Tuple[SupportsIndex, ...]] = ...,
+ ) -> ndarray[Any, _DType_co]: ...
+
+ def swapaxes(
+ self,
+ axis1: SupportsIndex,
+ axis2: SupportsIndex,
+ ) -> ndarray[Any, _DType_co]: ...
+
@overload
- def transpose(self: _ArraySelf, __axes: Sequence[int]) -> _ArraySelf: ...
+ def transpose(self: _ArraySelf, __axes: _ShapeLike) -> _ArraySelf: ...
@overload
- def transpose(self: _ArraySelf, *axes: int) -> _ArraySelf: ...
+ def transpose(self: _ArraySelf, *axes: SupportsIndex) -> _ArraySelf: ...
+
def argpartition(
self,
- kth: _ArrayLikeIntOrBool,
- axis: Optional[int] = ...,
+ kth: _ArrayLikeInt_co,
+ axis: Optional[SupportsIndex] = ...,
kind: _PartitionKind = ...,
order: Union[None, str, Sequence[str]] = ...,
- ) -> ndarray: ...
+ ) -> ndarray[Any, dtype[intp]]: ...
+
def diagonal(
- self: _ArraySelf, offset: int = ..., axis1: int = ..., axis2: int = ...
- ) -> _ArraySelf: ...
+ self,
+ offset: SupportsIndex = ...,
+ axis1: SupportsIndex = ...,
+ axis2: SupportsIndex = ...,
+ ) -> ndarray[Any, _DType_co]: ...
+
+ # 1D + 1D returns a scalar;
+ # all other with at least 1 non-0D array return an ndarray.
+ @overload
+ def dot(self, b: _ScalarLike_co, out: None = ...) -> ndarray: ...
@overload
- def dot(self, b: ArrayLike, out: None = ...) -> Union[number, ndarray]: ...
+ def dot(self, b: ArrayLike, out: None = ...) -> Any: ... # type: ignore[misc]
@overload
- def dot(self, b: ArrayLike, out: _NdArraySubClass = ...) -> _NdArraySubClass: ...
+ def dot(self, b: ArrayLike, out: _NdArraySubClass) -> _NdArraySubClass: ...
+
# `nonzero()` is deprecated for 0d arrays/generics
- def nonzero(self) -> Tuple[ndarray, ...]: ...
+ def nonzero(self) -> Tuple[ndarray[Any, dtype[intp]], ...]: ...
+
def partition(
self,
- kth: _ArrayLikeIntOrBool,
- axis: int = ...,
+ kth: _ArrayLikeInt_co,
+ axis: SupportsIndex = ...,
kind: _PartitionKind = ...,
order: Union[None, str, Sequence[str]] = ...,
) -> None: ...
+
# `put` is technically available to `generic`,
# but is pointless as `generic`s are immutable
def put(
- self, ind: _ArrayLikeIntOrBool, v: ArrayLike, mode: _ModeKind = ...
+ self,
+ ind: _ArrayLikeInt_co,
+ v: ArrayLike,
+ mode: _ModeKind = ...,
) -> None: ...
+
+ @overload
+ def searchsorted( # type: ignore[misc]
+ self, # >= 1D array
+ v: _ScalarLike_co, # 0D array-like
+ side: _SortSide = ...,
+ sorter: Optional[_ArrayLikeInt_co] = ...,
+ ) -> intp: ...
+ @overload
def searchsorted(
self, # >= 1D array
v: ArrayLike,
side: _SortSide = ...,
- sorter: Optional[_ArrayLikeIntOrBool] = ..., # 1D int array
- ) -> ndarray: ...
+ sorter: Optional[_ArrayLikeInt_co] = ...,
+ ) -> ndarray[Any, dtype[intp]]: ...
+
def setfield(
- self, val: ArrayLike, dtype: DTypeLike, offset: int = ...
+ self,
+ val: ArrayLike,
+ dtype: DTypeLike,
+ offset: SupportsIndex = ...,
) -> None: ...
+
def sort(
self,
- axis: int = ...,
+ axis: SupportsIndex = ...,
kind: Optional[_SortKind] = ...,
order: Union[None, str, Sequence[str]] = ...,
) -> None: ...
+
@overload
def trace(
self, # >= 2D array
- offset: int = ...,
- axis1: int = ...,
- axis2: int = ...,
+ offset: SupportsIndex = ...,
+ axis1: SupportsIndex = ...,
+ axis2: SupportsIndex = ...,
dtype: DTypeLike = ...,
out: None = ...,
- ) -> Union[number, ndarray]: ...
+ ) -> Any: ...
@overload
def trace(
self, # >= 2D array
- offset: int = ...,
- axis1: int = ...,
- axis2: int = ...,
+ offset: SupportsIndex = ...,
+ axis1: SupportsIndex = ...,
+ axis2: SupportsIndex = ...,
dtype: DTypeLike = ...,
out: _NdArraySubClass = ...,
) -> _NdArraySubClass: ...
- # Many of these special methods are irrelevant currently, since protocols
- # aren't supported yet. That said, I'm adding them for completeness.
- # https://docs.python.org/3/reference/datamodel.html
- def __int__(self) -> int: ...
- def __float__(self) -> float: ...
- def __complex__(self) -> complex: ...
+
+ @overload
+ def take( # type: ignore[misc]
+ self: ndarray[Any, dtype[_ScalarType]],
+ indices: _IntLike_co,
+ axis: Optional[SupportsIndex] = ...,
+ out: None = ...,
+ mode: _ModeKind = ...,
+ ) -> _ScalarType: ...
+ @overload
+ def take( # type: ignore[misc]
+ self,
+ indices: _ArrayLikeInt_co,
+ axis: Optional[SupportsIndex] = ...,
+ out: None = ...,
+ mode: _ModeKind = ...,
+ ) -> ndarray[Any, _DType_co]: ...
+ @overload
+ def take(
+ self,
+ indices: _ArrayLikeInt_co,
+ axis: Optional[SupportsIndex] = ...,
+ out: _NdArraySubClass = ...,
+ mode: _ModeKind = ...,
+ ) -> _NdArraySubClass: ...
+
+ def repeat(
+ self,
+ repeats: _ArrayLikeInt_co,
+ axis: Optional[SupportsIndex] = ...,
+ ) -> ndarray[Any, _DType_co]: ...
+
+ def flatten(
+ self,
+ order: _OrderKACF = ...,
+ ) -> ndarray[Any, _DType_co]: ...
+
+ def ravel(
+ self,
+ order: _OrderKACF = ...,
+ ) -> ndarray[Any, _DType_co]: ...
+
+ @overload
+ def reshape(
+ self, __shape: _ShapeLike, *, order: _OrderACF = ...
+ ) -> ndarray[Any, _DType_co]: ...
+ @overload
+ def reshape(
+ self, *shape: SupportsIndex, order: _OrderACF = ...
+ ) -> ndarray[Any, _DType_co]: ...
+
+ @overload
+ def astype(
+ self,
+ dtype: _DTypeLike[_ScalarType],
+ order: _OrderKACF = ...,
+ casting: _CastingKind = ...,
+ subok: bool = ...,
+ copy: bool = ...,
+ ) -> NDArray[_ScalarType]: ...
+ @overload
+ def astype(
+ self,
+ dtype: DTypeLike,
+ order: _OrderKACF = ...,
+ casting: _CastingKind = ...,
+ subok: bool = ...,
+ copy: bool = ...,
+ ) -> NDArray[Any]: ...
+
+ @overload
+ def view(self: _ArraySelf) -> _ArraySelf: ...
+ @overload
+ def view(self, type: Type[_NdArraySubClass]) -> _NdArraySubClass: ...
+ @overload
+ def view(self, dtype: _DTypeLike[_ScalarType]) -> NDArray[_ScalarType]: ...
+ @overload
+ def view(self, dtype: DTypeLike) -> NDArray[Any]: ...
+ @overload
+ def view(
+ self,
+ dtype: DTypeLike,
+ type: Type[_NdArraySubClass],
+ ) -> _NdArraySubClass: ...
+
+ @overload
+ def getfield(
+ self,
+ dtype: _DTypeLike[_ScalarType],
+ offset: SupportsIndex = ...
+ ) -> NDArray[_ScalarType]: ...
+ @overload
+ def getfield(
+ self,
+ dtype: DTypeLike,
+ offset: SupportsIndex = ...
+ ) -> NDArray[Any]: ...
+
+ # Dispatch to the underlying `generic` via protocols
+ def __int__(
+ self: ndarray[Any, dtype[SupportsInt]], # type: ignore[type-var]
+ ) -> int: ...
+
+ def __float__(
+ self: ndarray[Any, dtype[SupportsFloat]], # type: ignore[type-var]
+ ) -> float: ...
+
+ def __complex__(
+ self: ndarray[Any, dtype[SupportsComplex]], # type: ignore[type-var]
+ ) -> complex: ...
+
+ def __index__(
+ self: ndarray[Any, dtype[SupportsIndex]], # type: ignore[type-var]
+ ) -> int: ...
+
def __len__(self) -> int: ...
def __setitem__(self, key, value): ...
def __iter__(self) -> Any: ...
def __contains__(self, key) -> bool: ...
- def __index__(self) -> int: ...
- def __lt__(self, other: ArrayLike) -> Union[ndarray, bool_]: ...
- def __le__(self, other: ArrayLike) -> Union[ndarray, bool_]: ...
- def __gt__(self, other: ArrayLike) -> Union[ndarray, bool_]: ...
- def __ge__(self, other: ArrayLike) -> Union[ndarray, bool_]: ...
- def __matmul__(self, other: ArrayLike) -> Any: ...
+
+ # The last overload is for catching recursive objects whose
+ # nesting is too deep.
+ # The first overload is for catching `bytes` (as they are a subtype of
+ # `Sequence[int]`) and `str`. As `str` is a recusive sequence of
+ # strings, it will pass through the final overload otherwise
+
+ @overload
+ def __lt__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __lt__(self: _ArrayNumber_co, other: _ArrayLikeNumber_co) -> NDArray[bool_]: ...
+ @overload
+ def __lt__(self: _ArrayTD64_co, other: _ArrayLikeTD64_co) -> NDArray[bool_]: ...
+ @overload
+ def __lt__(self: NDArray[datetime64], other: _ArrayLikeDT64_co) -> NDArray[bool_]: ...
+ @overload
+ def __lt__(self: NDArray[object_], other: Any) -> NDArray[bool_]: ...
+ @overload
+ def __lt__(self: NDArray[Any], other: _ArrayLikeObject_co) -> NDArray[bool_]: ...
+ @overload
+ def __lt__(
+ self: NDArray[Union[number[Any], datetime64, timedelta64, bool_]],
+ other: _RecursiveSequence,
+ ) -> NDArray[bool_]: ...
+
+ @overload
+ def __le__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __le__(self: _ArrayNumber_co, other: _ArrayLikeNumber_co) -> NDArray[bool_]: ...
+ @overload
+ def __le__(self: _ArrayTD64_co, other: _ArrayLikeTD64_co) -> NDArray[bool_]: ...
+ @overload
+ def __le__(self: NDArray[datetime64], other: _ArrayLikeDT64_co) -> NDArray[bool_]: ...
+ @overload
+ def __le__(self: NDArray[object_], other: Any) -> NDArray[bool_]: ...
+ @overload
+ def __le__(self: NDArray[Any], other: _ArrayLikeObject_co) -> NDArray[bool_]: ...
+ @overload
+ def __le__(
+ self: NDArray[Union[number[Any], datetime64, timedelta64, bool_]],
+ other: _RecursiveSequence,
+ ) -> NDArray[bool_]: ...
+
+ @overload
+ def __gt__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __gt__(self: _ArrayNumber_co, other: _ArrayLikeNumber_co) -> NDArray[bool_]: ...
+ @overload
+ def __gt__(self: _ArrayTD64_co, other: _ArrayLikeTD64_co) -> NDArray[bool_]: ...
+ @overload
+ def __gt__(self: NDArray[datetime64], other: _ArrayLikeDT64_co) -> NDArray[bool_]: ...
+ @overload
+ def __gt__(self: NDArray[object_], other: Any) -> NDArray[bool_]: ...
+ @overload
+ def __gt__(self: NDArray[Any], other: _ArrayLikeObject_co) -> NDArray[bool_]: ...
+ @overload
+ def __gt__(
+ self: NDArray[Union[number[Any], datetime64, timedelta64, bool_]],
+ other: _RecursiveSequence,
+ ) -> NDArray[bool_]: ...
+
+ @overload
+ def __ge__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __ge__(self: _ArrayNumber_co, other: _ArrayLikeNumber_co) -> NDArray[bool_]: ...
+ @overload
+ def __ge__(self: _ArrayTD64_co, other: _ArrayLikeTD64_co) -> NDArray[bool_]: ...
+ @overload
+ def __ge__(self: NDArray[datetime64], other: _ArrayLikeDT64_co) -> NDArray[bool_]: ...
+ @overload
+ def __ge__(self: NDArray[object_], other: Any) -> NDArray[bool_]: ...
+ @overload
+ def __ge__(self: NDArray[Any], other: _ArrayLikeObject_co) -> NDArray[bool_]: ...
+ @overload
+ def __ge__(
+ self: NDArray[Union[number[Any], datetime64, timedelta64, bool_]],
+ other: _RecursiveSequence,
+ ) -> NDArray[bool_]: ...
+
+ # Unary ops
+ @overload
+ def __abs__(self: NDArray[bool_]) -> NDArray[bool_]: ...
+ @overload
+ def __abs__(self: NDArray[complexfloating[_NBit1, _NBit1]]) -> NDArray[floating[_NBit1]]: ...
+ @overload
+ def __abs__(self: NDArray[_NumberType]) -> NDArray[_NumberType]: ...
+ @overload
+ def __abs__(self: NDArray[timedelta64]) -> NDArray[timedelta64]: ...
+ @overload
+ def __abs__(self: NDArray[object_]) -> Any: ...
+
+ @overload
+ def __invert__(self: NDArray[bool_]) -> NDArray[bool_]: ...
+ @overload
+ def __invert__(self: NDArray[_IntType]) -> NDArray[_IntType]: ...
+ @overload
+ def __invert__(self: NDArray[object_]) -> Any: ...
+
+ @overload
+ def __pos__(self: NDArray[_NumberType]) -> NDArray[_NumberType]: ...
+ @overload
+ def __pos__(self: NDArray[timedelta64]) -> NDArray[timedelta64]: ...
+ @overload
+ def __pos__(self: NDArray[object_]) -> Any: ...
+
+ @overload
+ def __neg__(self: NDArray[_NumberType]) -> NDArray[_NumberType]: ...
+ @overload
+ def __neg__(self: NDArray[timedelta64]) -> NDArray[timedelta64]: ...
+ @overload
+ def __neg__(self: NDArray[object_]) -> Any: ...
+
+ # Binary ops
# NOTE: `ndarray` does not implement `__imatmul__`
- def __rmatmul__(self, other: ArrayLike) -> Any: ...
- def __neg__(self: _ArraySelf) -> Any: ...
- def __pos__(self: _ArraySelf) -> Any: ...
- def __abs__(self: _ArraySelf) -> Any: ...
- def __mod__(self, other: ArrayLike) -> Any: ...
- def __rmod__(self, other: ArrayLike) -> Any: ...
- def __divmod__(self, other: ArrayLike) -> Tuple[Any, Any]: ...
- def __rdivmod__(self, other: ArrayLike) -> Tuple[Any, Any]: ...
- def __add__(self, other: ArrayLike) -> Any: ...
- def __radd__(self, other: ArrayLike) -> Any: ...
- def __sub__(self, other: ArrayLike) -> Any: ...
- def __rsub__(self, other: ArrayLike) -> Any: ...
- def __mul__(self, other: ArrayLike) -> Any: ...
- def __rmul__(self, other: ArrayLike) -> Any: ...
- def __floordiv__(self, other: ArrayLike) -> Any: ...
- def __rfloordiv__(self, other: ArrayLike) -> Any: ...
- def __pow__(self, other: ArrayLike) -> Any: ...
- def __rpow__(self, other: ArrayLike) -> Any: ...
- def __truediv__(self, other: ArrayLike) -> Any: ...
- def __rtruediv__(self, other: ArrayLike) -> Any: ...
- def __invert__(self: _ArraySelf) -> Any: ...
- def __lshift__(self, other: ArrayLike) -> Any: ...
- def __rlshift__(self, other: ArrayLike) -> Any: ...
- def __rshift__(self, other: ArrayLike) -> Any: ...
- def __rrshift__(self, other: ArrayLike) -> Any: ...
- def __and__(self, other: ArrayLike) -> Any: ...
- def __rand__(self, other: ArrayLike) -> Any: ...
- def __xor__(self, other: ArrayLike) -> Any: ...
- def __rxor__(self, other: ArrayLike) -> Any: ...
- def __or__(self, other: ArrayLike) -> Any: ...
- def __ror__(self, other: ArrayLike) -> Any: ...
+ @overload
+ def __matmul__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __matmul__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[bool_]: ... # type: ignore[misc]
+ @overload
+ def __matmul__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __matmul__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __matmul__(self: _ArrayFloat_co, other: _ArrayLikeFloat_co) -> NDArray[floating[Any]]: ... # type: ignore[misc]
+ @overload
+ def __matmul__(self: _ArrayComplex_co, other: _ArrayLikeComplex_co) -> NDArray[complexfloating[Any, Any]]: ...
+ @overload
+ def __matmul__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __matmul__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __matmul__(
+ self: _ArrayNumber_co,
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __rmatmul__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __rmatmul__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[bool_]: ... # type: ignore[misc]
+ @overload
+ def __rmatmul__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rmatmul__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rmatmul__(self: _ArrayFloat_co, other: _ArrayLikeFloat_co) -> NDArray[floating[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rmatmul__(self: _ArrayComplex_co, other: _ArrayLikeComplex_co) -> NDArray[complexfloating[Any, Any]]: ...
+ @overload
+ def __rmatmul__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __rmatmul__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __rmatmul__(
+ self: _ArrayNumber_co,
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __mod__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __mod__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[int8]: ... # type: ignore[misc]
+ @overload
+ def __mod__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __mod__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __mod__(self: _ArrayFloat_co, other: _ArrayLikeFloat_co) -> NDArray[floating[Any]]: ... # type: ignore[misc]
+ @overload
+ def __mod__(self: _ArrayTD64_co, other: _NestedSequence[_SupportsArray[dtype[timedelta64]]]) -> NDArray[timedelta64]: ...
+ @overload
+ def __mod__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __mod__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __mod__(
+ self: NDArray[Union[bool_, integer[Any], floating[Any], timedelta64]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __rmod__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __rmod__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[int8]: ... # type: ignore[misc]
+ @overload
+ def __rmod__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rmod__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rmod__(self: _ArrayFloat_co, other: _ArrayLikeFloat_co) -> NDArray[floating[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rmod__(self: _ArrayTD64_co, other: _NestedSequence[_SupportsArray[dtype[timedelta64]]]) -> NDArray[timedelta64]: ...
+ @overload
+ def __rmod__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __rmod__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __rmod__(
+ self: NDArray[Union[bool_, integer[Any], floating[Any], timedelta64]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __divmod__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __divmod__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> _2Tuple[NDArray[int8]]: ... # type: ignore[misc]
+ @overload
+ def __divmod__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> _2Tuple[NDArray[unsignedinteger[Any]]]: ... # type: ignore[misc]
+ @overload
+ def __divmod__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> _2Tuple[NDArray[signedinteger[Any]]]: ... # type: ignore[misc]
+ @overload
+ def __divmod__(self: _ArrayFloat_co, other: _ArrayLikeFloat_co) -> _2Tuple[NDArray[floating[Any]]]: ... # type: ignore[misc]
+ @overload
+ def __divmod__(self: _ArrayTD64_co, other: _NestedSequence[_SupportsArray[dtype[timedelta64]]]) -> Tuple[NDArray[int64], NDArray[timedelta64]]: ...
+ @overload
+ def __divmod__(
+ self: NDArray[Union[bool_, integer[Any], floating[Any], timedelta64]],
+ other: _RecursiveSequence,
+ ) -> _2Tuple[Any]: ...
+
+ @overload
+ def __rdivmod__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __rdivmod__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> _2Tuple[NDArray[int8]]: ... # type: ignore[misc]
+ @overload
+ def __rdivmod__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> _2Tuple[NDArray[unsignedinteger[Any]]]: ... # type: ignore[misc]
+ @overload
+ def __rdivmod__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> _2Tuple[NDArray[signedinteger[Any]]]: ... # type: ignore[misc]
+ @overload
+ def __rdivmod__(self: _ArrayFloat_co, other: _ArrayLikeFloat_co) -> _2Tuple[NDArray[floating[Any]]]: ... # type: ignore[misc]
+ @overload
+ def __rdivmod__(self: _ArrayTD64_co, other: _NestedSequence[_SupportsArray[dtype[timedelta64]]]) -> Tuple[NDArray[int64], NDArray[timedelta64]]: ...
+ @overload
+ def __rdivmod__(
+ self: NDArray[Union[bool_, integer[Any], floating[Any], timedelta64]],
+ other: _RecursiveSequence,
+ ) -> _2Tuple[Any]: ...
+
+ @overload
+ def __add__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __add__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[bool_]: ... # type: ignore[misc]
+ @overload
+ def __add__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __add__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __add__(self: _ArrayFloat_co, other: _ArrayLikeFloat_co) -> NDArray[floating[Any]]: ... # type: ignore[misc]
+ @overload
+ def __add__(self: _ArrayComplex_co, other: _ArrayLikeComplex_co) -> NDArray[complexfloating[Any, Any]]: ... # type: ignore[misc]
+ @overload
+ def __add__(self: _ArrayTD64_co, other: _ArrayLikeTD64_co) -> NDArray[timedelta64]: ... # type: ignore[misc]
+ @overload
+ def __add__(self: _ArrayTD64_co, other: _ArrayLikeDT64_co) -> NDArray[datetime64]: ...
+ @overload
+ def __add__(self: NDArray[datetime64], other: _ArrayLikeTD64_co) -> NDArray[datetime64]: ...
+ @overload
+ def __add__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __add__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __add__(
+ self: NDArray[Union[bool_, number[Any], timedelta64, datetime64]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __radd__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __radd__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[bool_]: ... # type: ignore[misc]
+ @overload
+ def __radd__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __radd__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __radd__(self: _ArrayFloat_co, other: _ArrayLikeFloat_co) -> NDArray[floating[Any]]: ... # type: ignore[misc]
+ @overload
+ def __radd__(self: _ArrayComplex_co, other: _ArrayLikeComplex_co) -> NDArray[complexfloating[Any, Any]]: ... # type: ignore[misc]
+ @overload
+ def __radd__(self: _ArrayTD64_co, other: _ArrayLikeTD64_co) -> NDArray[timedelta64]: ... # type: ignore[misc]
+ @overload
+ def __radd__(self: _ArrayTD64_co, other: _ArrayLikeDT64_co) -> NDArray[datetime64]: ...
+ @overload
+ def __radd__(self: NDArray[datetime64], other: _ArrayLikeTD64_co) -> NDArray[datetime64]: ...
+ @overload
+ def __radd__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __radd__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __radd__(
+ self: NDArray[Union[bool_, number[Any], timedelta64, datetime64]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __sub__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __sub__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NoReturn: ...
+ @overload
+ def __sub__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __sub__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __sub__(self: _ArrayFloat_co, other: _ArrayLikeFloat_co) -> NDArray[floating[Any]]: ... # type: ignore[misc]
+ @overload
+ def __sub__(self: _ArrayComplex_co, other: _ArrayLikeComplex_co) -> NDArray[complexfloating[Any, Any]]: ... # type: ignore[misc]
+ @overload
+ def __sub__(self: _ArrayTD64_co, other: _ArrayLikeTD64_co) -> NDArray[timedelta64]: ... # type: ignore[misc]
+ @overload
+ def __sub__(self: NDArray[datetime64], other: _ArrayLikeTD64_co) -> NDArray[datetime64]: ...
+ @overload
+ def __sub__(self: NDArray[datetime64], other: _ArrayLikeDT64_co) -> NDArray[timedelta64]: ...
+ @overload
+ def __sub__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __sub__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __sub__(
+ self: NDArray[Union[bool_, number[Any], timedelta64, datetime64]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __rsub__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __rsub__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NoReturn: ...
+ @overload
+ def __rsub__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rsub__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rsub__(self: _ArrayFloat_co, other: _ArrayLikeFloat_co) -> NDArray[floating[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rsub__(self: _ArrayComplex_co, other: _ArrayLikeComplex_co) -> NDArray[complexfloating[Any, Any]]: ... # type: ignore[misc]
+ @overload
+ def __rsub__(self: _ArrayTD64_co, other: _ArrayLikeTD64_co) -> NDArray[timedelta64]: ... # type: ignore[misc]
+ @overload
+ def __rsub__(self: _ArrayTD64_co, other: _ArrayLikeDT64_co) -> NDArray[datetime64]: ... # type: ignore[misc]
+ @overload
+ def __rsub__(self: NDArray[datetime64], other: _ArrayLikeDT64_co) -> NDArray[timedelta64]: ...
+ @overload
+ def __rsub__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __rsub__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __rsub__(
+ self: NDArray[Union[bool_, number[Any], timedelta64, datetime64]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __mul__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __mul__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[bool_]: ... # type: ignore[misc]
+ @overload
+ def __mul__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __mul__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __mul__(self: _ArrayFloat_co, other: _ArrayLikeFloat_co) -> NDArray[floating[Any]]: ... # type: ignore[misc]
+ @overload
+ def __mul__(self: _ArrayComplex_co, other: _ArrayLikeComplex_co) -> NDArray[complexfloating[Any, Any]]: ... # type: ignore[misc]
+ @overload
+ def __mul__(self: _ArrayTD64_co, other: _ArrayLikeFloat_co) -> NDArray[timedelta64]: ...
+ @overload
+ def __mul__(self: _ArrayFloat_co, other: _ArrayLikeTD64_co) -> NDArray[timedelta64]: ...
+ @overload
+ def __mul__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __mul__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __mul__(
+ self: NDArray[Union[bool_, number[Any], timedelta64]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __rmul__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __rmul__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[bool_]: ... # type: ignore[misc]
+ @overload
+ def __rmul__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rmul__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rmul__(self: _ArrayFloat_co, other: _ArrayLikeFloat_co) -> NDArray[floating[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rmul__(self: _ArrayComplex_co, other: _ArrayLikeComplex_co) -> NDArray[complexfloating[Any, Any]]: ... # type: ignore[misc]
+ @overload
+ def __rmul__(self: _ArrayTD64_co, other: _ArrayLikeFloat_co) -> NDArray[timedelta64]: ...
+ @overload
+ def __rmul__(self: _ArrayFloat_co, other: _ArrayLikeTD64_co) -> NDArray[timedelta64]: ...
+ @overload
+ def __rmul__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __rmul__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __rmul__(
+ self: NDArray[Union[bool_, number[Any], timedelta64]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __floordiv__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __floordiv__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[int8]: ... # type: ignore[misc]
+ @overload
+ def __floordiv__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __floordiv__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __floordiv__(self: _ArrayFloat_co, other: _ArrayLikeFloat_co) -> NDArray[floating[Any]]: ... # type: ignore[misc]
+ @overload
+ def __floordiv__(self: NDArray[timedelta64], other: _NestedSequence[_SupportsArray[dtype[timedelta64]]]) -> NDArray[int64]: ...
+ @overload
+ def __floordiv__(self: NDArray[timedelta64], other: _ArrayLikeBool_co) -> NoReturn: ...
+ @overload
+ def __floordiv__(self: NDArray[timedelta64], other: _ArrayLikeFloat_co) -> NDArray[timedelta64]: ...
+ @overload
+ def __floordiv__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __floordiv__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __floordiv__(
+ self: NDArray[Union[bool_, number[Any], timedelta64]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __rfloordiv__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __rfloordiv__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[int8]: ... # type: ignore[misc]
+ @overload
+ def __rfloordiv__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rfloordiv__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rfloordiv__(self: _ArrayFloat_co, other: _ArrayLikeFloat_co) -> NDArray[floating[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rfloordiv__(self: NDArray[timedelta64], other: _NestedSequence[_SupportsArray[dtype[timedelta64]]]) -> NDArray[int64]: ...
+ @overload
+ def __rfloordiv__(self: NDArray[bool_], other: _ArrayLikeTD64_co) -> NoReturn: ...
+ @overload
+ def __rfloordiv__(self: _ArrayFloat_co, other: _ArrayLikeTD64_co) -> NDArray[timedelta64]: ...
+ @overload
+ def __rfloordiv__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __rfloordiv__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __rfloordiv__(
+ self: NDArray[Union[bool_, number[Any], timedelta64]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __pow__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __pow__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[int8]: ... # type: ignore[misc]
+ @overload
+ def __pow__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __pow__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __pow__(self: _ArrayFloat_co, other: _ArrayLikeFloat_co) -> NDArray[floating[Any]]: ... # type: ignore[misc]
+ @overload
+ def __pow__(self: _ArrayComplex_co, other: _ArrayLikeComplex_co) -> NDArray[complexfloating[Any, Any]]: ...
+ @overload
+ def __pow__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __pow__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __pow__(
+ self: NDArray[Union[bool_, number[Any]]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __rpow__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __rpow__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[int8]: ... # type: ignore[misc]
+ @overload
+ def __rpow__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rpow__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rpow__(self: _ArrayFloat_co, other: _ArrayLikeFloat_co) -> NDArray[floating[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rpow__(self: _ArrayComplex_co, other: _ArrayLikeComplex_co) -> NDArray[complexfloating[Any, Any]]: ...
+ @overload
+ def __rpow__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __rpow__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __rpow__(
+ self: NDArray[Union[bool_, number[Any]]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __truediv__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __truediv__(self: _ArrayInt_co, other: _ArrayInt_co) -> NDArray[float64]: ... # type: ignore[misc]
+ @overload
+ def __truediv__(self: _ArrayFloat_co, other: _ArrayLikeFloat_co) -> NDArray[floating[Any]]: ... # type: ignore[misc]
+ @overload
+ def __truediv__(self: _ArrayComplex_co, other: _ArrayLikeComplex_co) -> NDArray[complexfloating[Any, Any]]: ... # type: ignore[misc]
+ @overload
+ def __truediv__(self: NDArray[timedelta64], other: _NestedSequence[_SupportsArray[dtype[timedelta64]]]) -> NDArray[float64]: ...
+ @overload
+ def __truediv__(self: NDArray[timedelta64], other: _ArrayLikeBool_co) -> NoReturn: ...
+ @overload
+ def __truediv__(self: NDArray[timedelta64], other: _ArrayLikeFloat_co) -> NDArray[timedelta64]: ...
+ @overload
+ def __truediv__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __truediv__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __truediv__(
+ self: NDArray[Union[bool_, number[Any], timedelta64]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __rtruediv__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __rtruediv__(self: _ArrayInt_co, other: _ArrayInt_co) -> NDArray[float64]: ... # type: ignore[misc]
+ @overload
+ def __rtruediv__(self: _ArrayFloat_co, other: _ArrayLikeFloat_co) -> NDArray[floating[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rtruediv__(self: _ArrayComplex_co, other: _ArrayLikeComplex_co) -> NDArray[complexfloating[Any, Any]]: ... # type: ignore[misc]
+ @overload
+ def __rtruediv__(self: NDArray[timedelta64], other: _NestedSequence[_SupportsArray[dtype[timedelta64]]]) -> NDArray[float64]: ...
+ @overload
+ def __rtruediv__(self: NDArray[bool_], other: _ArrayLikeTD64_co) -> NoReturn: ...
+ @overload
+ def __rtruediv__(self: _ArrayFloat_co, other: _ArrayLikeTD64_co) -> NDArray[timedelta64]: ...
+ @overload
+ def __rtruediv__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __rtruediv__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __rtruediv__(
+ self: NDArray[Union[bool_, number[Any], timedelta64]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __lshift__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __lshift__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[int8]: ... # type: ignore[misc]
+ @overload
+ def __lshift__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __lshift__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ...
+ @overload
+ def __lshift__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __lshift__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __lshift__(
+ self: NDArray[Union[bool_, integer[Any]]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __rlshift__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __rlshift__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[int8]: ... # type: ignore[misc]
+ @overload
+ def __rlshift__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rlshift__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ...
+ @overload
+ def __rlshift__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __rlshift__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __rlshift__(
+ self: NDArray[Union[bool_, integer[Any]]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __rshift__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __rshift__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[int8]: ... # type: ignore[misc]
+ @overload
+ def __rshift__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rshift__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ...
+ @overload
+ def __rshift__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __rshift__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __rshift__(
+ self: NDArray[Union[bool_, integer[Any]]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __rrshift__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __rrshift__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[int8]: ... # type: ignore[misc]
+ @overload
+ def __rrshift__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rrshift__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ...
+ @overload
+ def __rrshift__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __rrshift__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __rrshift__(
+ self: NDArray[Union[bool_, integer[Any]]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __and__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __and__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[bool_]: ... # type: ignore[misc]
+ @overload
+ def __and__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __and__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ...
+ @overload
+ def __and__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __and__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __and__(
+ self: NDArray[Union[bool_, integer[Any]]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __rand__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __rand__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[bool_]: ... # type: ignore[misc]
+ @overload
+ def __rand__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rand__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ...
+ @overload
+ def __rand__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __rand__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __rand__(
+ self: NDArray[Union[bool_, integer[Any]]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __xor__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __xor__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[bool_]: ... # type: ignore[misc]
+ @overload
+ def __xor__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __xor__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ...
+ @overload
+ def __xor__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __xor__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __xor__(
+ self: NDArray[Union[bool_, integer[Any]]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __rxor__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __rxor__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[bool_]: ... # type: ignore[misc]
+ @overload
+ def __rxor__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __rxor__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ...
+ @overload
+ def __rxor__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __rxor__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __rxor__(
+ self: NDArray[Union[bool_, integer[Any]]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __or__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __or__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[bool_]: ... # type: ignore[misc]
+ @overload
+ def __or__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __or__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ...
+ @overload
+ def __or__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __or__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __or__(
+ self: NDArray[Union[bool_, integer[Any]]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
+ @overload
+ def __ror__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __ror__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[bool_]: ... # type: ignore[misc]
+ @overload
+ def __ror__(self: _ArrayUInt_co, other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+ @overload
+ def __ror__(self: _ArrayInt_co, other: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ...
+ @overload
+ def __ror__(self: NDArray[object_], other: Any) -> Any: ...
+ @overload
+ def __ror__(self: NDArray[Any], other: _ArrayLikeObject_co) -> Any: ...
+ @overload
+ def __ror__(
+ self: NDArray[Union[bool_, integer[Any]]],
+ other: _RecursiveSequence,
+ ) -> Any: ...
+
# `np.generic` does not support inplace operations
- def __iadd__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
- def __isub__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
- def __imul__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
- def __itruediv__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
- def __ifloordiv__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
- def __ipow__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
- def __imod__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
- def __ilshift__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
- def __irshift__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
- def __iand__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
- def __ixor__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
- def __ior__(self: _ArraySelf, other: ArrayLike) -> _ArraySelf: ...
+ @overload # type: ignore[misc]
+ def __iadd__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __iadd__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[bool_]: ...
+ @overload
+ def __iadd__(self: NDArray[unsignedinteger[_NBit1]], other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[_NBit1]]: ...
+ @overload
+ def __iadd__(self: NDArray[signedinteger[_NBit1]], other: _ArrayLikeInt_co) -> NDArray[signedinteger[_NBit1]]: ...
+ @overload
+ def __iadd__(self: NDArray[floating[_NBit1]], other: _ArrayLikeFloat_co) -> NDArray[floating[_NBit1]]: ...
+ @overload
+ def __iadd__(self: NDArray[complexfloating[_NBit1, _NBit1]], other: _ArrayLikeComplex_co) -> NDArray[complexfloating[_NBit1, _NBit1]]: ...
+ @overload
+ def __iadd__(self: NDArray[timedelta64], other: _ArrayLikeTD64_co) -> NDArray[timedelta64]: ...
+ @overload
+ def __iadd__(self: NDArray[datetime64], other: _ArrayLikeTD64_co) -> NDArray[datetime64]: ...
+ @overload
+ def __iadd__(self: NDArray[object_], other: Any) -> NDArray[object_]: ...
+ @overload
+ def __iadd__(self: NDArray[_ScalarType], other: _RecursiveSequence) -> NDArray[_ScalarType]: ...
+
+ @overload # type: ignore[misc]
+ def __isub__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __isub__(self: NDArray[unsignedinteger[_NBit1]], other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[_NBit1]]: ...
+ @overload
+ def __isub__(self: NDArray[signedinteger[_NBit1]], other: _ArrayLikeInt_co) -> NDArray[signedinteger[_NBit1]]: ...
+ @overload
+ def __isub__(self: NDArray[floating[_NBit1]], other: _ArrayLikeFloat_co) -> NDArray[floating[_NBit1]]: ...
+ @overload
+ def __isub__(self: NDArray[complexfloating[_NBit1, _NBit1]], other: _ArrayLikeComplex_co) -> NDArray[complexfloating[_NBit1, _NBit1]]: ...
+ @overload
+ def __isub__(self: NDArray[timedelta64], other: _ArrayLikeTD64_co) -> NDArray[timedelta64]: ...
+ @overload
+ def __isub__(self: NDArray[datetime64], other: _ArrayLikeTD64_co) -> NDArray[datetime64]: ...
+ @overload
+ def __isub__(self: NDArray[object_], other: Any) -> NDArray[object_]: ...
+ @overload
+ def __isub__(self: NDArray[_ScalarType], other: _RecursiveSequence) -> NDArray[_ScalarType]: ...
+
+ @overload # type: ignore[misc]
+ def __imul__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __imul__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[bool_]: ...
+ @overload
+ def __imul__(self: NDArray[unsignedinteger[_NBit1]], other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[_NBit1]]: ...
+ @overload
+ def __imul__(self: NDArray[signedinteger[_NBit1]], other: _ArrayLikeInt_co) -> NDArray[signedinteger[_NBit1]]: ...
+ @overload
+ def __imul__(self: NDArray[floating[_NBit1]], other: _ArrayLikeFloat_co) -> NDArray[floating[_NBit1]]: ...
+ @overload
+ def __imul__(self: NDArray[complexfloating[_NBit1, _NBit1]], other: _ArrayLikeComplex_co) -> NDArray[complexfloating[_NBit1, _NBit1]]: ...
+ @overload
+ def __imul__(self: NDArray[timedelta64], other: _ArrayLikeFloat_co) -> NDArray[timedelta64]: ...
+ @overload
+ def __imul__(self: NDArray[object_], other: Any) -> NDArray[object_]: ...
+ @overload
+ def __imul__(self: NDArray[_ScalarType], other: _RecursiveSequence) -> NDArray[_ScalarType]: ...
+
+ @overload # type: ignore[misc]
+ def __itruediv__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __itruediv__(self: NDArray[floating[_NBit1]], other: _ArrayLikeFloat_co) -> NDArray[floating[_NBit1]]: ...
+ @overload
+ def __itruediv__(self: NDArray[complexfloating[_NBit1, _NBit1]], other: _ArrayLikeComplex_co) -> NDArray[complexfloating[_NBit1, _NBit1]]: ...
+ @overload
+ def __itruediv__(self: NDArray[timedelta64], other: _ArrayLikeBool_co) -> NoReturn: ...
+ @overload
+ def __itruediv__(self: NDArray[timedelta64], other: _ArrayLikeInt_co) -> NDArray[timedelta64]: ...
+ @overload
+ def __itruediv__(self: NDArray[object_], other: Any) -> NDArray[object_]: ...
+ @overload
+ def __itruediv__(self: NDArray[_ScalarType], other: _RecursiveSequence) -> NDArray[_ScalarType]: ...
+
+ @overload # type: ignore[misc]
+ def __ifloordiv__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __ifloordiv__(self: NDArray[unsignedinteger[_NBit1]], other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[_NBit1]]: ...
+ @overload
+ def __ifloordiv__(self: NDArray[signedinteger[_NBit1]], other: _ArrayLikeInt_co) -> NDArray[signedinteger[_NBit1]]: ...
+ @overload
+ def __ifloordiv__(self: NDArray[floating[_NBit1]], other: _ArrayLikeFloat_co) -> NDArray[floating[_NBit1]]: ...
+ @overload
+ def __ifloordiv__(self: NDArray[complexfloating[_NBit1, _NBit1]], other: _ArrayLikeComplex_co) -> NDArray[complexfloating[_NBit1, _NBit1]]: ...
+ @overload
+ def __ifloordiv__(self: NDArray[timedelta64], other: _ArrayLikeBool_co) -> NoReturn: ...
+ @overload
+ def __ifloordiv__(self: NDArray[timedelta64], other: _ArrayLikeInt_co) -> NDArray[timedelta64]: ...
+ @overload
+ def __ifloordiv__(self: NDArray[object_], other: Any) -> NDArray[object_]: ...
+ @overload
+ def __ifloordiv__(self: NDArray[_ScalarType], other: _RecursiveSequence) -> NDArray[_ScalarType]: ...
+
+ @overload # type: ignore[misc]
+ def __ipow__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __ipow__(self: NDArray[unsignedinteger[_NBit1]], other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[_NBit1]]: ...
+ @overload
+ def __ipow__(self: NDArray[signedinteger[_NBit1]], other: _ArrayLikeInt_co) -> NDArray[signedinteger[_NBit1]]: ...
+ @overload
+ def __ipow__(self: NDArray[floating[_NBit1]], other: _ArrayLikeFloat_co) -> NDArray[floating[_NBit1]]: ...
+ @overload
+ def __ipow__(self: NDArray[complexfloating[_NBit1, _NBit1]], other: _ArrayLikeComplex_co) -> NDArray[complexfloating[_NBit1, _NBit1]]: ...
+ @overload
+ def __ipow__(self: NDArray[object_], other: Any) -> NDArray[object_]: ...
+ @overload
+ def __ipow__(self: NDArray[_ScalarType], other: _RecursiveSequence) -> NDArray[_ScalarType]: ...
+
+ @overload # type: ignore[misc]
+ def __imod__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __imod__(self: NDArray[unsignedinteger[_NBit1]], other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[_NBit1]]: ...
+ @overload
+ def __imod__(self: NDArray[signedinteger[_NBit1]], other: _ArrayLikeInt_co) -> NDArray[signedinteger[_NBit1]]: ...
+ @overload
+ def __imod__(self: NDArray[floating[_NBit1]], other: _ArrayLikeFloat_co) -> NDArray[floating[_NBit1]]: ...
+ @overload
+ def __imod__(self: NDArray[timedelta64], other: _NestedSequence[_SupportsArray[dtype[timedelta64]]]) -> NDArray[timedelta64]: ...
+ @overload
+ def __imod__(self: NDArray[object_], other: Any) -> NDArray[object_]: ...
+ @overload
+ def __imod__(self: NDArray[_ScalarType], other: _RecursiveSequence) -> NDArray[_ScalarType]: ...
+
+ @overload # type: ignore[misc]
+ def __ilshift__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __ilshift__(self: NDArray[unsignedinteger[_NBit1]], other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[_NBit1]]: ...
+ @overload
+ def __ilshift__(self: NDArray[signedinteger[_NBit1]], other: _ArrayLikeInt_co) -> NDArray[signedinteger[_NBit1]]: ...
+ @overload
+ def __ilshift__(self: NDArray[object_], other: Any) -> NDArray[object_]: ...
+ @overload
+ def __ilshift__(self: NDArray[_ScalarType], other: _RecursiveSequence) -> NDArray[_ScalarType]: ...
+
+ @overload # type: ignore[misc]
+ def __irshift__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __irshift__(self: NDArray[unsignedinteger[_NBit1]], other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[_NBit1]]: ...
+ @overload
+ def __irshift__(self: NDArray[signedinteger[_NBit1]], other: _ArrayLikeInt_co) -> NDArray[signedinteger[_NBit1]]: ...
+ @overload
+ def __irshift__(self: NDArray[object_], other: Any) -> NDArray[object_]: ...
+ @overload
+ def __irshift__(self: NDArray[_ScalarType], other: _RecursiveSequence) -> NDArray[_ScalarType]: ...
+
+ @overload # type: ignore[misc]
+ def __iand__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __iand__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[bool_]: ...
+ @overload
+ def __iand__(self: NDArray[unsignedinteger[_NBit1]], other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[_NBit1]]: ...
+ @overload
+ def __iand__(self: NDArray[signedinteger[_NBit1]], other: _ArrayLikeInt_co) -> NDArray[signedinteger[_NBit1]]: ...
+ @overload
+ def __iand__(self: NDArray[object_], other: Any) -> NDArray[object_]: ...
+ @overload
+ def __iand__(self: NDArray[_ScalarType], other: _RecursiveSequence) -> NDArray[_ScalarType]: ...
+
+ @overload # type: ignore[misc]
+ def __ixor__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __ixor__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[bool_]: ...
+ @overload
+ def __ixor__(self: NDArray[unsignedinteger[_NBit1]], other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[_NBit1]]: ...
+ @overload
+ def __ixor__(self: NDArray[signedinteger[_NBit1]], other: _ArrayLikeInt_co) -> NDArray[signedinteger[_NBit1]]: ...
+ @overload
+ def __ixor__(self: NDArray[object_], other: Any) -> NDArray[object_]: ...
+ @overload
+ def __ixor__(self: NDArray[_ScalarType], other: _RecursiveSequence) -> NDArray[_ScalarType]: ...
+
+ @overload # type: ignore[misc]
+ def __ior__(self: NDArray[Any], other: _NestedSequence[Union[str, bytes]]) -> NoReturn: ...
+ @overload
+ def __ior__(self: NDArray[bool_], other: _ArrayLikeBool_co) -> NDArray[bool_]: ...
+ @overload
+ def __ior__(self: NDArray[unsignedinteger[_NBit1]], other: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[_NBit1]]: ...
+ @overload
+ def __ior__(self: NDArray[signedinteger[_NBit1]], other: _ArrayLikeInt_co) -> NDArray[signedinteger[_NBit1]]: ...
+ @overload
+ def __ior__(self: NDArray[object_], other: Any) -> NDArray[object_]: ...
+ @overload
+ def __ior__(self: NDArray[_ScalarType], other: _RecursiveSequence) -> NDArray[_ScalarType]: ...
+
+ # Keep `dtype` at the bottom to avoid name conflicts with `np.dtype`
+ @property
+ def dtype(self) -> _DType_co: ...
# NOTE: while `np.generic` is not technically an instance of `ABCMeta`,
# the `@abstractmethod` decorator is herein used to (forcefully) deny
@@ -1636,37 +2896,146 @@ class ndarray(_ArrayOrScalarCommon, Iterable, Sized, Container):
# See https://github.com/numpy/numpy-stubs/pull/80 for more details.
_ScalarType = TypeVar("_ScalarType", bound=generic)
-_NBit_co = TypeVar("_NBit_co", covariant=True, bound=NBitBase)
-_NBit_co2 = TypeVar("_NBit_co2", covariant=True, bound=NBitBase)
+_NBit1 = TypeVar("_NBit1", bound=NBitBase)
+_NBit2 = TypeVar("_NBit2", bound=NBitBase)
class generic(_ArrayOrScalarCommon):
@abstractmethod
def __init__(self, *args: Any, **kwargs: Any) -> None: ...
+ @overload
+ def __array__(self: _ScalarType, __dtype: None = ...) -> ndarray[Any, dtype[_ScalarType]]: ...
+ @overload
+ def __array__(self, __dtype: _DType) -> ndarray[Any, _DType]: ...
@property
def base(self) -> None: ...
@property
- def dtype(self: _ScalarType) -> _DType[_ScalarType]: ...
- @property
- def ndim(self) -> Literal[0]: ...
+ def ndim(self) -> L[0]: ...
@property
- def size(self) -> Literal[1]: ...
+ def size(self) -> L[1]: ...
@property
def shape(self) -> Tuple[()]: ...
@property
def strides(self) -> Tuple[()]: ...
- def byteswap(self: _ScalarType, inplace: Literal[False] = ...) -> _ScalarType: ...
+ def byteswap(self: _ScalarType, inplace: L[False] = ...) -> _ScalarType: ...
@property
- def flat(self) -> flatiter[ndarray]: ...
- def item(
+ def flat(self: _ScalarType) -> flatiter[ndarray[Any, dtype[_ScalarType]]]: ...
+
+ @overload
+ def astype(
+ self,
+ dtype: _DTypeLike[_ScalarType],
+ order: _OrderKACF = ...,
+ casting: _CastingKind = ...,
+ subok: bool = ...,
+ copy: bool = ...,
+ ) -> _ScalarType: ...
+ @overload
+ def astype(
+ self,
+ dtype: DTypeLike,
+ order: _OrderKACF = ...,
+ casting: _CastingKind = ...,
+ subok: bool = ...,
+ copy: bool = ...,
+ ) -> Any: ...
+
+ # NOTE: `view` will perform a 0D->scalar cast,
+ # thus the array `type` is irrelevant to the output type
+ @overload
+ def view(
self: _ScalarType,
- __args: Union[Literal[0], Tuple[()], Tuple[Literal[0]]] = ...,
+ type: Type[ndarray[Any, Any]] = ...,
+ ) -> _ScalarType: ...
+ @overload
+ def view(
+ self,
+ dtype: _DTypeLike[_ScalarType],
+ type: Type[ndarray[Any, Any]] = ...,
+ ) -> _ScalarType: ...
+ @overload
+ def view(
+ self,
+ dtype: DTypeLike,
+ type: Type[ndarray[Any, Any]] = ...,
) -> Any: ...
+
+ @overload
+ def getfield(
+ self,
+ dtype: _DTypeLike[_ScalarType],
+ offset: SupportsIndex = ...
+ ) -> _ScalarType: ...
+ @overload
+ def getfield(
+ self,
+ dtype: DTypeLike,
+ offset: SupportsIndex = ...
+ ) -> Any: ...
+
+ def item(
+ self,
+ __args: Union[L[0], Tuple[()], Tuple[L[0]]] = ...,
+ ) -> Any: ...
+
+ @overload
+ def take( # type: ignore[misc]
+ self: _ScalarType,
+ indices: _IntLike_co,
+ axis: Optional[SupportsIndex] = ...,
+ out: None = ...,
+ mode: _ModeKind = ...,
+ ) -> _ScalarType: ...
+ @overload
+ def take( # type: ignore[misc]
+ self: _ScalarType,
+ indices: _ArrayLikeInt_co,
+ axis: Optional[SupportsIndex] = ...,
+ out: None = ...,
+ mode: _ModeKind = ...,
+ ) -> ndarray[Any, dtype[_ScalarType]]: ...
+ @overload
+ def take(
+ self,
+ indices: _ArrayLikeInt_co,
+ axis: Optional[SupportsIndex] = ...,
+ out: _NdArraySubClass = ...,
+ mode: _ModeKind = ...,
+ ) -> _NdArraySubClass: ...
+
+ def repeat(
+ self: _ScalarType,
+ repeats: _ArrayLikeInt_co,
+ axis: Optional[SupportsIndex] = ...,
+ ) -> ndarray[Any, dtype[_ScalarType]]: ...
+
+ def flatten(
+ self: _ScalarType,
+ order: _OrderKACF = ...,
+ ) -> ndarray[Any, dtype[_ScalarType]]: ...
+
+ def ravel(
+ self: _ScalarType,
+ order: _OrderKACF = ...,
+ ) -> ndarray[Any, dtype[_ScalarType]]: ...
+
+ @overload
+ def reshape(
+ self: _ScalarType, __shape: _ShapeLike, *, order: _OrderACF = ...
+ ) -> ndarray[Any, dtype[_ScalarType]]: ...
+ @overload
+ def reshape(
+ self: _ScalarType, *shape: SupportsIndex, order: _OrderACF = ...
+ ) -> ndarray[Any, dtype[_ScalarType]]: ...
+
def squeeze(
- self: _ScalarType, axis: Union[Literal[0], Tuple[()]] = ...
+ self: _ScalarType, axis: Union[L[0], Tuple[()]] = ...
) -> _ScalarType: ...
def transpose(self: _ScalarType, __axes: Tuple[()] = ...) -> _ScalarType: ...
+ # Keep `dtype` at the bottom to avoid name conflicts with `np.dtype`
+ @property
+ def dtype(self: _ScalarType) -> dtype[_ScalarType]: ...
-class number(generic, Generic[_NBit_co]): # type: ignore
+class number(generic, Generic[_NBit1]): # type: ignore
@property
def real(self: _ArraySelf) -> _ArraySelf: ...
@property
@@ -1690,13 +3059,18 @@ class number(generic, Generic[_NBit_co]): # type: ignore
__rpow__: _NumberOp
__truediv__: _NumberOp
__rtruediv__: _NumberOp
- __lt__: _ComparisonOp[_NumberLike]
- __le__: _ComparisonOp[_NumberLike]
- __gt__: _ComparisonOp[_NumberLike]
- __ge__: _ComparisonOp[_NumberLike]
+ __lt__: _ComparisonOp[_NumberLike_co, _ArrayLikeNumber_co]
+ __le__: _ComparisonOp[_NumberLike_co, _ArrayLikeNumber_co]
+ __gt__: _ComparisonOp[_NumberLike_co, _ArrayLikeNumber_co]
+ __ge__: _ComparisonOp[_NumberLike_co, _ArrayLikeNumber_co]
class bool_(generic):
def __init__(self, __value: object = ...) -> None: ...
+ def item(
+ self,
+ __args: Union[L[0], Tuple[()], Tuple[L[0]]] = ...,
+ ) -> bool: ...
+ def tolist(self) -> bool: ...
@property
def real(self: _ArraySelf) -> _ArraySelf: ...
@property
@@ -1732,10 +3106,12 @@ class bool_(generic):
__rmod__: _BoolMod
__divmod__: _BoolDivMod
__rdivmod__: _BoolDivMod
- __lt__: _ComparisonOp[_NumberLike]
- __le__: _ComparisonOp[_NumberLike]
- __gt__: _ComparisonOp[_NumberLike]
- __ge__: _ComparisonOp[_NumberLike]
+ __lt__: _ComparisonOp[_NumberLike_co, _ArrayLikeNumber_co]
+ __le__: _ComparisonOp[_NumberLike_co, _ArrayLikeNumber_co]
+ __gt__: _ComparisonOp[_NumberLike_co, _ArrayLikeNumber_co]
+ __ge__: _ComparisonOp[_NumberLike_co, _ArrayLikeNumber_co]
+
+bool8 = bool_
class object_(generic):
def __init__(self, __value: object = ...) -> None: ...
@@ -1743,113 +3119,176 @@ class object_(generic):
def real(self: _ArraySelf) -> _ArraySelf: ...
@property
def imag(self: _ArraySelf) -> _ArraySelf: ...
+ # The 3 protocols below may or may not raise,
+ # depending on the underlying object
+ def __int__(self) -> int: ...
+ def __float__(self) -> float: ...
+ def __complex__(self) -> complex: ...
+object0 = object_
+
+# The `datetime64` constructors requires an object with the three attributes below,
+# and thus supports datetime duck typing
+class _DatetimeScalar(Protocol):
+ @property
+ def day(self) -> int: ...
+ @property
+ def month(self) -> int: ...
+ @property
+ def year(self) -> int: ...
+
+# TODO: `item`/`tolist` returns either `dt.date`, `dt.datetime` or `int`
+# depending on the unit
class datetime64(generic):
@overload
def __init__(
self,
- __value: Union[None, datetime64, _CharLike, dt.datetime] = ...,
- __format: Union[_CharLike, Tuple[_CharLike, _IntLike]] = ...,
+ __value: Union[None, datetime64, _CharLike_co, _DatetimeScalar] = ...,
+ __format: Union[_CharLike_co, Tuple[_CharLike_co, _IntLike_co]] = ...,
) -> None: ...
@overload
def __init__(
self,
__value: int,
- __format: Union[_CharLike, Tuple[_CharLike, _IntLike]]
+ __format: Union[_CharLike_co, Tuple[_CharLike_co, _IntLike_co]]
) -> None: ...
- def __add__(self, other: Union[timedelta64, _IntLike, _BoolLike]) -> datetime64: ...
- def __radd__(self, other: Union[timedelta64, _IntLike, _BoolLike]) -> datetime64: ...
+ def __add__(self, other: _TD64Like_co) -> datetime64: ...
+ def __radd__(self, other: _TD64Like_co) -> datetime64: ...
@overload
def __sub__(self, other: datetime64) -> timedelta64: ...
@overload
- def __sub__(self, other: Union[timedelta64, _IntLike, _BoolLike]) -> datetime64: ...
+ def __sub__(self, other: _TD64Like_co) -> datetime64: ...
def __rsub__(self, other: datetime64) -> timedelta64: ...
- __lt__: _ComparisonOp[datetime64]
- __le__: _ComparisonOp[datetime64]
- __gt__: _ComparisonOp[datetime64]
- __ge__: _ComparisonOp[datetime64]
+ __lt__: _ComparisonOp[datetime64, _ArrayLikeDT64_co]
+ __le__: _ComparisonOp[datetime64, _ArrayLikeDT64_co]
+ __gt__: _ComparisonOp[datetime64, _ArrayLikeDT64_co]
+ __ge__: _ComparisonOp[datetime64, _ArrayLikeDT64_co]
# Support for `__index__` was added in python 3.8 (bpo-20092)
if sys.version_info >= (3, 8):
- _IntValue = Union[SupportsInt, _CharLike, SupportsIndex]
- _FloatValue = Union[None, _CharLike, SupportsFloat, SupportsIndex]
- _ComplexValue = Union[None, _CharLike, SupportsFloat, SupportsComplex, SupportsIndex]
+ _IntValue = Union[SupportsInt, _CharLike_co, SupportsIndex]
+ _FloatValue = Union[None, _CharLike_co, SupportsFloat, SupportsIndex]
+ _ComplexValue = Union[
+ None,
+ _CharLike_co,
+ SupportsFloat,
+ SupportsComplex,
+ SupportsIndex,
+ complex, # `complex` is not a subtype of `SupportsComplex`
+ ]
else:
- _IntValue = Union[SupportsInt, _CharLike]
- _FloatValue = Union[None, _CharLike, SupportsFloat]
- _ComplexValue = Union[None, _CharLike, SupportsFloat, SupportsComplex]
+ _IntValue = Union[SupportsInt, _CharLike_co]
+ _FloatValue = Union[None, _CharLike_co, SupportsFloat]
+ _ComplexValue = Union[
+ None,
+ _CharLike_co,
+ SupportsFloat,
+ SupportsComplex,
+ complex,
+ ]
+
+class integer(number[_NBit1]): # type: ignore
+ @property
+ def numerator(self: _ScalarType) -> _ScalarType: ...
+ @property
+ def denominator(self) -> L[1]: ...
+ @overload
+ def __round__(self, ndigits: None = ...) -> int: ...
+ @overload
+ def __round__(self: _ScalarType, ndigits: SupportsIndex) -> _ScalarType: ...
-class integer(number[_NBit_co]): # type: ignore
# NOTE: `__index__` is technically defined in the bottom-most
# sub-classes (`int64`, `uint32`, etc)
+ def item(
+ self,
+ __args: Union[L[0], Tuple[()], Tuple[L[0]]] = ...,
+ ) -> int: ...
+ def tolist(self) -> int: ...
def __index__(self) -> int: ...
- __truediv__: _IntTrueDiv[_NBit_co]
- __rtruediv__: _IntTrueDiv[_NBit_co]
- def __mod__(self, value: Union[_IntLike, integer]) -> integer: ...
- def __rmod__(self, value: Union[_IntLike, integer]) -> integer: ...
+ __truediv__: _IntTrueDiv[_NBit1]
+ __rtruediv__: _IntTrueDiv[_NBit1]
+ def __mod__(self, value: _IntLike_co) -> integer: ...
+ def __rmod__(self, value: _IntLike_co) -> integer: ...
def __invert__(self: _IntType) -> _IntType: ...
# Ensure that objects annotated as `integer` support bit-wise operations
- def __lshift__(self, other: Union[_IntLike, _BoolLike]) -> integer: ...
- def __rlshift__(self, other: Union[_IntLike, _BoolLike]) -> integer: ...
- def __rshift__(self, other: Union[_IntLike, _BoolLike]) -> integer: ...
- def __rrshift__(self, other: Union[_IntLike, _BoolLike]) -> integer: ...
- def __and__(self, other: Union[_IntLike, _BoolLike]) -> integer: ...
- def __rand__(self, other: Union[_IntLike, _BoolLike]) -> integer: ...
- def __or__(self, other: Union[_IntLike, _BoolLike]) -> integer: ...
- def __ror__(self, other: Union[_IntLike, _BoolLike]) -> integer: ...
- def __xor__(self, other: Union[_IntLike, _BoolLike]) -> integer: ...
- def __rxor__(self, other: Union[_IntLike, _BoolLike]) -> integer: ...
-
-class signedinteger(integer[_NBit_co]):
+ def __lshift__(self, other: _IntLike_co) -> integer: ...
+ def __rlshift__(self, other: _IntLike_co) -> integer: ...
+ def __rshift__(self, other: _IntLike_co) -> integer: ...
+ def __rrshift__(self, other: _IntLike_co) -> integer: ...
+ def __and__(self, other: _IntLike_co) -> integer: ...
+ def __rand__(self, other: _IntLike_co) -> integer: ...
+ def __or__(self, other: _IntLike_co) -> integer: ...
+ def __ror__(self, other: _IntLike_co) -> integer: ...
+ def __xor__(self, other: _IntLike_co) -> integer: ...
+ def __rxor__(self, other: _IntLike_co) -> integer: ...
+
+class signedinteger(integer[_NBit1]):
def __init__(self, __value: _IntValue = ...) -> None: ...
- __add__: _SignedIntOp[_NBit_co]
- __radd__: _SignedIntOp[_NBit_co]
- __sub__: _SignedIntOp[_NBit_co]
- __rsub__: _SignedIntOp[_NBit_co]
- __mul__: _SignedIntOp[_NBit_co]
- __rmul__: _SignedIntOp[_NBit_co]
- __floordiv__: _SignedIntOp[_NBit_co]
- __rfloordiv__: _SignedIntOp[_NBit_co]
- __pow__: _SignedIntOp[_NBit_co]
- __rpow__: _SignedIntOp[_NBit_co]
- __lshift__: _SignedIntBitOp[_NBit_co]
- __rlshift__: _SignedIntBitOp[_NBit_co]
- __rshift__: _SignedIntBitOp[_NBit_co]
- __rrshift__: _SignedIntBitOp[_NBit_co]
- __and__: _SignedIntBitOp[_NBit_co]
- __rand__: _SignedIntBitOp[_NBit_co]
- __xor__: _SignedIntBitOp[_NBit_co]
- __rxor__: _SignedIntBitOp[_NBit_co]
- __or__: _SignedIntBitOp[_NBit_co]
- __ror__: _SignedIntBitOp[_NBit_co]
- __mod__: _SignedIntMod[_NBit_co]
- __rmod__: _SignedIntMod[_NBit_co]
- __divmod__: _SignedIntDivMod[_NBit_co]
- __rdivmod__: _SignedIntDivMod[_NBit_co]
+ __add__: _SignedIntOp[_NBit1]
+ __radd__: _SignedIntOp[_NBit1]
+ __sub__: _SignedIntOp[_NBit1]
+ __rsub__: _SignedIntOp[_NBit1]
+ __mul__: _SignedIntOp[_NBit1]
+ __rmul__: _SignedIntOp[_NBit1]
+ __floordiv__: _SignedIntOp[_NBit1]
+ __rfloordiv__: _SignedIntOp[_NBit1]
+ __pow__: _SignedIntOp[_NBit1]
+ __rpow__: _SignedIntOp[_NBit1]
+ __lshift__: _SignedIntBitOp[_NBit1]
+ __rlshift__: _SignedIntBitOp[_NBit1]
+ __rshift__: _SignedIntBitOp[_NBit1]
+ __rrshift__: _SignedIntBitOp[_NBit1]
+ __and__: _SignedIntBitOp[_NBit1]
+ __rand__: _SignedIntBitOp[_NBit1]
+ __xor__: _SignedIntBitOp[_NBit1]
+ __rxor__: _SignedIntBitOp[_NBit1]
+ __or__: _SignedIntBitOp[_NBit1]
+ __ror__: _SignedIntBitOp[_NBit1]
+ __mod__: _SignedIntMod[_NBit1]
+ __rmod__: _SignedIntMod[_NBit1]
+ __divmod__: _SignedIntDivMod[_NBit1]
+ __rdivmod__: _SignedIntDivMod[_NBit1]
int8 = signedinteger[_8Bit]
int16 = signedinteger[_16Bit]
int32 = signedinteger[_32Bit]
int64 = signedinteger[_64Bit]
+byte = signedinteger[_NBitByte]
+short = signedinteger[_NBitShort]
+intc = signedinteger[_NBitIntC]
+intp = signedinteger[_NBitIntP]
+int0 = signedinteger[_NBitIntP]
+int_ = signedinteger[_NBitInt]
+longlong = signedinteger[_NBitLongLong]
+
+# TODO: `item`/`tolist` returns either `dt.timedelta` or `int`
+# depending on the unit
class timedelta64(generic):
def __init__(
self,
- __value: Union[None, int, _CharLike, dt.timedelta, timedelta64] = ...,
- __format: Union[_CharLike, Tuple[_CharLike, _IntLike]] = ...,
+ __value: Union[None, int, _CharLike_co, dt.timedelta, timedelta64] = ...,
+ __format: Union[_CharLike_co, Tuple[_CharLike_co, _IntLike_co]] = ...,
) -> None: ...
+ @property
+ def numerator(self: _ScalarType) -> _ScalarType: ...
+ @property
+ def denominator(self) -> L[1]: ...
+
+ # NOTE: Only a limited number of units support conversion
+ # to builtin scalar types: `Y`, `M`, `ns`, `ps`, `fs`, `as`
def __int__(self) -> int: ...
def __float__(self) -> float: ...
def __complex__(self) -> complex: ...
def __neg__(self: _ArraySelf) -> _ArraySelf: ...
def __pos__(self: _ArraySelf) -> _ArraySelf: ...
def __abs__(self: _ArraySelf) -> _ArraySelf: ...
- def __add__(self, other: Union[timedelta64, _IntLike, _BoolLike]) -> timedelta64: ...
- def __radd__(self, other: Union[timedelta64, _IntLike, _BoolLike]) -> timedelta64: ...
- def __sub__(self, other: Union[timedelta64, _IntLike, _BoolLike]) -> timedelta64: ...
- def __rsub__(self, other: Union[timedelta64, _IntLike, _BoolLike]) -> timedelta64: ...
- def __mul__(self, other: Union[_FloatLike, _BoolLike]) -> timedelta64: ...
- def __rmul__(self, other: Union[_FloatLike, _BoolLike]) -> timedelta64: ...
+ def __add__(self, other: _TD64Like_co) -> timedelta64: ...
+ def __radd__(self, other: _TD64Like_co) -> timedelta64: ...
+ def __sub__(self, other: _TD64Like_co) -> timedelta64: ...
+ def __rsub__(self, other: _TD64Like_co) -> timedelta64: ...
+ def __mul__(self, other: _FloatLike_co) -> timedelta64: ...
+ def __rmul__(self, other: _FloatLike_co) -> timedelta64: ...
__truediv__: _TD64Div[float64]
__floordiv__: _TD64Div[int64]
def __rtruediv__(self, other: timedelta64) -> float64: ...
@@ -1858,103 +3297,157 @@ class timedelta64(generic):
def __rmod__(self, other: timedelta64) -> timedelta64: ...
def __divmod__(self, other: timedelta64) -> Tuple[int64, timedelta64]: ...
def __rdivmod__(self, other: timedelta64) -> Tuple[int64, timedelta64]: ...
- __lt__: _ComparisonOp[Union[timedelta64, _IntLike, _BoolLike]]
- __le__: _ComparisonOp[Union[timedelta64, _IntLike, _BoolLike]]
- __gt__: _ComparisonOp[Union[timedelta64, _IntLike, _BoolLike]]
- __ge__: _ComparisonOp[Union[timedelta64, _IntLike, _BoolLike]]
+ __lt__: _ComparisonOp[_TD64Like_co, _ArrayLikeTD64_co]
+ __le__: _ComparisonOp[_TD64Like_co, _ArrayLikeTD64_co]
+ __gt__: _ComparisonOp[_TD64Like_co, _ArrayLikeTD64_co]
+ __ge__: _ComparisonOp[_TD64Like_co, _ArrayLikeTD64_co]
-class unsignedinteger(integer[_NBit_co]):
+class unsignedinteger(integer[_NBit1]):
# NOTE: `uint64 + signedinteger -> float64`
def __init__(self, __value: _IntValue = ...) -> None: ...
- __add__: _UnsignedIntOp[_NBit_co]
- __radd__: _UnsignedIntOp[_NBit_co]
- __sub__: _UnsignedIntOp[_NBit_co]
- __rsub__: _UnsignedIntOp[_NBit_co]
- __mul__: _UnsignedIntOp[_NBit_co]
- __rmul__: _UnsignedIntOp[_NBit_co]
- __floordiv__: _UnsignedIntOp[_NBit_co]
- __rfloordiv__: _UnsignedIntOp[_NBit_co]
- __pow__: _UnsignedIntOp[_NBit_co]
- __rpow__: _UnsignedIntOp[_NBit_co]
- __lshift__: _UnsignedIntBitOp[_NBit_co]
- __rlshift__: _UnsignedIntBitOp[_NBit_co]
- __rshift__: _UnsignedIntBitOp[_NBit_co]
- __rrshift__: _UnsignedIntBitOp[_NBit_co]
- __and__: _UnsignedIntBitOp[_NBit_co]
- __rand__: _UnsignedIntBitOp[_NBit_co]
- __xor__: _UnsignedIntBitOp[_NBit_co]
- __rxor__: _UnsignedIntBitOp[_NBit_co]
- __or__: _UnsignedIntBitOp[_NBit_co]
- __ror__: _UnsignedIntBitOp[_NBit_co]
- __mod__: _UnsignedIntMod[_NBit_co]
- __rmod__: _UnsignedIntMod[_NBit_co]
- __divmod__: _UnsignedIntDivMod[_NBit_co]
- __rdivmod__: _UnsignedIntDivMod[_NBit_co]
+ __add__: _UnsignedIntOp[_NBit1]
+ __radd__: _UnsignedIntOp[_NBit1]
+ __sub__: _UnsignedIntOp[_NBit1]
+ __rsub__: _UnsignedIntOp[_NBit1]
+ __mul__: _UnsignedIntOp[_NBit1]
+ __rmul__: _UnsignedIntOp[_NBit1]
+ __floordiv__: _UnsignedIntOp[_NBit1]
+ __rfloordiv__: _UnsignedIntOp[_NBit1]
+ __pow__: _UnsignedIntOp[_NBit1]
+ __rpow__: _UnsignedIntOp[_NBit1]
+ __lshift__: _UnsignedIntBitOp[_NBit1]
+ __rlshift__: _UnsignedIntBitOp[_NBit1]
+ __rshift__: _UnsignedIntBitOp[_NBit1]
+ __rrshift__: _UnsignedIntBitOp[_NBit1]
+ __and__: _UnsignedIntBitOp[_NBit1]
+ __rand__: _UnsignedIntBitOp[_NBit1]
+ __xor__: _UnsignedIntBitOp[_NBit1]
+ __rxor__: _UnsignedIntBitOp[_NBit1]
+ __or__: _UnsignedIntBitOp[_NBit1]
+ __ror__: _UnsignedIntBitOp[_NBit1]
+ __mod__: _UnsignedIntMod[_NBit1]
+ __rmod__: _UnsignedIntMod[_NBit1]
+ __divmod__: _UnsignedIntDivMod[_NBit1]
+ __rdivmod__: _UnsignedIntDivMod[_NBit1]
uint8 = unsignedinteger[_8Bit]
uint16 = unsignedinteger[_16Bit]
uint32 = unsignedinteger[_32Bit]
uint64 = unsignedinteger[_64Bit]
-class inexact(number[_NBit_co]): ... # type: ignore
+ubyte = unsignedinteger[_NBitByte]
+ushort = unsignedinteger[_NBitShort]
+uintc = unsignedinteger[_NBitIntC]
+uintp = unsignedinteger[_NBitIntP]
+uint0 = unsignedinteger[_NBitIntP]
+uint = unsignedinteger[_NBitInt]
+ulonglong = unsignedinteger[_NBitLongLong]
+
+class inexact(number[_NBit1]): # type: ignore
+ def __getnewargs__(self: inexact[_64Bit]) -> Tuple[float, ...]: ...
_IntType = TypeVar("_IntType", bound=integer)
_FloatType = TypeVar('_FloatType', bound=floating)
-class floating(inexact[_NBit_co]):
+class floating(inexact[_NBit1]):
def __init__(self, __value: _FloatValue = ...) -> None: ...
- __add__: _FloatOp[_NBit_co]
- __radd__: _FloatOp[_NBit_co]
- __sub__: _FloatOp[_NBit_co]
- __rsub__: _FloatOp[_NBit_co]
- __mul__: _FloatOp[_NBit_co]
- __rmul__: _FloatOp[_NBit_co]
- __truediv__: _FloatOp[_NBit_co]
- __rtruediv__: _FloatOp[_NBit_co]
- __floordiv__: _FloatOp[_NBit_co]
- __rfloordiv__: _FloatOp[_NBit_co]
- __pow__: _FloatOp[_NBit_co]
- __rpow__: _FloatOp[_NBit_co]
- __mod__: _FloatMod[_NBit_co]
- __rmod__: _FloatMod[_NBit_co]
- __divmod__: _FloatDivMod[_NBit_co]
- __rdivmod__: _FloatDivMod[_NBit_co]
+ def item(
+ self,
+ __args: Union[L[0], Tuple[()], Tuple[L[0]]] = ...,
+ ) -> float: ...
+ def tolist(self) -> float: ...
+ def is_integer(self: float64) -> bool: ...
+ def hex(self: float64) -> str: ...
+ @classmethod
+ def fromhex(cls: Type[float64], __string: str) -> float64: ...
+ def as_integer_ratio(self) -> Tuple[int, int]: ...
+ if sys.version_info >= (3, 9):
+ def __ceil__(self: float64) -> int: ...
+ def __floor__(self: float64) -> int: ...
+ def __trunc__(self: float64) -> int: ...
+ def __getnewargs__(self: float64) -> Tuple[float]: ...
+ def __getformat__(self: float64, __typestr: L["double", "float"]) -> str: ...
+ @overload
+ def __round__(self, ndigits: None = ...) -> int: ...
+ @overload
+ def __round__(self: _ScalarType, ndigits: SupportsIndex) -> _ScalarType: ...
+ __add__: _FloatOp[_NBit1]
+ __radd__: _FloatOp[_NBit1]
+ __sub__: _FloatOp[_NBit1]
+ __rsub__: _FloatOp[_NBit1]
+ __mul__: _FloatOp[_NBit1]
+ __rmul__: _FloatOp[_NBit1]
+ __truediv__: _FloatOp[_NBit1]
+ __rtruediv__: _FloatOp[_NBit1]
+ __floordiv__: _FloatOp[_NBit1]
+ __rfloordiv__: _FloatOp[_NBit1]
+ __pow__: _FloatOp[_NBit1]
+ __rpow__: _FloatOp[_NBit1]
+ __mod__: _FloatMod[_NBit1]
+ __rmod__: _FloatMod[_NBit1]
+ __divmod__: _FloatDivMod[_NBit1]
+ __rdivmod__: _FloatDivMod[_NBit1]
float16 = floating[_16Bit]
float32 = floating[_32Bit]
float64 = floating[_64Bit]
+half = floating[_NBitHalf]
+single = floating[_NBitSingle]
+double = floating[_NBitDouble]
+float_ = floating[_NBitDouble]
+longdouble = floating[_NBitLongDouble]
+longfloat = floating[_NBitLongDouble]
+
# The main reason for `complexfloating` having two typevars is cosmetic.
# It is used to clarify why `complex128`s precision is `_64Bit`, the latter
# describing the two 64 bit floats representing its real and imaginary component
-class complexfloating(inexact[_NBit_co], Generic[_NBit_co, _NBit_co2]):
+class complexfloating(inexact[_NBit1], Generic[_NBit1, _NBit2]):
def __init__(self, __value: _ComplexValue = ...) -> None: ...
- @property
- def real(self) -> floating[_NBit_co]: ... # type: ignore[override]
- @property
- def imag(self) -> floating[_NBit_co2]: ... # type: ignore[override]
- def __abs__(self) -> floating[_NBit_co]: ... # type: ignore[override]
- __add__: _ComplexOp[_NBit_co]
- __radd__: _ComplexOp[_NBit_co]
- __sub__: _ComplexOp[_NBit_co]
- __rsub__: _ComplexOp[_NBit_co]
- __mul__: _ComplexOp[_NBit_co]
- __rmul__: _ComplexOp[_NBit_co]
- __truediv__: _ComplexOp[_NBit_co]
- __rtruediv__: _ComplexOp[_NBit_co]
- __floordiv__: _ComplexOp[_NBit_co]
- __rfloordiv__: _ComplexOp[_NBit_co]
- __pow__: _ComplexOp[_NBit_co]
- __rpow__: _ComplexOp[_NBit_co]
+ def item(
+ self,
+ __args: Union[L[0], Tuple[()], Tuple[L[0]]] = ...,
+ ) -> complex: ...
+ def tolist(self) -> complex: ...
+ @property
+ def real(self) -> floating[_NBit1]: ... # type: ignore[override]
+ @property
+ def imag(self) -> floating[_NBit2]: ... # type: ignore[override]
+ def __abs__(self) -> floating[_NBit1]: ... # type: ignore[override]
+ def __getnewargs__(self: complex128) -> Tuple[float, float]: ...
+ # NOTE: Deprecated
+ # def __round__(self, ndigits=...): ...
+ __add__: _ComplexOp[_NBit1]
+ __radd__: _ComplexOp[_NBit1]
+ __sub__: _ComplexOp[_NBit1]
+ __rsub__: _ComplexOp[_NBit1]
+ __mul__: _ComplexOp[_NBit1]
+ __rmul__: _ComplexOp[_NBit1]
+ __truediv__: _ComplexOp[_NBit1]
+ __rtruediv__: _ComplexOp[_NBit1]
+ __pow__: _ComplexOp[_NBit1]
+ __rpow__: _ComplexOp[_NBit1]
complex64 = complexfloating[_32Bit, _32Bit]
complex128 = complexfloating[_64Bit, _64Bit]
+csingle = complexfloating[_NBitSingle, _NBitSingle]
+singlecomplex = complexfloating[_NBitSingle, _NBitSingle]
+cdouble = complexfloating[_NBitDouble, _NBitDouble]
+complex_ = complexfloating[_NBitDouble, _NBitDouble]
+cfloat = complexfloating[_NBitDouble, _NBitDouble]
+clongdouble = complexfloating[_NBitLongDouble, _NBitLongDouble]
+clongfloat = complexfloating[_NBitLongDouble, _NBitLongDouble]
+longcomplex = complexfloating[_NBitLongDouble, _NBitLongDouble]
+
class flexible(generic): ... # type: ignore
+# TODO: `item`/`tolist` returns either `bytes` or `tuple`
+# depending on whether or not it's used as an opaque bytes sequence
+# or a structure
class void(flexible):
- def __init__(self, __value: Union[_IntLike, _BoolLike, bytes]): ...
+ def __init__(self, __value: Union[_IntLike_co, bytes]) -> None: ...
@property
def real(self: _ArraySelf) -> _ArraySelf: ...
@property
@@ -1962,6 +3455,10 @@ class void(flexible):
def setfield(
self, val: ArrayLike, dtype: DTypeLike, offset: int = ...
) -> None: ...
+ def __getitem__(self, key: SupportsIndex) -> Any: ...
+ def __setitem__(self, key: SupportsIndex, value: ArrayLike) -> None: ...
+
+void0 = void
class character(flexible): # type: ignore
def __int__(self) -> int: ...
@@ -1977,6 +3474,14 @@ class bytes_(character, bytes):
def __init__(
self, __value: str, encoding: str = ..., errors: str = ...
) -> None: ...
+ def item(
+ self,
+ __args: Union[L[0], Tuple[()], Tuple[L[0]]] = ...,
+ ) -> bytes: ...
+ def tolist(self) -> bytes: ...
+
+string_ = bytes_
+bytes0 = bytes_
class str_(character, str):
@overload
@@ -1985,43 +3490,14 @@ class str_(character, str):
def __init__(
self, __value: bytes, encoding: str = ..., errors: str = ...
) -> None: ...
+ def item(
+ self,
+ __args: Union[L[0], Tuple[()], Tuple[L[0]]] = ...,
+ ) -> str: ...
+ def tolist(self) -> str: ...
-unicode_ = str0 = str_
-
-# TODO(alan): Platform dependent types
-# longcomplex, longdouble, longfloat
-# bytes, short, intc, intp, longlong
-# half, single, double, longdouble
-# uint_, int_, float_, complex_
-# float128, complex256
-# float96
-
-def array(
- object: object,
- dtype: DTypeLike = ...,
- *,
- copy: bool = ...,
- order: _OrderKACF = ...,
- subok: bool = ...,
- ndmin: int = ...,
- like: ArrayLike = ...,
-) -> ndarray: ...
-def zeros(
- shape: _ShapeLike,
- dtype: DTypeLike = ...,
- order: _OrderCF = ...,
- *,
- like: ArrayLike = ...,
-) -> ndarray: ...
-def empty(
- shape: _ShapeLike,
- dtype: DTypeLike = ...,
- order: _OrderCF = ...,
- *,
- like: ArrayLike = ...,
-) -> ndarray: ...
-
-def broadcast_shapes(*args: _ShapeLike) -> _Shape: ...
+unicode_ = str_
+str0 = str_
#
# Constants
@@ -2041,65 +3517,47 @@ inf: Final[float]
infty: Final[float]
nan: Final[float]
pi: Final[float]
-ALLOW_THREADS: Final[int]
-BUFSIZE: Final[int]
-CLIP: Final[int]
-ERR_CALL: Final[int]
-ERR_DEFAULT: Final[int]
-ERR_IGNORE: Final[int]
-ERR_LOG: Final[int]
-ERR_PRINT: Final[int]
-ERR_RAISE: Final[int]
-ERR_WARN: Final[int]
-FLOATING_POINT_SUPPORT: Final[int]
-FPE_DIVIDEBYZERO: Final[int]
-FPE_INVALID: Final[int]
-FPE_OVERFLOW: Final[int]
-FPE_UNDERFLOW: Final[int]
-MAXDIMS: Final[int]
-MAY_SHARE_BOUNDS: Final[int]
-MAY_SHARE_EXACT: Final[int]
-RAISE: Final[int]
-SHIFT_DIVIDEBYZERO: Final[int]
-SHIFT_INVALID: Final[int]
-SHIFT_OVERFLOW: Final[int]
-SHIFT_UNDERFLOW: Final[int]
-UFUNC_BUFSIZE_DEFAULT: Final[int]
-WRAP: Final[int]
-tracemalloc_domain: Final[int]
+
+CLIP: L[0]
+WRAP: L[1]
+RAISE: L[2]
+
+ERR_IGNORE: L[0]
+ERR_WARN: L[1]
+ERR_RAISE: L[2]
+ERR_CALL: L[3]
+ERR_PRINT: L[4]
+ERR_LOG: L[5]
+ERR_DEFAULT: L[521]
+
+SHIFT_DIVIDEBYZERO: L[0]
+SHIFT_OVERFLOW: L[3]
+SHIFT_UNDERFLOW: L[6]
+SHIFT_INVALID: L[9]
+
+FPE_DIVIDEBYZERO: L[1]
+FPE_OVERFLOW: L[2]
+FPE_UNDERFLOW: L[4]
+FPE_INVALID: L[8]
+
+FLOATING_POINT_SUPPORT: L[1]
+UFUNC_BUFSIZE_DEFAULT = BUFSIZE
little_endian: Final[bool]
True_: Final[bool_]
False_: Final[bool_]
-UFUNC_PYVALS_NAME: Final[str]
+UFUNC_PYVALS_NAME: L["UFUNC_PYVALS"]
+
+newaxis: None
+# See `npt._ufunc` for more concrete nin-/nout-specific stubs
class ufunc:
@property
def __name__(self) -> str: ...
- def __call__(
- self,
- *args: ArrayLike,
- out: Optional[Union[ndarray, Tuple[ndarray, ...]]] = ...,
- where: Optional[ndarray] = ...,
- # The list should be a list of tuples of ints, but since we
- # don't know the signature it would need to be
- # Tuple[int, ...]. But, since List is invariant something like
- # e.g. List[Tuple[int, int]] isn't a subtype of
- # List[Tuple[int, ...]], so we can't type precisely here.
- axes: List[Any] = ...,
- axis: int = ...,
- keepdims: bool = ...,
- casting: _Casting = ...,
- order: _OrderKACF = ...,
- dtype: DTypeLike = ...,
- subok: bool = ...,
- signature: Union[str, Tuple[str]] = ...,
- # In reality this should be a length of list 3 containing an
- # int, an int, and a callable, but there's no way to express
- # that.
- extobj: List[Union[int, Callable]] = ...,
- ) -> Any: ...
+ @property
+ def __doc__(self) -> str: ...
+ __call__: Callable[..., Any]
@property
def nin(self) -> int: ...
@property
@@ -2129,105 +3587,105 @@ class ufunc:
# raise a ValueError ufuncs with that don't accept two input
# arguments and return one output argument. Because of that we
# can't type them very precisely.
- @property
- def reduce(self) -> Any: ...
- @property
- def accumulate(self) -> Any: ...
- @property
- def reduceat(self) -> Any: ...
- @property
- def outer(self) -> Any: ...
+ reduce: Any
+ accumulate: Any
+ reduce: Any
+ outer: Any
# Similarly at won't be defined for ufuncs that return multiple
# outputs, so we can't type it very precisely.
- @property
- def at(self) -> Any: ...
-
-absolute: ufunc
-add: ufunc
-arccos: ufunc
-arccosh: ufunc
-arcsin: ufunc
-arcsinh: ufunc
-arctan2: ufunc
-arctan: ufunc
-arctanh: ufunc
-bitwise_and: ufunc
-bitwise_or: ufunc
-bitwise_xor: ufunc
-cbrt: ufunc
-ceil: ufunc
-conjugate: ufunc
-copysign: ufunc
-cos: ufunc
-cosh: ufunc
-deg2rad: ufunc
-degrees: ufunc
-divmod: ufunc
-equal: ufunc
-exp2: ufunc
-exp: ufunc
-expm1: ufunc
-fabs: ufunc
-float_power: ufunc
-floor: ufunc
-floor_divide: ufunc
-fmax: ufunc
-fmin: ufunc
-fmod: ufunc
-frexp: ufunc
-gcd: ufunc
-greater: ufunc
-greater_equal: ufunc
-heaviside: ufunc
-hypot: ufunc
-invert: ufunc
-isfinite: ufunc
-isinf: ufunc
-isnan: ufunc
-isnat: ufunc
-lcm: ufunc
-ldexp: ufunc
-left_shift: ufunc
-less: ufunc
-less_equal: ufunc
-log10: ufunc
-log1p: ufunc
-log2: ufunc
-log: ufunc
-logaddexp2: ufunc
-logaddexp: ufunc
-logical_and: ufunc
-logical_not: ufunc
-logical_or: ufunc
-logical_xor: ufunc
-matmul: ufunc
-maximum: ufunc
-minimum: ufunc
-modf: ufunc
-multiply: ufunc
-negative: ufunc
-nextafter: ufunc
-not_equal: ufunc
-positive: ufunc
-power: ufunc
-rad2deg: ufunc
-radians: ufunc
-reciprocal: ufunc
-remainder: ufunc
-right_shift: ufunc
-rint: ufunc
-sign: ufunc
-signbit: ufunc
-sin: ufunc
-sinh: ufunc
-spacing: ufunc
-sqrt: ufunc
-square: ufunc
-subtract: ufunc
-tan: ufunc
-tanh: ufunc
-true_divide: ufunc
-trunc: ufunc
+ at: Any
+
+# Parameters: `__name__`, `ntypes` and `identity`
+absolute: _UFunc_Nin1_Nout1[L['absolute'], L[20], None]
+add: _UFunc_Nin2_Nout1[L['add'], L[22], L[0]]
+arccos: _UFunc_Nin1_Nout1[L['arccos'], L[8], None]
+arccosh: _UFunc_Nin1_Nout1[L['arccosh'], L[8], None]
+arcsin: _UFunc_Nin1_Nout1[L['arcsin'], L[8], None]
+arcsinh: _UFunc_Nin1_Nout1[L['arcsinh'], L[8], None]
+arctan2: _UFunc_Nin2_Nout1[L['arctan2'], L[5], None]
+arctan: _UFunc_Nin1_Nout1[L['arctan'], L[8], None]
+arctanh: _UFunc_Nin1_Nout1[L['arctanh'], L[8], None]
+bitwise_and: _UFunc_Nin2_Nout1[L['bitwise_and'], L[12], L[-1]]
+bitwise_not: _UFunc_Nin1_Nout1[L['invert'], L[12], None]
+bitwise_or: _UFunc_Nin2_Nout1[L['bitwise_or'], L[12], L[0]]
+bitwise_xor: _UFunc_Nin2_Nout1[L['bitwise_xor'], L[12], L[0]]
+cbrt: _UFunc_Nin1_Nout1[L['cbrt'], L[5], None]
+ceil: _UFunc_Nin1_Nout1[L['ceil'], L[7], None]
+conj: _UFunc_Nin1_Nout1[L['conjugate'], L[18], None]
+conjugate: _UFunc_Nin1_Nout1[L['conjugate'], L[18], None]
+copysign: _UFunc_Nin2_Nout1[L['copysign'], L[4], None]
+cos: _UFunc_Nin1_Nout1[L['cos'], L[9], None]
+cosh: _UFunc_Nin1_Nout1[L['cosh'], L[8], None]
+deg2rad: _UFunc_Nin1_Nout1[L['deg2rad'], L[5], None]
+degrees: _UFunc_Nin1_Nout1[L['degrees'], L[5], None]
+divide: _UFunc_Nin2_Nout1[L['true_divide'], L[11], None]
+divmod: _UFunc_Nin2_Nout2[L['divmod'], L[15], None]
+equal: _UFunc_Nin2_Nout1[L['equal'], L[23], None]
+exp2: _UFunc_Nin1_Nout1[L['exp2'], L[8], None]
+exp: _UFunc_Nin1_Nout1[L['exp'], L[10], None]
+expm1: _UFunc_Nin1_Nout1[L['expm1'], L[8], None]
+fabs: _UFunc_Nin1_Nout1[L['fabs'], L[5], None]
+float_power: _UFunc_Nin2_Nout1[L['float_power'], L[4], None]
+floor: _UFunc_Nin1_Nout1[L['floor'], L[7], None]
+floor_divide: _UFunc_Nin2_Nout1[L['floor_divide'], L[21], None]
+fmax: _UFunc_Nin2_Nout1[L['fmax'], L[21], None]
+fmin: _UFunc_Nin2_Nout1[L['fmin'], L[21], None]
+fmod: _UFunc_Nin2_Nout1[L['fmod'], L[15], None]
+frexp: _UFunc_Nin1_Nout2[L['frexp'], L[4], None]
+gcd: _UFunc_Nin2_Nout1[L['gcd'], L[11], L[0]]
+greater: _UFunc_Nin2_Nout1[L['greater'], L[23], None]
+greater_equal: _UFunc_Nin2_Nout1[L['greater_equal'], L[23], None]
+heaviside: _UFunc_Nin2_Nout1[L['heaviside'], L[4], None]
+hypot: _UFunc_Nin2_Nout1[L['hypot'], L[5], L[0]]
+invert: _UFunc_Nin1_Nout1[L['invert'], L[12], None]
+isfinite: _UFunc_Nin1_Nout1[L['isfinite'], L[20], None]
+isinf: _UFunc_Nin1_Nout1[L['isinf'], L[20], None]
+isnan: _UFunc_Nin1_Nout1[L['isnan'], L[20], None]
+isnat: _UFunc_Nin1_Nout1[L['isnat'], L[2], None]
+lcm: _UFunc_Nin2_Nout1[L['lcm'], L[11], None]
+ldexp: _UFunc_Nin2_Nout1[L['ldexp'], L[8], None]
+left_shift: _UFunc_Nin2_Nout1[L['left_shift'], L[11], None]
+less: _UFunc_Nin2_Nout1[L['less'], L[23], None]
+less_equal: _UFunc_Nin2_Nout1[L['less_equal'], L[23], None]
+log10: _UFunc_Nin1_Nout1[L['log10'], L[8], None]
+log1p: _UFunc_Nin1_Nout1[L['log1p'], L[8], None]
+log2: _UFunc_Nin1_Nout1[L['log2'], L[8], None]
+log: _UFunc_Nin1_Nout1[L['log'], L[10], None]
+logaddexp2: _UFunc_Nin2_Nout1[L['logaddexp2'], L[4], float]
+logaddexp: _UFunc_Nin2_Nout1[L['logaddexp'], L[4], float]
+logical_and: _UFunc_Nin2_Nout1[L['logical_and'], L[20], L[True]]
+logical_not: _UFunc_Nin1_Nout1[L['logical_not'], L[20], None]
+logical_or: _UFunc_Nin2_Nout1[L['logical_or'], L[20], L[False]]
+logical_xor: _UFunc_Nin2_Nout1[L['logical_xor'], L[19], L[False]]
+matmul: _GUFunc_Nin2_Nout1[L['matmul'], L[19], None]
+maximum: _UFunc_Nin2_Nout1[L['maximum'], L[21], None]
+minimum: _UFunc_Nin2_Nout1[L['minimum'], L[21], None]
+mod: _UFunc_Nin2_Nout1[L['remainder'], L[16], None]
+modf: _UFunc_Nin1_Nout2[L['modf'], L[4], None]
+multiply: _UFunc_Nin2_Nout1[L['multiply'], L[23], L[1]]
+negative: _UFunc_Nin1_Nout1[L['negative'], L[19], None]
+nextafter: _UFunc_Nin2_Nout1[L['nextafter'], L[4], None]
+not_equal: _UFunc_Nin2_Nout1[L['not_equal'], L[23], None]
+positive: _UFunc_Nin1_Nout1[L['positive'], L[19], None]
+power: _UFunc_Nin2_Nout1[L['power'], L[18], None]
+rad2deg: _UFunc_Nin1_Nout1[L['rad2deg'], L[5], None]
+radians: _UFunc_Nin1_Nout1[L['radians'], L[5], None]
+reciprocal: _UFunc_Nin1_Nout1[L['reciprocal'], L[18], None]
+remainder: _UFunc_Nin2_Nout1[L['remainder'], L[16], None]
+right_shift: _UFunc_Nin2_Nout1[L['right_shift'], L[11], None]
+rint: _UFunc_Nin1_Nout1[L['rint'], L[10], None]
+sign: _UFunc_Nin1_Nout1[L['sign'], L[19], None]
+signbit: _UFunc_Nin1_Nout1[L['signbit'], L[4], None]
+sin: _UFunc_Nin1_Nout1[L['sin'], L[9], None]
+sinh: _UFunc_Nin1_Nout1[L['sinh'], L[8], None]
+spacing: _UFunc_Nin1_Nout1[L['spacing'], L[4], None]
+sqrt: _UFunc_Nin1_Nout1[L['sqrt'], L[10], None]
+square: _UFunc_Nin1_Nout1[L['square'], L[18], None]
+subtract: _UFunc_Nin2_Nout1[L['subtract'], L[21], None]
+tan: _UFunc_Nin1_Nout1[L['tan'], L[8], None]
+tanh: _UFunc_Nin1_Nout1[L['tanh'], L[8], None]
+true_divide: _UFunc_Nin2_Nout1[L['true_divide'], L[11], None]
+trunc: _UFunc_Nin1_Nout1[L['trunc'], L[7], None]
abs = absolute
@@ -2241,9 +3699,12 @@ class RankWarning(UserWarning): ...
class TooHardError(RuntimeError): ...
class AxisError(ValueError, IndexError):
- def __init__(
- self, axis: int, ndim: Optional[int] = ..., msg_prefix: Optional[str] = ...
- ) -> None: ...
+ axis: None | int
+ ndim: None | int
+ @overload
+ def __init__(self, axis: str, ndim: None = ..., msg_prefix: None = ...) -> None: ...
+ @overload
+ def __init__(self, axis: int, ndim: int, msg_prefix: None | str = ...) -> None: ...
_CallType = TypeVar("_CallType", bound=Union[_ErrFunc, _SupportsWrite])
@@ -2269,3 +3730,143 @@ class errstate(Generic[_CallType], ContextDecorator):
__exc_value: Optional[BaseException],
__traceback: Optional[TracebackType],
) -> None: ...
+
+class ndenumerate(Generic[_ScalarType]):
+ iter: flatiter[NDArray[_ScalarType]]
+ @overload
+ def __new__(
+ cls, arr: _NestedSequence[_SupportsArray[dtype[_ScalarType]]],
+ ) -> ndenumerate[_ScalarType]: ...
+ @overload
+ def __new__(cls, arr: _NestedSequence[str]) -> ndenumerate[str_]: ...
+ @overload
+ def __new__(cls, arr: _NestedSequence[bytes]) -> ndenumerate[bytes_]: ...
+ @overload
+ def __new__(cls, arr: _NestedSequence[bool]) -> ndenumerate[bool_]: ...
+ @overload
+ def __new__(cls, arr: _NestedSequence[int]) -> ndenumerate[int_]: ...
+ @overload
+ def __new__(cls, arr: _NestedSequence[float]) -> ndenumerate[float_]: ...
+ @overload
+ def __new__(cls, arr: _NestedSequence[complex]) -> ndenumerate[complex_]: ...
+ @overload
+ def __new__(cls, arr: _RecursiveSequence) -> ndenumerate[Any]: ...
+ def __next__(self: ndenumerate[_ScalarType]) -> Tuple[_Shape, _ScalarType]: ...
+ def __iter__(self: _T) -> _T: ...
+
+class ndindex:
+ def __init__(self, *shape: SupportsIndex) -> None: ...
+ def __iter__(self: _T) -> _T: ...
+ def __next__(self) -> _Shape: ...
+
+class DataSource:
+ def __init__(
+ self,
+ destpath: Union[None, str, os.PathLike[str]] = ...,
+ ) -> None: ...
+ def __del__(self) -> None: ...
+ def abspath(self, path: str) -> str: ...
+ def exists(self, path: str) -> bool: ...
+
+ # Whether the file-object is opened in string or bytes mode (by default)
+ # depends on the file-extension of `path`
+ def open(
+ self,
+ path: str,
+ mode: str = ...,
+ encoding: Optional[str] = ...,
+ newline: Optional[str] = ...,
+ ) -> IO[Any]: ...
+
+# TODO: The type of each `__next__` and `iters` return-type depends
+# on the length and dtype of `args`; we can't describe this behavior yet
+# as we lack variadics (PEP 646).
+class broadcast:
+ def __new__(cls, *args: ArrayLike) -> broadcast: ...
+ @property
+ def index(self) -> int: ...
+ @property
+ def iters(self) -> Tuple[flatiter[Any], ...]: ...
+ @property
+ def nd(self) -> int: ...
+ @property
+ def ndim(self) -> int: ...
+ @property
+ def numiter(self) -> int: ...
+ @property
+ def shape(self) -> _Shape: ...
+ @property
+ def size(self) -> int: ...
+ def __next__(self) -> Tuple[Any, ...]: ...
+ def __iter__(self: _T) -> _T: ...
+ def reset(self) -> None: ...
+
+class busdaycalendar:
+ def __new__(
+ cls,
+ weekmask: ArrayLike = ...,
+ holidays: ArrayLike = ...,
+ ) -> busdaycalendar: ...
+ @property
+ def weekmask(self) -> NDArray[bool_]: ...
+ @property
+ def holidays(self) -> NDArray[datetime64]: ...
+
+class finfo(Generic[_FloatType]):
+ dtype: dtype[_FloatType]
+ bits: int
+ eps: _FloatType
+ epsneg: _FloatType
+ iexp: int
+ machep: int
+ max: _FloatType
+ maxexp: int
+ min: _FloatType
+ minexp: int
+ negep: int
+ nexp: int
+ nmant: int
+ precision: int
+ resolution: _FloatType
+ smallest_subnormal: _FloatType
+ @property
+ def smallest_normal(self) -> _FloatType: ...
+ @property
+ def tiny(self) -> _FloatType: ...
+
+ # NOTE: Not technically a property, but this is the only way we can
+ # access the precision of the underlying float
+ @property
+ def machar(self: finfo[floating[_NBit1]]) -> MachArLike[_NBit1]: ...
+ @machar.setter
+ def machar(self: finfo[floating[_NBit1]], value: MachArLike[_NBit1]) -> None: ...
+
+ @overload
+ def __new__(
+ cls, dtype: inexact[_NBit1] | _DTypeLike[inexact[_NBit1]]
+ ) -> finfo[floating[_NBit1]]: ...
+ @overload
+ def __new__(
+ cls, dtype: complex | float | Type[complex] | Type[float]
+ ) -> finfo[float_]: ...
+ @overload
+ def __new__(
+ cls, dtype: str
+ ) -> finfo[floating[Any]]: ...
+
+class iinfo(Generic[_IntType]):
+ dtype: dtype[_IntType]
+ kind: str
+ bits: int
+ key: str
+ @property
+ def min(self) -> int: ...
+ @property
+ def max(self) -> int: ...
+
+ @overload
+ def __new__(cls, dtype: _IntType | _DTypeLike[_IntType]) -> iinfo[_IntType]: ...
+ @overload
+ def __new__(cls, dtype: int | Type[int]) -> iinfo[int_]: ...
+ @overload
+ def __new__(cls, dtype: str) -> iinfo[Any]: ...
diff --git a/numpy/_globals.py b/numpy/_globals.py
index 9f44c7729..0b715c870 100644
--- a/numpy/_globals.py
+++ b/numpy/_globals.py
@@ -58,14 +58,26 @@ class _NoValueType:
"""Special keyword value.
The instance of this class may be used as the default value assigned to a
- deprecated keyword in order to check if it has been given a user defined
- value.
+ keyword if no other obvious default (e.g., `None`) is suitable,
+
+ Common reasons for using this keyword are:
+
+ - A new keyword is added to a function, and that function forwards its
+ inputs to another function or method which can be defined outside of
+ NumPy. For example, ``np.std(x)`` calls ``x.std``, so when a ``keepdims``
+ keyword was added that could only be forwarded if the user explicitly
+ specified ``keepdims``; downstream array libraries may not have added
+ the same keyword, so adding ``x.std(..., keepdims=keepdims)``
+ unconditionally could have broken previously working code.
+ - A keyword is being deprecated, and a deprecation warning must only be
+ emitted when the keyword is used.
+
"""
__instance = None
def __new__(cls):
# ensure that only one instance exists
if not cls.__instance:
- cls.__instance = super(_NoValueType, cls).__new__(cls)
+ cls.__instance = super().__new__(cls)
return cls.__instance
# needed for python 2 to preserve identity through a pickle
diff --git a/numpy/_pytesttester.py b/numpy/_pytesttester.py
index 813e069a4..acfaa1ca5 100644
--- a/numpy/_pytesttester.py
+++ b/numpy/_pytesttester.py
@@ -35,25 +35,13 @@ __all__ = ['PytestTester']
def _show_numpy_info():
- from numpy.core._multiarray_umath import (
- __cpu_features__, __cpu_baseline__, __cpu_dispatch__
- )
import numpy as np
print("NumPy version %s" % np.__version__)
relaxed_strides = np.ones((10, 1), order="C").flags.f_contiguous
print("NumPy relaxed strides checking option:", relaxed_strides)
-
- if len(__cpu_baseline__) == 0 and len(__cpu_dispatch__) == 0:
- enabled_features = "nothing enabled"
- else:
- enabled_features = ' '.join(__cpu_baseline__)
- for feature in __cpu_dispatch__:
- if __cpu_features__[feature]:
- enabled_features += " %s*" % feature
- else:
- enabled_features += " %s?" % feature
- print("NumPy CPU features:", enabled_features)
+ info = np.lib.utils._opt_info()
+ print("NumPy CPU features: ", (info if info else 'nothing enabled'))
diff --git a/numpy/_pytesttester.pyi b/numpy/_pytesttester.pyi
new file mode 100644
index 000000000..693f4128a
--- /dev/null
+++ b/numpy/_pytesttester.pyi
@@ -0,0 +1,18 @@
+from typing import List, Iterable
+from typing_extensions import Literal as L
+
+__all__: List[str]
+
+class PytestTester:
+ module_name: str
+ def __init__(self, module_name: str) -> None: ...
+ def __call__(
+ self,
+ label: L["fast", "full"] = ...,
+ verbose: int = ...,
+ extra_argv: None | Iterable[str] = ...,
+ doctests: L[False] = ...,
+ coverage: bool = ...,
+ durations: int = ...,
+ tests: None | Iterable[str] = ...,
+ ) -> bool: ...
diff --git a/numpy/_version.py b/numpy/_version.py
new file mode 100644
index 000000000..6d2c55669
--- /dev/null
+++ b/numpy/_version.py
@@ -0,0 +1,523 @@
+# This file helps to compute a version number in source trees obtained from
+# git-archive tarball (such as those provided by githubs download-from-tag
+# feature). Distribution tarballs (built by setup.py sdist) and build
+# directories (produced by setup.py build) will contain a much shorter file
+# that just contains the computed version number.
+
+# This file is released into the public domain. Generated by
+# versioneer-0.19 (https://github.com/python-versioneer/python-versioneer)
+
+"""Git implementation of _version.py."""
+
+import errno
+import os
+import re
+import subprocess
+import sys
+
+
+def get_keywords():
+ """Get the keywords needed to look up the version information."""
+ # these strings will be replaced by git during git-archive.
+ # setup.py/versioneer.py will grep for the variable names, so they must
+ # each be defined on a line of their own. _version.py will just call
+ # get_keywords().
+ git_refnames = "$Format:%d$"
+ git_full = "$Format:%H$"
+ git_date = "$Format:%ci$"
+ keywords = {"refnames": git_refnames, "full": git_full, "date": git_date}
+ return keywords
+
+
+class VersioneerConfig:
+ """Container for Versioneer configuration parameters."""
+
+
+def get_config():
+ """Create, populate and return the VersioneerConfig() object."""
+ # these strings are filled in when 'setup.py versioneer' creates
+ # _version.py
+ cfg = VersioneerConfig()
+ cfg.VCS = "git"
+ cfg.style = "pep440"
+ cfg.tag_prefix = "v"
+ cfg.parentdir_prefix = "numpy-"
+ cfg.versionfile_source = "numpy/_version.py"
+ cfg.verbose = False
+ return cfg
+
+
+class NotThisMethod(Exception):
+ """Exception raised if a method is not valid for the current scenario."""
+
+
+LONG_VERSION_PY = {}
+HANDLERS = {}
+
+
+def register_vcs_handler(vcs, method): # decorator
+ """Create decorator to mark a method as the handler of a VCS."""
+ def decorate(f):
+ """Store f in HANDLERS[vcs][method]."""
+ if vcs not in HANDLERS:
+ HANDLERS[vcs] = {}
+ HANDLERS[vcs][method] = f
+ return f
+ return decorate
+
+
+def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False,
+ env=None):
+ """Call the given command(s)."""
+ assert isinstance(commands, list)
+ p = None
+ for c in commands:
+ try:
+ dispcmd = str([c] + args)
+ # remember shell=False, so use git.cmd on windows, not just git
+ p = subprocess.Popen([c] + args, cwd=cwd, env=env,
+ stdout=subprocess.PIPE,
+ stderr=(subprocess.PIPE if hide_stderr
+ else None))
+ break
+ except EnvironmentError:
+ e = sys.exc_info()[1]
+ if e.errno == errno.ENOENT:
+ continue
+ if verbose:
+ print("unable to run %s" % dispcmd)
+ print(e)
+ return None, None
+ else:
+ if verbose:
+ print("unable to find command, tried %s" % (commands,))
+ return None, None
+ stdout = p.communicate()[0].strip().decode()
+ if p.returncode != 0:
+ if verbose:
+ print("unable to run %s (error)" % dispcmd)
+ print("stdout was %s" % stdout)
+ return None, p.returncode
+ return stdout, p.returncode
+
+
+def versions_from_parentdir(parentdir_prefix, root, verbose):
+ """Try to determine the version from the parent directory name.
+
+ Source tarballs conventionally unpack into a directory that includes both
+ the project name and a version string. We will also support searching up
+ two directory levels for an appropriately named parent directory
+ """
+ rootdirs = []
+
+ for i in range(3):
+ dirname = os.path.basename(root)
+ if dirname.startswith(parentdir_prefix):
+ return {"version": dirname[len(parentdir_prefix):],
+ "full-revisionid": None,
+ "dirty": False, "error": None, "date": None}
+ else:
+ rootdirs.append(root)
+ root = os.path.dirname(root) # up a level
+
+ if verbose:
+ print("Tried directories %s but none started with prefix %s" %
+ (str(rootdirs), parentdir_prefix))
+ raise NotThisMethod("rootdir doesn't start with parentdir_prefix")
+
+
+@register_vcs_handler("git", "get_keywords")
+def git_get_keywords(versionfile_abs):
+ """Extract version information from the given file."""
+ # the code embedded in _version.py can just fetch the value of these
+ # keywords. When used from setup.py, we don't want to import _version.py,
+ # so we do it with a regexp instead. This function is not used from
+ # _version.py.
+ keywords = {}
+ try:
+ with open(versionfile_abs, "r") as f:
+ for line in f.readlines():
+ if line.strip().startswith("git_refnames ="):
+ mo = re.search(r'=\s*"(.*)"', line)
+ if mo:
+ keywords["refnames"] = mo.group(1)
+ if line.strip().startswith("git_full ="):
+ mo = re.search(r'=\s*"(.*)"', line)
+ if mo:
+ keywords["full"] = mo.group(1)
+ if line.strip().startswith("git_date ="):
+ mo = re.search(r'=\s*"(.*)"', line)
+ if mo:
+ keywords["date"] = mo.group(1)
+ except EnvironmentError:
+ pass
+ return keywords
+
+
+@register_vcs_handler("git", "keywords")
+def git_versions_from_keywords(keywords, tag_prefix, verbose):
+ """Get version information from git keywords."""
+ if not keywords:
+ raise NotThisMethod("no keywords at all, weird")
+ date = keywords.get("date")
+ if date is not None:
+ # Use only the last line. Previous lines may contain GPG signature
+ # information.
+ date = date.splitlines()[-1]
+
+ # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant
+ # datestamp. However we prefer "%ci" (which expands to an "ISO-8601
+ # -like" string, which we must then edit to make compliant), because
+ # it's been around since git-1.5.3, and it's too difficult to
+ # discover which version we're using, or to work around using an
+ # older one.
+ date = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
+ refnames = keywords["refnames"].strip()
+ if refnames.startswith("$Format"):
+ if verbose:
+ print("keywords are unexpanded, not using")
+ raise NotThisMethod("unexpanded keywords, not a git-archive tarball")
+ refs = set([r.strip() for r in refnames.strip("()").split(",")])
+ # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of
+ # just "foo-1.0". If we see a "tag: " prefix, prefer those.
+ TAG = "tag: "
+ tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)])
+ if not tags:
+ # Either we're using git < 1.8.3, or there really are no tags. We use
+ # a heuristic: assume all version tags have a digit. The old git %d
+ # expansion behaves like git log --decorate=short and strips out the
+ # refs/heads/ and refs/tags/ prefixes that would let us distinguish
+ # between branches and tags. By ignoring refnames without digits, we
+ # filter out many common branch names like "release" and
+ # "stabilization", as well as "HEAD" and "main".
+ tags = set([r for r in refs if re.search(r'\d', r)])
+ if verbose:
+ print("discarding '%s', no digits" % ",".join(refs - tags))
+ if verbose:
+ print("likely tags: %s" % ",".join(sorted(tags)))
+ for ref in sorted(tags):
+ # sorting will prefer e.g. "2.0" over "2.0rc1"
+ if ref.startswith(tag_prefix):
+ r = ref[len(tag_prefix):]
+ if verbose:
+ print("picking %s" % r)
+ return {"version": r,
+ "full-revisionid": keywords["full"].strip(),
+ "dirty": False, "error": None,
+ "date": date}
+ # no suitable tags, so version is "0+unknown", but full hex is still there
+ if verbose:
+ print("no suitable tags, using unknown + full revision id")
+ return {"version": "0+unknown",
+ "full-revisionid": keywords["full"].strip(),
+ "dirty": False, "error": "no suitable tags", "date": None}
+
+
+@register_vcs_handler("git", "pieces_from_vcs")
+def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command):
+ """Get version from 'git describe' in the root of the source tree.
+
+ This only gets called if the git-archive 'subst' keywords were *not*
+ expanded, and _version.py hasn't already been rewritten with a short
+ version string, meaning we're inside a checked out source tree.
+ """
+ GITS = ["git"]
+ if sys.platform == "win32":
+ GITS = ["git.cmd", "git.exe"]
+
+ out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root,
+ hide_stderr=True)
+ if rc != 0:
+ if verbose:
+ print("Directory %s not under git control" % root)
+ raise NotThisMethod("'git rev-parse --git-dir' returned error")
+
+ # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty]
+ # if there isn't one, this yields HEX[-dirty] (no NUM)
+ describe_out, rc = run_command(GITS, ["describe", "--tags", "--dirty=",
+ "--always", "--long",
+ "--match", "%s*" % tag_prefix],
+ cwd=root)
+ # --long was added in git-1.5.5
+ if describe_out is None:
+ raise NotThisMethod("'git describe' failed")
+ describe_out = describe_out.strip()
+ full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root)
+ if full_out is None:
+ raise NotThisMethod("'git rev-parse' failed")
+ full_out = full_out.strip()
+
+ pieces = {}
+ pieces["long"] = full_out
+ pieces["short"] = full_out[:7] # maybe improved later
+ pieces["error"] = None
+
+ # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty]
+ # TAG might have hyphens.
+ git_describe = describe_out
+
+ # look for -dirty suffix
+ dirty = git_describe.endswith("-dirty")
+ pieces["dirty"] = dirty
+ if dirty:
+ git_describe = git_describe[:git_describe.rindex("-dirty")]
+
+ # now we have TAG-NUM-gHEX or HEX
+
+ if "-" in git_describe:
+ # TAG-NUM-gHEX
+ mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe)
+ if not mo:
+ # unparseable. Maybe git-describe is misbehaving?
+ pieces["error"] = ("unable to parse git-describe output: '%s'"
+ % describe_out)
+ return pieces
+
+ # tag
+ full_tag = mo.group(1)
+ if not full_tag.startswith(tag_prefix):
+ if verbose:
+ fmt = "tag '%s' doesn't start with prefix '%s'"
+ print(fmt % (full_tag, tag_prefix))
+ pieces["error"] = ("tag '%s' doesn't start with prefix '%s'"
+ % (full_tag, tag_prefix))
+ return pieces
+ pieces["closest-tag"] = full_tag[len(tag_prefix):]
+
+ # distance: number of commits since tag
+ pieces["distance"] = int(mo.group(2))
+
+ # commit: short hex revision ID
+ pieces["short"] = mo.group(3)
+
+ else:
+ # HEX: no tags
+ pieces["closest-tag"] = None
+ count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"],
+ cwd=root)
+ pieces["distance"] = int(count_out) # total number of commits
+
+ # commit date: see ISO-8601 comment in git_versions_from_keywords()
+ date = run_command(GITS, ["show", "-s", "--format=%ci", "HEAD"],
+ cwd=root)[0].strip()
+ # Use only the last line. Previous lines may contain GPG signature
+ # information.
+ date = date.splitlines()[-1]
+ pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
+
+ return pieces
+
+
+def plus_or_dot(pieces):
+ """Return a + if we don't already have one, else return a ."""
+ if "+" in pieces.get("closest-tag", ""):
+ return "."
+ return "+"
+
+
+def render_pep440(pieces):
+ """Build up version string, with post-release "local version identifier".
+
+ Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you
+ get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty
+
+ Exceptions:
+ 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty]
+ """
+ if pieces["closest-tag"]:
+ rendered = pieces["closest-tag"]
+ if pieces["distance"] or pieces["dirty"]:
+ rendered += plus_or_dot(pieces)
+ rendered += "%d.g%s" % (pieces["distance"], pieces["short"])
+ if pieces["dirty"]:
+ rendered += ".dirty"
+ else:
+ # exception #1
+ rendered = "0+untagged.%d.g%s" % (pieces["distance"],
+ pieces["short"])
+ if pieces["dirty"]:
+ rendered += ".dirty"
+ return rendered
+
+
+def render_pep440_pre(pieces):
+ """TAG[.post0.devDISTANCE] -- No -dirty.
+
+ Exceptions:
+ 1: no tags. 0.post0.devDISTANCE
+ """
+ if pieces["closest-tag"]:
+ rendered = pieces["closest-tag"]
+ if pieces["distance"]:
+ rendered += ".post0.dev%d" % pieces["distance"]
+ else:
+ # exception #1
+ rendered = "0.post0.dev%d" % pieces["distance"]
+ return rendered
+
+
+def render_pep440_post(pieces):
+ """TAG[.postDISTANCE[.dev0]+gHEX] .
+
+ The ".dev0" means dirty. Note that .dev0 sorts backwards
+ (a dirty tree will appear "older" than the corresponding clean one),
+ but you shouldn't be releasing software with -dirty anyways.
+
+ Exceptions:
+ 1: no tags. 0.postDISTANCE[.dev0]
+ """
+ if pieces["closest-tag"]:
+ rendered = pieces["closest-tag"]
+ if pieces["distance"] or pieces["dirty"]:
+ rendered += ".post%d" % pieces["distance"]
+ if pieces["dirty"]:
+ rendered += ".dev0"
+ rendered += plus_or_dot(pieces)
+ rendered += "g%s" % pieces["short"]
+ else:
+ # exception #1
+ rendered = "0.post%d" % pieces["distance"]
+ if pieces["dirty"]:
+ rendered += ".dev0"
+ rendered += "+g%s" % pieces["short"]
+ return rendered
+
+
+def render_pep440_old(pieces):
+ """TAG[.postDISTANCE[.dev0]] .
+
+ The ".dev0" means dirty.
+
+ Exceptions:
+ 1: no tags. 0.postDISTANCE[.dev0]
+ """
+ if pieces["closest-tag"]:
+ rendered = pieces["closest-tag"]
+ if pieces["distance"] or pieces["dirty"]:
+ rendered += ".post%d" % pieces["distance"]
+ if pieces["dirty"]:
+ rendered += ".dev0"
+ else:
+ # exception #1
+ rendered = "0.post%d" % pieces["distance"]
+ if pieces["dirty"]:
+ rendered += ".dev0"
+ return rendered
+
+
+def render_git_describe(pieces):
+ """TAG[-DISTANCE-gHEX][-dirty].
+
+ Like 'git describe --tags --dirty --always'.
+
+ Exceptions:
+ 1: no tags. HEX[-dirty] (note: no 'g' prefix)
+ """
+ if pieces["closest-tag"]:
+ rendered = pieces["closest-tag"]
+ if pieces["distance"]:
+ rendered += "-%d-g%s" % (pieces["distance"], pieces["short"])
+ else:
+ # exception #1
+ rendered = pieces["short"]
+ if pieces["dirty"]:
+ rendered += "-dirty"
+ return rendered
+
+
+def render_git_describe_long(pieces):
+ """TAG-DISTANCE-gHEX[-dirty].
+
+ Like 'git describe --tags --dirty --always -long'.
+ The distance/hash is unconditional.
+
+ Exceptions:
+ 1: no tags. HEX[-dirty] (note: no 'g' prefix)
+ """
+ if pieces["closest-tag"]:
+ rendered = pieces["closest-tag"]
+ rendered += "-%d-g%s" % (pieces["distance"], pieces["short"])
+ else:
+ # exception #1
+ rendered = pieces["short"]
+ if pieces["dirty"]:
+ rendered += "-dirty"
+ return rendered
+
+
+def render(pieces, style):
+ """Render the given version pieces into the requested style."""
+ if pieces["error"]:
+ return {"version": "unknown",
+ "full-revisionid": pieces.get("long"),
+ "dirty": None,
+ "error": pieces["error"],
+ "date": None}
+
+ if not style or style == "default":
+ style = "pep440" # the default
+
+ if style == "pep440":
+ rendered = render_pep440(pieces)
+ elif style == "pep440-pre":
+ rendered = render_pep440_pre(pieces)
+ elif style == "pep440-post":
+ rendered = render_pep440_post(pieces)
+ elif style == "pep440-old":
+ rendered = render_pep440_old(pieces)
+ elif style == "git-describe":
+ rendered = render_git_describe(pieces)
+ elif style == "git-describe-long":
+ rendered = render_git_describe_long(pieces)
+ else:
+ raise ValueError("unknown style '%s'" % style)
+
+ return {"version": rendered, "full-revisionid": pieces["long"],
+ "dirty": pieces["dirty"], "error": None,
+ "date": pieces.get("date")}
+
+
+def get_versions():
+ """Get version information or return default if unable to do so."""
+ # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have
+ # __file__, we can work backwards from there to the root. Some
+ # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which
+ # case we can only use expanded keywords.
+
+ cfg = get_config()
+ verbose = cfg.verbose
+
+ try:
+ return git_versions_from_keywords(get_keywords(), cfg.tag_prefix,
+ verbose)
+ except NotThisMethod:
+ pass
+
+ try:
+ root = os.path.realpath(__file__)
+ # versionfile_source is the relative path from the top of the source
+ # tree (where the .git directory might live) to this file. Invert
+ # this to find the root from __file__.
+ for i in cfg.versionfile_source.split('/'):
+ root = os.path.dirname(root)
+ except NameError:
+ return {"version": "0+unknown", "full-revisionid": None,
+ "dirty": None,
+ "error": "unable to find root of source tree",
+ "date": None}
+
+ try:
+ pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose)
+ return render(pieces, cfg.style)
+ except NotThisMethod:
+ pass
+
+ try:
+ if cfg.parentdir_prefix:
+ return versions_from_parentdir(cfg.parentdir_prefix, root, verbose)
+ except NotThisMethod:
+ pass
+
+ return {"version": "0+unknown", "full-revisionid": None,
+ "dirty": None,
+ "error": "unable to compute version", "date": None}
diff --git a/numpy/char.pyi b/numpy/char.pyi
index 0e7342c0b..4904aa27a 100644
--- a/numpy/char.pyi
+++ b/numpy/char.pyi
@@ -1,53 +1,59 @@
-from typing import Any
+from typing import Any, List
-equal: Any
-not_equal: Any
-greater_equal: Any
-less_equal: Any
-greater: Any
-less: Any
-str_len: Any
-add: Any
-multiply: Any
-mod: Any
-capitalize: Any
-center: Any
-count: Any
-decode: Any
-encode: Any
-endswith: Any
-expandtabs: Any
-find: Any
-index: Any
-isalnum: Any
-isalpha: Any
-isdigit: Any
-islower: Any
-isspace: Any
-istitle: Any
-isupper: Any
-join: Any
-ljust: Any
-lower: Any
-lstrip: Any
-partition: Any
-replace: Any
-rfind: Any
-rindex: Any
-rjust: Any
-rpartition: Any
-rsplit: Any
-rstrip: Any
-split: Any
-splitlines: Any
-startswith: Any
-strip: Any
-swapcase: Any
-title: Any
-translate: Any
-upper: Any
-zfill: Any
-isnumeric: Any
-isdecimal: Any
-array: Any
-asarray: Any
+from numpy import (
+ chararray as chararray,
+)
+
+__all__: List[str]
+
+def equal(x1, x2): ...
+def not_equal(x1, x2): ...
+def greater_equal(x1, x2): ...
+def less_equal(x1, x2): ...
+def greater(x1, x2): ...
+def less(x1, x2): ...
+def str_len(a): ...
+def add(x1, x2): ...
+def multiply(a, i): ...
+def mod(a, values): ...
+def capitalize(a): ...
+def center(a, width, fillchar=...): ...
+def count(a, sub, start=..., end=...): ...
+def decode(a, encoding=..., errors=...): ...
+def encode(a, encoding=..., errors=...): ...
+def endswith(a, suffix, start=..., end=...): ...
+def expandtabs(a, tabsize=...): ...
+def find(a, sub, start=..., end=...): ...
+def index(a, sub, start=..., end=...): ...
+def isalnum(a): ...
+def isalpha(a): ...
+def isdigit(a): ...
+def islower(a): ...
+def isspace(a): ...
+def istitle(a): ...
+def isupper(a): ...
+def join(sep, seq): ...
+def ljust(a, width, fillchar=...): ...
+def lower(a): ...
+def lstrip(a, chars=...): ...
+def partition(a, sep): ...
+def replace(a, old, new, count=...): ...
+def rfind(a, sub, start=..., end=...): ...
+def rindex(a, sub, start=..., end=...): ...
+def rjust(a, width, fillchar=...): ...
+def rpartition(a, sep): ...
+def rsplit(a, sep=..., maxsplit=...): ...
+def rstrip(a, chars=...): ...
+def split(a, sep=..., maxsplit=...): ...
+def splitlines(a, keepends=...): ...
+def startswith(a, prefix, start=..., end=...): ...
+def strip(a, chars=...): ...
+def swapcase(a): ...
+def title(a): ...
+def translate(a, table, deletechars=...): ...
+def upper(a): ...
+def zfill(a, width): ...
+def isnumeric(a): ...
+def isdecimal(a): ...
+def array(obj, itemsize=..., copy=..., unicode=..., order=...): ...
+def asarray(obj, itemsize=..., unicode=..., order=...): ...
diff --git a/numpy/compat/py3k.py b/numpy/compat/py3k.py
index f36aaca17..1fa17621a 100644
--- a/numpy/compat/py3k.py
+++ b/numpy/compat/py3k.py
@@ -20,10 +20,6 @@ import sys
import os
from pathlib import Path
import io
-
-import abc
-from abc import ABC as abc_ABC
-
try:
import pickle5 as pickle
except ImportError:
@@ -94,6 +90,9 @@ class contextlib_nullcontext:
cm = optional_cm if condition else nullcontext()
with cm:
# Perform operation, using optional_cm if condition is True
+
+ .. note::
+ Prefer using `contextlib.nullcontext` instead of this context manager.
"""
def __init__(self, enter_result=None):
diff --git a/numpy/core/__init__.py b/numpy/core/__init__.py
index e8d3a381b..dad9293e1 100644
--- a/numpy/core/__init__.py
+++ b/numpy/core/__init__.py
@@ -75,7 +75,7 @@ from . import fromnumeric
from .fromnumeric import *
from . import defchararray as char
from . import records as rec
-from .records import *
+from .records import record, recarray, format_parser
from .memmap import *
from .defchararray import chararray
from . import function_base
@@ -106,7 +106,7 @@ from . import _methods
__all__ = ['char', 'rec', 'memmap']
__all__ += numeric.__all__
__all__ += fromnumeric.__all__
-__all__ += rec.__all__
+__all__ += ['record', 'recarray', 'format_parser']
__all__ += ['chararray']
__all__ += function_base.__all__
__all__ += machar.__all__
@@ -125,6 +125,7 @@ def _ufunc_reconstruct(module, name):
mod = __import__(module, fromlist=[name])
return getattr(mod, name)
+
def _ufunc_reduce(func):
# Report the `__name__`. pickle will try to find the module. Note that
# pickle supports for this `__name__` to be a `__qualname__`. It may
@@ -134,12 +135,31 @@ def _ufunc_reduce(func):
return func.__name__
+def _DType_reconstruct(scalar_type):
+ # This is a work-around to pickle type(np.dtype(np.float64)), etc.
+ # and it should eventually be replaced with a better solution, e.g. when
+ # DTypes become HeapTypes.
+ return type(dtype(scalar_type))
+
+
+def _DType_reduce(DType):
+ # To pickle a DType without having to add top-level names, pickle the
+ # scalar type for now (and assume that reconstruction will be possible).
+ if DType is dtype:
+ return "dtype" # must pickle `np.dtype` as a singleton.
+ scalar_type = DType.type # pickle the scalar type for reconstruction
+ return _DType_reconstruct, (scalar_type,)
+
+
import copyreg
copyreg.pickle(ufunc, _ufunc_reduce)
-# Unclutter namespace (must keep _ufunc_reconstruct for unpickling)
+copyreg.pickle(type(dtype), _DType_reduce, _DType_reconstruct)
+
+# Unclutter namespace (must keep _*_reconstruct for unpickling)
del copyreg
del _ufunc_reduce
+del _DType_reduce
from numpy._pytesttester import PytestTester
test = PytestTester(__name__)
diff --git a/numpy/core/__init__.pyi b/numpy/core/__init__.pyi
index e69de29bb..4c7a42bf3 100644
--- a/numpy/core/__init__.pyi
+++ b/numpy/core/__init__.pyi
@@ -0,0 +1,2 @@
+# NOTE: The `np.core` namespace is deliberately kept empty due to it
+# being private (despite the lack of leading underscore)
diff --git a/numpy/core/_add_newdocs.py b/numpy/core/_add_newdocs.py
index c9968f122..759a91d27 100644
--- a/numpy/core/_add_newdocs.py
+++ b/numpy/core/_add_newdocs.py
@@ -377,7 +377,7 @@ add_newdoc('numpy.core', 'nditer',
... while not it.finished:
... it[0] = lamdaexpr(*it[1:])
... it.iternext()
- ... return it.operands[0]
+ ... return it.operands[0]
>>> a = np.arange(5)
>>> b = np.ones(5)
@@ -796,6 +796,8 @@ add_newdoc('numpy.core.multiarray', 'array',
object : array_like
An array, any object exposing the array interface, an object whose
__array__ method returns an array, or any (nested) sequence.
+ If object is a scalar, a 0-dimensional array containing object is
+ returned.
dtype : data-type, optional
The desired data-type for the array. If not given, then the type will
be determined as the minimum type required to hold the objects in the
@@ -821,7 +823,7 @@ add_newdoc('numpy.core.multiarray', 'array',
===== ========= ===================================================
When ``copy=False`` and a copy is made for other reasons, the result is
- the same as if ``copy=True``, with some exceptions for `A`, see the
+ the same as if ``copy=True``, with some exceptions for 'A', see the
Notes section. The default order is 'K'.
subok : bool, optional
If True, then sub-classes will be passed-through, otherwise
@@ -904,6 +906,242 @@ add_newdoc('numpy.core.multiarray', 'array',
array_function_like_doc,
))
+add_newdoc('numpy.core.multiarray', 'asarray',
+ """
+ asarray(a, dtype=None, order=None, *, like=None)
+
+ Convert the input to an array.
+
+ Parameters
+ ----------
+ a : array_like
+ Input data, in any form that can be converted to an array. This
+ includes lists, lists of tuples, tuples, tuples of tuples, tuples
+ of lists and ndarrays.
+ dtype : data-type, optional
+ By default, the data-type is inferred from the input data.
+ order : {'C', 'F', 'A', 'K'}, optional
+ Memory layout. 'A' and 'K' depend on the order of input array a.
+ 'C' row-major (C-style),
+ 'F' column-major (Fortran-style) memory representation.
+ 'A' (any) means 'F' if `a` is Fortran contiguous, 'C' otherwise
+ 'K' (keep) preserve input order
+ Defaults to 'K'.
+ ${ARRAY_FUNCTION_LIKE}
+
+ .. versionadded:: 1.20.0
+
+ Returns
+ -------
+ out : ndarray
+ Array interpretation of `a`. No copy is performed if the input
+ is already an ndarray with matching dtype and order. If `a` is a
+ subclass of ndarray, a base class ndarray is returned.
+
+ See Also
+ --------
+ asanyarray : Similar function which passes through subclasses.
+ ascontiguousarray : Convert input to a contiguous array.
+ asfarray : Convert input to a floating point ndarray.
+ asfortranarray : Convert input to an ndarray with column-major
+ memory order.
+ asarray_chkfinite : Similar function which checks input for NaNs and Infs.
+ fromiter : Create an array from an iterator.
+ fromfunction : Construct an array by executing a function on grid
+ positions.
+
+ Examples
+ --------
+ Convert a list into an array:
+
+ >>> a = [1, 2]
+ >>> np.asarray(a)
+ array([1, 2])
+
+ Existing arrays are not copied:
+
+ >>> a = np.array([1, 2])
+ >>> np.asarray(a) is a
+ True
+
+ If `dtype` is set, array is copied only if dtype does not match:
+
+ >>> a = np.array([1, 2], dtype=np.float32)
+ >>> np.asarray(a, dtype=np.float32) is a
+ True
+ >>> np.asarray(a, dtype=np.float64) is a
+ False
+
+ Contrary to `asanyarray`, ndarray subclasses are not passed through:
+
+ >>> issubclass(np.recarray, np.ndarray)
+ True
+ >>> a = np.array([(1.0, 2), (3.0, 4)], dtype='f4,i4').view(np.recarray)
+ >>> np.asarray(a) is a
+ False
+ >>> np.asanyarray(a) is a
+ True
+
+ """.replace(
+ "${ARRAY_FUNCTION_LIKE}",
+ array_function_like_doc,
+ ))
+
+add_newdoc('numpy.core.multiarray', 'asanyarray',
+ """
+ asanyarray(a, dtype=None, order=None, *, like=None)
+
+ Convert the input to an ndarray, but pass ndarray subclasses through.
+
+ Parameters
+ ----------
+ a : array_like
+ Input data, in any form that can be converted to an array. This
+ includes scalars, lists, lists of tuples, tuples, tuples of tuples,
+ tuples of lists, and ndarrays.
+ dtype : data-type, optional
+ By default, the data-type is inferred from the input data.
+ order : {'C', 'F', 'A', 'K'}, optional
+ Memory layout. 'A' and 'K' depend on the order of input array a.
+ 'C' row-major (C-style),
+ 'F' column-major (Fortran-style) memory representation.
+ 'A' (any) means 'F' if `a` is Fortran contiguous, 'C' otherwise
+ 'K' (keep) preserve input order
+ Defaults to 'C'.
+ ${ARRAY_FUNCTION_LIKE}
+
+ .. versionadded:: 1.20.0
+
+ Returns
+ -------
+ out : ndarray or an ndarray subclass
+ Array interpretation of `a`. If `a` is an ndarray or a subclass
+ of ndarray, it is returned as-is and no copy is performed.
+
+ See Also
+ --------
+ asarray : Similar function which always returns ndarrays.
+ ascontiguousarray : Convert input to a contiguous array.
+ asfarray : Convert input to a floating point ndarray.
+ asfortranarray : Convert input to an ndarray with column-major
+ memory order.
+ asarray_chkfinite : Similar function which checks input for NaNs and
+ Infs.
+ fromiter : Create an array from an iterator.
+ fromfunction : Construct an array by executing a function on grid
+ positions.
+
+ Examples
+ --------
+ Convert a list into an array:
+
+ >>> a = [1, 2]
+ >>> np.asanyarray(a)
+ array([1, 2])
+
+ Instances of `ndarray` subclasses are passed through as-is:
+
+ >>> a = np.array([(1.0, 2), (3.0, 4)], dtype='f4,i4').view(np.recarray)
+ >>> np.asanyarray(a) is a
+ True
+
+ """.replace(
+ "${ARRAY_FUNCTION_LIKE}",
+ array_function_like_doc,
+ ))
+
+add_newdoc('numpy.core.multiarray', 'ascontiguousarray',
+ """
+ ascontiguousarray(a, dtype=None, *, like=None)
+
+ Return a contiguous array (ndim >= 1) in memory (C order).
+
+ Parameters
+ ----------
+ a : array_like
+ Input array.
+ dtype : str or dtype object, optional
+ Data-type of returned array.
+ ${ARRAY_FUNCTION_LIKE}
+
+ .. versionadded:: 1.20.0
+
+ Returns
+ -------
+ out : ndarray
+ Contiguous array of same shape and content as `a`, with type `dtype`
+ if specified.
+
+ See Also
+ --------
+ asfortranarray : Convert input to an ndarray with column-major
+ memory order.
+ require : Return an ndarray that satisfies requirements.
+ ndarray.flags : Information about the memory layout of the array.
+
+ Examples
+ --------
+ >>> x = np.arange(6).reshape(2,3)
+ >>> np.ascontiguousarray(x, dtype=np.float32)
+ array([[0., 1., 2.],
+ [3., 4., 5.]], dtype=float32)
+ >>> x.flags['C_CONTIGUOUS']
+ True
+
+ Note: This function returns an array with at least one-dimension (1-d)
+ so it will not preserve 0-d arrays.
+
+ """.replace(
+ "${ARRAY_FUNCTION_LIKE}",
+ array_function_like_doc,
+ ))
+
+add_newdoc('numpy.core.multiarray', 'asfortranarray',
+ """
+ asfortranarray(a, dtype=None, *, like=None)
+
+ Return an array (ndim >= 1) laid out in Fortran order in memory.
+
+ Parameters
+ ----------
+ a : array_like
+ Input array.
+ dtype : str or dtype object, optional
+ By default, the data-type is inferred from the input data.
+ ${ARRAY_FUNCTION_LIKE}
+
+ .. versionadded:: 1.20.0
+
+ Returns
+ -------
+ out : ndarray
+ The input `a` in Fortran, or column-major, order.
+
+ See Also
+ --------
+ ascontiguousarray : Convert input to a contiguous (C order) array.
+ asanyarray : Convert input to an ndarray with either row or
+ column-major memory order.
+ require : Return an ndarray that satisfies requirements.
+ ndarray.flags : Information about the memory layout of the array.
+
+ Examples
+ --------
+ >>> x = np.arange(6).reshape(2,3)
+ >>> y = np.asfortranarray(x)
+ >>> x.flags['F_CONTIGUOUS']
+ False
+ >>> y.flags['F_CONTIGUOUS']
+ True
+
+ Note: This function returns an array with at least one-dimension (1-d)
+ so it will not preserve 0-d arrays.
+
+ """.replace(
+ "${ARRAY_FUNCTION_LIKE}",
+ array_function_like_doc,
+ ))
+
add_newdoc('numpy.core.multiarray', 'empty',
"""
empty(shape, dtype=float, order='C', *, like=None)
@@ -1044,7 +1282,7 @@ add_newdoc('numpy.core.multiarray', 'set_typeDict',
add_newdoc('numpy.core.multiarray', 'fromstring',
"""
- fromstring(string, dtype=float, count=-1, sep='', *, like=None)
+ fromstring(string, dtype=float, count=-1, *, sep, like=None)
A new 1-D array initialized from text data in a string.
@@ -1110,16 +1348,16 @@ add_newdoc('numpy.core.multiarray', 'fromstring',
add_newdoc('numpy.core.multiarray', 'compare_chararrays',
"""
- compare_chararrays(a, b, cmp_op, rstrip)
+ compare_chararrays(a1, a2, cmp, rstrip)
Performs element-wise comparison of two string arrays using the
comparison operator specified by `cmp_op`.
Parameters
----------
- a, b : array_like
+ a1, a2 : array_like
Arrays to be compared.
- cmp_op : {"<", "<=", "==", ">=", ">", "!="}
+ cmp : {"<", "<=", "==", ">=", ">", "!="}
Type of comparison.
rstrip : Boolean
If True, the spaces at the end of Strings are removed before the comparison.
@@ -1147,13 +1385,13 @@ add_newdoc('numpy.core.multiarray', 'compare_chararrays',
add_newdoc('numpy.core.multiarray', 'fromiter',
"""
- fromiter(iterable, dtype, count=-1, *, like=None)
+ fromiter(iter, dtype, count=-1, *, like=None)
Create a new 1-dimensional array from an iterable object.
Parameters
----------
- iterable : iterable object
+ iter : iterable object
An iterable object providing data for the array.
dtype : data-type
The data-type of the returned array.
@@ -1300,6 +1538,10 @@ add_newdoc('numpy.core.multiarray', 'frombuffer',
.. versionadded:: 1.20.0
+ Returns
+ -------
+ out : ndarray
+
Notes
-----
If the buffer has data that is not in machine byte-order, this should
@@ -1345,8 +1587,8 @@ add_newdoc('numpy.core.multiarray', 'arange',
For integer arguments the function is equivalent to the Python built-in
`range` function, but returns an ndarray rather than a list.
- When using a non-integer step, such as 0.1, the results will often not
- be consistent. It is better to use `numpy.linspace` for these cases.
+ When using a non-integer step, such as 0.1, it is often better to use
+ `numpy.linspace`. See the warnings section below for more information.
Parameters
----------
@@ -1379,6 +1621,25 @@ add_newdoc('numpy.core.multiarray', 'arange',
this rule may result in the last element of `out` being greater
than `stop`.
+ Warnings
+ --------
+ The length of the output might not be numerically stable.
+
+ Another stability issue is due to the internal implementation of
+ `numpy.arange`.
+ The actual step value used to populate the array is
+ ``dtype(start + step) - dtype(start)`` and not `step`. Precision loss
+ can occur here, due to casting or due to using floating points when
+ `start` is much larger than `step`. This can lead to unexpected
+ behaviour. For example::
+
+ >>> np.arange(0, 5, 0.5, dtype=int)
+ array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
+ >>> np.arange(-3, 3, 0.5, dtype=int)
+ array([-3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8])
+
+ In such cases, the use of `numpy.linspace` should be preferred.
+
See Also
--------
numpy.linspace : Evenly spaced numbers with careful handling of endpoints.
@@ -1940,6 +2201,8 @@ add_newdoc('numpy.core.multiarray', 'ndarray',
empty : Create an array, but leave its allocated memory unchanged (i.e.,
it contains "garbage").
dtype : Create a data-type.
+ numpy.typing.NDArray : A :term:`generic <generic type>` version
+ of ndarray.
Notes
-----
@@ -2510,13 +2773,17 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('__array__',
add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_prepare__',
- """a.__array_prepare__(obj) -> Object of same type as ndarray object obj.
+ """a.__array_prepare__(array[, context], /)
+
+ Returns a view of `array` with the same type as self.
"""))
add_newdoc('numpy.core.multiarray', 'ndarray', ('__array_wrap__',
- """a.__array_wrap__(obj) -> Object of same type as ndarray object a.
+ """a.__array_wrap__(array[, context], /)
+
+ Returns a view of `array` with the same type as self.
"""))
@@ -2570,7 +2837,7 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('__setstate__',
add_newdoc('numpy.core.multiarray', 'ndarray', ('all',
"""
- a.all(axis=None, out=None, keepdims=False)
+ a.all(axis=None, out=None, keepdims=False, *, where=True)
Returns True if all elements evaluate to True.
@@ -2585,7 +2852,7 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('all',
add_newdoc('numpy.core.multiarray', 'ndarray', ('any',
"""
- a.any(axis=None, out=None, keepdims=False)
+ a.any(axis=None, out=None, keepdims=False, *, where=True)
Returns True if any of the elements of `a` evaluate to True.
@@ -2877,14 +3144,20 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('copy',
'F' means F-order, 'A' means 'F' if `a` is Fortran contiguous,
'C' otherwise. 'K' means match the layout of `a` as closely
as possible. (Note that this function and :func:`numpy.copy` are very
- similar, but have different default values for their order=
- arguments.)
+ similar but have different default values for their order=
+ arguments, and this function always passes sub-classes through.)
See also
--------
- numpy.copy
+ numpy.copy : Similar function with different default behavior
numpy.copyto
+ Notes
+ -----
+ This function is the preferred method for creating an array copy. The
+ function :func:`numpy.copy` is similar, but it defaults to using order 'K',
+ and will not pass sub-classes through by default.
+
Examples
--------
>>> x = np.array([[1,2,3],[4,5,6]], order='F')
@@ -2954,33 +3227,7 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('diagonal',
"""))
-add_newdoc('numpy.core.multiarray', 'ndarray', ('dot',
- """
- a.dot(b, out=None)
-
- Dot product of two arrays.
-
- Refer to `numpy.dot` for full documentation.
-
- See Also
- --------
- numpy.dot : equivalent function
-
- Examples
- --------
- >>> a = np.eye(2)
- >>> b = np.ones((2, 2)) * 2
- >>> a.dot(b)
- array([[2., 2.],
- [2., 2.]])
-
- This array method can be conveniently chained:
-
- >>> a.dot(b).dot(b)
- array([[8., 8.],
- [8., 8.]])
-
- """))
+add_newdoc('numpy.core.multiarray', 'ndarray', ('dot'))
add_newdoc('numpy.core.multiarray', 'ndarray', ('dump',
@@ -3242,7 +3489,7 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('max',
add_newdoc('numpy.core.multiarray', 'ndarray', ('mean',
"""
- a.mean(axis=None, dtype=None, out=None, keepdims=False)
+ a.mean(axis=None, dtype=None, out=None, keepdims=False, *, where=True)
Returns the average of the array elements along given axis.
@@ -3694,7 +3941,7 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('sort',
actual implementation will vary with datatype. The 'mergesort' option
is retained for backwards compatibility.
- .. versionchanged:: 1.15.0.
+ .. versionchanged:: 1.15.0
The 'stable' option was added.
order : str or list of str, optional
@@ -3813,7 +4060,7 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('squeeze',
add_newdoc('numpy.core.multiarray', 'ndarray', ('std',
"""
- a.std(axis=None, dtype=None, out=None, ddof=0, keepdims=False)
+ a.std(axis=None, dtype=None, out=None, ddof=0, keepdims=False, *, where=True)
Returns the standard deviation of the array elements along given axis.
@@ -4076,6 +4323,7 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('transpose',
See Also
--------
+ transpose : Equivalent function
ndarray.T : Array property returning the array transposed.
ndarray.reshape : Give a new shape to an array without changing its data.
@@ -4100,7 +4348,7 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('transpose',
add_newdoc('numpy.core.multiarray', 'ndarray', ('var',
"""
- a.var(axis=None, dtype=None, out=None, ddof=0, keepdims=False)
+ a.var(axis=None, dtype=None, out=None, ddof=0, keepdims=False, *, where=True)
Returns the variance of the array elements, along given axis.
@@ -4226,7 +4474,7 @@ add_newdoc('numpy.core.multiarray', 'ndarray', ('view',
add_newdoc('numpy.core.umath', 'frompyfunc',
"""
- frompyfunc(func, nin, nout, *[, identity])
+ frompyfunc(func, /, nin, nout, *[, identity])
Takes an arbitrary Python function and returns a NumPy ufunc.
@@ -4340,7 +4588,7 @@ add_newdoc('numpy.core.umath', 'geterrobj',
add_newdoc('numpy.core.umath', 'seterrobj',
"""
- seterrobj(errobj)
+ seterrobj(errobj, /)
Set the object that defines floating-point error handling.
@@ -5070,7 +5318,7 @@ add_newdoc('numpy.core', 'ufunc', ('outer',
r = empty(len(A),len(B))
for i in range(len(A)):
for j in range(len(B)):
- r[i,j] = op(A[i], B[j]) # op = ufunc in question
+ r[i,j] = op(A[i], B[j]) # op = ufunc in question
Parameters
----------
@@ -5080,6 +5328,7 @@ add_newdoc('numpy.core', 'ufunc', ('outer',
Second array
kwargs : any
Arguments to pass on to the ufunc. Typically `dtype` or `out`.
+ See `ufunc` for a comprehensive overview of all available arguments.
Returns
-------
@@ -5571,7 +5820,7 @@ add_newdoc('numpy.core.multiarray', 'dtype', ('metadata',
>>> (arr + arr).dtype.metadata
mappingproxy({'key': 'value'})
- But if the arrays have different dtype metadata, the metadata may be
+ But if the arrays have different dtype metadata, the metadata may be
dropped:
>>> dt2 = np.dtype(float, metadata={"key2": "value2"})
diff --git a/numpy/core/_add_newdocs_scalars.py b/numpy/core/_add_newdocs_scalars.py
index b9b151224..602b1db6e 100644
--- a/numpy/core/_add_newdocs_scalars.py
+++ b/numpy/core/_add_newdocs_scalars.py
@@ -6,6 +6,7 @@ platform-dependent information.
from numpy.core import dtype
from numpy.core import numerictypes as _numerictypes
from numpy.core.function_base import add_newdoc
+import platform
##############################################################################
#
@@ -49,6 +50,8 @@ possible_aliases = numeric_type_aliases([
])
+
+
def add_newdoc_for_scalar_type(obj, fixed_aliases, doc):
# note: `:field: value` is rST syntax which renders as field lists.
o = getattr(_numerictypes, obj)
@@ -56,7 +59,7 @@ def add_newdoc_for_scalar_type(obj, fixed_aliases, doc):
character_code = dtype(o).char
canonical_name_doc = "" if obj == o.__name__ else ":Canonical name: `numpy.{}`\n ".format(obj)
alias_doc = ''.join(":Alias: `numpy.{}`\n ".format(alias) for alias in fixed_aliases)
- alias_doc += ''.join(":Alias on this platform: `numpy.{}`: {}.\n ".format(alias, doc)
+ alias_doc += ''.join(":Alias on this platform ({} {}): `numpy.{}`: {}.\n ".format(platform.system(), platform.machine(), alias, doc)
for (alias_type, alias, doc) in possible_aliases if alias_type is o)
docstring = """
{doc}
@@ -215,10 +218,15 @@ add_newdoc_for_scalar_type('void', [],
add_newdoc_for_scalar_type('datetime64', [],
"""
- A datetime stored as a 64-bit integer, counting from ``1970-01-01T00:00:00``.
+ If created from a 64-bit integer, it represents an offset from
+ ``1970-01-01T00:00:00``.
+ If created from string, the string can be in ISO 8601 date
+ or datetime format.
>>> np.datetime64(10, 'Y')
numpy.datetime64('1980')
+ >>> np.datetime64('1980', 'Y')
+ numpy.datetime64('1980')
>>> np.datetime64(10, 'D')
numpy.datetime64('1970-01-11')
diff --git a/numpy/core/_asarray.py b/numpy/core/_asarray.py
index a406308f3..ecb4e7c39 100644
--- a/numpy/core/_asarray.py
+++ b/numpy/core/_asarray.py
@@ -8,283 +8,12 @@ from .overrides import (
set_array_function_like_doc,
set_module,
)
-from .multiarray import array
+from .multiarray import array, asanyarray
-__all__ = [
- "asarray", "asanyarray", "ascontiguousarray", "asfortranarray", "require",
-]
+__all__ = ["require"]
-def _asarray_dispatcher(a, dtype=None, order=None, *, like=None):
- return (like,)
-
-
-@set_array_function_like_doc
-@set_module('numpy')
-def asarray(a, dtype=None, order=None, *, like=None):
- """Convert the input to an array.
-
- Parameters
- ----------
- a : array_like
- Input data, in any form that can be converted to an array. This
- includes lists, lists of tuples, tuples, tuples of tuples, tuples
- of lists and ndarrays.
- dtype : data-type, optional
- By default, the data-type is inferred from the input data.
- order : {'C', 'F', 'A', 'K'}, optional
- Memory layout. 'A' and 'K' depend on the order of input array a.
- 'C' row-major (C-style),
- 'F' column-major (Fortran-style) memory representation.
- 'A' (any) means 'F' if `a` is Fortran contiguous, 'C' otherwise
- 'K' (keep) preserve input order
- Defaults to 'C'.
- ${ARRAY_FUNCTION_LIKE}
-
- .. versionadded:: 1.20.0
-
- Returns
- -------
- out : ndarray
- Array interpretation of `a`. No copy is performed if the input
- is already an ndarray with matching dtype and order. If `a` is a
- subclass of ndarray, a base class ndarray is returned.
-
- See Also
- --------
- asanyarray : Similar function which passes through subclasses.
- ascontiguousarray : Convert input to a contiguous array.
- asfarray : Convert input to a floating point ndarray.
- asfortranarray : Convert input to an ndarray with column-major
- memory order.
- asarray_chkfinite : Similar function which checks input for NaNs and Infs.
- fromiter : Create an array from an iterator.
- fromfunction : Construct an array by executing a function on grid
- positions.
-
- Examples
- --------
- Convert a list into an array:
-
- >>> a = [1, 2]
- >>> np.asarray(a)
- array([1, 2])
-
- Existing arrays are not copied:
-
- >>> a = np.array([1, 2])
- >>> np.asarray(a) is a
- True
-
- If `dtype` is set, array is copied only if dtype does not match:
-
- >>> a = np.array([1, 2], dtype=np.float32)
- >>> np.asarray(a, dtype=np.float32) is a
- True
- >>> np.asarray(a, dtype=np.float64) is a
- False
-
- Contrary to `asanyarray`, ndarray subclasses are not passed through:
-
- >>> issubclass(np.recarray, np.ndarray)
- True
- >>> a = np.array([(1.0, 2), (3.0, 4)], dtype='f4,i4').view(np.recarray)
- >>> np.asarray(a) is a
- False
- >>> np.asanyarray(a) is a
- True
-
- """
- if like is not None:
- return _asarray_with_like(a, dtype=dtype, order=order, like=like)
-
- return array(a, dtype, copy=False, order=order)
-
-
-_asarray_with_like = array_function_dispatch(
- _asarray_dispatcher
-)(asarray)
-
-
-@set_array_function_like_doc
-@set_module('numpy')
-def asanyarray(a, dtype=None, order=None, *, like=None):
- """Convert the input to an ndarray, but pass ndarray subclasses through.
-
- Parameters
- ----------
- a : array_like
- Input data, in any form that can be converted to an array. This
- includes scalars, lists, lists of tuples, tuples, tuples of tuples,
- tuples of lists, and ndarrays.
- dtype : data-type, optional
- By default, the data-type is inferred from the input data.
- order : {'C', 'F', 'A', 'K'}, optional
- Memory layout. 'A' and 'K' depend on the order of input array a.
- 'C' row-major (C-style),
- 'F' column-major (Fortran-style) memory representation.
- 'A' (any) means 'F' if `a` is Fortran contiguous, 'C' otherwise
- 'K' (keep) preserve input order
- Defaults to 'C'.
- ${ARRAY_FUNCTION_LIKE}
-
- .. versionadded:: 1.20.0
-
- Returns
- -------
- out : ndarray or an ndarray subclass
- Array interpretation of `a`. If `a` is an ndarray or a subclass
- of ndarray, it is returned as-is and no copy is performed.
-
- See Also
- --------
- asarray : Similar function which always returns ndarrays.
- ascontiguousarray : Convert input to a contiguous array.
- asfarray : Convert input to a floating point ndarray.
- asfortranarray : Convert input to an ndarray with column-major
- memory order.
- asarray_chkfinite : Similar function which checks input for NaNs and
- Infs.
- fromiter : Create an array from an iterator.
- fromfunction : Construct an array by executing a function on grid
- positions.
-
- Examples
- --------
- Convert a list into an array:
-
- >>> a = [1, 2]
- >>> np.asanyarray(a)
- array([1, 2])
-
- Instances of `ndarray` subclasses are passed through as-is:
-
- >>> a = np.array([(1.0, 2), (3.0, 4)], dtype='f4,i4').view(np.recarray)
- >>> np.asanyarray(a) is a
- True
-
- """
- if like is not None:
- return _asanyarray_with_like(a, dtype=dtype, order=order, like=like)
-
- return array(a, dtype, copy=False, order=order, subok=True)
-
-
-_asanyarray_with_like = array_function_dispatch(
- _asarray_dispatcher
-)(asanyarray)
-
-
-def _asarray_contiguous_fortran_dispatcher(a, dtype=None, *, like=None):
- return (like,)
-
-
-@set_array_function_like_doc
-@set_module('numpy')
-def ascontiguousarray(a, dtype=None, *, like=None):
- """
- Return a contiguous array (ndim >= 1) in memory (C order).
-
- Parameters
- ----------
- a : array_like
- Input array.
- dtype : str or dtype object, optional
- Data-type of returned array.
- ${ARRAY_FUNCTION_LIKE}
-
- .. versionadded:: 1.20.0
-
- Returns
- -------
- out : ndarray
- Contiguous array of same shape and content as `a`, with type `dtype`
- if specified.
-
- See Also
- --------
- asfortranarray : Convert input to an ndarray with column-major
- memory order.
- require : Return an ndarray that satisfies requirements.
- ndarray.flags : Information about the memory layout of the array.
-
- Examples
- --------
- >>> x = np.arange(6).reshape(2,3)
- >>> np.ascontiguousarray(x, dtype=np.float32)
- array([[0., 1., 2.],
- [3., 4., 5.]], dtype=float32)
- >>> x.flags['C_CONTIGUOUS']
- True
-
- Note: This function returns an array with at least one-dimension (1-d)
- so it will not preserve 0-d arrays.
-
- """
- if like is not None:
- return _ascontiguousarray_with_like(a, dtype=dtype, like=like)
-
- return array(a, dtype, copy=False, order='C', ndmin=1)
-
-
-_ascontiguousarray_with_like = array_function_dispatch(
- _asarray_contiguous_fortran_dispatcher
-)(ascontiguousarray)
-
-
-@set_array_function_like_doc
-@set_module('numpy')
-def asfortranarray(a, dtype=None, *, like=None):
- """
- Return an array (ndim >= 1) laid out in Fortran order in memory.
-
- Parameters
- ----------
- a : array_like
- Input array.
- dtype : str or dtype object, optional
- By default, the data-type is inferred from the input data.
- ${ARRAY_FUNCTION_LIKE}
-
- .. versionadded:: 1.20.0
-
- Returns
- -------
- out : ndarray
- The input `a` in Fortran, or column-major, order.
-
- See Also
- --------
- ascontiguousarray : Convert input to a contiguous (C order) array.
- asanyarray : Convert input to an ndarray with either row or
- column-major memory order.
- require : Return an ndarray that satisfies requirements.
- ndarray.flags : Information about the memory layout of the array.
-
- Examples
- --------
- >>> x = np.arange(6).reshape(2,3)
- >>> y = np.asfortranarray(x)
- >>> x.flags['F_CONTIGUOUS']
- False
- >>> y.flags['F_CONTIGUOUS']
- True
-
- Note: This function returns an array with at least one-dimension (1-d)
- so it will not preserve 0-d arrays.
-
- """
- if like is not None:
- return _asfortranarray_with_like(a, dtype=dtype, like=like)
-
- return array(a, dtype, copy=False, order='F', ndmin=1)
-
-
-_asfortranarray_with_like = array_function_dispatch(
- _asarray_contiguous_fortran_dispatcher
-)(asfortranarray)
-
def _require_dispatcher(a, dtype=None, requirements=None, *, like=None):
return (like,)
diff --git a/numpy/core/_asarray.pyi b/numpy/core/_asarray.pyi
index 8c200ba22..1928cfe12 100644
--- a/numpy/core/_asarray.pyi
+++ b/numpy/core/_asarray.pyi
@@ -1,7 +1,7 @@
import sys
from typing import TypeVar, Union, Iterable, overload
-from numpy import ndarray, _OrderKACF
+from numpy import ndarray
from numpy.typing import ArrayLike, DTypeLike
if sys.version_info >= (3, 8):
@@ -11,36 +11,6 @@ else:
_ArrayType = TypeVar("_ArrayType", bound=ndarray)
-def asarray(
- a: object,
- dtype: DTypeLike = ...,
- order: _OrderKACF = ...,
- *,
- like: ArrayLike = ...
-) -> ndarray: ...
-@overload
-def asanyarray(
- a: _ArrayType,
- dtype: None = ...,
- order: _OrderKACF = ...,
- *,
- like: ArrayLike = ...
-) -> _ArrayType: ...
-@overload
-def asanyarray(
- a: object,
- dtype: DTypeLike = ...,
- order: _OrderKACF = ...,
- *,
- like: ArrayLike = ...
-) -> ndarray: ...
-def ascontiguousarray(
- a: object, dtype: DTypeLike = ..., *, like: ArrayLike = ...
-) -> ndarray: ...
-def asfortranarray(
- a: object, dtype: DTypeLike = ..., *, like: ArrayLike = ...
-) -> ndarray: ...
-
_Requirements = Literal[
"C", "C_CONTIGUOUS", "CONTIGUOUS",
"F", "F_CONTIGUOUS", "FORTRAN",
diff --git a/numpy/core/_exceptions.py b/numpy/core/_exceptions.py
index 5e17ed3b2..3cd8042ce 100644
--- a/numpy/core/_exceptions.py
+++ b/numpy/core/_exceptions.py
@@ -122,20 +122,94 @@ class TooHardError(RuntimeError):
@set_module('numpy')
class AxisError(ValueError, IndexError):
- """ Axis supplied was invalid. """
- def __init__(self, axis, ndim=None, msg_prefix=None):
- # single-argument form just delegates to base class
- if ndim is None and msg_prefix is None:
- msg = axis
+ """Axis supplied was invalid.
+
+ This is raised whenever an ``axis`` parameter is specified that is larger
+ than the number of array dimensions.
+ For compatibility with code written against older numpy versions, which
+ raised a mixture of `ValueError` and `IndexError` for this situation, this
+ exception subclasses both to ensure that ``except ValueError`` and
+ ``except IndexError`` statements continue to catch `AxisError`.
+
+ .. versionadded:: 1.13
+
+ Parameters
+ ----------
+ axis : int or str
+ The out of bounds axis or a custom exception message.
+ If an axis is provided, then `ndim` should be specified as well.
+ ndim : int, optional
+ The number of array dimensions.
+ msg_prefix : str, optional
+ A prefix for the exception message.
+
+ Attributes
+ ----------
+ axis : int, optional
+ The out of bounds axis or ``None`` if a custom exception
+ message was provided. This should be the axis as passed by
+ the user, before any normalization to resolve negative indices.
+
+ .. versionadded:: 1.22
+ ndim : int, optional
+ The number of array dimensions or ``None`` if a custom exception
+ message was provided.
+
+ .. versionadded:: 1.22
+
+
+ Examples
+ --------
+ >>> array_1d = np.arange(10)
+ >>> np.cumsum(array_1d, axis=1)
+ Traceback (most recent call last):
+ ...
+ numpy.AxisError: axis 1 is out of bounds for array of dimension 1
+
+ Negative axes are preserved:
+
+ >>> np.cumsum(array_1d, axis=-2)
+ Traceback (most recent call last):
+ ...
+ numpy.AxisError: axis -2 is out of bounds for array of dimension 1
- # do the string formatting here, to save work in the C code
+ The class constructor generally takes the axis and arrays'
+ dimensionality as arguments:
+
+ >>> print(np.AxisError(2, 1, msg_prefix='error'))
+ error: axis 2 is out of bounds for array of dimension 1
+
+ Alternatively, a custom exception message can be passed:
+
+ >>> print(np.AxisError('Custom error message'))
+ Custom error message
+
+ """
+
+ __slots__ = ("axis", "ndim", "_msg")
+
+ def __init__(self, axis, ndim=None, msg_prefix=None):
+ if ndim is msg_prefix is None:
+ # single-argument form: directly set the error message
+ self._msg = axis
+ self.axis = None
+ self.ndim = None
else:
- msg = ("axis {} is out of bounds for array of dimension {}"
- .format(axis, ndim))
- if msg_prefix is not None:
- msg = "{}: {}".format(msg_prefix, msg)
+ self._msg = msg_prefix
+ self.axis = axis
+ self.ndim = ndim
- super(AxisError, self).__init__(msg)
+ def __str__(self):
+ axis = self.axis
+ ndim = self.ndim
+
+ if axis is ndim is None:
+ return self._msg
+ else:
+ msg = f"axis {axis} is out of bounds for array of dimension {ndim}"
+ if self._msg is not None:
+ msg = f"{self._msg}: {msg}"
+ return msg
@_display_as_base
diff --git a/numpy/core/_internal.py b/numpy/core/_internal.py
index 449926f58..8942955f6 100644
--- a/numpy/core/_internal.py
+++ b/numpy/core/_internal.py
@@ -8,6 +8,7 @@ import ast
import re
import sys
import platform
+import warnings
from .multiarray import dtype, array, ndarray
try:
@@ -323,10 +324,10 @@ class _ctypes:
"""
(c_intp*self.ndim): A ctypes array of length self.ndim where
the basetype is the C-integer corresponding to ``dtype('p')`` on this
- platform. This base-type could be `ctypes.c_int`, `ctypes.c_long`, or
- `ctypes.c_longlong` depending on the platform.
- The c_intp type is defined accordingly in `numpy.ctypeslib`.
- The ctypes array contains the shape of the underlying array.
+ platform (see `~numpy.ctypeslib.c_intp`). This base-type could be
+ `ctypes.c_int`, `ctypes.c_long`, or `ctypes.c_longlong` depending on
+ the platform. The ctypes array contains the shape of
+ the underlying array.
"""
return self.shape_as(_getintp_ctype())
@@ -350,11 +351,45 @@ class _ctypes:
"""
return self.data_as(ctypes.c_void_p)
- # kept for compatibility
- get_data = data.fget
- get_shape = shape.fget
- get_strides = strides.fget
- get_as_parameter = _as_parameter_.fget
+ # Numpy 1.21.0, 2021-05-18
+
+ def get_data(self):
+ """Deprecated getter for the `_ctypes.data` property.
+
+ .. deprecated:: 1.21
+ """
+ warnings.warn('"get_data" is deprecated. Use "data" instead',
+ DeprecationWarning, stacklevel=2)
+ return self.data
+
+ def get_shape(self):
+ """Deprecated getter for the `_ctypes.shape` property.
+
+ .. deprecated:: 1.21
+ """
+ warnings.warn('"get_shape" is deprecated. Use "shape" instead',
+ DeprecationWarning, stacklevel=2)
+ return self.shape
+
+ def get_strides(self):
+ """Deprecated getter for the `_ctypes.strides` property.
+
+ .. deprecated:: 1.21
+ """
+ warnings.warn('"get_strides" is deprecated. Use "strides" instead',
+ DeprecationWarning, stacklevel=2)
+ return self.strides
+
+ def get_as_parameter(self):
+ """Deprecated getter for the `_ctypes._as_parameter_` property.
+
+ .. deprecated:: 1.21
+ """
+ warnings.warn(
+ '"get_as_parameter" is deprecated. Use "_as_parameter_" instead',
+ DeprecationWarning, stacklevel=2,
+ )
+ return self._as_parameter_
def _newnames(datatype, order):
@@ -808,11 +843,13 @@ def _ufunc_doc_signature_formatter(ufunc):
", order='K'"
", dtype=None"
", subok=True"
- "[, signature"
- ", extobj]"
)
+
+ # NOTE: gufuncs may or may not support the `axis` parameter
if ufunc.signature is None:
- kwargs = ", where=True" + kwargs
+ kwargs = f", where=True{kwargs}[, signature, extobj]"
+ else:
+ kwargs += "[, signature, extobj, axes, axis]"
# join all the parts together
return '{name}({in_args}{out_args}, *{kwargs})'.format(
@@ -839,35 +876,3 @@ def npy_ctypes_check(cls):
return '_ctypes' in ctype_base.__module__
except Exception:
return False
-
-
-class recursive:
- '''
- A decorator class for recursive nested functions.
- Naive recursive nested functions hold a reference to themselves:
-
- def outer(*args):
- def stringify_leaky(arg0, *arg1):
- if len(arg1) > 0:
- return stringify_leaky(*arg1) # <- HERE
- return str(arg0)
- stringify_leaky(*args)
-
- This design pattern creates a reference cycle that is difficult for a
- garbage collector to resolve. The decorator class prevents the
- cycle by passing the nested function in as an argument `self`:
-
- def outer(*args):
- @recursive
- def stringify(self, arg0, *arg1):
- if len(arg1) > 0:
- return self(*arg1)
- return str(arg0)
- stringify(*args)
-
- '''
- def __init__(self, func):
- self.func = func
- def __call__(self, *args, **kwargs):
- return self.func(self, *args, **kwargs)
-
diff --git a/numpy/core/_internal.pyi b/numpy/core/_internal.pyi
index 1b3889e51..f4bfd770f 100644
--- a/numpy/core/_internal.pyi
+++ b/numpy/core/_internal.pyi
@@ -1,18 +1,30 @@
-from typing import Any
+from typing import Any, TypeVar, Type, overload, Optional, Generic
+import ctypes as ct
-# TODO: add better annotations when ctypes is stubbed out
+from numpy import ndarray
+from numpy.ctypeslib import c_intp
-class _ctypes:
+_CastT = TypeVar("_CastT", bound=ct._CanCastTo) # Copied from `ctypes.cast`
+_CT = TypeVar("_CT", bound=ct._CData)
+_PT = TypeVar("_PT", bound=Optional[int])
+
+# TODO: Let the likes of `shape_as` and `strides_as` return `None`
+# for 0D arrays once we've got shape-support
+
+class _ctypes(Generic[_PT]):
+ @overload
+ def __new__(cls, array: ndarray[Any, Any], ptr: None = ...) -> _ctypes[None]: ...
+ @overload
+ def __new__(cls, array: ndarray[Any, Any], ptr: _PT) -> _ctypes[_PT]: ...
@property
- def data(self) -> int: ...
+ def data(self) -> _PT: ...
@property
- def shape(self) -> Any: ...
+ def shape(self) -> ct.Array[c_intp]: ...
@property
- def strides(self) -> Any: ...
- def data_as(self, obj: Any) -> Any: ...
- def shape_as(self, obj: Any) -> Any: ...
- def strides_as(self, obj: Any) -> Any: ...
- def get_data(self) -> int: ...
- def get_shape(self) -> Any: ...
- def get_strides(self) -> Any: ...
- def get_as_parameter(self) -> Any: ...
+ def strides(self) -> ct.Array[c_intp]: ...
+ @property
+ def _as_parameter_(self) -> ct.c_void_p: ...
+
+ def data_as(self, obj: Type[_CastT]) -> _CastT: ...
+ def shape_as(self, obj: Type[_CT]) -> ct.Array[_CT]: ...
+ def strides_as(self, obj: Type[_CT]) -> ct.Array[_CT]: ...
diff --git a/numpy/core/_methods.py b/numpy/core/_methods.py
index 75fd32ec8..e475b94df 100644
--- a/numpy/core/_methods.py
+++ b/numpy/core/_methods.py
@@ -4,14 +4,15 @@ and the Python code for the NumPy-namespace function
"""
import warnings
+from contextlib import nullcontext
from numpy.core import multiarray as mu
from numpy.core import umath as um
-from numpy.core._asarray import asanyarray
+from numpy.core.multiarray import asanyarray
from numpy.core import numerictypes as nt
from numpy.core import _exceptions
from numpy._globals import _NoValue
-from numpy.compat import pickle, os_fspath, contextlib_nullcontext
+from numpy.compat import pickle, os_fspath
# save those O(100) nanoseconds!
umr_maximum = um.maximum.reduce
@@ -51,9 +52,15 @@ def _prod(a, axis=None, dtype=None, out=None, keepdims=False,
return umr_prod(a, axis, dtype, out, keepdims, initial, where)
def _any(a, axis=None, dtype=None, out=None, keepdims=False, *, where=True):
+ # Parsing keyword arguments is currently fairly slow, so avoid it for now
+ if where is True:
+ return umr_any(a, axis, dtype, out, keepdims)
return umr_any(a, axis, dtype, out, keepdims, where=where)
def _all(a, axis=None, dtype=None, out=None, keepdims=False, *, where=True):
+ # Parsing keyword arguments is currently fairly slow, so avoid it for now
+ if where is True:
+ return umr_all(a, axis, dtype, out, keepdims)
return umr_all(a, axis, dtype, out, keepdims, where=where)
def _count_reduce_items(arr, axis, keepdims=False, where=True):
@@ -158,7 +165,7 @@ def _mean(a, axis=None, dtype=None, out=None, keepdims=False, *, where=True):
is_float16_result = False
rcount = _count_reduce_items(arr, axis, keepdims=keepdims, where=where)
- if umr_any(rcount == 0, axis=None):
+ if rcount == 0 if where is True else umr_any(rcount == 0, axis=None):
warnings.warn("Mean of empty slice.", RuntimeWarning, stacklevel=2)
# Cast bool, unsigned int, and int to float64 by default
@@ -191,7 +198,7 @@ def _var(a, axis=None, dtype=None, out=None, ddof=0, keepdims=False, *,
rcount = _count_reduce_items(arr, axis, keepdims=keepdims, where=where)
# Make this warning show up on top.
- if umr_any(ddof >= rcount, axis=None):
+ if ddof >= rcount if where is True else umr_any(ddof >= rcount, axis=None):
warnings.warn("Degrees of freedom <= 0 for slice", RuntimeWarning,
stacklevel=2)
@@ -273,7 +280,7 @@ def _ptp(a, axis=None, out=None, keepdims=False):
def _dump(self, file, protocol=2):
if hasattr(file, 'write'):
- ctx = contextlib_nullcontext(file)
+ ctx = nullcontext(file)
else:
ctx = open(os_fspath(file), "wb")
with ctx as f:
diff --git a/numpy/core/_type_aliases.py b/numpy/core/_type_aliases.py
index de90fd818..67addef48 100644
--- a/numpy/core/_type_aliases.py
+++ b/numpy/core/_type_aliases.py
@@ -46,7 +46,8 @@ def _bits_of(obj):
info = next(v for v in _concrete_typeinfo.values() if v.type is obj)
except StopIteration:
if obj in _abstract_types.values():
- raise ValueError("Cannot count the bits of an abstract type")
+ msg = "Cannot count the bits of an abstract type"
+ raise ValueError(msg) from None
# some third-party type - make a best-guess
return dtype(obj).itemsize * 8
diff --git a/numpy/core/_ufunc_config.py b/numpy/core/_ufunc_config.py
index 454d911cf..b40e7445e 100644
--- a/numpy/core/_ufunc_config.py
+++ b/numpy/core/_ufunc_config.py
@@ -98,10 +98,9 @@ def seterr(all=None, divide=None, over=None, under=None, invalid=None):
File "<stdin>", line 1, in <module>
FloatingPointError: overflow encountered in short_scalars
- >>> from collections import OrderedDict
>>> old_settings = np.seterr(all='print')
- >>> OrderedDict(np.geterr())
- OrderedDict([('divide', 'print'), ('over', 'print'), ('under', 'print'), ('invalid', 'print')])
+ >>> np.geterr()
+ {'divide': 'print', 'over': 'print', 'under': 'print', 'invalid': 'print'}
>>> np.int16(32000) * np.int16(3)
30464
@@ -153,15 +152,14 @@ def geterr():
Examples
--------
- >>> from collections import OrderedDict
- >>> sorted(np.geterr().items())
- [('divide', 'warn'), ('invalid', 'warn'), ('over', 'warn'), ('under', 'ignore')]
+ >>> np.geterr()
+ {'divide': 'warn', 'over': 'warn', 'under': 'ignore', 'invalid': 'warn'}
>>> np.arange(3.) / np.arange(3.)
array([nan, 1., 1.])
>>> oldsettings = np.seterr(all='warn', over='raise')
- >>> OrderedDict(sorted(np.geterr().items()))
- OrderedDict([('divide', 'warn'), ('invalid', 'warn'), ('over', 'raise'), ('under', 'warn')])
+ >>> np.geterr()
+ {'divide': 'warn', 'over': 'raise', 'under': 'warn', 'invalid': 'warn'}
>>> np.arange(3.) / np.arange(3.)
array([nan, 1., 1.])
@@ -270,7 +268,6 @@ def seterrcall(func):
>>> saved_handler = np.seterrcall(err_handler)
>>> save_err = np.seterr(all='call')
- >>> from collections import OrderedDict
>>> np.array([1, 2, 3]) / 0.0
Floating point error (divide by zero), with flag 1
@@ -278,8 +275,8 @@ def seterrcall(func):
>>> np.seterrcall(saved_handler)
<function err_handler at 0x...>
- >>> OrderedDict(sorted(np.seterr(**save_err).items()))
- OrderedDict([('divide', 'call'), ('invalid', 'call'), ('over', 'call'), ('under', 'call')])
+ >>> np.seterr(**save_err)
+ {'divide': 'call', 'over': 'call', 'under': 'call', 'invalid': 'call'}
Log error message:
@@ -298,8 +295,8 @@ def seterrcall(func):
>>> np.seterrcall(saved_handler)
<numpy.core.numeric.Log object at 0x...>
- >>> OrderedDict(sorted(np.seterr(**save_err).items()))
- OrderedDict([('divide', 'log'), ('invalid', 'log'), ('over', 'log'), ('under', 'log')])
+ >>> np.seterr(**save_err)
+ {'divide': 'log', 'over': 'log', 'under': 'log', 'invalid': 'log'}
"""
if func is not None and not isinstance(func, collections.abc.Callable):
@@ -402,7 +399,6 @@ class errstate(contextlib.ContextDecorator):
Examples
--------
- >>> from collections import OrderedDict
>>> olderr = np.seterr(all='ignore') # Set error handling to known state.
>>> np.arange(3) / 0.
@@ -421,8 +417,8 @@ class errstate(contextlib.ContextDecorator):
Outside the context the error handling behavior has not changed:
- >>> OrderedDict(sorted(np.geterr().items()))
- OrderedDict([('divide', 'ignore'), ('invalid', 'ignore'), ('over', 'ignore'), ('under', 'ignore')])
+ >>> np.geterr()
+ {'divide': 'ignore', 'over': 'ignore', 'under': 'ignore', 'invalid': 'ignore'}
"""
diff --git a/numpy/core/arrayprint.py b/numpy/core/arrayprint.py
index ad1530419..2a4bef669 100644
--- a/numpy/core/arrayprint.py
+++ b/numpy/core/arrayprint.py
@@ -41,6 +41,7 @@ from .numeric import concatenate, asarray, errstate
from .numerictypes import (longlong, intc, int_, float_, complex_, bool_,
flexible)
from .overrides import array_function_dispatch, set_module
+import operator
import warnings
import contextlib
@@ -78,6 +79,7 @@ def _make_options_dict(precision=None, threshold=None, edgeitems=None,
if legacy not in [None, False, '1.13']:
warnings.warn("legacy printing option can currently only be '1.13' or "
"`False`", stacklevel=3)
+
if threshold is not None:
# forbid the bad threshold arg suggested by stack overflow, gh-12351
if not isinstance(threshold, numbers.Number):
@@ -85,6 +87,14 @@ def _make_options_dict(precision=None, threshold=None, edgeitems=None,
if np.isnan(threshold):
raise ValueError("threshold must be non-NAN, try "
"sys.maxsize for untruncated representation")
+
+ if precision is not None:
+ # forbid the bad precision arg as suggested by issue #18254
+ try:
+ options['precision'] = operator.index(precision)
+ except TypeError as e:
+ raise TypeError('precision must be an integer') from e
+
return options
@@ -146,7 +156,6 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None,
- 'longcomplexfloat' : composed of two 128-bit floats
- 'numpystr' : types `numpy.string_` and `numpy.unicode_`
- 'object' : `np.object_` arrays
- - 'str' : all other strings
Other keys that can be used to set a group of types at once are:
@@ -154,7 +163,7 @@ def set_printoptions(precision=None, threshold=None, edgeitems=None,
- 'int_kind' : sets 'int'
- 'float_kind' : sets 'float' and 'longfloat'
- 'complex_kind' : sets 'complexfloat' and 'longcomplexfloat'
- - 'str_kind' : sets 'str' and 'numpystr'
+ - 'str_kind' : sets 'numpystr'
floatmode : str, optional
Controls the interpretation of the `precision` option for
floating-point types. Can take the following values
@@ -375,8 +384,7 @@ def _get_formatdict(data, *, precision, floatmode, suppress, sign, legacy,
'timedelta': lambda: TimedeltaFormat(data),
'object': lambda: _object_format,
'void': lambda: str_format,
- 'numpystr': lambda: repr_format,
- 'str': lambda: str}
+ 'numpystr': lambda: repr_format}
# we need to wrap values in `formatter` in a lambda, so that the interface
# is the same as the above values.
@@ -398,8 +406,7 @@ def _get_formatdict(data, *, precision, floatmode, suppress, sign, legacy,
for key in ['complexfloat', 'longcomplexfloat']:
formatdict[key] = indirect(formatter['complex_kind'])
if 'str_kind' in fkeys:
- for key in ['numpystr', 'str']:
- formatdict[key] = indirect(formatter['str_kind'])
+ formatdict['numpystr'] = indirect(formatter['str_kind'])
for key in formatdict.keys():
if key in fkeys:
formatdict[key] = indirect(formatter[key])
@@ -413,7 +420,9 @@ def _get_format_function(data, **options):
dtype_ = data.dtype
dtypeobj = dtype_.type
formatdict = _get_formatdict(data, **options)
- if issubclass(dtypeobj, _nt.bool_):
+ if dtypeobj is None:
+ return formatdict["numpystr"]()
+ elif issubclass(dtypeobj, _nt.bool_):
return formatdict['bool']()
elif issubclass(dtypeobj, _nt.integer):
if issubclass(dtypeobj, _nt.timedelta64):
@@ -524,7 +533,7 @@ def array2string(a, max_line_width=None, precision=None,
Parameters
----------
- a : array_like
+ a : ndarray
Input array.
max_line_width : int, optional
Inserts newlines if text is longer than `max_line_width`.
@@ -541,7 +550,7 @@ def array2string(a, max_line_width=None, precision=None,
separator : str, optional
Inserted between elements.
prefix : str, optional
- suffix: str, optional
+ suffix : str, optional
The length of the prefix and suffix strings are used to respectively
align and wrap the output. An array is typically printed as::
@@ -572,7 +581,6 @@ def array2string(a, max_line_width=None, precision=None,
- 'longcomplexfloat' : composed of two 128-bit floats
- 'void' : type `numpy.void`
- 'numpystr' : types `numpy.string_` and `numpy.unicode_`
- - 'str' : all other strings
Other keys that can be used to set a group of types at once are:
@@ -580,7 +588,7 @@ def array2string(a, max_line_width=None, precision=None,
- 'int_kind' : sets 'int'
- 'float_kind' : sets 'float' and 'longfloat'
- 'complex_kind' : sets 'complexfloat' and 'longcomplexfloat'
- - 'str_kind' : sets 'str' and 'numpystr'
+ - 'str_kind' : sets 'numpystr'
threshold : int, optional
Total number of array elements which trigger summarization
rather than full repr.
@@ -908,6 +916,7 @@ class FloatingFormat:
self.trim = '.'
self.exp_size = -1
self.unique = True
+ self.min_digits = None
elif self.exp_format:
trim, unique = '.', True
if self.floatmode == 'fixed' or self._legacy == '1.13':
@@ -921,6 +930,8 @@ class FloatingFormat:
self.trim = 'k'
self.precision = max(len(s) for s in frac_part)
+ self.min_digits = self.precision
+ self.unique = unique
# for back-compat with np 1.13, use 2 spaces & sign and full prec
if self._legacy == '1.13':
@@ -930,10 +941,7 @@ class FloatingFormat:
self.pad_left = max(len(s) for s in int_part)
# pad_right is only needed for nan length calculation
self.pad_right = self.exp_size + 2 + self.precision
-
- self.unique = False
else:
- # first pass printing to determine sizes
trim, unique = '.', True
if self.floatmode == 'fixed':
trim, unique = 'k', False
@@ -949,14 +957,14 @@ class FloatingFormat:
self.pad_left = max(len(s) for s in int_part)
self.pad_right = max(len(s) for s in frac_part)
self.exp_size = -1
+ self.unique = unique
if self.floatmode in ['fixed', 'maxprec_equal']:
- self.precision = self.pad_right
- self.unique = False
+ self.precision = self.min_digits = self.pad_right
self.trim = 'k'
else:
- self.unique = True
self.trim = '.'
+ self.min_digits = 0
if self._legacy != '1.13':
# account for sign = ' ' by adding one to pad_left
@@ -985,6 +993,7 @@ class FloatingFormat:
if self.exp_format:
return dragon4_scientific(x,
precision=self.precision,
+ min_digits=self.min_digits,
unique=self.unique,
trim=self.trim,
sign=self.sign == '+',
@@ -993,6 +1002,7 @@ class FloatingFormat:
else:
return dragon4_positional(x,
precision=self.precision,
+ min_digits=self.min_digits,
unique=self.unique,
fractional=True,
trim=self.trim,
@@ -1003,7 +1013,8 @@ class FloatingFormat:
@set_module('numpy')
def format_float_scientific(x, precision=None, unique=True, trim='k',
- sign=False, pad_left=None, exp_digits=None):
+ sign=False, pad_left=None, exp_digits=None,
+ min_digits=None):
"""
Format a floating-point scalar as a decimal string in scientific notation.
@@ -1021,11 +1032,12 @@ def format_float_scientific(x, precision=None, unique=True, trim='k',
If `True`, use a digit-generation strategy which gives the shortest
representation which uniquely identifies the floating-point number from
other values of the same type, by judicious rounding. If `precision`
- was omitted, print all necessary digits, otherwise digit generation is
- cut off after `precision` digits and the remaining value is rounded.
+ is given fewer digits than necessary can be printed. If `min_digits`
+ is given more can be printed, in which cases the last digit is rounded
+ with unbiased rounding.
If `False`, digits are generated as if printing an infinite-precision
value and stopping after `precision` digits, rounding the remaining
- value.
+ value with unbiased rounding
trim : one of 'k', '.', '0', '-', optional
Controls post-processing trimming of trailing digits, as follows:
@@ -1042,7 +1054,13 @@ def format_float_scientific(x, precision=None, unique=True, trim='k',
exp_digits : non-negative integer, optional
Pad the exponent with zeros until it contains at least this many digits.
If omitted, the exponent will be at least 2 digits.
+ min_digits : non-negative integer or None, optional
+ Minimum number of digits to print. This only has an effect for
+ `unique=True`. In that case more digits than necessary to uniquely
+ identify the value may be printed and rounded unbiased.
+ -- versionadded:: 1.21.0
+
Returns
-------
rep : string
@@ -1065,15 +1083,18 @@ def format_float_scientific(x, precision=None, unique=True, trim='k',
precision = _none_or_positive_arg(precision, 'precision')
pad_left = _none_or_positive_arg(pad_left, 'pad_left')
exp_digits = _none_or_positive_arg(exp_digits, 'exp_digits')
+ min_digits = _none_or_positive_arg(min_digits, 'min_digits')
+ if min_digits > 0 and precision > 0 and min_digits > precision:
+ raise ValueError("min_digits must be less than or equal to precision")
return dragon4_scientific(x, precision=precision, unique=unique,
trim=trim, sign=sign, pad_left=pad_left,
- exp_digits=exp_digits)
+ exp_digits=exp_digits, min_digits=min_digits)
@set_module('numpy')
def format_float_positional(x, precision=None, unique=True,
fractional=True, trim='k', sign=False,
- pad_left=None, pad_right=None):
+ pad_left=None, pad_right=None, min_digits=None):
"""
Format a floating-point scalar as a decimal string in positional notation.
@@ -1091,16 +1112,19 @@ def format_float_positional(x, precision=None, unique=True,
If `True`, use a digit-generation strategy which gives the shortest
representation which uniquely identifies the floating-point number from
other values of the same type, by judicious rounding. If `precision`
- was omitted, print out all necessary digits, otherwise digit generation
- is cut off after `precision` digits and the remaining value is rounded.
+ is given fewer digits than necessary can be printed, or if `min_digits`
+ is given more can be printed, in which cases the last digit is rounded
+ with unbiased rounding.
If `False`, digits are generated as if printing an infinite-precision
value and stopping after `precision` digits, rounding the remaining
- value.
+ value with unbiased rounding
fractional : boolean, optional
- If `True`, the cutoff of `precision` digits refers to the total number
- of digits after the decimal point, including leading zeros.
- If `False`, `precision` refers to the total number of significant
- digits, before or after the decimal point, ignoring leading zeros.
+ If `True`, the cutoffs of `precision` and `min_digits` refer to the
+ total number of digits after the decimal point, including leading
+ zeros.
+ If `False`, `precision` and `min_digits` refer to the total number of
+ significant digits, before or after the decimal point, ignoring leading
+ zeros.
trim : one of 'k', '.', '0', '-', optional
Controls post-processing trimming of trailing digits, as follows:
@@ -1117,6 +1141,12 @@ def format_float_positional(x, precision=None, unique=True,
pad_right : non-negative integer, optional
Pad the right side of the string with whitespace until at least that
many characters are to the right of the decimal point.
+ min_digits : non-negative integer or None, optional
+ Minimum number of digits to print. Only has an effect if `unique=True`
+ in which case additional digits past those necessary to uniquely
+ identify the value may be printed, rounding the last additional digit.
+
+ -- versionadded:: 1.21.0
Returns
-------
@@ -1141,10 +1171,16 @@ def format_float_positional(x, precision=None, unique=True,
precision = _none_or_positive_arg(precision, 'precision')
pad_left = _none_or_positive_arg(pad_left, 'pad_left')
pad_right = _none_or_positive_arg(pad_right, 'pad_right')
+ min_digits = _none_or_positive_arg(min_digits, 'min_digits')
+ if not fractional and precision == 0:
+ raise ValueError("precision must be greater than 0 if "
+ "fractional=False")
+ if min_digits > 0 and precision > 0 and min_digits > precision:
+ raise ValueError("min_digits must be less than or equal to precision")
return dragon4_positional(x, precision=precision, unique=unique,
fractional=fractional, trim=trim,
sign=sign, pad_left=pad_left,
- pad_right=pad_right)
+ pad_right=pad_right, min_digits=min_digits)
class IntegerFormat:
@@ -1247,12 +1283,12 @@ class DatetimeFormat(_TimelikeFormat):
self.legacy = legacy
# must be called after the above are configured
- super(DatetimeFormat, self).__init__(x)
+ super().__init__(x)
def __call__(self, x):
if self.legacy == '1.13':
return self._format_non_nat(x)
- return super(DatetimeFormat, self).__call__(x)
+ return super().__call__(x)
def _format_non_nat(self, x):
return "'%s'" % datetime_as_string(x,
@@ -1374,6 +1410,9 @@ def dtype_short_repr(dtype):
>>> dt = np.int64([1, 2]).dtype
>>> assert eval(dtype_short_repr(dt)) == dt
"""
+ if type(dtype).__repr__ != np.dtype.__repr__:
+ # TODO: Custom repr for user DTypes, logic should likely move.
+ return repr(dtype)
if dtype.names is not None:
# structured dtypes give a list or tuple repr
return str(dtype)
diff --git a/numpy/core/arrayprint.pyi b/numpy/core/arrayprint.pyi
new file mode 100644
index 000000000..ac2b6f5a8
--- /dev/null
+++ b/numpy/core/arrayprint.pyi
@@ -0,0 +1,147 @@
+import sys
+from types import TracebackType
+from typing import Any, Optional, Callable, Union, Type
+
+# Using a private class is by no means ideal, but it is simply a consquence
+# of a `contextlib.context` returning an instance of aformentioned class
+from contextlib import _GeneratorContextManager
+
+from numpy import (
+ ndarray,
+ generic,
+ bool_,
+ integer,
+ timedelta64,
+ datetime64,
+ floating,
+ complexfloating,
+ void,
+ str_,
+ bytes_,
+ longdouble,
+ clongdouble,
+)
+from numpy.typing import ArrayLike, _CharLike_co, _FloatLike_co
+
+if sys.version_info > (3, 8):
+ from typing import Literal, TypedDict, SupportsIndex
+else:
+ from typing_extensions import Literal, TypedDict, SupportsIndex
+
+_FloatMode = Literal["fixed", "unique", "maxprec", "maxprec_equal"]
+
+class _FormatDict(TypedDict, total=False):
+ bool: Callable[[bool_], str]
+ int: Callable[[integer[Any]], str]
+ timedelta: Callable[[timedelta64], str]
+ datetime: Callable[[datetime64], str]
+ float: Callable[[floating[Any]], str]
+ longfloat: Callable[[longdouble], str]
+ complexfloat: Callable[[complexfloating[Any, Any]], str]
+ longcomplexfloat: Callable[[clongdouble], str]
+ void: Callable[[void], str]
+ numpystr: Callable[[_CharLike_co], str]
+ object: Callable[[object], str]
+ all: Callable[[object], str]
+ int_kind: Callable[[integer[Any]], str]
+ float_kind: Callable[[floating[Any]], str]
+ complex_kind: Callable[[complexfloating[Any, Any]], str]
+ str_kind: Callable[[_CharLike_co], str]
+
+class _FormatOptions(TypedDict):
+ precision: int
+ threshold: int
+ edgeitems: int
+ linewidth: int
+ suppress: bool
+ nanstr: str
+ infstr: str
+ formatter: Optional[_FormatDict]
+ sign: Literal["-", "+", " "]
+ floatmode: _FloatMode
+ legacy: Literal[False, "1.13"]
+
+def set_printoptions(
+ precision: Optional[SupportsIndex] = ...,
+ threshold: Optional[int] = ...,
+ edgeitems: Optional[int] = ...,
+ linewidth: Optional[int] = ...,
+ suppress: Optional[bool] = ...,
+ nanstr: Optional[str] = ...,
+ infstr: Optional[str] = ...,
+ formatter: Optional[_FormatDict] = ...,
+ sign: Optional[Literal["-", "+", " "]] = ...,
+ floatmode: Optional[_FloatMode] = ...,
+ *,
+ legacy: Optional[Literal[False, "1.13"]] = ...
+) -> None: ...
+def get_printoptions() -> _FormatOptions: ...
+def array2string(
+ a: ndarray[Any, Any],
+ max_line_width: Optional[int] = ...,
+ precision: Optional[SupportsIndex] = ...,
+ suppress_small: Optional[bool] = ...,
+ separator: str = ...,
+ prefix: str = ...,
+ # NOTE: With the `style` argument being deprecated,
+ # all arguments between `formatter` and `suffix` are de facto
+ # keyworld-only arguments
+ *,
+ formatter: Optional[_FormatDict] = ...,
+ threshold: Optional[int] = ...,
+ edgeitems: Optional[int] = ...,
+ sign: Optional[Literal["-", "+", " "]] = ...,
+ floatmode: Optional[_FloatMode] = ...,
+ suffix: str = ...,
+ legacy: Optional[Literal[False, "1.13"]] = ...,
+) -> str: ...
+def format_float_scientific(
+ x: _FloatLike_co,
+ precision: Optional[int] = ...,
+ unique: bool = ...,
+ trim: Literal["k", ".", "0", "-"] = ...,
+ sign: bool = ...,
+ pad_left: Optional[int] = ...,
+ exp_digits: Optional[int] = ...,
+ min_digits: Optional[int] = ...,
+) -> str: ...
+def format_float_positional(
+ x: _FloatLike_co,
+ precision: Optional[int] = ...,
+ unique: bool = ...,
+ fractional: bool = ...,
+ trim: Literal["k", ".", "0", "-"] = ...,
+ sign: bool = ...,
+ pad_left: Optional[int] = ...,
+ pad_right: Optional[int] = ...,
+ min_digits: Optional[int] = ...,
+) -> str: ...
+def array_repr(
+ arr: ndarray[Any, Any],
+ max_line_width: Optional[int] = ...,
+ precision: Optional[SupportsIndex] = ...,
+ suppress_small: Optional[bool] = ...,
+) -> str: ...
+def array_str(
+ a: ndarray[Any, Any],
+ max_line_width: Optional[int] = ...,
+ precision: Optional[SupportsIndex] = ...,
+ suppress_small: Optional[bool] = ...,
+) -> str: ...
+def set_string_function(
+ f: Optional[Callable[[ndarray[Any, Any]], str]], repr: bool = ...
+) -> None: ...
+def printoptions(
+ precision: Optional[SupportsIndex] = ...,
+ threshold: Optional[int] = ...,
+ edgeitems: Optional[int] = ...,
+ linewidth: Optional[int] = ...,
+ suppress: Optional[bool] = ...,
+ nanstr: Optional[str] = ...,
+ infstr: Optional[str] = ...,
+ formatter: Optional[_FormatDict] = ...,
+ sign: Optional[Literal["-", "+", " "]] = ...,
+ floatmode: Optional[_FloatMode] = ...,
+ *,
+ legacy: Optional[Literal[False, "1.13"]] = ...
+) -> _GeneratorContextManager[_FormatOptions]: ...
diff --git a/numpy/core/code_generators/cversions.txt b/numpy/core/code_generators/cversions.txt
index 2d3a65391..a02c7153a 100644
--- a/numpy/core/code_generators/cversions.txt
+++ b/numpy/core/code_generators/cversions.txt
@@ -55,4 +55,6 @@
# Version 14 (NumPy 1.20)
# DType related API additions.
# A new field was added to the end of PyArrayObject_fields.
+# Version 14 (NumPy 1.21) No change.
+# Version 14 (NumPy 1.22) No change.
0x0000000e = 17a0f366e55ec05e5c5c149123478452
diff --git a/numpy/core/code_generators/genapi.py b/numpy/core/code_generators/genapi.py
index ca6a22828..c2458c2b5 100644
--- a/numpy/core/code_generators/genapi.py
+++ b/numpy/core/code_generators/genapi.py
@@ -31,6 +31,7 @@ API_FILES = [join('multiarray', 'alloc.c'),
join('multiarray', 'arraytypes.c.src'),
join('multiarray', 'buffer.c'),
join('multiarray', 'calculation.c'),
+ join('multiarray', 'common_dtype.c'),
join('multiarray', 'conversion_utils.c'),
join('multiarray', 'convert.c'),
join('multiarray', 'convert_datatype.c'),
@@ -175,7 +176,7 @@ def split_arguments(argstr):
def finish_arg():
if current_argument:
argstr = ''.join(current_argument).strip()
- m = re.match(r'(.*(\s+|[*]))(\w+)$', argstr)
+ m = re.match(r'(.*(\s+|\*))(\w+)$', argstr)
if m:
typename = m.group(1).strip()
name = m.group(3)
@@ -281,9 +282,11 @@ def find_functions(filename, tag='API'):
state = SCANNING
else:
function_args.append(line)
- except Exception:
- print(filename, lineno + 1)
+ except ParseError:
raise
+ except Exception as e:
+ msg = "see chained exception for details"
+ raise ParseError(filename, lineno + 1, msg) from e
fo.close()
return functions
diff --git a/numpy/core/code_generators/generate_numpy_api.py b/numpy/core/code_generators/generate_numpy_api.py
index 7997135bb..37975966f 100644
--- a/numpy/core/code_generators/generate_numpy_api.py
+++ b/numpy/core/code_generators/generate_numpy_api.py
@@ -177,9 +177,6 @@ def do_generate_api(targets, sources):
numpyapi_list = genapi.get_api_functions('NUMPY_API',
multiarray_funcs)
- # FIXME: ordered_funcs_api is unused
- ordered_funcs_api = genapi.order_dict(multiarray_funcs)
-
# Create dict name -> *Api instance
api_name = 'PyArray_API'
multiarray_api_dict = {}
diff --git a/numpy/core/code_generators/generate_umath.py b/numpy/core/code_generators/generate_umath.py
index cb1147b93..1b6917ebc 100644
--- a/numpy/core/code_generators/generate_umath.py
+++ b/numpy/core/code_generators/generate_umath.py
@@ -45,14 +45,20 @@ class TypeDescription:
astype : dict or None, optional
If astype['x'] is 'y', uses PyUFunc_x_x_As_y_y/PyUFunc_xx_x_As_yy_y
instead of PyUFunc_x_x/PyUFunc_xx_x.
+ cfunc_alias : str or none, optional
+ Appended to inner loop C function name, e.g., FLOAT_{cfunc_alias}. See make_arrays.
+ NOTE: it doesn't support 'astype'
simd: list
Available SIMD ufunc loops, dispatched at runtime in specified order
Currently only supported for simples types (see make_arrays)
- dispatch: list
- Available SIMD ufunc loops, dispatched at runtime in specified order
- Currently only supported for simples types (see make_arrays)
+ dispatch: str or None, optional
+ Dispatch-able source name without its extension '.dispatch.c' that
+ contains the definition of ufunc, dispatched at runtime depending on the
+ specified targets of the dispatch-able source.
+ NOTE: it doesn't support 'astype'
"""
- def __init__(self, type, f=None, in_=None, out=None, astype=None, simd=None, dispatch=None):
+ def __init__(self, type, f=None, in_=None, out=None, astype=None, cfunc_alias=None,
+ simd=None, dispatch=None):
self.type = type
self.func_data = f
if astype is None:
@@ -64,6 +70,7 @@ class TypeDescription:
if out is not None:
out = out.replace('P', type)
self.out = out
+ self.cfunc_alias = cfunc_alias
self.simd = simd
self.dispatch = dispatch
@@ -90,7 +97,8 @@ def build_func_data(types, f):
func_data = [_fdata_map.get(t, '%s') % (f,) for t in types]
return func_data
-def TD(types, f=None, astype=None, in_=None, out=None, simd=None, dispatch=None):
+def TD(types, f=None, astype=None, in_=None, out=None, cfunc_alias=None,
+ simd=None, dispatch=None):
if f is not None:
if isinstance(f, str):
func_data = build_func_data(types, f)
@@ -119,13 +127,15 @@ def TD(types, f=None, astype=None, in_=None, out=None, simd=None, dispatch=None)
simdt = [k for k, v in simd if t in v]
else:
simdt = []
+
# [(dispatch file name without extension '.dispatch.c*', list of types)]
if dispatch:
- dispt = [k for k, v in dispatch if t in v]
+ dispt = ([k for k, v in dispatch if t in v]+[None])[0]
else:
- dispt = []
+ dispt = None
tds.append(TypeDescription(
- t, f=fd, in_=i, out=o, astype=astype, simd=simdt, dispatch=dispt
+ t, f=fd, in_=i, out=o, astype=astype, cfunc_alias=cfunc_alias,
+ simd=simdt, dispatch=dispt
))
return tds
@@ -235,6 +245,8 @@ all = '?bBhHiIlLqQefdgFDGOmM'
O = 'O'
P = 'P'
ints = 'bBhHiIlLqQ'
+sints = 'bhilq'
+uints = 'BHILQ'
times = 'Mm'
timedeltaonly = 'm'
intsO = ints + O
@@ -280,7 +292,7 @@ defdict = {
Ufunc(2, 1, Zero,
docstrings.get('numpy.core.umath.add'),
'PyUFunc_AdditionTypeResolver',
- TD(notimes_or_obj, simd=[('avx512f', cmplxvec),('avx2', ints)]),
+ TD(notimes_or_obj, simd=[('avx2', ints)], dispatch=[('loops_arithm_fp', 'fdFD')]),
[TypeDescription('M', FullTypeDescr, 'Mm', 'M'),
TypeDescription('m', FullTypeDescr, 'mm', 'm'),
TypeDescription('M', FullTypeDescr, 'mM', 'M'),
@@ -291,7 +303,7 @@ defdict = {
Ufunc(2, 1, None, # Zero is only a unit to the right, not the left
docstrings.get('numpy.core.umath.subtract'),
'PyUFunc_SubtractionTypeResolver',
- TD(ints + inexact, simd=[('avx512f', cmplxvec),('avx2', ints)]),
+ TD(ints + inexact, simd=[('avx2', ints)], dispatch=[('loops_arithm_fp', 'fdFD')]),
[TypeDescription('M', FullTypeDescr, 'Mm', 'M'),
TypeDescription('m', FullTypeDescr, 'mm', 'm'),
TypeDescription('M', FullTypeDescr, 'MM', 'm'),
@@ -302,7 +314,7 @@ defdict = {
Ufunc(2, 1, One,
docstrings.get('numpy.core.umath.multiply'),
'PyUFunc_MultiplicationTypeResolver',
- TD(notimes_or_obj, simd=[('avx512f', cmplxvec),('avx2', ints)]),
+ TD(notimes_or_obj, simd=[('avx2', ints)], dispatch=[('loops_arithm_fp', 'fdFD')]),
[TypeDescription('m', FullTypeDescr, 'mq', 'm'),
TypeDescription('m', FullTypeDescr, 'qm', 'm'),
TypeDescription('m', FullTypeDescr, 'md', 'm'),
@@ -315,7 +327,9 @@ defdict = {
Ufunc(2, 1, None, # One is only a unit to the right, not the left
docstrings.get('numpy.core.umath.floor_divide'),
'PyUFunc_DivisionTypeResolver',
- TD(intfltcmplx),
+ TD(ints, cfunc_alias='divide',
+ dispatch=[('loops_arithmetic', 'bBhHiIlLqQ')]),
+ TD(flts),
[TypeDescription('m', FullTypeDescr, 'mq', 'm'),
TypeDescription('m', FullTypeDescr, 'md', 'm'),
TypeDescription('m', FullTypeDescr, 'mm', 'q'),
@@ -326,10 +340,10 @@ defdict = {
Ufunc(2, 1, None, # One is only a unit to the right, not the left
docstrings.get('numpy.core.umath.true_divide'),
'PyUFunc_TrueDivisionTypeResolver',
- TD(flts+cmplx),
- [TypeDescription('m', FullTypeDescr, 'mq', 'm'),
- TypeDescription('m', FullTypeDescr, 'md', 'm'),
- TypeDescription('m', FullTypeDescr, 'mm', 'd'),
+ TD(flts+cmplx, cfunc_alias='divide', dispatch=[('loops_arithm_fp', 'fd')]),
+ [TypeDescription('m', FullTypeDescr, 'mq', 'm', cfunc_alias='divide'),
+ TypeDescription('m', FullTypeDescr, 'md', 'm', cfunc_alias='divide'),
+ TypeDescription('m', FullTypeDescr, 'mm', 'd', cfunc_alias='divide'),
],
TD(O, f='PyNumber_TrueDivide'),
),
@@ -666,7 +680,7 @@ defdict = {
docstrings.get('numpy.core.umath.cos'),
None,
TD('e', f='cos', astype={'e':'f'}),
- TD('f', simd=[('fma', 'f'), ('avx512f', 'f')]),
+ TD('f', dispatch=[('loops_trigonometric', 'f')]),
TD('fdg' + cmplx, f='cos'),
TD(P, f='cos'),
),
@@ -675,7 +689,7 @@ defdict = {
docstrings.get('numpy.core.umath.sin'),
None,
TD('e', f='sin', astype={'e':'f'}),
- TD('f', simd=[('fma', 'f'), ('avx512f', 'f')]),
+ TD('f', dispatch=[('loops_trigonometric', 'f')]),
TD('fdg' + cmplx, f='sin'),
TD(P, f='sin'),
),
@@ -712,8 +726,7 @@ defdict = {
docstrings.get('numpy.core.umath.exp'),
None,
TD('e', f='exp', astype={'e':'f'}),
- TD('f', simd=[('fma', 'f'), ('avx512f', 'f')]),
- TD('d', simd=[('avx512f', 'd')]),
+ TD('fd', dispatch=[('loops_exponent_log', 'fd')]),
TD('fdg' + cmplx, f='exp'),
TD(P, f='exp'),
),
@@ -736,8 +749,7 @@ defdict = {
docstrings.get('numpy.core.umath.log'),
None,
TD('e', f='log', astype={'e':'f'}),
- TD('f', simd=[('fma', 'f'), ('avx512f', 'f')]),
- TD('d', simd=[('avx512f', 'd')]),
+ TD('fd', dispatch=[('loops_exponent_log', 'fd')]),
TD('fdg' + cmplx, f='log'),
TD(P, f='log'),
),
@@ -910,10 +922,10 @@ defdict = {
docstrings.get('numpy.core.umath.ldexp'),
None,
[TypeDescription('e', None, 'ei', 'e'),
- TypeDescription('f', None, 'fi', 'f', simd=['avx512_skx']),
+ TypeDescription('f', None, 'fi', 'f', dispatch='loops_exponent_log'),
TypeDescription('e', FuncNameSuffix('long'), 'el', 'e'),
TypeDescription('f', FuncNameSuffix('long'), 'fl', 'f'),
- TypeDescription('d', None, 'di', 'd', simd=['avx512_skx']),
+ TypeDescription('d', None, 'di', 'd', dispatch='loops_exponent_log'),
TypeDescription('d', FuncNameSuffix('long'), 'dl', 'd'),
TypeDescription('g', None, 'gi', 'g'),
TypeDescription('g', FuncNameSuffix('long'), 'gl', 'g'),
@@ -924,8 +936,8 @@ defdict = {
docstrings.get('numpy.core.umath.frexp'),
None,
[TypeDescription('e', None, 'e', 'ei'),
- TypeDescription('f', None, 'f', 'fi', simd=['avx512_skx']),
- TypeDescription('d', None, 'd', 'di', simd=['avx512_skx']),
+ TypeDescription('f', None, 'f', 'fi', dispatch='loops_exponent_log'),
+ TypeDescription('d', None, 'd', 'di', dispatch='loops_exponent_log'),
TypeDescription('g', None, 'g', 'gi'),
],
),
@@ -1000,6 +1012,7 @@ def make_arrays(funcdict):
# later
code1list = []
code2list = []
+ dispdict = {}
names = sorted(funcdict.keys())
for name in names:
uf = funcdict[name]
@@ -1010,44 +1023,33 @@ def make_arrays(funcdict):
sub = 0
for t in uf.type_descriptions:
+ cfunc_alias = t.cfunc_alias if t.cfunc_alias else name
+ cfunc_fname = None
if t.func_data is FullTypeDescr:
tname = english_upper(chartoname[t.type])
datalist.append('(void *)NULL')
- funclist.append(
- '%s_%s_%s_%s' % (tname, t.in_, t.out, name))
+ cfunc_fname = f"{tname}_{t.in_}_{t.out}_{cfunc_alias}"
elif isinstance(t.func_data, FuncNameSuffix):
datalist.append('(void *)NULL')
tname = english_upper(chartoname[t.type])
- funclist.append(
- '%s_%s_%s' % (tname, name, t.func_data.suffix))
+ cfunc_fname = f"{tname}_{cfunc_alias}_{t.func_data.suffix}"
elif t.func_data is None:
datalist.append('(void *)NULL')
tname = english_upper(chartoname[t.type])
- funclist.append('%s_%s' % (tname, name))
+ cfunc_fname = f"{tname}_{cfunc_alias}"
if t.simd is not None:
for vt in t.simd:
code2list.append(textwrap.dedent("""\
#ifdef HAVE_ATTRIBUTE_TARGET_{ISA}
if (NPY_CPU_HAVE({ISA})) {{
- {fname}_functions[{idx}] = {type}_{fname}_{isa};
+ {fname}_functions[{idx}] = {cname}_{isa};
}}
#endif
""").format(
ISA=vt.upper(), isa=vt,
- fname=name, type=tname, idx=k
- ))
- if t.dispatch is not None:
- for dname in t.dispatch:
- code2list.append(textwrap.dedent("""\
- #ifndef NPY_DISABLE_OPTIMIZATION
- #include "{dname}.dispatch.h"
- #endif
- NPY_CPU_DISPATCH_CALL_XB({name}_functions[{k}] = {tname}_{name});
- """).format(
- dname=dname, name=name, tname=tname, k=k
+ fname=name, cname=cfunc_fname, idx=k
))
else:
- funclist.append('NULL')
try:
thedict = arity_lookup[uf.nin, uf.nout]
except KeyError as e:
@@ -1077,6 +1079,13 @@ def make_arrays(funcdict):
#datalist.append('(void *)%s' % t.func_data)
sub += 1
+ if cfunc_fname:
+ funclist.append(cfunc_fname)
+ if t.dispatch:
+ dispdict.setdefault(t.dispatch, []).append((name, k, cfunc_fname))
+ else:
+ funclist.append('NULL')
+
for x in t.in_ + t.out:
siglist.append('NPY_%s' % (english_upper(chartoname[x]),))
@@ -1091,6 +1100,17 @@ def make_arrays(funcdict):
% (name, datanames))
code1list.append("static char %s_signatures[] = {%s};"
% (name, signames))
+
+ for dname, funcs in dispdict.items():
+ code2list.append(textwrap.dedent(f"""
+ #ifndef NPY_DISABLE_OPTIMIZATION
+ #include "{dname}.dispatch.h"
+ #endif
+ """))
+ for (ufunc_name, func_idx, cfunc_name) in funcs:
+ code2list.append(textwrap.dedent(f"""\
+ NPY_CPU_DISPATCH_CALL_XB({ufunc_name}_functions[{func_idx}] = {cfunc_name});
+ """))
return "\n".join(code1list), "\n".join(code2list)
def make_ufuncs(funcdict):
diff --git a/numpy/core/code_generators/ufunc_docstrings.py b/numpy/core/code_generators/ufunc_docstrings.py
index b7edd2834..f19946be4 100644
--- a/numpy/core/code_generators/ufunc_docstrings.py
+++ b/numpy/core/code_generators/ufunc_docstrings.py
@@ -185,7 +185,7 @@ add_newdoc('numpy.core.umath', 'arccos',
Notes
-----
`arccos` is a multivalued function: for each `x` there are infinitely
- many numbers `z` such that `cos(z) = x`. The convention is to return
+ many numbers `z` such that ``cos(z) = x``. The convention is to return
the angle `z` whose real part lies in `[0, pi]`.
For real-valued input data types, `arccos` always returns real output.
@@ -193,7 +193,7 @@ add_newdoc('numpy.core.umath', 'arccos',
it yields ``nan`` and sets the `invalid` floating point error flag.
For complex-valued input, `arccos` is a complex analytic function that
- has branch cuts `[-inf, -1]` and `[1, inf]` and is continuous from
+ has branch cuts ``[-inf, -1]`` and `[1, inf]` and is continuous from
above on the former and from below on the latter.
The inverse `cos` is also known as `acos` or cos^-1.
@@ -245,7 +245,7 @@ add_newdoc('numpy.core.umath', 'arccosh',
-----
`arccosh` is a multivalued function: for each `x` there are infinitely
many numbers `z` such that `cosh(z) = x`. The convention is to return the
- `z` whose imaginary part lies in `[-pi, pi]` and the real part in
+ `z` whose imaginary part lies in ``[-pi, pi]`` and the real part in
``[0, inf]``.
For real-valued input data types, `arccosh` always returns real output.
@@ -406,7 +406,7 @@ add_newdoc('numpy.core.umath', 'arctan',
it yields ``nan`` and sets the `invalid` floating point error flag.
For complex-valued input, `arctan` is a complex analytic function that
- has [`1j, infj`] and [`-1j, -infj`] as branch cuts, and is continuous
+ has [``1j, infj``] and [``-1j, -infj``] as branch cuts, and is continuous
from the left on the former and from the right on the latter.
The inverse tangent is also known as `atan` or tan^{-1}.
@@ -544,7 +544,7 @@ add_newdoc('numpy.core.umath', 'arctanh',
Notes
-----
`arctanh` is a multivalued function: for each `x` there are infinitely
- many numbers `z` such that `tanh(z) = x`. The convention is to return
+ many numbers `z` such that ``tanh(z) = x``. The convention is to return
the `z` whose imaginary part lies in `[-pi/2, pi/2]`.
For real-valued input data types, `arctanh` always returns real output.
@@ -765,7 +765,7 @@ add_newdoc('numpy.core.umath', 'ceil',
Return the ceiling of the input, element-wise.
The ceil of the scalar `x` is the smallest integer `i`, such that
- `i >= x`. It is often denoted as :math:`\\lceil x \\rceil`.
+ ``i >= x``. It is often denoted as :math:`\\lceil x \\rceil`.
Parameters
----------
@@ -781,7 +781,7 @@ add_newdoc('numpy.core.umath', 'ceil',
See Also
--------
- floor, trunc, rint
+ floor, trunc, rint, fix
Examples
--------
@@ -813,7 +813,7 @@ add_newdoc('numpy.core.umath', 'trunc',
See Also
--------
- ceil, floor, rint
+ ceil, floor, rint, fix
Notes
-----
@@ -1374,13 +1374,14 @@ add_newdoc('numpy.core.umath', 'floor',
See Also
--------
- ceil, trunc, rint
+ ceil, trunc, rint, fix
Notes
-----
- Some spreadsheet programs calculate the "floor-towards-zero", in other
- words ``floor(-2.5) == -2``. NumPy instead uses the definition of
- `floor` where `floor(-2.5) == -3`.
+ Some spreadsheet programs calculate the "floor-towards-zero", where
+ ``floor(-2.5) == -2``. NumPy instead uses the definition of
+ `floor` where `floor(-2.5) == -3`. The "floor-towards-zero"
+ function is called ``fix`` in NumPy.
Examples
--------
@@ -2808,8 +2809,8 @@ add_newdoc('numpy.core.umath', 'matmul',
(9, 5, 7, 3)
>>> # n is 7, k is 4, m is 3
- The matmul function implements the semantics of the `@` operator introduced
- in Python 3.5 following PEP465.
+ The matmul function implements the semantics of the ``@`` operator introduced
+ in Python 3.5 following :pep:`465`.
Examples
--------
@@ -3486,7 +3487,13 @@ add_newdoc('numpy.core.umath', 'rint',
See Also
--------
- ceil, floor, trunc
+ fix, ceil, floor, trunc
+
+ Notes
+ -----
+ For values exactly halfway between rounded decimal values, NumPy
+ rounds to the nearest even value. Thus 1.5 and 2.5 round to 2.0,
+ -0.5 and 0.5 round to 0.0, etc.
Examples
--------
@@ -4074,7 +4081,7 @@ add_newdoc('numpy.core.umath', 'frexp',
Decompose the elements of x into mantissa and twos exponent.
Returns (`mantissa`, `exponent`), where `x = mantissa * 2**exponent``.
- The mantissa is lies in the open interval(-1, 1), while the twos
+ The mantissa lies in the open interval(-1, 1), while the twos
exponent is a signed integer.
Parameters
diff --git a/numpy/core/defchararray.py b/numpy/core/defchararray.py
index 9d7b54a1a..e264fa210 100644
--- a/numpy/core/defchararray.py
+++ b/numpy/core/defchararray.py
@@ -16,7 +16,6 @@ The preferred alias for `defchararray` is `numpy.char`.
"""
import functools
-import sys
from .numerictypes import (
string_, unicode_, integer, int_, object_, bool_, character)
from .numeric import ndarray, compare_chararrays
@@ -273,7 +272,7 @@ def str_len(a):
out : ndarray
Output array of integers
- See also
+ See Also
--------
builtins.len
"""
@@ -368,7 +367,7 @@ def mod(a, values):
out : ndarray
Output array of str or unicode, depending on input types
- See also
+ See Also
--------
str.__mod__
@@ -398,7 +397,7 @@ def capitalize(a):
Output array of str or unicode, depending on input
types
- See also
+ See Also
--------
str.capitalize
@@ -443,7 +442,7 @@ def center(a, width, fillchar=' '):
Output array of str or unicode, depending on input
types
- See also
+ See Also
--------
str.center
@@ -485,7 +484,7 @@ def count(a, sub, start=0, end=None):
out : ndarray
Output array of ints.
- See also
+ See Also
--------
str.count
@@ -534,7 +533,7 @@ def decode(a, encoding=None, errors=None):
-------
out : ndarray
- See also
+ See Also
--------
str.decode
@@ -580,7 +579,7 @@ def encode(a, encoding=None, errors=None):
-------
out : ndarray
- See also
+ See Also
--------
str.encode
@@ -620,7 +619,7 @@ def endswith(a, suffix, start=0, end=None):
out : ndarray
Outputs an array of bools.
- See also
+ See Also
--------
str.endswith
@@ -672,7 +671,7 @@ def expandtabs(a, tabsize=8):
out : ndarray
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.expandtabs
@@ -708,7 +707,7 @@ def find(a, sub, start=0, end=None):
out : ndarray or int
Output array of ints. Returns -1 if `sub` is not found.
- See also
+ See Also
--------
str.find
@@ -737,7 +736,7 @@ def index(a, sub, start=0, end=None):
out : ndarray
Output array of ints. Returns -1 if `sub` is not found.
- See also
+ See Also
--------
find, str.find
@@ -765,7 +764,7 @@ def isalnum(a):
out : ndarray
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.isalnum
"""
@@ -791,7 +790,7 @@ def isalpha(a):
out : ndarray
Output array of bools
- See also
+ See Also
--------
str.isalpha
"""
@@ -817,7 +816,7 @@ def isdigit(a):
out : ndarray
Output array of bools
- See also
+ See Also
--------
str.isdigit
"""
@@ -844,7 +843,7 @@ def islower(a):
out : ndarray
Output array of bools
- See also
+ See Also
--------
str.islower
"""
@@ -871,7 +870,7 @@ def isspace(a):
out : ndarray
Output array of bools
- See also
+ See Also
--------
str.isspace
"""
@@ -897,7 +896,7 @@ def istitle(a):
out : ndarray
Output array of bools
- See also
+ See Also
--------
str.istitle
"""
@@ -924,7 +923,7 @@ def isupper(a):
out : ndarray
Output array of bools
- See also
+ See Also
--------
str.isupper
"""
@@ -953,7 +952,7 @@ def join(sep, seq):
out : ndarray
Output array of str or unicode, depending on input types
- See also
+ See Also
--------
str.join
"""
@@ -988,7 +987,7 @@ def ljust(a, width, fillchar=' '):
out : ndarray
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.ljust
@@ -1021,7 +1020,7 @@ def lower(a):
out : ndarray, {str, unicode}
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.lower
@@ -1066,7 +1065,7 @@ def lstrip(a, chars=None):
out : ndarray, {str, unicode}
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.lstrip
@@ -1127,7 +1126,7 @@ def partition(a, sep):
The output array will have an extra dimension with 3
elements per input element.
- See also
+ See Also
--------
str.partition
@@ -1163,7 +1162,7 @@ def replace(a, old, new, count=None):
out : ndarray
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.replace
@@ -1197,7 +1196,7 @@ def rfind(a, sub, start=0, end=None):
out : ndarray
Output array of ints. Return -1 on failure.
- See also
+ See Also
--------
str.rfind
@@ -1227,7 +1226,7 @@ def rindex(a, sub, start=0, end=None):
out : ndarray
Output array of ints.
- See also
+ See Also
--------
rfind, str.rindex
@@ -1258,7 +1257,7 @@ def rjust(a, width, fillchar=' '):
out : ndarray
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.rjust
@@ -1299,7 +1298,7 @@ def rpartition(a, sep):
type. The output array will have an extra dimension with
3 elements per input element.
- See also
+ See Also
--------
str.rpartition
@@ -1339,7 +1338,7 @@ def rsplit(a, sep=None, maxsplit=None):
out : ndarray
Array of list objects
- See also
+ See Also
--------
str.rsplit, split
@@ -1378,7 +1377,7 @@ def rstrip(a, chars=None):
out : ndarray
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.rstrip
@@ -1423,7 +1422,7 @@ def split(a, sep=None, maxsplit=None):
out : ndarray
Array of list objects
- See also
+ See Also
--------
str.split, rsplit
@@ -1459,7 +1458,7 @@ def splitlines(a, keepends=None):
out : ndarray
Array of list objects
- See also
+ See Also
--------
str.splitlines
@@ -1495,7 +1494,7 @@ def startswith(a, prefix, start=0, end=None):
out : ndarray
Array of booleans
- See also
+ See Also
--------
str.startswith
@@ -1528,7 +1527,7 @@ def strip(a, chars=None):
out : ndarray
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.strip
@@ -1569,7 +1568,7 @@ def swapcase(a):
out : ndarray, {str, unicode}
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.swapcase
@@ -1609,7 +1608,7 @@ def title(a):
out : ndarray
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.title
@@ -1654,7 +1653,7 @@ def translate(a, table, deletechars=None):
out : ndarray
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.translate
@@ -1687,7 +1686,7 @@ def upper(a):
out : ndarray, {str, unicode}
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.upper
@@ -1726,7 +1725,7 @@ def zfill(a, width):
out : ndarray, {str, unicode}
Output array of str or unicode, depending on input type
- See also
+ See Also
--------
str.zfill
@@ -1760,7 +1759,7 @@ def isnumeric(a):
out : ndarray, bool
Array of booleans of same shape as `a`.
- See also
+ See Also
--------
unicode.isnumeric
@@ -1792,7 +1791,7 @@ def isdecimal(a):
out : ndarray, bool
Array of booleans identical in shape to `a`.
- See also
+ See Also
--------
unicode.isdecimal
@@ -2004,7 +2003,7 @@ class chararray(ndarray):
"""
Return (self == other) element-wise.
- See also
+ See Also
--------
equal
"""
@@ -2014,7 +2013,7 @@ class chararray(ndarray):
"""
Return (self != other) element-wise.
- See also
+ See Also
--------
not_equal
"""
@@ -2024,7 +2023,7 @@ class chararray(ndarray):
"""
Return (self >= other) element-wise.
- See also
+ See Also
--------
greater_equal
"""
@@ -2034,7 +2033,7 @@ class chararray(ndarray):
"""
Return (self <= other) element-wise.
- See also
+ See Also
--------
less_equal
"""
@@ -2044,7 +2043,7 @@ class chararray(ndarray):
"""
Return (self > other) element-wise.
- See also
+ See Also
--------
greater
"""
@@ -2054,7 +2053,7 @@ class chararray(ndarray):
"""
Return (self < other) element-wise.
- See also
+ See Also
--------
less
"""
@@ -2065,7 +2064,7 @@ class chararray(ndarray):
Return (self + other), that is string concatenation,
element-wise for a pair of array_likes of str or unicode.
- See also
+ See Also
--------
add
"""
@@ -2076,7 +2075,7 @@ class chararray(ndarray):
Return (other + self), that is string concatenation,
element-wise for a pair of array_likes of `string_` or `unicode_`.
- See also
+ See Also
--------
add
"""
@@ -2087,7 +2086,7 @@ class chararray(ndarray):
Return (self * i), that is string multiple concatenation,
element-wise.
- See also
+ See Also
--------
multiply
"""
@@ -2098,7 +2097,7 @@ class chararray(ndarray):
Return (self * i), that is string multiple concatenation,
element-wise.
- See also
+ See Also
--------
multiply
"""
@@ -2110,7 +2109,7 @@ class chararray(ndarray):
(interpolation), element-wise for a pair of array_likes of `string_`
or `unicode_`.
- See also
+ See Also
--------
mod
"""
@@ -2145,7 +2144,7 @@ class chararray(ndarray):
Return a copy of `self` with only the first character of each element
capitalized.
- See also
+ See Also
--------
char.capitalize
@@ -2157,7 +2156,7 @@ class chararray(ndarray):
Return a copy of `self` with its elements centered in a
string of length `width`.
- See also
+ See Also
--------
center
"""
@@ -2168,7 +2167,7 @@ class chararray(ndarray):
Returns an array with the number of non-overlapping occurrences of
substring `sub` in the range [`start`, `end`].
- See also
+ See Also
--------
char.count
@@ -2179,7 +2178,7 @@ class chararray(ndarray):
"""
Calls `str.decode` element-wise.
- See also
+ See Also
--------
char.decode
@@ -2190,7 +2189,7 @@ class chararray(ndarray):
"""
Calls `str.encode` element-wise.
- See also
+ See Also
--------
char.encode
@@ -2202,7 +2201,7 @@ class chararray(ndarray):
Returns a boolean array which is `True` where the string element
in `self` ends with `suffix`, otherwise `False`.
- See also
+ See Also
--------
char.endswith
@@ -2214,7 +2213,7 @@ class chararray(ndarray):
Return a copy of each string element where all tab characters are
replaced by one or more spaces.
- See also
+ See Also
--------
char.expandtabs
@@ -2226,7 +2225,7 @@ class chararray(ndarray):
For each element, return the lowest index in the string where
substring `sub` is found.
- See also
+ See Also
--------
char.find
@@ -2237,7 +2236,7 @@ class chararray(ndarray):
"""
Like `find`, but raises `ValueError` when the substring is not found.
- See also
+ See Also
--------
char.index
@@ -2250,7 +2249,7 @@ class chararray(ndarray):
are alphanumeric and there is at least one character, false
otherwise.
- See also
+ See Also
--------
char.isalnum
@@ -2263,7 +2262,7 @@ class chararray(ndarray):
are alphabetic and there is at least one character, false
otherwise.
- See also
+ See Also
--------
char.isalpha
@@ -2275,7 +2274,7 @@ class chararray(ndarray):
Returns true for each element if all characters in the string are
digits and there is at least one character, false otherwise.
- See also
+ See Also
--------
char.isdigit
@@ -2288,7 +2287,7 @@ class chararray(ndarray):
string are lowercase and there is at least one cased character,
false otherwise.
- See also
+ See Also
--------
char.islower
@@ -2301,7 +2300,7 @@ class chararray(ndarray):
characters in the string and there is at least one character,
false otherwise.
- See also
+ See Also
--------
char.isspace
@@ -2313,7 +2312,7 @@ class chararray(ndarray):
Returns true for each element if the element is a titlecased
string and there is at least one character, false otherwise.
- See also
+ See Also
--------
char.istitle
@@ -2326,7 +2325,7 @@ class chararray(ndarray):
string are uppercase and there is at least one character, false
otherwise.
- See also
+ See Also
--------
char.isupper
@@ -2338,7 +2337,7 @@ class chararray(ndarray):
Return a string which is the concatenation of the strings in the
sequence `seq`.
- See also
+ See Also
--------
char.join
@@ -2350,7 +2349,7 @@ class chararray(ndarray):
Return an array with the elements of `self` left-justified in a
string of length `width`.
- See also
+ See Also
--------
char.ljust
@@ -2362,7 +2361,7 @@ class chararray(ndarray):
Return an array with the elements of `self` converted to
lowercase.
- See also
+ See Also
--------
char.lower
@@ -2374,7 +2373,7 @@ class chararray(ndarray):
For each element in `self`, return a copy with the leading characters
removed.
- See also
+ See Also
--------
char.lstrip
@@ -2385,7 +2384,7 @@ class chararray(ndarray):
"""
Partition each element in `self` around `sep`.
- See also
+ See Also
--------
partition
"""
@@ -2396,7 +2395,7 @@ class chararray(ndarray):
For each element in `self`, return a copy of the string with all
occurrences of substring `old` replaced by `new`.
- See also
+ See Also
--------
char.replace
@@ -2409,7 +2408,7 @@ class chararray(ndarray):
where substring `sub` is found, such that `sub` is contained
within [`start`, `end`].
- See also
+ See Also
--------
char.rfind
@@ -2421,7 +2420,7 @@ class chararray(ndarray):
Like `rfind`, but raises `ValueError` when the substring `sub` is
not found.
- See also
+ See Also
--------
char.rindex
@@ -2433,7 +2432,7 @@ class chararray(ndarray):
Return an array with the elements of `self`
right-justified in a string of length `width`.
- See also
+ See Also
--------
char.rjust
@@ -2444,7 +2443,7 @@ class chararray(ndarray):
"""
Partition each element in `self` around `sep`.
- See also
+ See Also
--------
rpartition
"""
@@ -2455,7 +2454,7 @@ class chararray(ndarray):
For each element in `self`, return a list of the words in
the string, using `sep` as the delimiter string.
- See also
+ See Also
--------
char.rsplit
@@ -2467,7 +2466,7 @@ class chararray(ndarray):
For each element in `self`, return a copy with the trailing
characters removed.
- See also
+ See Also
--------
char.rstrip
@@ -2479,7 +2478,7 @@ class chararray(ndarray):
For each element in `self`, return a list of the words in the
string, using `sep` as the delimiter string.
- See also
+ See Also
--------
char.split
@@ -2491,7 +2490,7 @@ class chararray(ndarray):
For each element in `self`, return a list of the lines in the
element, breaking at line boundaries.
- See also
+ See Also
--------
char.splitlines
@@ -2503,7 +2502,7 @@ class chararray(ndarray):
Returns a boolean array which is `True` where the string element
in `self` starts with `prefix`, otherwise `False`.
- See also
+ See Also
--------
char.startswith
@@ -2515,7 +2514,7 @@ class chararray(ndarray):
For each element in `self`, return a copy with the leading and
trailing characters removed.
- See also
+ See Also
--------
char.strip
@@ -2527,7 +2526,7 @@ class chararray(ndarray):
For each element in `self`, return a copy of the string with
uppercase characters converted to lowercase and vice versa.
- See also
+ See Also
--------
char.swapcase
@@ -2540,7 +2539,7 @@ class chararray(ndarray):
string: words start with uppercase characters, all remaining cased
characters are lowercase.
- See also
+ See Also
--------
char.title
@@ -2554,7 +2553,7 @@ class chararray(ndarray):
`deletechars` are removed, and the remaining characters have
been mapped through the given translation table.
- See also
+ See Also
--------
char.translate
@@ -2566,7 +2565,7 @@ class chararray(ndarray):
Return an array with the elements of `self` converted to
uppercase.
- See also
+ See Also
--------
char.upper
@@ -2578,7 +2577,7 @@ class chararray(ndarray):
Return the numeric string left-filled with zeros in a string of
length `width`.
- See also
+ See Also
--------
char.zfill
@@ -2590,7 +2589,7 @@ class chararray(ndarray):
For each element in `self`, return True if there are only
numeric characters in the element.
- See also
+ See Also
--------
char.isnumeric
@@ -2602,7 +2601,7 @@ class chararray(ndarray):
For each element in `self`, return True if there are only
decimal characters in the element.
- See also
+ See Also
--------
char.isdecimal
diff --git a/numpy/core/einsumfunc.py b/numpy/core/einsumfunc.py
index e0942beca..18157641a 100644
--- a/numpy/core/einsumfunc.py
+++ b/numpy/core/einsumfunc.py
@@ -327,7 +327,7 @@ def _greedy_path(input_sets, output_set, idx_dict, memory_limit):
Set that represents the rhs side of the overall einsum subscript
idx_dict : dictionary
Dictionary of index sizes
- memory_limit_limit : int
+ memory_limit : int
The maximum number of elements in a temporary array
Returns
@@ -1061,14 +1061,12 @@ def einsum(*operands, out=None, optimize=False, **kwargs):
See Also
--------
einsum_path, dot, inner, outer, tensordot, linalg.multi_dot
-
- einops:
+ einops :
similar verbose interface is provided by
`einops <https://github.com/arogozhnikov/einops>`_ package to cover
additional operations: transpose, reshape/flatten, repeat/tile,
squeeze/unsqueeze and reductions.
-
- opt_einsum:
+ opt_einsum :
`opt_einsum <https://optimized-einsum.readthedocs.io/en/stable/>`_
optimizes contraction order for einsum-like expressions
in backend-agnostic manner.
diff --git a/numpy/core/einsumfunc.pyi b/numpy/core/einsumfunc.pyi
new file mode 100644
index 000000000..2457e8719
--- /dev/null
+++ b/numpy/core/einsumfunc.pyi
@@ -0,0 +1,142 @@
+import sys
+from typing import List, TypeVar, Optional, Any, overload, Union, Tuple, Sequence
+
+from numpy import (
+ ndarray,
+ dtype,
+ bool_,
+ unsignedinteger,
+ signedinteger,
+ floating,
+ complexfloating,
+ number,
+ _OrderKACF,
+)
+from numpy.typing import (
+ _ArrayLikeBool_co,
+ _ArrayLikeUInt_co,
+ _ArrayLikeInt_co,
+ _ArrayLikeFloat_co,
+ _ArrayLikeComplex_co,
+ _DTypeLikeBool,
+ _DTypeLikeUInt,
+ _DTypeLikeInt,
+ _DTypeLikeFloat,
+ _DTypeLikeComplex,
+ _DTypeLikeComplex_co,
+)
+
+if sys.version_info >= (3, 8):
+ from typing import Literal
+else:
+ from typing_extensions import Literal
+
+_ArrayType = TypeVar(
+ "_ArrayType",
+ bound=ndarray[Any, dtype[Union[bool_, number[Any]]]],
+)
+
+_OptimizeKind = Union[
+ None, bool, Literal["greedy", "optimal"], Sequence[Any]
+]
+_CastingSafe = Literal["no", "equiv", "safe", "same_kind"]
+_CastingUnsafe = Literal["unsafe"]
+
+__all__: List[str]
+
+# TODO: Properly handle the `casting`-based combinatorics
+# TODO: We need to evaluate the content `__subscripts` in order
+# to identify whether or an array or scalar is returned. At a cursory
+# glance this seems like something that can quite easilly be done with
+# a mypy plugin.
+# Something like `is_scalar = bool(__subscripts.partition("->")[-1])`
+@overload
+def einsum(
+ __subscripts: str,
+ *operands: _ArrayLikeBool_co,
+ out: None = ...,
+ dtype: Optional[_DTypeLikeBool] = ...,
+ order: _OrderKACF = ...,
+ casting: _CastingSafe = ...,
+ optimize: _OptimizeKind = ...,
+) -> Any: ...
+@overload
+def einsum(
+ __subscripts: str,
+ *operands: _ArrayLikeUInt_co,
+ out: None = ...,
+ dtype: Optional[_DTypeLikeUInt] = ...,
+ order: _OrderKACF = ...,
+ casting: _CastingSafe = ...,
+ optimize: _OptimizeKind = ...,
+) -> Any: ...
+@overload
+def einsum(
+ __subscripts: str,
+ *operands: _ArrayLikeInt_co,
+ out: None = ...,
+ dtype: Optional[_DTypeLikeInt] = ...,
+ order: _OrderKACF = ...,
+ casting: _CastingSafe = ...,
+ optimize: _OptimizeKind = ...,
+) -> Any: ...
+@overload
+def einsum(
+ __subscripts: str,
+ *operands: _ArrayLikeFloat_co,
+ out: None = ...,
+ dtype: Optional[_DTypeLikeFloat] = ...,
+ order: _OrderKACF = ...,
+ casting: _CastingSafe = ...,
+ optimize: _OptimizeKind = ...,
+) -> Any: ...
+@overload
+def einsum(
+ __subscripts: str,
+ *operands: _ArrayLikeComplex_co,
+ out: None = ...,
+ dtype: Optional[_DTypeLikeComplex] = ...,
+ order: _OrderKACF = ...,
+ casting: _CastingSafe = ...,
+ optimize: _OptimizeKind = ...,
+) -> Any: ...
+@overload
+def einsum(
+ __subscripts: str,
+ *operands: Any,
+ casting: _CastingUnsafe,
+ dtype: Optional[_DTypeLikeComplex_co] = ...,
+ out: None = ...,
+ order: _OrderKACF = ...,
+ optimize: _OptimizeKind = ...,
+) -> Any: ...
+@overload
+def einsum(
+ __subscripts: str,
+ *operands: _ArrayLikeComplex_co,
+ out: _ArrayType,
+ dtype: Optional[_DTypeLikeComplex_co] = ...,
+ order: _OrderKACF = ...,
+ casting: _CastingSafe = ...,
+ optimize: _OptimizeKind = ...,
+) -> _ArrayType: ...
+@overload
+def einsum(
+ __subscripts: str,
+ *operands: Any,
+ out: _ArrayType,
+ casting: _CastingUnsafe,
+ dtype: Optional[_DTypeLikeComplex_co] = ...,
+ order: _OrderKACF = ...,
+ optimize: _OptimizeKind = ...,
+) -> _ArrayType: ...
+
+# NOTE: `einsum_call` is a hidden kwarg unavailable for public use.
+# It is therefore excluded from the signatures below.
+# NOTE: In practice the list consists of a `str` (first element)
+# and a variable number of integer tuples.
+def einsum_path(
+ __subscripts: str,
+ *operands: _ArrayLikeComplex_co,
+ optimize: _OptimizeKind = ...,
+) -> Tuple[List[Any], str]: ...
diff --git a/numpy/core/fromnumeric.py b/numpy/core/fromnumeric.py
index efb052bc2..764377bc9 100644
--- a/numpy/core/fromnumeric.py
+++ b/numpy/core/fromnumeric.py
@@ -10,8 +10,7 @@ from . import multiarray as mu
from . import overrides
from . import umath as um
from . import numerictypes as nt
-from ._asarray import asarray, array, asanyarray
-from .multiarray import concatenate
+from .multiarray import asarray, array, asanyarray, concatenate
from . import _methods
_dt_ = nt.sctype2char
@@ -308,7 +307,7 @@ def _choose_dispatcher(a, choices, out=None, mode=None):
@array_function_dispatch(_choose_dispatcher)
def choose(a, choices, out=None, mode='raise'):
"""
- Construct an array from an index array and a set of arrays to choose from.
+ Construct an array from an index array and a list of arrays to choose from.
First of all, if confused or uncertain, definitely look at the Examples -
in its full generality, this function is less simple than it might
@@ -319,34 +318,34 @@ def choose(a, choices, out=None, mode='raise'):
But this omits some subtleties. Here is a fully general summary:
- Given an "index" array (`a`) of integers and a sequence of `n` arrays
+ Given an "index" array (`a`) of integers and a sequence of ``n`` arrays
(`choices`), `a` and each choice array are first broadcast, as necessary,
to arrays of a common shape; calling these *Ba* and *Bchoices[i], i =
0,...,n-1* we have that, necessarily, ``Ba.shape == Bchoices[i].shape``
- for each `i`. Then, a new array with shape ``Ba.shape`` is created as
+ for each ``i``. Then, a new array with shape ``Ba.shape`` is created as
follows:
- * if ``mode=raise`` (the default), then, first of all, each element of
- `a` (and thus `Ba`) must be in the range `[0, n-1]`; now, suppose that
- `i` (in that range) is the value at the `(j0, j1, ..., jm)` position
- in `Ba` - then the value at the same position in the new array is the
- value in `Bchoices[i]` at that same position;
+ * if ``mode='raise'`` (the default), then, first of all, each element of
+ ``a`` (and thus ``Ba``) must be in the range ``[0, n-1]``; now, suppose
+ that ``i`` (in that range) is the value at the ``(j0, j1, ..., jm)``
+ position in ``Ba`` - then the value at the same position in the new array
+ is the value in ``Bchoices[i]`` at that same position;
- * if ``mode=wrap``, values in `a` (and thus `Ba`) may be any (signed)
+ * if ``mode='wrap'``, values in `a` (and thus `Ba`) may be any (signed)
integer; modular arithmetic is used to map integers outside the range
`[0, n-1]` back into that range; and then the new array is constructed
as above;
- * if ``mode=clip``, values in `a` (and thus `Ba`) may be any (signed)
- integer; negative integers are mapped to 0; values greater than `n-1`
- are mapped to `n-1`; and then the new array is constructed as above.
+ * if ``mode='clip'``, values in `a` (and thus ``Ba``) may be any (signed)
+ integer; negative integers are mapped to 0; values greater than ``n-1``
+ are mapped to ``n-1``; and then the new array is constructed as above.
Parameters
----------
a : int array
- This array must contain integers in `[0, n-1]`, where `n` is the number
- of choices, unless ``mode=wrap`` or ``mode=clip``, in which cases any
- integers are permissible.
+ This array must contain integers in ``[0, n-1]``, where ``n`` is the
+ number of choices, unless ``mode=wrap`` or ``mode=clip``, in which
+ cases any integers are permissible.
choices : sequence of arrays
Choice arrays. `a` and all of the choices must be broadcastable to the
same shape. If `choices` is itself an array (not recommended), then
@@ -355,12 +354,12 @@ def choose(a, choices, out=None, mode='raise'):
out : array, optional
If provided, the result will be inserted into this array. It should
be of the appropriate shape and dtype. Note that `out` is always
- buffered if `mode='raise'`; use other modes for better performance.
+ buffered if ``mode='raise'``; use other modes for better performance.
mode : {'raise' (default), 'wrap', 'clip'}, optional
- Specifies how indices outside `[0, n-1]` will be treated:
+ Specifies how indices outside ``[0, n-1]`` will be treated:
* 'raise' : an exception is raised
- * 'wrap' : value becomes value mod `n`
+ * 'wrap' : value becomes value mod ``n``
* 'clip' : values < 0 are mapped to 0, values > n-1 are mapped to n-1
Returns
@@ -606,6 +605,8 @@ def transpose(a, axes=None):
For an array a with two axes, transpose(a) gives the matrix transpose.
+ Refer to `numpy.ndarray.transpose` for full documentation.
+
Parameters
----------
a : array_like
@@ -625,6 +626,7 @@ def transpose(a, axes=None):
See Also
--------
+ ndarray.transpose : Equivalent method
moveaxis
argsort
@@ -1112,12 +1114,12 @@ def argsort(a, axis=-1, kind=None, order=None):
return _wrapfunc(a, 'argsort', axis=axis, kind=kind, order=order)
-def _argmax_dispatcher(a, axis=None, out=None):
+def _argmax_dispatcher(a, axis=None, out=None, *, keepdims=np._NoValue):
return (a, out)
@array_function_dispatch(_argmax_dispatcher)
-def argmax(a, axis=None, out=None):
+def argmax(a, axis=None, out=None, *, keepdims=np._NoValue):
"""
Returns the indices of the maximum values along an axis.
@@ -1131,12 +1133,18 @@ def argmax(a, axis=None, out=None):
out : array, optional
If provided, the result will be inserted into this array. It should
be of the appropriate shape and dtype.
+ keepdims : bool, optional
+ If this is set to True, the axes which are reduced are left
+ in the result as dimensions with size one. With this option,
+ the result will broadcast correctly against the array.
Returns
-------
index_array : ndarray of ints
Array of indices into the array. It has the same shape as `a.shape`
- with the dimension along `axis` removed.
+ with the dimension along `axis` removed. If `keepdims` is set to True,
+ then the size of `axis` will be 1 with the resulting array having same
+ shape as `a.shape`.
See Also
--------
@@ -1181,24 +1189,31 @@ def argmax(a, axis=None, out=None):
>>> x = np.array([[4,2,3], [1,0,3]])
>>> index_array = np.argmax(x, axis=-1)
- >>> # Same as np.max(x, axis=-1, keepdims=True)
+ >>> # Same as np.amax(x, axis=-1, keepdims=True)
>>> np.take_along_axis(x, np.expand_dims(index_array, axis=-1), axis=-1)
array([[4],
[3]])
- >>> # Same as np.max(x, axis=-1)
+ >>> # Same as np.amax(x, axis=-1)
>>> np.take_along_axis(x, np.expand_dims(index_array, axis=-1), axis=-1).squeeze(axis=-1)
array([4, 3])
+ Setting `keepdims` to `True`,
+
+ >>> x = np.arange(24).reshape((2, 3, 4))
+ >>> res = np.argmax(x, axis=1, keepdims=True)
+ >>> res.shape
+ (2, 1, 4)
"""
- return _wrapfunc(a, 'argmax', axis=axis, out=out)
+ kwds = {'keepdims': keepdims} if keepdims is not np._NoValue else {}
+ return _wrapfunc(a, 'argmax', axis=axis, out=out, **kwds)
-def _argmin_dispatcher(a, axis=None, out=None):
+def _argmin_dispatcher(a, axis=None, out=None, *, keepdims=np._NoValue):
return (a, out)
@array_function_dispatch(_argmin_dispatcher)
-def argmin(a, axis=None, out=None):
+def argmin(a, axis=None, out=None, *, keepdims=np._NoValue):
"""
Returns the indices of the minimum values along an axis.
@@ -1212,12 +1227,18 @@ def argmin(a, axis=None, out=None):
out : array, optional
If provided, the result will be inserted into this array. It should
be of the appropriate shape and dtype.
+ keepdims : bool, optional
+ If this is set to True, the axes which are reduced are left
+ in the result as dimensions with size one. With this option,
+ the result will broadcast correctly against the array.
Returns
-------
index_array : ndarray of ints
Array of indices into the array. It has the same shape as `a.shape`
- with the dimension along `axis` removed.
+ with the dimension along `axis` removed. If `keepdims` is set to True,
+ then the size of `axis` will be 1 with the resulting array having same
+ shape as `a.shape`.
See Also
--------
@@ -1262,16 +1283,23 @@ def argmin(a, axis=None, out=None):
>>> x = np.array([[4,2,3], [1,0,3]])
>>> index_array = np.argmin(x, axis=-1)
- >>> # Same as np.min(x, axis=-1, keepdims=True)
+ >>> # Same as np.amin(x, axis=-1, keepdims=True)
>>> np.take_along_axis(x, np.expand_dims(index_array, axis=-1), axis=-1)
array([[2],
[0]])
- >>> # Same as np.max(x, axis=-1)
+ >>> # Same as np.amax(x, axis=-1)
>>> np.take_along_axis(x, np.expand_dims(index_array, axis=-1), axis=-1).squeeze(axis=-1)
array([2, 0])
+ Setting `keepdims` to `True`,
+
+ >>> x = np.arange(24).reshape((2, 3, 4))
+ >>> res = np.argmin(x, axis=1, keepdims=True)
+ >>> res.shape
+ (2, 1, 4)
"""
- return _wrapfunc(a, 'argmin', axis=axis, out=out)
+ kwds = {'keepdims': keepdims} if keepdims is not np._NoValue else {}
+ return _wrapfunc(a, 'argmin', axis=axis, out=out, **kwds)
def _searchsorted_dispatcher(a, v, side=None, sorter=None):
@@ -1316,8 +1344,9 @@ def searchsorted(a, v, side='left', sorter=None):
Returns
-------
- indices : array of ints
- Array of insertion points with the same shape as `v`.
+ indices : int or array of ints
+ Array of insertion points with the same shape as `v`,
+ or an integer if `v` is a scalar.
See Also
--------
@@ -1379,9 +1408,9 @@ def resize(a, new_shape):
See Also
--------
- np.reshape : Reshape an array without changing the total size.
- np.pad : Enlarge and pad an array.
- np.repeat: Repeat elements of an array.
+ numpy.reshape : Reshape an array without changing the total size.
+ numpy.pad : Enlarge and pad an array.
+ numpy.repeat : Repeat elements of an array.
ndarray.resize : resize an array in-place.
Notes
@@ -2007,7 +2036,7 @@ def compress(condition, a, axis=None, out=None):
--------
take, choose, diag, diagonal, select
ndarray.compress : Equivalent method in ndarray
- extract: Equivalent method when working on 1-D arrays
+ extract : Equivalent method when working on 1-D arrays
:ref:`ufuncs-output-type`
Examples
@@ -2084,15 +2113,25 @@ def clip(a, a_min, a_max, out=None, **kwargs):
--------
:ref:`ufuncs-output-type`
+ Notes
+ -----
+ When `a_min` is greater than `a_max`, `clip` returns an
+ array in which all values are equal to `a_max`,
+ as shown in the second example.
+
Examples
--------
>>> a = np.arange(10)
- >>> np.clip(a, 1, 8)
- array([1, 1, 2, 3, 4, 5, 6, 7, 8, 8])
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+ >>> np.clip(a, 1, 8)
+ array([1, 1, 2, 3, 4, 5, 6, 7, 8, 8])
+ >>> np.clip(a, 8, 1)
+ array([1, 1, 1, 1, 1, 1, 1, 1, 1, 1])
>>> np.clip(a, 3, 6, out=a)
array([3, 3, 3, 3, 4, 5, 6, 6, 6, 6])
+ >>> a
+ array([3, 3, 3, 3, 4, 5, 6, 6, 6, 6])
>>> a = np.arange(10)
>>> a
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
@@ -2475,20 +2514,21 @@ def cumsum(a, axis=None, dtype=None, out=None):
result has the same size as `a`, and the same shape as `a` if
`axis` is not None or `a` is a 1-d array.
-
See Also
--------
sum : Sum array elements.
-
trapz : Integration of array values using the composite trapezoidal rule.
-
- diff : Calculate the n-th discrete difference along given axis.
+ diff : Calculate the n-th discrete difference along given axis.
Notes
-----
Arithmetic is modular when using integer types, and no error is
raised on overflow.
+ ``cumsum(a)[-1]`` may not be equal to ``sum(a)`` for floating-point
+ values since ``sum`` may use a pairwise summation routine, reducing
+ the roundoff-error. See `sum` for more information.
+
Examples
--------
>>> a = np.array([[1,2,3], [4,5,6]])
@@ -2507,6 +2547,14 @@ def cumsum(a, axis=None, dtype=None, out=None):
array([[ 1, 3, 6],
[ 4, 9, 15]])
+ ``cumsum(b)[-1]`` may not be equal to ``sum(b)``
+
+ >>> b = np.array([1, 2e-9, 3e-9] * 1000000)
+ >>> b.cumsum()[-1]
+ 1000000.0050045159
+ >>> b.sum()
+ 1000000.0050000029
+
"""
return _wrapfunc(a, 'cumsum', axis=axis, dtype=dtype, out=out)
@@ -2718,14 +2766,14 @@ def amax(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue,
You can use an initial value to compute the maximum of an empty slice, or
to initialize it to a different value:
- >>> np.max([[-50], [10]], axis=-1, initial=0)
+ >>> np.amax([[-50], [10]], axis=-1, initial=0)
array([ 0, 10])
Notice that the initial value is used as one of the elements for which the
maximum is determined, unlike for the default argument Python's max
function, which is only used for empty iterables.
- >>> np.max([5], initial=6)
+ >>> np.amax([5], initial=6)
6
>>> max([5], default=6)
5
@@ -2841,7 +2889,7 @@ def amin(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue,
>>> np.nanmin(b)
0.0
- >>> np.min([[-50], [10]], axis=-1, initial=0)
+ >>> np.amin([[-50], [10]], axis=-1, initial=0)
array([-50, 0])
Notice that the initial value is used as one of the elements for which the
@@ -2850,7 +2898,7 @@ def amin(a, axis=None, out=None, keepdims=np._NoValue, initial=np._NoValue,
Notice that this isn't the same as Python's ``default`` argument.
- >>> np.min([6], initial=5)
+ >>> np.amin([6], initial=5)
5
>>> min([6], default=5)
6
diff --git a/numpy/core/fromnumeric.pyi b/numpy/core/fromnumeric.pyi
index 66eb3bfb8..45057e4b1 100644
--- a/numpy/core/fromnumeric.pyi
+++ b/numpy/core/fromnumeric.pyi
@@ -6,12 +6,11 @@ from numpy import (
ndarray,
number,
integer,
+ intp,
bool_,
generic,
_OrderKACF,
_OrderACF,
- _ArrayLikeBool,
- _ArrayLikeIntOrBool,
_ModeKind,
_PartitionKind,
_SortKind,
@@ -22,9 +21,9 @@ from numpy.typing import (
ArrayLike,
_ShapeLike,
_Shape,
- _IntLike,
- _BoolLike,
- _NumberLike,
+ _ArrayLikeBool_co,
+ _ArrayLikeInt_co,
+ _NumberLike_co,
)
if sys.version_info >= (3, 8):
@@ -42,11 +41,7 @@ _ScalarBuiltin = Union[str, bytes, dt.date, dt.timedelta, bool, int, float, comp
_Scalar = Union[_ScalarBuiltin, _ScalarNumpy]
# Integers and booleans can generally be used interchangeably
-_ScalarIntOrBool = TypeVar("_ScalarIntOrBool", bound=Union[integer, bool_])
_ScalarGeneric = TypeVar("_ScalarGeneric", bound=generic)
-_ScalarGenericDT = TypeVar(
- "_ScalarGenericDT", bound=Union[dt.datetime, dt.timedelta, generic]
-)
_Number = TypeVar("_Number", bound=number)
@@ -55,144 +50,153 @@ _Number = TypeVar("_Number", bound=number)
# 2. A scalar comes in; a generic comes out
# 3. An array-like object comes in; some keyword ensures that a generic comes out
# 4. An array-like object comes in; an ndarray or generic comes out
-@overload
-def take(
- a: _ScalarGenericDT,
- indices: int,
- axis: Optional[int] = ...,
- out: Optional[ndarray] = ...,
- mode: _ModeKind = ...,
-) -> _ScalarGenericDT: ...
-@overload
-def take(
- a: _Scalar,
- indices: int,
- axis: Optional[int] = ...,
- out: Optional[ndarray] = ...,
- mode: _ModeKind = ...,
-) -> _ScalarNumpy: ...
-@overload
def take(
a: ArrayLike,
- indices: int,
+ indices: _ArrayLikeInt_co,
axis: Optional[int] = ...,
out: Optional[ndarray] = ...,
mode: _ModeKind = ...,
-) -> _ScalarNumpy: ...
-@overload
-def take(
+) -> Any: ...
+
+def reshape(
a: ArrayLike,
- indices: _ArrayLikeIntOrBool,
- axis: Optional[int] = ...,
- out: Optional[ndarray] = ...,
- mode: _ModeKind = ...,
-) -> Union[_ScalarNumpy, ndarray]: ...
-def reshape(a: ArrayLike, newshape: _ShapeLike, order: _OrderACF = ...) -> ndarray: ...
-@overload
-def choose(
- a: _ScalarIntOrBool,
- choices: ArrayLike,
- out: Optional[ndarray] = ...,
- mode: _ModeKind = ...,
-) -> _ScalarIntOrBool: ...
-@overload
-def choose(
- a: Union[_IntLike, _BoolLike], choices: ArrayLike, out: Optional[ndarray] = ..., mode: _ModeKind = ...
-) -> Union[integer, bool_]: ...
-@overload
+ newshape: _ShapeLike,
+ order: _OrderACF = ...,
+) -> ndarray: ...
+
def choose(
- a: _ArrayLikeIntOrBool,
+ a: _ArrayLikeInt_co,
choices: ArrayLike,
out: Optional[ndarray] = ...,
mode: _ModeKind = ...,
-) -> ndarray: ...
+) -> Any: ...
+
def repeat(
- a: ArrayLike, repeats: _ArrayLikeIntOrBool, axis: Optional[int] = ...
+ a: ArrayLike,
+ repeats: _ArrayLikeInt_co,
+ axis: Optional[int] = ...,
) -> ndarray: ...
+
def put(
- a: ndarray, ind: _ArrayLikeIntOrBool, v: ArrayLike, mode: _ModeKind = ...
+ a: ndarray,
+ ind: _ArrayLikeInt_co,
+ v: ArrayLike,
+ mode: _ModeKind = ...,
) -> None: ...
-def swapaxes(a: ArrayLike, axis1: int, axis2: int) -> ndarray: ...
+
+def swapaxes(
+ a: ArrayLike,
+ axis1: int,
+ axis2: int,
+) -> ndarray: ...
+
def transpose(
- a: ArrayLike, axes: Union[None, Sequence[int], ndarray] = ...
+ a: ArrayLike,
+ axes: Union[None, Sequence[int], ndarray] = ...
) -> ndarray: ...
+
def partition(
a: ArrayLike,
- kth: _ArrayLikeIntOrBool,
+ kth: _ArrayLikeInt_co,
axis: Optional[int] = ...,
kind: _PartitionKind = ...,
order: Union[None, str, Sequence[str]] = ...,
) -> ndarray: ...
-@overload
-def argpartition(
- a: generic,
- kth: _ArrayLikeIntOrBool,
- axis: Optional[int] = ...,
- kind: _PartitionKind = ...,
- order: Union[None, str, Sequence[str]] = ...,
-) -> integer: ...
-@overload
-def argpartition(
- a: _ScalarBuiltin,
- kth: _ArrayLikeIntOrBool,
- axis: Optional[int] = ...,
- kind: _PartitionKind = ...,
- order: Union[None, str, Sequence[str]] = ...,
-) -> ndarray: ...
-@overload
+
def argpartition(
a: ArrayLike,
- kth: _ArrayLikeIntOrBool,
+ kth: _ArrayLikeInt_co,
axis: Optional[int] = ...,
kind: _PartitionKind = ...,
order: Union[None, str, Sequence[str]] = ...,
-) -> ndarray: ...
+) -> Any: ...
+
def sort(
a: ArrayLike,
axis: Optional[int] = ...,
kind: Optional[_SortKind] = ...,
order: Union[None, str, Sequence[str]] = ...,
) -> ndarray: ...
+
def argsort(
a: ArrayLike,
axis: Optional[int] = ...,
kind: Optional[_SortKind] = ...,
order: Union[None, str, Sequence[str]] = ...,
) -> ndarray: ...
+
@overload
-def argmax(a: ArrayLike, axis: None = ..., out: Optional[ndarray] = ...) -> integer: ...
+def argmax(
+ a: ArrayLike,
+ axis: None = ...,
+ out: Optional[ndarray] = ...,
+ *,
+ keepdims: Literal[False] = ...,
+) -> intp: ...
@overload
def argmax(
- a: ArrayLike, axis: int = ..., out: Optional[ndarray] = ...
-) -> Union[integer, ndarray]: ...
+ a: ArrayLike,
+ axis: Optional[int] = ...,
+ out: Optional[ndarray] = ...,
+ *,
+ keepdims: bool = ...,
+) -> Any: ...
+
@overload
-def argmin(a: ArrayLike, axis: None = ..., out: Optional[ndarray] = ...) -> integer: ...
+def argmin(
+ a: ArrayLike,
+ axis: None = ...,
+ out: Optional[ndarray] = ...,
+ *,
+ keepdims: Literal[False] = ...,
+) -> intp: ...
@overload
def argmin(
- a: ArrayLike, axis: int = ..., out: Optional[ndarray] = ...
-) -> Union[integer, ndarray]: ...
+ a: ArrayLike,
+ axis: Optional[int] = ...,
+ out: Optional[ndarray] = ...,
+ *,
+ keepdims: bool = ...,
+) -> Any: ...
+
@overload
def searchsorted(
a: ArrayLike,
v: _Scalar,
side: _SortSide = ...,
- sorter: Optional[_ArrayLikeIntOrBool] = ..., # 1D int array
-) -> integer: ...
+ sorter: Optional[_ArrayLikeInt_co] = ..., # 1D int array
+) -> intp: ...
@overload
def searchsorted(
a: ArrayLike,
v: ArrayLike,
side: _SortSide = ...,
- sorter: Optional[_ArrayLikeIntOrBool] = ..., # 1D int array
+ sorter: Optional[_ArrayLikeInt_co] = ..., # 1D int array
+) -> ndarray: ...
+
+def resize(
+ a: ArrayLike,
+ new_shape: _ShapeLike,
) -> ndarray: ...
-def resize(a: ArrayLike, new_shape: _ShapeLike) -> ndarray: ...
+
@overload
-def squeeze(a: _ScalarGeneric, axis: Optional[_ShapeLike] = ...) -> _ScalarGeneric: ...
+def squeeze(
+ a: _ScalarGeneric,
+ axis: Optional[_ShapeLike] = ...,
+) -> _ScalarGeneric: ...
@overload
-def squeeze(a: ArrayLike, axis: Optional[_ShapeLike] = ...) -> ndarray: ...
+def squeeze(
+ a: ArrayLike,
+ axis: Optional[_ShapeLike] = ...,
+) -> ndarray: ...
+
def diagonal(
- a: ArrayLike, offset: int = ..., axis1: int = ..., axis2: int = ... # >= 2D array
+ a: ArrayLike,
+ offset: int = ...,
+ axis1: int = ...,
+ axis2: int = ..., # >= 2D array
) -> ndarray: ...
+
def trace(
a: ArrayLike, # >= 2D array
offset: int = ...,
@@ -200,32 +204,21 @@ def trace(
axis2: int = ...,
dtype: DTypeLike = ...,
out: Optional[ndarray] = ...,
-) -> Union[number, ndarray]: ...
+) -> Any: ...
+
def ravel(a: ArrayLike, order: _OrderKACF = ...) -> ndarray: ...
+
def nonzero(a: ArrayLike) -> Tuple[ndarray, ...]: ...
+
def shape(a: ArrayLike) -> _Shape: ...
+
def compress(
condition: ArrayLike, # 1D bool array
a: ArrayLike,
axis: Optional[int] = ...,
out: Optional[ndarray] = ...,
) -> ndarray: ...
-@overload
-def clip(
- a: _Number,
- a_min: ArrayLike,
- a_max: Optional[ArrayLike],
- out: Optional[ndarray] = ...,
- **kwargs: Any,
-) -> _Number: ...
-@overload
-def clip(
- a: _Number,
- a_min: None,
- a_max: ArrayLike,
- out: Optional[ndarray] = ...,
- **kwargs: Any,
-) -> _Number: ...
+
@overload
def clip(
a: ArrayLike,
@@ -233,7 +226,7 @@ def clip(
a_max: Optional[ArrayLike],
out: Optional[ndarray] = ...,
**kwargs: Any,
-) -> Union[number, ndarray]: ...
+) -> Any: ...
@overload
def clip(
a: ArrayLike,
@@ -241,32 +234,23 @@ def clip(
a_max: ArrayLike,
out: Optional[ndarray] = ...,
**kwargs: Any,
-) -> Union[number, ndarray]: ...
-@overload
-def sum(
- a: _Number,
- axis: Optional[_ShapeLike] = ...,
- dtype: DTypeLike = ...,
- out: Optional[ndarray] = ...,
- keepdims: bool = ...,
- initial: _NumberLike = ...,
- where: _ArrayLikeBool = ...,
-) -> _Number: ...
-@overload
+) -> Any: ...
+
def sum(
a: ArrayLike,
axis: _ShapeLike = ...,
dtype: DTypeLike = ...,
out: Optional[ndarray] = ...,
keepdims: bool = ...,
- initial: _NumberLike = ...,
- where: _ArrayLikeBool = ...,
-) -> Union[number, ndarray]: ...
+ initial: _NumberLike_co = ...,
+ where: _ArrayLikeBool_co = ...,
+) -> Any: ...
+
@overload
def all(
a: ArrayLike,
axis: None = ...,
- out: Optional[ndarray] = ...,
+ out: None = ...,
keepdims: Literal[False] = ...,
) -> bool_: ...
@overload
@@ -275,12 +259,13 @@ def all(
axis: Optional[_ShapeLike] = ...,
out: Optional[ndarray] = ...,
keepdims: bool = ...,
-) -> Union[bool_, ndarray]: ...
+) -> Any: ...
+
@overload
def any(
a: ArrayLike,
axis: None = ...,
- out: Optional[ndarray] = ...,
+ out: None = ...,
keepdims: Literal[False] = ...,
) -> bool_: ...
@overload
@@ -289,88 +274,39 @@ def any(
axis: Optional[_ShapeLike] = ...,
out: Optional[ndarray] = ...,
keepdims: bool = ...,
-) -> Union[bool_, ndarray]: ...
+) -> Any: ...
+
def cumsum(
a: ArrayLike,
axis: Optional[int] = ...,
dtype: DTypeLike = ...,
out: Optional[ndarray] = ...,
) -> ndarray: ...
-@overload
-def ptp(
- a: _Number,
- axis: Optional[_ShapeLike] = ...,
- out: Optional[ndarray] = ...,
- keepdims: bool = ...,
-) -> _Number: ...
-@overload
-def ptp(
- a: ArrayLike,
- axis: None = ...,
- out: Optional[ndarray] = ...,
- keepdims: Literal[False] = ...,
-) -> number: ...
-@overload
+
def ptp(
a: ArrayLike,
axis: Optional[_ShapeLike] = ...,
out: Optional[ndarray] = ...,
keepdims: bool = ...,
-) -> Union[number, ndarray]: ...
-@overload
-def amax(
- a: _Number,
- axis: Optional[_ShapeLike] = ...,
- out: Optional[ndarray] = ...,
- keepdims: bool = ...,
- initial: _NumberLike = ...,
- where: _ArrayLikeBool = ...,
-) -> _Number: ...
-@overload
-def amax(
- a: ArrayLike,
- axis: None = ...,
- out: Optional[ndarray] = ...,
- keepdims: Literal[False] = ...,
- initial: _NumberLike = ...,
- where: _ArrayLikeBool = ...,
-) -> number: ...
-@overload
+) -> Any: ...
+
def amax(
a: ArrayLike,
axis: Optional[_ShapeLike] = ...,
out: Optional[ndarray] = ...,
keepdims: bool = ...,
- initial: _NumberLike = ...,
- where: _ArrayLikeBool = ...,
-) -> Union[number, ndarray]: ...
-@overload
-def amin(
- a: _Number,
- axis: Optional[_ShapeLike] = ...,
- out: Optional[ndarray] = ...,
- keepdims: bool = ...,
- initial: _NumberLike = ...,
- where: _ArrayLikeBool = ...,
-) -> _Number: ...
-@overload
-def amin(
- a: ArrayLike,
- axis: None = ...,
- out: Optional[ndarray] = ...,
- keepdims: Literal[False] = ...,
- initial: _NumberLike = ...,
- where: _ArrayLikeBool = ...,
-) -> number: ...
-@overload
+ initial: _NumberLike_co = ...,
+ where: _ArrayLikeBool_co = ...,
+) -> Any: ...
+
def amin(
a: ArrayLike,
axis: Optional[_ShapeLike] = ...,
out: Optional[ndarray] = ...,
keepdims: bool = ...,
- initial: _NumberLike = ...,
- where: _ArrayLikeBool = ...,
-) -> Union[number, ndarray]: ...
+ initial: _NumberLike_co = ...,
+ where: _ArrayLikeBool_co = ...,
+) -> Any: ...
# TODO: `np.prod()``: For object arrays `initial` does not necessarily
# have to be a numerical scalar.
@@ -379,82 +315,41 @@ def amin(
# Note that the same situation holds for all wrappers around
# `np.ufunc.reduce`, e.g. `np.sum()` (`.__add__()`).
-@overload
-def prod(
- a: _Number,
- axis: Optional[_ShapeLike] = ...,
- dtype: DTypeLike = ...,
- out: None = ...,
- keepdims: bool = ...,
- initial: _NumberLike = ...,
- where: _ArrayLikeBool = ...,
-) -> _Number: ...
-@overload
-def prod(
- a: ArrayLike,
- axis: None = ...,
- dtype: DTypeLike = ...,
- out: None = ...,
- keepdims: Literal[False] = ...,
- initial: _NumberLike = ...,
- where: _ArrayLikeBool = ...,
-) -> number: ...
-@overload
def prod(
a: ArrayLike,
axis: Optional[_ShapeLike] = ...,
dtype: DTypeLike = ...,
out: Optional[ndarray] = ...,
keepdims: bool = ...,
- initial: _NumberLike = ...,
- where: _ArrayLikeBool = ...,
-) -> Union[number, ndarray]: ...
+ initial: _NumberLike_co = ...,
+ where: _ArrayLikeBool_co = ...,
+) -> Any: ...
+
def cumprod(
a: ArrayLike,
axis: Optional[int] = ...,
dtype: DTypeLike = ...,
out: Optional[ndarray] = ...,
) -> ndarray: ...
+
def ndim(a: ArrayLike) -> int: ...
+
def size(a: ArrayLike, axis: Optional[int] = ...) -> int: ...
-@overload
-def around(
- a: _Number, decimals: int = ..., out: Optional[ndarray] = ...
-) -> _Number: ...
-@overload
-def around(
- a: _NumberLike, decimals: int = ..., out: Optional[ndarray] = ...
-) -> number: ...
-@overload
+
def around(
- a: ArrayLike, decimals: int = ..., out: Optional[ndarray] = ...
-) -> ndarray: ...
-@overload
-def mean(
a: ArrayLike,
- axis: None = ...,
- dtype: DTypeLike = ...,
- out: None = ...,
- keepdims: Literal[False] = ...,
-) -> number: ...
-@overload
+ decimals: int = ...,
+ out: Optional[ndarray] = ...,
+) -> Any: ...
+
def mean(
a: ArrayLike,
axis: Optional[_ShapeLike] = ...,
dtype: DTypeLike = ...,
out: Optional[ndarray] = ...,
keepdims: bool = ...,
-) -> Union[number, ndarray]: ...
-@overload
-def std(
- a: ArrayLike,
- axis: None = ...,
- dtype: DTypeLike = ...,
- out: None = ...,
- ddof: int = ...,
- keepdims: Literal[False] = ...,
-) -> number: ...
-@overload
+) -> Any: ...
+
def std(
a: ArrayLike,
axis: Optional[_ShapeLike] = ...,
@@ -462,17 +357,8 @@ def std(
out: Optional[ndarray] = ...,
ddof: int = ...,
keepdims: bool = ...,
-) -> Union[number, ndarray]: ...
-@overload
-def var(
- a: ArrayLike,
- axis: None = ...,
- dtype: DTypeLike = ...,
- out: None = ...,
- ddof: int = ...,
- keepdims: Literal[False] = ...,
-) -> number: ...
-@overload
+) -> Any: ...
+
def var(
a: ArrayLike,
axis: Optional[_ShapeLike] = ...,
@@ -480,4 +366,4 @@ def var(
out: Optional[ndarray] = ...,
ddof: int = ...,
keepdims: bool = ...,
-) -> Union[number, ndarray]: ...
+) -> Any: ...
diff --git a/numpy/core/function_base.py b/numpy/core/function_base.py
index 8a1fee99b..e940ac230 100644
--- a/numpy/core/function_base.py
+++ b/numpy/core/function_base.py
@@ -371,7 +371,7 @@ def geomspace(start, stop, num=50, endpoint=True, dtype=None, axis=0):
6.12323400e-17+1.00000000e+00j, 7.07106781e-01+7.07106781e-01j,
1.00000000e+00+0.00000000e+00j])
- Graphical illustration of ``endpoint`` parameter:
+ Graphical illustration of `endpoint` parameter:
>>> import matplotlib.pyplot as plt
>>> N = 10
diff --git a/numpy/core/function_base.pyi b/numpy/core/function_base.pyi
index 1490bed4a..b5d6ca6ab 100644
--- a/numpy/core/function_base.pyi
+++ b/numpy/core/function_base.pyi
@@ -1,21 +1,18 @@
import sys
from typing import overload, Tuple, Union, Sequence, Any
-from numpy import ndarray, inexact
-from numpy.typing import ArrayLike, DTypeLike, _SupportsArray, _NumberLike
+from numpy import ndarray
+from numpy.typing import ArrayLike, DTypeLike, _SupportsArray, _NumberLike_co
if sys.version_info >= (3, 8):
from typing import SupportsIndex, Literal
else:
- from typing_extensions import Literal, Protocol
-
- class SupportsIndex(Protocol):
- def __index__(self) -> int: ...
+ from typing_extensions import SupportsIndex, Literal
# TODO: wait for support for recursive types
_ArrayLikeNested = Sequence[Sequence[Any]]
_ArrayLikeNumber = Union[
- _NumberLike, Sequence[_NumberLike], ndarray, _SupportsArray, _ArrayLikeNested
+ _NumberLike_co, Sequence[_NumberLike_co], ndarray, _SupportsArray, _ArrayLikeNested
]
@overload
def linspace(
@@ -36,7 +33,8 @@ def linspace(
retstep: Literal[True] = ...,
dtype: DTypeLike = ...,
axis: SupportsIndex = ...,
-) -> Tuple[ndarray, inexact]: ...
+) -> Tuple[ndarray, Any]: ...
+
def logspace(
start: _ArrayLikeNumber,
stop: _ArrayLikeNumber,
@@ -46,6 +44,7 @@ def logspace(
dtype: DTypeLike = ...,
axis: SupportsIndex = ...,
) -> ndarray: ...
+
def geomspace(
start: _ArrayLikeNumber,
stop: _ArrayLikeNumber,
diff --git a/numpy/core/getlimits.py b/numpy/core/getlimits.py
index fcb73e8ba..0f7031bac 100644
--- a/numpy/core/getlimits.py
+++ b/numpy/core/getlimits.py
@@ -9,8 +9,8 @@ from .machar import MachAr
from .overrides import set_module
from . import numeric
from . import numerictypes as ntypes
-from .numeric import array, inf
-from .umath import log10, exp2
+from .numeric import array, inf, NaN
+from .umath import log10, exp2, nextafter, isnan
from . import umath
@@ -29,32 +29,96 @@ def _fr1(a):
a.shape = ()
return a
+
class MachArLike:
""" Object to simulate MachAr instance """
-
- def __init__(self,
- ftype,
- *, eps, epsneg, huge, tiny, ibeta, **kwargs):
- params = _MACHAR_PARAMS[ftype]
- float_conv = lambda v: array([v], ftype)
- float_to_float = lambda v : _fr1(float_conv(v))
- float_to_str = lambda v: (params['fmt'] % array(_fr0(v)[0], ftype))
-
- self.title = params['title']
+ def __init__(self, ftype, *, eps, epsneg, huge, tiny,
+ ibeta, smallest_subnormal=None, **kwargs):
+ self.params = _MACHAR_PARAMS[ftype]
+ self.ftype = ftype
+ self.title = self.params['title']
# Parameter types same as for discovered MachAr object.
- self.epsilon = self.eps = float_to_float(eps)
- self.epsneg = float_to_float(epsneg)
- self.xmax = self.huge = float_to_float(huge)
- self.xmin = self.tiny = float_to_float(tiny)
- self.ibeta = params['itype'](ibeta)
+ if not smallest_subnormal:
+ self._smallest_subnormal = nextafter(
+ self.ftype(0), self.ftype(1), dtype=self.ftype)
+ else:
+ self._smallest_subnormal = smallest_subnormal
+ self.epsilon = self.eps = self._float_to_float(eps)
+ self.epsneg = self._float_to_float(epsneg)
+ self.xmax = self.huge = self._float_to_float(huge)
+ self.xmin = self._float_to_float(tiny)
+ self.smallest_normal = self.tiny = self._float_to_float(tiny)
+ self.ibeta = self.params['itype'](ibeta)
self.__dict__.update(kwargs)
self.precision = int(-log10(self.eps))
- self.resolution = float_to_float(float_conv(10) ** (-self.precision))
- self._str_eps = float_to_str(self.eps)
- self._str_epsneg = float_to_str(self.epsneg)
- self._str_xmin = float_to_str(self.xmin)
- self._str_xmax = float_to_str(self.xmax)
- self._str_resolution = float_to_str(self.resolution)
+ self.resolution = self._float_to_float(
+ self._float_conv(10) ** (-self.precision))
+ self._str_eps = self._float_to_str(self.eps)
+ self._str_epsneg = self._float_to_str(self.epsneg)
+ self._str_xmin = self._float_to_str(self.xmin)
+ self._str_xmax = self._float_to_str(self.xmax)
+ self._str_resolution = self._float_to_str(self.resolution)
+ self._str_smallest_normal = self._float_to_str(self.xmin)
+
+ @property
+ def smallest_subnormal(self):
+ """Return the value for the smallest subnormal.
+
+ Returns
+ -------
+ smallest_subnormal : float
+ value for the smallest subnormal.
+
+ Warns
+ -----
+ UserWarning
+ If the calculated value for the smallest subnormal is zero.
+ """
+ # Check that the calculated value is not zero, in case it raises a
+ # warning.
+ value = self._smallest_subnormal
+ if self.ftype(0) == value:
+ warnings.warn(
+ 'The value of the smallest subnormal for {} type '
+ 'is zero.'.format(self.ftype), UserWarning, stacklevel=2)
+
+ return self._float_to_float(value)
+
+ @property
+ def _str_smallest_subnormal(self):
+ """Return the string representation of the smallest subnormal."""
+ return self._float_to_str(self.smallest_subnormal)
+
+ def _float_to_float(self, value):
+ """Converts float to float.
+
+ Parameters
+ ----------
+ value : float
+ value to be converted.
+ """
+ return _fr1(self._float_conv(value))
+
+ def _float_conv(self, value):
+ """Converts float to conv.
+
+ Parameters
+ ----------
+ value : float
+ value to be converted.
+ """
+ return array([value], self.ftype)
+
+ def _float_to_str(self, value):
+ """Converts float to str.
+
+ Parameters
+ ----------
+ value : float
+ value to be converted.
+ """
+ return self.params['fmt'] % array(_fr0(value)[0], self.ftype)
+
_convert_to_float = {
ntypes.csingle: ntypes.single,
@@ -91,6 +155,7 @@ def _register_type(machar, bytepat):
_KNOWN_TYPES[bytepat] = machar
_float_ma = {}
+
def _register_known_types():
# Known parameters for float16
# See docstring of MachAr class for description of parameters.
@@ -208,23 +273,27 @@ def _register_known_types():
# https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format#Double-double_arithmetic
# These numbers have the same exponent range as float64, but extended number of
# digits in the significand.
- huge_dd = (umath.nextafter(ld(inf), ld(0))
- if hasattr(umath, 'nextafter') # Missing on some platforms?
- else float64_ma.huge)
+ huge_dd = nextafter(ld(inf), ld(0), dtype=ld)
+ # As the smallest_normal in double double is so hard to calculate we set
+ # it to NaN.
+ smallest_normal_dd = NaN
+ # Leave the same value for the smallest subnormal as double
+ smallest_subnormal_dd = ld(nextafter(0., 1.))
float_dd_ma = MachArLike(ld,
- machep=-105,
- negep=-106,
- minexp=-1022,
- maxexp=1024,
- it=105,
- iexp=11,
- ibeta=2,
- irnd=5,
- ngrd=0,
- eps=exp2(ld(-105)),
- epsneg= exp2(ld(-106)),
- huge=huge_dd,
- tiny=exp2(ld(-1022)))
+ machep=-105,
+ negep=-106,
+ minexp=-1022,
+ maxexp=1024,
+ it=105,
+ iexp=11,
+ ibeta=2,
+ irnd=5,
+ ngrd=0,
+ eps=exp2(ld(-105)),
+ epsneg=exp2(ld(-106)),
+ huge=huge_dd,
+ tiny=smallest_normal_dd,
+ smallest_subnormal=smallest_subnormal_dd)
# double double; low, high order (e.g. PPC 64)
_register_type(float_dd_ma,
b'\x9a\x99\x99\x99\x99\x99Y<\x9a\x99\x99\x99\x99\x99\xb9\xbf')
@@ -341,8 +410,13 @@ class finfo:
The approximate decimal resolution of this type, i.e.,
``10**-precision``.
tiny : float
- The smallest positive floating point number with full precision
- (see Notes).
+ An alias for `smallest_normal`, kept for backwards compatibility.
+ smallest_normal : float
+ The smallest positive floating point number with 1 as leading bit in
+ the mantissa following IEEE-754 (see Notes).
+ smallest_subnormal : float
+ The smallest positive floating point number with 0 as leading bit in
+ the mantissa following IEEE-754.
Parameters
----------
@@ -363,12 +437,12 @@ class finfo:
impacts import times. These objects are cached, so calling ``finfo()``
repeatedly inside your functions is not a problem.
- Note that ``tiny`` is not actually the smallest positive representable
- value in a NumPy floating point type. As in the IEEE-754 standard [1]_,
- NumPy floating point types make use of subnormal numbers to fill the
- gap between 0 and ``tiny``. However, subnormal numbers may have
- significantly reduced precision [2]_.
-
+ Note that ``smallest_normal`` is not actually the smallest positive
+ representable value in a NumPy floating point type. As in the IEEE-754
+ standard [1]_, NumPy floating point types make use of subnormal numbers to
+ fill the gap between 0 and ``smallest_normal``. However, subnormal numbers
+ may have significantly reduced precision [2]_.
+
References
----------
.. [1] IEEE Standard for Floating-Point Arithmetic, IEEE Std 754-2008,
@@ -420,7 +494,7 @@ class finfo:
'maxexp', 'minexp', 'negep',
'machep']:
setattr(self, word, getattr(machar, word))
- for word in ['tiny', 'resolution', 'epsneg']:
+ for word in ['resolution', 'epsneg', 'smallest_subnormal']:
setattr(self, word, getattr(machar, word).flat[0])
self.bits = self.dtype.itemsize * 8
self.max = machar.huge.flat[0]
@@ -434,6 +508,8 @@ class finfo:
self._str_epsneg = machar._str_epsneg.strip()
self._str_eps = machar._str_eps.strip()
self._str_resolution = machar._str_resolution.strip()
+ self._str_smallest_normal = machar._str_smallest_normal.strip()
+ self._str_smallest_subnormal = machar._str_smallest_subnormal.strip()
return self
def __str__(self):
@@ -446,6 +522,8 @@ class finfo:
'minexp = %(minexp)6s tiny = %(_str_tiny)s\n'
'maxexp = %(maxexp)6s max = %(_str_max)s\n'
'nexp = %(nexp)6s min = -max\n'
+ 'smallest_normal = %(_str_smallest_normal)s '
+ 'smallest_subnormal = %(_str_smallest_subnormal)s\n'
'---------------------------------------------------------------\n'
)
return fmt % self.__dict__
@@ -457,6 +535,46 @@ class finfo:
return (("%(klass)s(resolution=%(resolution)s, min=-%(_str_max)s,"
" max=%(_str_max)s, dtype=%(dtype)s)") % d)
+ @property
+ def smallest_normal(self):
+ """Return the value for the smallest normal.
+
+ Returns
+ -------
+ smallest_normal : float
+ Value for the smallest normal.
+
+ Warns
+ -----
+ UserWarning
+ If the calculated value for the smallest normal is requested for
+ double-double.
+ """
+ # This check is necessary because the value for smallest_normal is
+ # platform dependent for longdouble types.
+ if isnan(self.machar.smallest_normal.flat[0]):
+ warnings.warn(
+ 'The value of smallest normal is undefined for double double',
+ UserWarning, stacklevel=2)
+ return self.machar.smallest_normal.flat[0]
+
+ @property
+ def tiny(self):
+ """Return the value for tiny, alias of smallest_normal.
+
+ Returns
+ -------
+ tiny : float
+ Value for the smallest normal, alias of smallest_normal.
+
+ Warns
+ -----
+ UserWarning
+ If the calculated value for the smallest normal is requested for
+ double-double.
+ """
+ return self.smallest_normal
+
@set_module('numpy')
class iinfo:
diff --git a/numpy/core/getlimits.pyi b/numpy/core/getlimits.pyi
new file mode 100644
index 000000000..ca22e18f7
--- /dev/null
+++ b/numpy/core/getlimits.pyi
@@ -0,0 +1,58 @@
+from typing import Any, Generic, List, Type, TypeVar
+
+from numpy import (
+ finfo as finfo,
+ iinfo as iinfo,
+ floating,
+ signedinteger,
+)
+
+from numpy.typing import NBitBase, NDArray
+
+_NBit = TypeVar("_NBit", bound=NBitBase)
+
+__all__: List[str]
+
+class MachArLike(Generic[_NBit]):
+ def __init__(
+ self,
+ ftype: Type[floating[_NBit]],
+ *,
+ eps: floating[Any],
+ epsneg: floating[Any],
+ huge: floating[Any],
+ tiny: floating[Any],
+ ibeta: int,
+ smallest_subnormal: None | floating[Any] = ...,
+ # Expand `**kwargs` into keyword-only arguments
+ machep: int,
+ negep: int,
+ minexp: int,
+ maxexp: int,
+ it: int,
+ iexp: int,
+ irnd: int,
+ ngrd: int,
+ ) -> None: ...
+ @property
+ def smallest_subnormal(self) -> NDArray[floating[_NBit]]: ...
+ eps: NDArray[floating[_NBit]]
+ epsilon: NDArray[floating[_NBit]]
+ epsneg: NDArray[floating[_NBit]]
+ huge: NDArray[floating[_NBit]]
+ ibeta: signedinteger[_NBit]
+ iexp: int
+ irnd: int
+ it: int
+ machep: int
+ maxexp: int
+ minexp: int
+ negep: int
+ ngrd: int
+ precision: int
+ resolution: NDArray[floating[_NBit]]
+ smallest_normal: NDArray[floating[_NBit]]
+ tiny: NDArray[floating[_NBit]]
+ title: str
+ xmax: NDArray[floating[_NBit]]
+ xmin: NDArray[floating[_NBit]]
diff --git a/numpy/core/include/numpy/libdivide/LICENSE.txt b/numpy/core/include/numpy/libdivide/LICENSE.txt
new file mode 100644
index 000000000..d72a7c388
--- /dev/null
+++ b/numpy/core/include/numpy/libdivide/LICENSE.txt
@@ -0,0 +1,21 @@
+ zlib License
+ ------------
+
+ Copyright (C) 2010 - 2019 ridiculous_fish, <libdivide@ridiculousfish.com>
+ Copyright (C) 2016 - 2019 Kim Walisch, <kim.walisch@gmail.com>
+
+ This software is provided 'as-is', without any express or implied
+ warranty. In no event will the authors be held liable for any damages
+ arising from the use of this software.
+
+ Permission is granted to anyone to use this software for any purpose,
+ including commercial applications, and to alter it and redistribute it
+ freely, subject to the following restrictions:
+
+ 1. The origin of this software must not be misrepresented; you must not
+ claim that you wrote the original software. If you use this software
+ in a product, an acknowledgment in the product documentation would be
+ appreciated but is not required.
+ 2. Altered source versions must be plainly marked as such, and must not be
+ misrepresented as being the original software.
+ 3. This notice may not be removed or altered from any source distribution.
diff --git a/numpy/core/include/numpy/libdivide/libdivide.h b/numpy/core/include/numpy/libdivide/libdivide.h
new file mode 100644
index 000000000..81057b7b4
--- /dev/null
+++ b/numpy/core/include/numpy/libdivide/libdivide.h
@@ -0,0 +1,2079 @@
+// libdivide.h - Optimized integer division
+// https://libdivide.com
+//
+// Copyright (C) 2010 - 2019 ridiculous_fish, <libdivide@ridiculousfish.com>
+// Copyright (C) 2016 - 2019 Kim Walisch, <kim.walisch@gmail.com>
+//
+// libdivide is dual-licensed under the Boost or zlib licenses.
+// You may use libdivide under the terms of either of these.
+// See LICENSE.txt for more details.
+
+#ifndef LIBDIVIDE_H
+#define LIBDIVIDE_H
+
+#define LIBDIVIDE_VERSION "3.0"
+#define LIBDIVIDE_VERSION_MAJOR 3
+#define LIBDIVIDE_VERSION_MINOR 0
+
+#include <stdint.h>
+
+#if defined(__cplusplus)
+ #include <cstdlib>
+ #include <cstdio>
+ #include <type_traits>
+#else
+ #include <stdlib.h>
+ #include <stdio.h>
+#endif
+
+#if defined(LIBDIVIDE_AVX512)
+ #include <immintrin.h>
+#elif defined(LIBDIVIDE_AVX2)
+ #include <immintrin.h>
+#elif defined(LIBDIVIDE_SSE2)
+ #include <emmintrin.h>
+#endif
+
+#if defined(_MSC_VER)
+ #include <intrin.h>
+ // disable warning C4146: unary minus operator applied
+ // to unsigned type, result still unsigned
+ #pragma warning(disable: 4146)
+ #define LIBDIVIDE_VC
+#endif
+
+#if !defined(__has_builtin)
+ #define __has_builtin(x) 0
+#endif
+
+#if defined(__SIZEOF_INT128__)
+ #define HAS_INT128_T
+ // clang-cl on Windows does not yet support 128-bit division
+ #if !(defined(__clang__) && defined(LIBDIVIDE_VC))
+ #define HAS_INT128_DIV
+ #endif
+#endif
+
+#if defined(__x86_64__) || defined(_M_X64)
+ #define LIBDIVIDE_X86_64
+#endif
+
+#if defined(__i386__)
+ #define LIBDIVIDE_i386
+#endif
+
+#if defined(__GNUC__) || defined(__clang__)
+ #define LIBDIVIDE_GCC_STYLE_ASM
+#endif
+
+#if defined(__cplusplus) || defined(LIBDIVIDE_VC)
+ #define LIBDIVIDE_FUNCTION __FUNCTION__
+#else
+ #define LIBDIVIDE_FUNCTION __func__
+#endif
+
+#define LIBDIVIDE_ERROR(msg) \
+ do { \
+ fprintf(stderr, "libdivide.h:%d: %s(): Error: %s\n", \
+ __LINE__, LIBDIVIDE_FUNCTION, msg); \
+ abort(); \
+ } while (0)
+
+#if defined(LIBDIVIDE_ASSERTIONS_ON)
+ #define LIBDIVIDE_ASSERT(x) \
+ do { \
+ if (!(x)) { \
+ fprintf(stderr, "libdivide.h:%d: %s(): Assertion failed: %s\n", \
+ __LINE__, LIBDIVIDE_FUNCTION, #x); \
+ abort(); \
+ } \
+ } while (0)
+#else
+ #define LIBDIVIDE_ASSERT(x)
+#endif
+
+#ifdef __cplusplus
+namespace libdivide {
+#endif
+
+// pack divider structs to prevent compilers from padding.
+// This reduces memory usage by up to 43% when using a large
+// array of libdivide dividers and improves performance
+// by up to 10% because of reduced memory bandwidth.
+#pragma pack(push, 1)
+
+struct libdivide_u32_t {
+ uint32_t magic;
+ uint8_t more;
+};
+
+struct libdivide_s32_t {
+ int32_t magic;
+ uint8_t more;
+};
+
+struct libdivide_u64_t {
+ uint64_t magic;
+ uint8_t more;
+};
+
+struct libdivide_s64_t {
+ int64_t magic;
+ uint8_t more;
+};
+
+struct libdivide_u32_branchfree_t {
+ uint32_t magic;
+ uint8_t more;
+};
+
+struct libdivide_s32_branchfree_t {
+ int32_t magic;
+ uint8_t more;
+};
+
+struct libdivide_u64_branchfree_t {
+ uint64_t magic;
+ uint8_t more;
+};
+
+struct libdivide_s64_branchfree_t {
+ int64_t magic;
+ uint8_t more;
+};
+
+#pragma pack(pop)
+
+// Explanation of the "more" field:
+//
+// * Bits 0-5 is the shift value (for shift path or mult path).
+// * Bit 6 is the add indicator for mult path.
+// * Bit 7 is set if the divisor is negative. We use bit 7 as the negative
+// divisor indicator so that we can efficiently use sign extension to
+// create a bitmask with all bits set to 1 (if the divisor is negative)
+// or 0 (if the divisor is positive).
+//
+// u32: [0-4] shift value
+// [5] ignored
+// [6] add indicator
+// magic number of 0 indicates shift path
+//
+// s32: [0-4] shift value
+// [5] ignored
+// [6] add indicator
+// [7] indicates negative divisor
+// magic number of 0 indicates shift path
+//
+// u64: [0-5] shift value
+// [6] add indicator
+// magic number of 0 indicates shift path
+//
+// s64: [0-5] shift value
+// [6] add indicator
+// [7] indicates negative divisor
+// magic number of 0 indicates shift path
+//
+// In s32 and s64 branchfree modes, the magic number is negated according to
+// whether the divisor is negated. In branchfree strategy, it is not negated.
+
+enum {
+ LIBDIVIDE_32_SHIFT_MASK = 0x1F,
+ LIBDIVIDE_64_SHIFT_MASK = 0x3F,
+ LIBDIVIDE_ADD_MARKER = 0x40,
+ LIBDIVIDE_NEGATIVE_DIVISOR = 0x80
+};
+
+static inline struct libdivide_s32_t libdivide_s32_gen(int32_t d);
+static inline struct libdivide_u32_t libdivide_u32_gen(uint32_t d);
+static inline struct libdivide_s64_t libdivide_s64_gen(int64_t d);
+static inline struct libdivide_u64_t libdivide_u64_gen(uint64_t d);
+
+static inline struct libdivide_s32_branchfree_t libdivide_s32_branchfree_gen(int32_t d);
+static inline struct libdivide_u32_branchfree_t libdivide_u32_branchfree_gen(uint32_t d);
+static inline struct libdivide_s64_branchfree_t libdivide_s64_branchfree_gen(int64_t d);
+static inline struct libdivide_u64_branchfree_t libdivide_u64_branchfree_gen(uint64_t d);
+
+static inline int32_t libdivide_s32_do(int32_t numer, const struct libdivide_s32_t *denom);
+static inline uint32_t libdivide_u32_do(uint32_t numer, const struct libdivide_u32_t *denom);
+static inline int64_t libdivide_s64_do(int64_t numer, const struct libdivide_s64_t *denom);
+static inline uint64_t libdivide_u64_do(uint64_t numer, const struct libdivide_u64_t *denom);
+
+static inline int32_t libdivide_s32_branchfree_do(int32_t numer, const struct libdivide_s32_branchfree_t *denom);
+static inline uint32_t libdivide_u32_branchfree_do(uint32_t numer, const struct libdivide_u32_branchfree_t *denom);
+static inline int64_t libdivide_s64_branchfree_do(int64_t numer, const struct libdivide_s64_branchfree_t *denom);
+static inline uint64_t libdivide_u64_branchfree_do(uint64_t numer, const struct libdivide_u64_branchfree_t *denom);
+
+static inline int32_t libdivide_s32_recover(const struct libdivide_s32_t *denom);
+static inline uint32_t libdivide_u32_recover(const struct libdivide_u32_t *denom);
+static inline int64_t libdivide_s64_recover(const struct libdivide_s64_t *denom);
+static inline uint64_t libdivide_u64_recover(const struct libdivide_u64_t *denom);
+
+static inline int32_t libdivide_s32_branchfree_recover(const struct libdivide_s32_branchfree_t *denom);
+static inline uint32_t libdivide_u32_branchfree_recover(const struct libdivide_u32_branchfree_t *denom);
+static inline int64_t libdivide_s64_branchfree_recover(const struct libdivide_s64_branchfree_t *denom);
+static inline uint64_t libdivide_u64_branchfree_recover(const struct libdivide_u64_branchfree_t *denom);
+
+//////// Internal Utility Functions
+
+static inline uint32_t libdivide_mullhi_u32(uint32_t x, uint32_t y) {
+ uint64_t xl = x, yl = y;
+ uint64_t rl = xl * yl;
+ return (uint32_t)(rl >> 32);
+}
+
+static inline int32_t libdivide_mullhi_s32(int32_t x, int32_t y) {
+ int64_t xl = x, yl = y;
+ int64_t rl = xl * yl;
+ // needs to be arithmetic shift
+ return (int32_t)(rl >> 32);
+}
+
+static inline uint64_t libdivide_mullhi_u64(uint64_t x, uint64_t y) {
+#if defined(LIBDIVIDE_VC) && \
+ defined(LIBDIVIDE_X86_64)
+ return __umulh(x, y);
+#elif defined(HAS_INT128_T)
+ __uint128_t xl = x, yl = y;
+ __uint128_t rl = xl * yl;
+ return (uint64_t)(rl >> 64);
+#else
+ // full 128 bits are x0 * y0 + (x0 * y1 << 32) + (x1 * y0 << 32) + (x1 * y1 << 64)
+ uint32_t mask = 0xFFFFFFFF;
+ uint32_t x0 = (uint32_t)(x & mask);
+ uint32_t x1 = (uint32_t)(x >> 32);
+ uint32_t y0 = (uint32_t)(y & mask);
+ uint32_t y1 = (uint32_t)(y >> 32);
+ uint32_t x0y0_hi = libdivide_mullhi_u32(x0, y0);
+ uint64_t x0y1 = x0 * (uint64_t)y1;
+ uint64_t x1y0 = x1 * (uint64_t)y0;
+ uint64_t x1y1 = x1 * (uint64_t)y1;
+ uint64_t temp = x1y0 + x0y0_hi;
+ uint64_t temp_lo = temp & mask;
+ uint64_t temp_hi = temp >> 32;
+
+ return x1y1 + temp_hi + ((temp_lo + x0y1) >> 32);
+#endif
+}
+
+static inline int64_t libdivide_mullhi_s64(int64_t x, int64_t y) {
+#if defined(LIBDIVIDE_VC) && \
+ defined(LIBDIVIDE_X86_64)
+ return __mulh(x, y);
+#elif defined(HAS_INT128_T)
+ __int128_t xl = x, yl = y;
+ __int128_t rl = xl * yl;
+ return (int64_t)(rl >> 64);
+#else
+ // full 128 bits are x0 * y0 + (x0 * y1 << 32) + (x1 * y0 << 32) + (x1 * y1 << 64)
+ uint32_t mask = 0xFFFFFFFF;
+ uint32_t x0 = (uint32_t)(x & mask);
+ uint32_t y0 = (uint32_t)(y & mask);
+ int32_t x1 = (int32_t)(x >> 32);
+ int32_t y1 = (int32_t)(y >> 32);
+ uint32_t x0y0_hi = libdivide_mullhi_u32(x0, y0);
+ int64_t t = x1 * (int64_t)y0 + x0y0_hi;
+ int64_t w1 = x0 * (int64_t)y1 + (t & mask);
+
+ return x1 * (int64_t)y1 + (t >> 32) + (w1 >> 32);
+#endif
+}
+
+static inline int32_t libdivide_count_leading_zeros32(uint32_t val) {
+#if defined(__GNUC__) || \
+ __has_builtin(__builtin_clz)
+ // Fast way to count leading zeros
+ return __builtin_clz(val);
+#elif defined(LIBDIVIDE_VC)
+ unsigned long result;
+ if (_BitScanReverse(&result, val)) {
+ return 31 - result;
+ }
+ return 0;
+#else
+ if (val == 0)
+ return 32;
+ int32_t result = 8;
+ uint32_t hi = 0xFFU << 24;
+ while ((val & hi) == 0) {
+ hi >>= 8;
+ result += 8;
+ }
+ while (val & hi) {
+ result -= 1;
+ hi <<= 1;
+ }
+ return result;
+#endif
+}
+
+static inline int32_t libdivide_count_leading_zeros64(uint64_t val) {
+#if defined(__GNUC__) || \
+ __has_builtin(__builtin_clzll)
+ // Fast way to count leading zeros
+ return __builtin_clzll(val);
+#elif defined(LIBDIVIDE_VC) && defined(_WIN64)
+ unsigned long result;
+ if (_BitScanReverse64(&result, val)) {
+ return 63 - result;
+ }
+ return 0;
+#else
+ uint32_t hi = val >> 32;
+ uint32_t lo = val & 0xFFFFFFFF;
+ if (hi != 0) return libdivide_count_leading_zeros32(hi);
+ return 32 + libdivide_count_leading_zeros32(lo);
+#endif
+}
+
+// libdivide_64_div_32_to_32: divides a 64-bit uint {u1, u0} by a 32-bit
+// uint {v}. The result must fit in 32 bits.
+// Returns the quotient directly and the remainder in *r
+static inline uint32_t libdivide_64_div_32_to_32(uint32_t u1, uint32_t u0, uint32_t v, uint32_t *r) {
+#if (defined(LIBDIVIDE_i386) || defined(LIBDIVIDE_X86_64)) && \
+ defined(LIBDIVIDE_GCC_STYLE_ASM)
+ uint32_t result;
+ __asm__("divl %[v]"
+ : "=a"(result), "=d"(*r)
+ : [v] "r"(v), "a"(u0), "d"(u1)
+ );
+ return result;
+#else
+ uint64_t n = ((uint64_t)u1 << 32) | u0;
+ uint32_t result = (uint32_t)(n / v);
+ *r = (uint32_t)(n - result * (uint64_t)v);
+ return result;
+#endif
+}
+
+// libdivide_128_div_64_to_64: divides a 128-bit uint {u1, u0} by a 64-bit
+// uint {v}. The result must fit in 64 bits.
+// Returns the quotient directly and the remainder in *r
+static uint64_t libdivide_128_div_64_to_64(uint64_t u1, uint64_t u0, uint64_t v, uint64_t *r) {
+#if defined(LIBDIVIDE_X86_64) && \
+ defined(LIBDIVIDE_GCC_STYLE_ASM)
+ uint64_t result;
+ __asm__("divq %[v]"
+ : "=a"(result), "=d"(*r)
+ : [v] "r"(v), "a"(u0), "d"(u1)
+ );
+ return result;
+#elif defined(HAS_INT128_T) && \
+ defined(HAS_INT128_DIV)
+ __uint128_t n = ((__uint128_t)u1 << 64) | u0;
+ uint64_t result = (uint64_t)(n / v);
+ *r = (uint64_t)(n - result * (__uint128_t)v);
+ return result;
+#else
+ // Code taken from Hacker's Delight:
+ // http://www.hackersdelight.org/HDcode/divlu.c.
+ // License permits inclusion here per:
+ // http://www.hackersdelight.org/permissions.htm
+
+ const uint64_t b = (1ULL << 32); // Number base (32 bits)
+ uint64_t un1, un0; // Norm. dividend LSD's
+ uint64_t vn1, vn0; // Norm. divisor digits
+ uint64_t q1, q0; // Quotient digits
+ uint64_t un64, un21, un10; // Dividend digit pairs
+ uint64_t rhat; // A remainder
+ int32_t s; // Shift amount for norm
+
+ // If overflow, set rem. to an impossible value,
+ // and return the largest possible quotient
+ if (u1 >= v) {
+ *r = (uint64_t) -1;
+ return (uint64_t) -1;
+ }
+
+ // count leading zeros
+ s = libdivide_count_leading_zeros64(v);
+ if (s > 0) {
+ // Normalize divisor
+ v = v << s;
+ un64 = (u1 << s) | (u0 >> (64 - s));
+ un10 = u0 << s; // Shift dividend left
+ } else {
+ // Avoid undefined behavior of (u0 >> 64).
+ // The behavior is undefined if the right operand is
+ // negative, or greater than or equal to the length
+ // in bits of the promoted left operand.
+ un64 = u1;
+ un10 = u0;
+ }
+
+ // Break divisor up into two 32-bit digits
+ vn1 = v >> 32;
+ vn0 = v & 0xFFFFFFFF;
+
+ // Break right half of dividend into two digits
+ un1 = un10 >> 32;
+ un0 = un10 & 0xFFFFFFFF;
+
+ // Compute the first quotient digit, q1
+ q1 = un64 / vn1;
+ rhat = un64 - q1 * vn1;
+
+ while (q1 >= b || q1 * vn0 > b * rhat + un1) {
+ q1 = q1 - 1;
+ rhat = rhat + vn1;
+ if (rhat >= b)
+ break;
+ }
+
+ // Multiply and subtract
+ un21 = un64 * b + un1 - q1 * v;
+
+ // Compute the second quotient digit
+ q0 = un21 / vn1;
+ rhat = un21 - q0 * vn1;
+
+ while (q0 >= b || q0 * vn0 > b * rhat + un0) {
+ q0 = q0 - 1;
+ rhat = rhat + vn1;
+ if (rhat >= b)
+ break;
+ }
+
+ *r = (un21 * b + un0 - q0 * v) >> s;
+ return q1 * b + q0;
+#endif
+}
+
+// Bitshift a u128 in place, left (signed_shift > 0) or right (signed_shift < 0)
+static inline void libdivide_u128_shift(uint64_t *u1, uint64_t *u0, int32_t signed_shift) {
+ if (signed_shift > 0) {
+ uint32_t shift = signed_shift;
+ *u1 <<= shift;
+ *u1 |= *u0 >> (64 - shift);
+ *u0 <<= shift;
+ }
+ else if (signed_shift < 0) {
+ uint32_t shift = -signed_shift;
+ *u0 >>= shift;
+ *u0 |= *u1 << (64 - shift);
+ *u1 >>= shift;
+ }
+}
+
+// Computes a 128 / 128 -> 64 bit division, with a 128 bit remainder.
+static uint64_t libdivide_128_div_128_to_64(uint64_t u_hi, uint64_t u_lo, uint64_t v_hi, uint64_t v_lo, uint64_t *r_hi, uint64_t *r_lo) {
+#if defined(HAS_INT128_T) && \
+ defined(HAS_INT128_DIV)
+ __uint128_t ufull = u_hi;
+ __uint128_t vfull = v_hi;
+ ufull = (ufull << 64) | u_lo;
+ vfull = (vfull << 64) | v_lo;
+ uint64_t res = (uint64_t)(ufull / vfull);
+ __uint128_t remainder = ufull - (vfull * res);
+ *r_lo = (uint64_t)remainder;
+ *r_hi = (uint64_t)(remainder >> 64);
+ return res;
+#else
+ // Adapted from "Unsigned Doubleword Division" in Hacker's Delight
+ // We want to compute u / v
+ typedef struct { uint64_t hi; uint64_t lo; } u128_t;
+ u128_t u = {u_hi, u_lo};
+ u128_t v = {v_hi, v_lo};
+
+ if (v.hi == 0) {
+ // divisor v is a 64 bit value, so we just need one 128/64 division
+ // Note that we are simpler than Hacker's Delight here, because we know
+ // the quotient fits in 64 bits whereas Hacker's Delight demands a full
+ // 128 bit quotient
+ *r_hi = 0;
+ return libdivide_128_div_64_to_64(u.hi, u.lo, v.lo, r_lo);
+ }
+ // Here v >= 2**64
+ // We know that v.hi != 0, so count leading zeros is OK
+ // We have 0 <= n <= 63
+ uint32_t n = libdivide_count_leading_zeros64(v.hi);
+
+ // Normalize the divisor so its MSB is 1
+ u128_t v1t = v;
+ libdivide_u128_shift(&v1t.hi, &v1t.lo, n);
+ uint64_t v1 = v1t.hi; // i.e. v1 = v1t >> 64
+
+ // To ensure no overflow
+ u128_t u1 = u;
+ libdivide_u128_shift(&u1.hi, &u1.lo, -1);
+
+ // Get quotient from divide unsigned insn.
+ uint64_t rem_ignored;
+ uint64_t q1 = libdivide_128_div_64_to_64(u1.hi, u1.lo, v1, &rem_ignored);
+
+ // Undo normalization and division of u by 2.
+ u128_t q0 = {0, q1};
+ libdivide_u128_shift(&q0.hi, &q0.lo, n);
+ libdivide_u128_shift(&q0.hi, &q0.lo, -63);
+
+ // Make q0 correct or too small by 1
+ // Equivalent to `if (q0 != 0) q0 = q0 - 1;`
+ if (q0.hi != 0 || q0.lo != 0) {
+ q0.hi -= (q0.lo == 0); // borrow
+ q0.lo -= 1;
+ }
+
+ // Now q0 is correct.
+ // Compute q0 * v as q0v
+ // = (q0.hi << 64 + q0.lo) * (v.hi << 64 + v.lo)
+ // = (q0.hi * v.hi << 128) + (q0.hi * v.lo << 64) +
+ // (q0.lo * v.hi << 64) + q0.lo * v.lo)
+ // Each term is 128 bit
+ // High half of full product (upper 128 bits!) are dropped
+ u128_t q0v = {0, 0};
+ q0v.hi = q0.hi*v.lo + q0.lo*v.hi + libdivide_mullhi_u64(q0.lo, v.lo);
+ q0v.lo = q0.lo*v.lo;
+
+ // Compute u - q0v as u_q0v
+ // This is the remainder
+ u128_t u_q0v = u;
+ u_q0v.hi -= q0v.hi + (u.lo < q0v.lo); // second term is borrow
+ u_q0v.lo -= q0v.lo;
+
+ // Check if u_q0v >= v
+ // This checks if our remainder is larger than the divisor
+ if ((u_q0v.hi > v.hi) ||
+ (u_q0v.hi == v.hi && u_q0v.lo >= v.lo)) {
+ // Increment q0
+ q0.lo += 1;
+ q0.hi += (q0.lo == 0); // carry
+
+ // Subtract v from remainder
+ u_q0v.hi -= v.hi + (u_q0v.lo < v.lo);
+ u_q0v.lo -= v.lo;
+ }
+
+ *r_hi = u_q0v.hi;
+ *r_lo = u_q0v.lo;
+
+ LIBDIVIDE_ASSERT(q0.hi == 0);
+ return q0.lo;
+#endif
+}
+
+////////// UINT32
+
+static inline struct libdivide_u32_t libdivide_internal_u32_gen(uint32_t d, int branchfree) {
+ if (d == 0) {
+ LIBDIVIDE_ERROR("divider must be != 0");
+ }
+
+ struct libdivide_u32_t result;
+ uint32_t floor_log_2_d = 31 - libdivide_count_leading_zeros32(d);
+
+ // Power of 2
+ if ((d & (d - 1)) == 0) {
+ // We need to subtract 1 from the shift value in case of an unsigned
+ // branchfree divider because there is a hardcoded right shift by 1
+ // in its division algorithm. Because of this we also need to add back
+ // 1 in its recovery algorithm.
+ result.magic = 0;
+ result.more = (uint8_t)(floor_log_2_d - (branchfree != 0));
+ } else {
+ uint8_t more;
+ uint32_t rem, proposed_m;
+ proposed_m = libdivide_64_div_32_to_32(1U << floor_log_2_d, 0, d, &rem);
+
+ LIBDIVIDE_ASSERT(rem > 0 && rem < d);
+ const uint32_t e = d - rem;
+
+ // This power works if e < 2**floor_log_2_d.
+ if (!branchfree && (e < (1U << floor_log_2_d))) {
+ // This power works
+ more = floor_log_2_d;
+ } else {
+ // We have to use the general 33-bit algorithm. We need to compute
+ // (2**power) / d. However, we already have (2**(power-1))/d and
+ // its remainder. By doubling both, and then correcting the
+ // remainder, we can compute the larger division.
+ // don't care about overflow here - in fact, we expect it
+ proposed_m += proposed_m;
+ const uint32_t twice_rem = rem + rem;
+ if (twice_rem >= d || twice_rem < rem) proposed_m += 1;
+ more = floor_log_2_d | LIBDIVIDE_ADD_MARKER;
+ }
+ result.magic = 1 + proposed_m;
+ result.more = more;
+ // result.more's shift should in general be ceil_log_2_d. But if we
+ // used the smaller power, we subtract one from the shift because we're
+ // using the smaller power. If we're using the larger power, we
+ // subtract one from the shift because it's taken care of by the add
+ // indicator. So floor_log_2_d happens to be correct in both cases.
+ }
+ return result;
+}
+
+struct libdivide_u32_t libdivide_u32_gen(uint32_t d) {
+ return libdivide_internal_u32_gen(d, 0);
+}
+
+struct libdivide_u32_branchfree_t libdivide_u32_branchfree_gen(uint32_t d) {
+ if (d == 1) {
+ LIBDIVIDE_ERROR("branchfree divider must be != 1");
+ }
+ struct libdivide_u32_t tmp = libdivide_internal_u32_gen(d, 1);
+ struct libdivide_u32_branchfree_t ret = {tmp.magic, (uint8_t)(tmp.more & LIBDIVIDE_32_SHIFT_MASK)};
+ return ret;
+}
+
+uint32_t libdivide_u32_do(uint32_t numer, const struct libdivide_u32_t *denom) {
+ uint8_t more = denom->more;
+ if (!denom->magic) {
+ return numer >> more;
+ }
+ else {
+ uint32_t q = libdivide_mullhi_u32(denom->magic, numer);
+ if (more & LIBDIVIDE_ADD_MARKER) {
+ uint32_t t = ((numer - q) >> 1) + q;
+ return t >> (more & LIBDIVIDE_32_SHIFT_MASK);
+ }
+ else {
+ // All upper bits are 0,
+ // don't need to mask them off.
+ return q >> more;
+ }
+ }
+}
+
+uint32_t libdivide_u32_branchfree_do(uint32_t numer, const struct libdivide_u32_branchfree_t *denom) {
+ uint32_t q = libdivide_mullhi_u32(denom->magic, numer);
+ uint32_t t = ((numer - q) >> 1) + q;
+ return t >> denom->more;
+}
+
+uint32_t libdivide_u32_recover(const struct libdivide_u32_t *denom) {
+ uint8_t more = denom->more;
+ uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
+
+ if (!denom->magic) {
+ return 1U << shift;
+ } else if (!(more & LIBDIVIDE_ADD_MARKER)) {
+ // We compute q = n/d = n*m / 2^(32 + shift)
+ // Therefore we have d = 2^(32 + shift) / m
+ // We need to ceil it.
+ // We know d is not a power of 2, so m is not a power of 2,
+ // so we can just add 1 to the floor
+ uint32_t hi_dividend = 1U << shift;
+ uint32_t rem_ignored;
+ return 1 + libdivide_64_div_32_to_32(hi_dividend, 0, denom->magic, &rem_ignored);
+ } else {
+ // Here we wish to compute d = 2^(32+shift+1)/(m+2^32).
+ // Notice (m + 2^32) is a 33 bit number. Use 64 bit division for now
+ // Also note that shift may be as high as 31, so shift + 1 will
+ // overflow. So we have to compute it as 2^(32+shift)/(m+2^32), and
+ // then double the quotient and remainder.
+ uint64_t half_n = 1ULL << (32 + shift);
+ uint64_t d = (1ULL << 32) | denom->magic;
+ // Note that the quotient is guaranteed <= 32 bits, but the remainder
+ // may need 33!
+ uint32_t half_q = (uint32_t)(half_n / d);
+ uint64_t rem = half_n % d;
+ // We computed 2^(32+shift)/(m+2^32)
+ // Need to double it, and then add 1 to the quotient if doubling th
+ // remainder would increase the quotient.
+ // Note that rem<<1 cannot overflow, since rem < d and d is 33 bits
+ uint32_t full_q = half_q + half_q + ((rem<<1) >= d);
+
+ // We rounded down in gen (hence +1)
+ return full_q + 1;
+ }
+}
+
+uint32_t libdivide_u32_branchfree_recover(const struct libdivide_u32_branchfree_t *denom) {
+ uint8_t more = denom->more;
+ uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
+
+ if (!denom->magic) {
+ return 1U << (shift + 1);
+ } else {
+ // Here we wish to compute d = 2^(32+shift+1)/(m+2^32).
+ // Notice (m + 2^32) is a 33 bit number. Use 64 bit division for now
+ // Also note that shift may be as high as 31, so shift + 1 will
+ // overflow. So we have to compute it as 2^(32+shift)/(m+2^32), and
+ // then double the quotient and remainder.
+ uint64_t half_n = 1ULL << (32 + shift);
+ uint64_t d = (1ULL << 32) | denom->magic;
+ // Note that the quotient is guaranteed <= 32 bits, but the remainder
+ // may need 33!
+ uint32_t half_q = (uint32_t)(half_n / d);
+ uint64_t rem = half_n % d;
+ // We computed 2^(32+shift)/(m+2^32)
+ // Need to double it, and then add 1 to the quotient if doubling th
+ // remainder would increase the quotient.
+ // Note that rem<<1 cannot overflow, since rem < d and d is 33 bits
+ uint32_t full_q = half_q + half_q + ((rem<<1) >= d);
+
+ // We rounded down in gen (hence +1)
+ return full_q + 1;
+ }
+}
+
+/////////// UINT64
+
+static inline struct libdivide_u64_t libdivide_internal_u64_gen(uint64_t d, int branchfree) {
+ if (d == 0) {
+ LIBDIVIDE_ERROR("divider must be != 0");
+ }
+
+ struct libdivide_u64_t result;
+ uint32_t floor_log_2_d = 63 - libdivide_count_leading_zeros64(d);
+
+ // Power of 2
+ if ((d & (d - 1)) == 0) {
+ // We need to subtract 1 from the shift value in case of an unsigned
+ // branchfree divider because there is a hardcoded right shift by 1
+ // in its division algorithm. Because of this we also need to add back
+ // 1 in its recovery algorithm.
+ result.magic = 0;
+ result.more = (uint8_t)(floor_log_2_d - (branchfree != 0));
+ } else {
+ uint64_t proposed_m, rem;
+ uint8_t more;
+ // (1 << (64 + floor_log_2_d)) / d
+ proposed_m = libdivide_128_div_64_to_64(1ULL << floor_log_2_d, 0, d, &rem);
+
+ LIBDIVIDE_ASSERT(rem > 0 && rem < d);
+ const uint64_t e = d - rem;
+
+ // This power works if e < 2**floor_log_2_d.
+ if (!branchfree && e < (1ULL << floor_log_2_d)) {
+ // This power works
+ more = floor_log_2_d;
+ } else {
+ // We have to use the general 65-bit algorithm. We need to compute
+ // (2**power) / d. However, we already have (2**(power-1))/d and
+ // its remainder. By doubling both, and then correcting the
+ // remainder, we can compute the larger division.
+ // don't care about overflow here - in fact, we expect it
+ proposed_m += proposed_m;
+ const uint64_t twice_rem = rem + rem;
+ if (twice_rem >= d || twice_rem < rem) proposed_m += 1;
+ more = floor_log_2_d | LIBDIVIDE_ADD_MARKER;
+ }
+ result.magic = 1 + proposed_m;
+ result.more = more;
+ // result.more's shift should in general be ceil_log_2_d. But if we
+ // used the smaller power, we subtract one from the shift because we're
+ // using the smaller power. If we're using the larger power, we
+ // subtract one from the shift because it's taken care of by the add
+ // indicator. So floor_log_2_d happens to be correct in both cases,
+ // which is why we do it outside of the if statement.
+ }
+ return result;
+}
+
+struct libdivide_u64_t libdivide_u64_gen(uint64_t d) {
+ return libdivide_internal_u64_gen(d, 0);
+}
+
+struct libdivide_u64_branchfree_t libdivide_u64_branchfree_gen(uint64_t d) {
+ if (d == 1) {
+ LIBDIVIDE_ERROR("branchfree divider must be != 1");
+ }
+ struct libdivide_u64_t tmp = libdivide_internal_u64_gen(d, 1);
+ struct libdivide_u64_branchfree_t ret = {tmp.magic, (uint8_t)(tmp.more & LIBDIVIDE_64_SHIFT_MASK)};
+ return ret;
+}
+
+uint64_t libdivide_u64_do(uint64_t numer, const struct libdivide_u64_t *denom) {
+ uint8_t more = denom->more;
+ if (!denom->magic) {
+ return numer >> more;
+ }
+ else {
+ uint64_t q = libdivide_mullhi_u64(denom->magic, numer);
+ if (more & LIBDIVIDE_ADD_MARKER) {
+ uint64_t t = ((numer - q) >> 1) + q;
+ return t >> (more & LIBDIVIDE_64_SHIFT_MASK);
+ }
+ else {
+ // All upper bits are 0,
+ // don't need to mask them off.
+ return q >> more;
+ }
+ }
+}
+
+uint64_t libdivide_u64_branchfree_do(uint64_t numer, const struct libdivide_u64_branchfree_t *denom) {
+ uint64_t q = libdivide_mullhi_u64(denom->magic, numer);
+ uint64_t t = ((numer - q) >> 1) + q;
+ return t >> denom->more;
+}
+
+uint64_t libdivide_u64_recover(const struct libdivide_u64_t *denom) {
+ uint8_t more = denom->more;
+ uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
+
+ if (!denom->magic) {
+ return 1ULL << shift;
+ } else if (!(more & LIBDIVIDE_ADD_MARKER)) {
+ // We compute q = n/d = n*m / 2^(64 + shift)
+ // Therefore we have d = 2^(64 + shift) / m
+ // We need to ceil it.
+ // We know d is not a power of 2, so m is not a power of 2,
+ // so we can just add 1 to the floor
+ uint64_t hi_dividend = 1ULL << shift;
+ uint64_t rem_ignored;
+ return 1 + libdivide_128_div_64_to_64(hi_dividend, 0, denom->magic, &rem_ignored);
+ } else {
+ // Here we wish to compute d = 2^(64+shift+1)/(m+2^64).
+ // Notice (m + 2^64) is a 65 bit number. This gets hairy. See
+ // libdivide_u32_recover for more on what we do here.
+ // TODO: do something better than 128 bit math
+
+ // Full n is a (potentially) 129 bit value
+ // half_n is a 128 bit value
+ // Compute the hi half of half_n. Low half is 0.
+ uint64_t half_n_hi = 1ULL << shift, half_n_lo = 0;
+ // d is a 65 bit value. The high bit is always set to 1.
+ const uint64_t d_hi = 1, d_lo = denom->magic;
+ // Note that the quotient is guaranteed <= 64 bits,
+ // but the remainder may need 65!
+ uint64_t r_hi, r_lo;
+ uint64_t half_q = libdivide_128_div_128_to_64(half_n_hi, half_n_lo, d_hi, d_lo, &r_hi, &r_lo);
+ // We computed 2^(64+shift)/(m+2^64)
+ // Double the remainder ('dr') and check if that is larger than d
+ // Note that d is a 65 bit value, so r1 is small and so r1 + r1
+ // cannot overflow
+ uint64_t dr_lo = r_lo + r_lo;
+ uint64_t dr_hi = r_hi + r_hi + (dr_lo < r_lo); // last term is carry
+ int dr_exceeds_d = (dr_hi > d_hi) || (dr_hi == d_hi && dr_lo >= d_lo);
+ uint64_t full_q = half_q + half_q + (dr_exceeds_d ? 1 : 0);
+ return full_q + 1;
+ }
+}
+
+uint64_t libdivide_u64_branchfree_recover(const struct libdivide_u64_branchfree_t *denom) {
+ uint8_t more = denom->more;
+ uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
+
+ if (!denom->magic) {
+ return 1ULL << (shift + 1);
+ } else {
+ // Here we wish to compute d = 2^(64+shift+1)/(m+2^64).
+ // Notice (m + 2^64) is a 65 bit number. This gets hairy. See
+ // libdivide_u32_recover for more on what we do here.
+ // TODO: do something better than 128 bit math
+
+ // Full n is a (potentially) 129 bit value
+ // half_n is a 128 bit value
+ // Compute the hi half of half_n. Low half is 0.
+ uint64_t half_n_hi = 1ULL << shift, half_n_lo = 0;
+ // d is a 65 bit value. The high bit is always set to 1.
+ const uint64_t d_hi = 1, d_lo = denom->magic;
+ // Note that the quotient is guaranteed <= 64 bits,
+ // but the remainder may need 65!
+ uint64_t r_hi, r_lo;
+ uint64_t half_q = libdivide_128_div_128_to_64(half_n_hi, half_n_lo, d_hi, d_lo, &r_hi, &r_lo);
+ // We computed 2^(64+shift)/(m+2^64)
+ // Double the remainder ('dr') and check if that is larger than d
+ // Note that d is a 65 bit value, so r1 is small and so r1 + r1
+ // cannot overflow
+ uint64_t dr_lo = r_lo + r_lo;
+ uint64_t dr_hi = r_hi + r_hi + (dr_lo < r_lo); // last term is carry
+ int dr_exceeds_d = (dr_hi > d_hi) || (dr_hi == d_hi && dr_lo >= d_lo);
+ uint64_t full_q = half_q + half_q + (dr_exceeds_d ? 1 : 0);
+ return full_q + 1;
+ }
+}
+
+/////////// SINT32
+
+static inline struct libdivide_s32_t libdivide_internal_s32_gen(int32_t d, int branchfree) {
+ if (d == 0) {
+ LIBDIVIDE_ERROR("divider must be != 0");
+ }
+
+ struct libdivide_s32_t result;
+
+ // If d is a power of 2, or negative a power of 2, we have to use a shift.
+ // This is especially important because the magic algorithm fails for -1.
+ // To check if d is a power of 2 or its inverse, it suffices to check
+ // whether its absolute value has exactly one bit set. This works even for
+ // INT_MIN, because abs(INT_MIN) == INT_MIN, and INT_MIN has one bit set
+ // and is a power of 2.
+ uint32_t ud = (uint32_t)d;
+ uint32_t absD = (d < 0) ? -ud : ud;
+ uint32_t floor_log_2_d = 31 - libdivide_count_leading_zeros32(absD);
+ // check if exactly one bit is set,
+ // don't care if absD is 0 since that's divide by zero
+ if ((absD & (absD - 1)) == 0) {
+ // Branchfree and normal paths are exactly the same
+ result.magic = 0;
+ result.more = floor_log_2_d | (d < 0 ? LIBDIVIDE_NEGATIVE_DIVISOR : 0);
+ } else {
+ LIBDIVIDE_ASSERT(floor_log_2_d >= 1);
+
+ uint8_t more;
+ // the dividend here is 2**(floor_log_2_d + 31), so the low 32 bit word
+ // is 0 and the high word is floor_log_2_d - 1
+ uint32_t rem, proposed_m;
+ proposed_m = libdivide_64_div_32_to_32(1U << (floor_log_2_d - 1), 0, absD, &rem);
+ const uint32_t e = absD - rem;
+
+ // We are going to start with a power of floor_log_2_d - 1.
+ // This works if works if e < 2**floor_log_2_d.
+ if (!branchfree && e < (1U << floor_log_2_d)) {
+ // This power works
+ more = floor_log_2_d - 1;
+ } else {
+ // We need to go one higher. This should not make proposed_m
+ // overflow, but it will make it negative when interpreted as an
+ // int32_t.
+ proposed_m += proposed_m;
+ const uint32_t twice_rem = rem + rem;
+ if (twice_rem >= absD || twice_rem < rem) proposed_m += 1;
+ more = floor_log_2_d | LIBDIVIDE_ADD_MARKER;
+ }
+
+ proposed_m += 1;
+ int32_t magic = (int32_t)proposed_m;
+
+ // Mark if we are negative. Note we only negate the magic number in the
+ // branchfull case.
+ if (d < 0) {
+ more |= LIBDIVIDE_NEGATIVE_DIVISOR;
+ if (!branchfree) {
+ magic = -magic;
+ }
+ }
+
+ result.more = more;
+ result.magic = magic;
+ }
+ return result;
+}
+
+struct libdivide_s32_t libdivide_s32_gen(int32_t d) {
+ return libdivide_internal_s32_gen(d, 0);
+}
+
+struct libdivide_s32_branchfree_t libdivide_s32_branchfree_gen(int32_t d) {
+ struct libdivide_s32_t tmp = libdivide_internal_s32_gen(d, 1);
+ struct libdivide_s32_branchfree_t result = {tmp.magic, tmp.more};
+ return result;
+}
+
+int32_t libdivide_s32_do(int32_t numer, const struct libdivide_s32_t *denom) {
+ uint8_t more = denom->more;
+ uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
+
+ if (!denom->magic) {
+ uint32_t sign = (int8_t)more >> 7;
+ uint32_t mask = (1U << shift) - 1;
+ uint32_t uq = numer + ((numer >> 31) & mask);
+ int32_t q = (int32_t)uq;
+ q >>= shift;
+ q = (q ^ sign) - sign;
+ return q;
+ } else {
+ uint32_t uq = (uint32_t)libdivide_mullhi_s32(denom->magic, numer);
+ if (more & LIBDIVIDE_ADD_MARKER) {
+ // must be arithmetic shift and then sign extend
+ int32_t sign = (int8_t)more >> 7;
+ // q += (more < 0 ? -numer : numer)
+ // cast required to avoid UB
+ uq += ((uint32_t)numer ^ sign) - sign;
+ }
+ int32_t q = (int32_t)uq;
+ q >>= shift;
+ q += (q < 0);
+ return q;
+ }
+}
+
+int32_t libdivide_s32_branchfree_do(int32_t numer, const struct libdivide_s32_branchfree_t *denom) {
+ uint8_t more = denom->more;
+ uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
+ // must be arithmetic shift and then sign extend
+ int32_t sign = (int8_t)more >> 7;
+ int32_t magic = denom->magic;
+ int32_t q = libdivide_mullhi_s32(magic, numer);
+ q += numer;
+
+ // If q is non-negative, we have nothing to do
+ // If q is negative, we want to add either (2**shift)-1 if d is a power of
+ // 2, or (2**shift) if it is not a power of 2
+ uint32_t is_power_of_2 = (magic == 0);
+ uint32_t q_sign = (uint32_t)(q >> 31);
+ q += q_sign & ((1U << shift) - is_power_of_2);
+
+ // Now arithmetic right shift
+ q >>= shift;
+ // Negate if needed
+ q = (q ^ sign) - sign;
+
+ return q;
+}
+
+int32_t libdivide_s32_recover(const struct libdivide_s32_t *denom) {
+ uint8_t more = denom->more;
+ uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
+ if (!denom->magic) {
+ uint32_t absD = 1U << shift;
+ if (more & LIBDIVIDE_NEGATIVE_DIVISOR) {
+ absD = -absD;
+ }
+ return (int32_t)absD;
+ } else {
+ // Unsigned math is much easier
+ // We negate the magic number only in the branchfull case, and we don't
+ // know which case we're in. However we have enough information to
+ // determine the correct sign of the magic number. The divisor was
+ // negative if LIBDIVIDE_NEGATIVE_DIVISOR is set. If ADD_MARKER is set,
+ // the magic number's sign is opposite that of the divisor.
+ // We want to compute the positive magic number.
+ int negative_divisor = (more & LIBDIVIDE_NEGATIVE_DIVISOR);
+ int magic_was_negated = (more & LIBDIVIDE_ADD_MARKER)
+ ? denom->magic > 0 : denom->magic < 0;
+
+ // Handle the power of 2 case (including branchfree)
+ if (denom->magic == 0) {
+ int32_t result = 1U << shift;
+ return negative_divisor ? -result : result;
+ }
+
+ uint32_t d = (uint32_t)(magic_was_negated ? -denom->magic : denom->magic);
+ uint64_t n = 1ULL << (32 + shift); // this shift cannot exceed 30
+ uint32_t q = (uint32_t)(n / d);
+ int32_t result = (int32_t)q;
+ result += 1;
+ return negative_divisor ? -result : result;
+ }
+}
+
+int32_t libdivide_s32_branchfree_recover(const struct libdivide_s32_branchfree_t *denom) {
+ return libdivide_s32_recover((const struct libdivide_s32_t *)denom);
+}
+
+///////////// SINT64
+
+static inline struct libdivide_s64_t libdivide_internal_s64_gen(int64_t d, int branchfree) {
+ if (d == 0) {
+ LIBDIVIDE_ERROR("divider must be != 0");
+ }
+
+ struct libdivide_s64_t result;
+
+ // If d is a power of 2, or negative a power of 2, we have to use a shift.
+ // This is especially important because the magic algorithm fails for -1.
+ // To check if d is a power of 2 or its inverse, it suffices to check
+ // whether its absolute value has exactly one bit set. This works even for
+ // INT_MIN, because abs(INT_MIN) == INT_MIN, and INT_MIN has one bit set
+ // and is a power of 2.
+ uint64_t ud = (uint64_t)d;
+ uint64_t absD = (d < 0) ? -ud : ud;
+ uint32_t floor_log_2_d = 63 - libdivide_count_leading_zeros64(absD);
+ // check if exactly one bit is set,
+ // don't care if absD is 0 since that's divide by zero
+ if ((absD & (absD - 1)) == 0) {
+ // Branchfree and non-branchfree cases are the same
+ result.magic = 0;
+ result.more = floor_log_2_d | (d < 0 ? LIBDIVIDE_NEGATIVE_DIVISOR : 0);
+ } else {
+ // the dividend here is 2**(floor_log_2_d + 63), so the low 64 bit word
+ // is 0 and the high word is floor_log_2_d - 1
+ uint8_t more;
+ uint64_t rem, proposed_m;
+ proposed_m = libdivide_128_div_64_to_64(1ULL << (floor_log_2_d - 1), 0, absD, &rem);
+ const uint64_t e = absD - rem;
+
+ // We are going to start with a power of floor_log_2_d - 1.
+ // This works if works if e < 2**floor_log_2_d.
+ if (!branchfree && e < (1ULL << floor_log_2_d)) {
+ // This power works
+ more = floor_log_2_d - 1;
+ } else {
+ // We need to go one higher. This should not make proposed_m
+ // overflow, but it will make it negative when interpreted as an
+ // int32_t.
+ proposed_m += proposed_m;
+ const uint64_t twice_rem = rem + rem;
+ if (twice_rem >= absD || twice_rem < rem) proposed_m += 1;
+ // note that we only set the LIBDIVIDE_NEGATIVE_DIVISOR bit if we
+ // also set ADD_MARKER this is an annoying optimization that
+ // enables algorithm #4 to avoid the mask. However we always set it
+ // in the branchfree case
+ more = floor_log_2_d | LIBDIVIDE_ADD_MARKER;
+ }
+ proposed_m += 1;
+ int64_t magic = (int64_t)proposed_m;
+
+ // Mark if we are negative
+ if (d < 0) {
+ more |= LIBDIVIDE_NEGATIVE_DIVISOR;
+ if (!branchfree) {
+ magic = -magic;
+ }
+ }
+
+ result.more = more;
+ result.magic = magic;
+ }
+ return result;
+}
+
+struct libdivide_s64_t libdivide_s64_gen(int64_t d) {
+ return libdivide_internal_s64_gen(d, 0);
+}
+
+struct libdivide_s64_branchfree_t libdivide_s64_branchfree_gen(int64_t d) {
+ struct libdivide_s64_t tmp = libdivide_internal_s64_gen(d, 1);
+ struct libdivide_s64_branchfree_t ret = {tmp.magic, tmp.more};
+ return ret;
+}
+
+int64_t libdivide_s64_do(int64_t numer, const struct libdivide_s64_t *denom) {
+ uint8_t more = denom->more;
+ uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
+
+ if (!denom->magic) { // shift path
+ uint64_t mask = (1ULL << shift) - 1;
+ uint64_t uq = numer + ((numer >> 63) & mask);
+ int64_t q = (int64_t)uq;
+ q >>= shift;
+ // must be arithmetic shift and then sign-extend
+ int64_t sign = (int8_t)more >> 7;
+ q = (q ^ sign) - sign;
+ return q;
+ } else {
+ uint64_t uq = (uint64_t)libdivide_mullhi_s64(denom->magic, numer);
+ if (more & LIBDIVIDE_ADD_MARKER) {
+ // must be arithmetic shift and then sign extend
+ int64_t sign = (int8_t)more >> 7;
+ // q += (more < 0 ? -numer : numer)
+ // cast required to avoid UB
+ uq += ((uint64_t)numer ^ sign) - sign;
+ }
+ int64_t q = (int64_t)uq;
+ q >>= shift;
+ q += (q < 0);
+ return q;
+ }
+}
+
+int64_t libdivide_s64_branchfree_do(int64_t numer, const struct libdivide_s64_branchfree_t *denom) {
+ uint8_t more = denom->more;
+ uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
+ // must be arithmetic shift and then sign extend
+ int64_t sign = (int8_t)more >> 7;
+ int64_t magic = denom->magic;
+ int64_t q = libdivide_mullhi_s64(magic, numer);
+ q += numer;
+
+ // If q is non-negative, we have nothing to do.
+ // If q is negative, we want to add either (2**shift)-1 if d is a power of
+ // 2, or (2**shift) if it is not a power of 2.
+ uint64_t is_power_of_2 = (magic == 0);
+ uint64_t q_sign = (uint64_t)(q >> 63);
+ q += q_sign & ((1ULL << shift) - is_power_of_2);
+
+ // Arithmetic right shift
+ q >>= shift;
+ // Negate if needed
+ q = (q ^ sign) - sign;
+
+ return q;
+}
+
+int64_t libdivide_s64_recover(const struct libdivide_s64_t *denom) {
+ uint8_t more = denom->more;
+ uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
+ if (denom->magic == 0) { // shift path
+ uint64_t absD = 1ULL << shift;
+ if (more & LIBDIVIDE_NEGATIVE_DIVISOR) {
+ absD = -absD;
+ }
+ return (int64_t)absD;
+ } else {
+ // Unsigned math is much easier
+ int negative_divisor = (more & LIBDIVIDE_NEGATIVE_DIVISOR);
+ int magic_was_negated = (more & LIBDIVIDE_ADD_MARKER)
+ ? denom->magic > 0 : denom->magic < 0;
+
+ uint64_t d = (uint64_t)(magic_was_negated ? -denom->magic : denom->magic);
+ uint64_t n_hi = 1ULL << shift, n_lo = 0;
+ uint64_t rem_ignored;
+ uint64_t q = libdivide_128_div_64_to_64(n_hi, n_lo, d, &rem_ignored);
+ int64_t result = (int64_t)(q + 1);
+ if (negative_divisor) {
+ result = -result;
+ }
+ return result;
+ }
+}
+
+int64_t libdivide_s64_branchfree_recover(const struct libdivide_s64_branchfree_t *denom) {
+ return libdivide_s64_recover((const struct libdivide_s64_t *)denom);
+}
+
+#if defined(LIBDIVIDE_AVX512)
+
+static inline __m512i libdivide_u32_do_vector(__m512i numers, const struct libdivide_u32_t *denom);
+static inline __m512i libdivide_s32_do_vector(__m512i numers, const struct libdivide_s32_t *denom);
+static inline __m512i libdivide_u64_do_vector(__m512i numers, const struct libdivide_u64_t *denom);
+static inline __m512i libdivide_s64_do_vector(__m512i numers, const struct libdivide_s64_t *denom);
+
+static inline __m512i libdivide_u32_branchfree_do_vector(__m512i numers, const struct libdivide_u32_branchfree_t *denom);
+static inline __m512i libdivide_s32_branchfree_do_vector(__m512i numers, const struct libdivide_s32_branchfree_t *denom);
+static inline __m512i libdivide_u64_branchfree_do_vector(__m512i numers, const struct libdivide_u64_branchfree_t *denom);
+static inline __m512i libdivide_s64_branchfree_do_vector(__m512i numers, const struct libdivide_s64_branchfree_t *denom);
+
+//////// Internal Utility Functions
+
+static inline __m512i libdivide_s64_signbits(__m512i v) {;
+ return _mm512_srai_epi64(v, 63);
+}
+
+static inline __m512i libdivide_s64_shift_right_vector(__m512i v, int amt) {
+ return _mm512_srai_epi64(v, amt);
+}
+
+// Here, b is assumed to contain one 32-bit value repeated.
+static inline __m512i libdivide_mullhi_u32_vector(__m512i a, __m512i b) {
+ __m512i hi_product_0Z2Z = _mm512_srli_epi64(_mm512_mul_epu32(a, b), 32);
+ __m512i a1X3X = _mm512_srli_epi64(a, 32);
+ __m512i mask = _mm512_set_epi32(-1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0);
+ __m512i hi_product_Z1Z3 = _mm512_and_si512(_mm512_mul_epu32(a1X3X, b), mask);
+ return _mm512_or_si512(hi_product_0Z2Z, hi_product_Z1Z3);
+}
+
+// b is one 32-bit value repeated.
+static inline __m512i libdivide_mullhi_s32_vector(__m512i a, __m512i b) {
+ __m512i hi_product_0Z2Z = _mm512_srli_epi64(_mm512_mul_epi32(a, b), 32);
+ __m512i a1X3X = _mm512_srli_epi64(a, 32);
+ __m512i mask = _mm512_set_epi32(-1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0);
+ __m512i hi_product_Z1Z3 = _mm512_and_si512(_mm512_mul_epi32(a1X3X, b), mask);
+ return _mm512_or_si512(hi_product_0Z2Z, hi_product_Z1Z3);
+}
+
+// Here, y is assumed to contain one 64-bit value repeated.
+// https://stackoverflow.com/a/28827013
+static inline __m512i libdivide_mullhi_u64_vector(__m512i x, __m512i y) {
+ __m512i lomask = _mm512_set1_epi64(0xffffffff);
+ __m512i xh = _mm512_shuffle_epi32(x, (_MM_PERM_ENUM) 0xB1);
+ __m512i yh = _mm512_shuffle_epi32(y, (_MM_PERM_ENUM) 0xB1);
+ __m512i w0 = _mm512_mul_epu32(x, y);
+ __m512i w1 = _mm512_mul_epu32(x, yh);
+ __m512i w2 = _mm512_mul_epu32(xh, y);
+ __m512i w3 = _mm512_mul_epu32(xh, yh);
+ __m512i w0h = _mm512_srli_epi64(w0, 32);
+ __m512i s1 = _mm512_add_epi64(w1, w0h);
+ __m512i s1l = _mm512_and_si512(s1, lomask);
+ __m512i s1h = _mm512_srli_epi64(s1, 32);
+ __m512i s2 = _mm512_add_epi64(w2, s1l);
+ __m512i s2h = _mm512_srli_epi64(s2, 32);
+ __m512i hi = _mm512_add_epi64(w3, s1h);
+ hi = _mm512_add_epi64(hi, s2h);
+
+ return hi;
+}
+
+// y is one 64-bit value repeated.
+static inline __m512i libdivide_mullhi_s64_vector(__m512i x, __m512i y) {
+ __m512i p = libdivide_mullhi_u64_vector(x, y);
+ __m512i t1 = _mm512_and_si512(libdivide_s64_signbits(x), y);
+ __m512i t2 = _mm512_and_si512(libdivide_s64_signbits(y), x);
+ p = _mm512_sub_epi64(p, t1);
+ p = _mm512_sub_epi64(p, t2);
+ return p;
+}
+
+////////// UINT32
+
+__m512i libdivide_u32_do_vector(__m512i numers, const struct libdivide_u32_t *denom) {
+ uint8_t more = denom->more;
+ if (!denom->magic) {
+ return _mm512_srli_epi32(numers, more);
+ }
+ else {
+ __m512i q = libdivide_mullhi_u32_vector(numers, _mm512_set1_epi32(denom->magic));
+ if (more & LIBDIVIDE_ADD_MARKER) {
+ // uint32_t t = ((numer - q) >> 1) + q;
+ // return t >> denom->shift;
+ uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
+ __m512i t = _mm512_add_epi32(_mm512_srli_epi32(_mm512_sub_epi32(numers, q), 1), q);
+ return _mm512_srli_epi32(t, shift);
+ }
+ else {
+ return _mm512_srli_epi32(q, more);
+ }
+ }
+}
+
+__m512i libdivide_u32_branchfree_do_vector(__m512i numers, const struct libdivide_u32_branchfree_t *denom) {
+ __m512i q = libdivide_mullhi_u32_vector(numers, _mm512_set1_epi32(denom->magic));
+ __m512i t = _mm512_add_epi32(_mm512_srli_epi32(_mm512_sub_epi32(numers, q), 1), q);
+ return _mm512_srli_epi32(t, denom->more);
+}
+
+////////// UINT64
+
+__m512i libdivide_u64_do_vector(__m512i numers, const struct libdivide_u64_t *denom) {
+ uint8_t more = denom->more;
+ if (!denom->magic) {
+ return _mm512_srli_epi64(numers, more);
+ }
+ else {
+ __m512i q = libdivide_mullhi_u64_vector(numers, _mm512_set1_epi64(denom->magic));
+ if (more & LIBDIVIDE_ADD_MARKER) {
+ // uint32_t t = ((numer - q) >> 1) + q;
+ // return t >> denom->shift;
+ uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
+ __m512i t = _mm512_add_epi64(_mm512_srli_epi64(_mm512_sub_epi64(numers, q), 1), q);
+ return _mm512_srli_epi64(t, shift);
+ }
+ else {
+ return _mm512_srli_epi64(q, more);
+ }
+ }
+}
+
+__m512i libdivide_u64_branchfree_do_vector(__m512i numers, const struct libdivide_u64_branchfree_t *denom) {
+ __m512i q = libdivide_mullhi_u64_vector(numers, _mm512_set1_epi64(denom->magic));
+ __m512i t = _mm512_add_epi64(_mm512_srli_epi64(_mm512_sub_epi64(numers, q), 1), q);
+ return _mm512_srli_epi64(t, denom->more);
+}
+
+////////// SINT32
+
+__m512i libdivide_s32_do_vector(__m512i numers, const struct libdivide_s32_t *denom) {
+ uint8_t more = denom->more;
+ if (!denom->magic) {
+ uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
+ uint32_t mask = (1U << shift) - 1;
+ __m512i roundToZeroTweak = _mm512_set1_epi32(mask);
+ // q = numer + ((numer >> 31) & roundToZeroTweak);
+ __m512i q = _mm512_add_epi32(numers, _mm512_and_si512(_mm512_srai_epi32(numers, 31), roundToZeroTweak));
+ q = _mm512_srai_epi32(q, shift);
+ __m512i sign = _mm512_set1_epi32((int8_t)more >> 7);
+ // q = (q ^ sign) - sign;
+ q = _mm512_sub_epi32(_mm512_xor_si512(q, sign), sign);
+ return q;
+ }
+ else {
+ __m512i q = libdivide_mullhi_s32_vector(numers, _mm512_set1_epi32(denom->magic));
+ if (more & LIBDIVIDE_ADD_MARKER) {
+ // must be arithmetic shift
+ __m512i sign = _mm512_set1_epi32((int8_t)more >> 7);
+ // q += ((numer ^ sign) - sign);
+ q = _mm512_add_epi32(q, _mm512_sub_epi32(_mm512_xor_si512(numers, sign), sign));
+ }
+ // q >>= shift
+ q = _mm512_srai_epi32(q, more & LIBDIVIDE_32_SHIFT_MASK);
+ q = _mm512_add_epi32(q, _mm512_srli_epi32(q, 31)); // q += (q < 0)
+ return q;
+ }
+}
+
+__m512i libdivide_s32_branchfree_do_vector(__m512i numers, const struct libdivide_s32_branchfree_t *denom) {
+ int32_t magic = denom->magic;
+ uint8_t more = denom->more;
+ uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
+ // must be arithmetic shift
+ __m512i sign = _mm512_set1_epi32((int8_t)more >> 7);
+ __m512i q = libdivide_mullhi_s32_vector(numers, _mm512_set1_epi32(magic));
+ q = _mm512_add_epi32(q, numers); // q += numers
+
+ // If q is non-negative, we have nothing to do
+ // If q is negative, we want to add either (2**shift)-1 if d is
+ // a power of 2, or (2**shift) if it is not a power of 2
+ uint32_t is_power_of_2 = (magic == 0);
+ __m512i q_sign = _mm512_srai_epi32(q, 31); // q_sign = q >> 31
+ __m512i mask = _mm512_set1_epi32((1U << shift) - is_power_of_2);
+ q = _mm512_add_epi32(q, _mm512_and_si512(q_sign, mask)); // q = q + (q_sign & mask)
+ q = _mm512_srai_epi32(q, shift); // q >>= shift
+ q = _mm512_sub_epi32(_mm512_xor_si512(q, sign), sign); // q = (q ^ sign) - sign
+ return q;
+}
+
+////////// SINT64
+
+__m512i libdivide_s64_do_vector(__m512i numers, const struct libdivide_s64_t *denom) {
+ uint8_t more = denom->more;
+ int64_t magic = denom->magic;
+ if (magic == 0) { // shift path
+ uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
+ uint64_t mask = (1ULL << shift) - 1;
+ __m512i roundToZeroTweak = _mm512_set1_epi64(mask);
+ // q = numer + ((numer >> 63) & roundToZeroTweak);
+ __m512i q = _mm512_add_epi64(numers, _mm512_and_si512(libdivide_s64_signbits(numers), roundToZeroTweak));
+ q = libdivide_s64_shift_right_vector(q, shift);
+ __m512i sign = _mm512_set1_epi32((int8_t)more >> 7);
+ // q = (q ^ sign) - sign;
+ q = _mm512_sub_epi64(_mm512_xor_si512(q, sign), sign);
+ return q;
+ }
+ else {
+ __m512i q = libdivide_mullhi_s64_vector(numers, _mm512_set1_epi64(magic));
+ if (more & LIBDIVIDE_ADD_MARKER) {
+ // must be arithmetic shift
+ __m512i sign = _mm512_set1_epi32((int8_t)more >> 7);
+ // q += ((numer ^ sign) - sign);
+ q = _mm512_add_epi64(q, _mm512_sub_epi64(_mm512_xor_si512(numers, sign), sign));
+ }
+ // q >>= denom->mult_path.shift
+ q = libdivide_s64_shift_right_vector(q, more & LIBDIVIDE_64_SHIFT_MASK);
+ q = _mm512_add_epi64(q, _mm512_srli_epi64(q, 63)); // q += (q < 0)
+ return q;
+ }
+}
+
+__m512i libdivide_s64_branchfree_do_vector(__m512i numers, const struct libdivide_s64_branchfree_t *denom) {
+ int64_t magic = denom->magic;
+ uint8_t more = denom->more;
+ uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
+ // must be arithmetic shift
+ __m512i sign = _mm512_set1_epi32((int8_t)more >> 7);
+
+ // libdivide_mullhi_s64(numers, magic);
+ __m512i q = libdivide_mullhi_s64_vector(numers, _mm512_set1_epi64(magic));
+ q = _mm512_add_epi64(q, numers); // q += numers
+
+ // If q is non-negative, we have nothing to do.
+ // If q is negative, we want to add either (2**shift)-1 if d is
+ // a power of 2, or (2**shift) if it is not a power of 2.
+ uint32_t is_power_of_2 = (magic == 0);
+ __m512i q_sign = libdivide_s64_signbits(q); // q_sign = q >> 63
+ __m512i mask = _mm512_set1_epi64((1ULL << shift) - is_power_of_2);
+ q = _mm512_add_epi64(q, _mm512_and_si512(q_sign, mask)); // q = q + (q_sign & mask)
+ q = libdivide_s64_shift_right_vector(q, shift); // q >>= shift
+ q = _mm512_sub_epi64(_mm512_xor_si512(q, sign), sign); // q = (q ^ sign) - sign
+ return q;
+}
+
+#elif defined(LIBDIVIDE_AVX2)
+
+static inline __m256i libdivide_u32_do_vector(__m256i numers, const struct libdivide_u32_t *denom);
+static inline __m256i libdivide_s32_do_vector(__m256i numers, const struct libdivide_s32_t *denom);
+static inline __m256i libdivide_u64_do_vector(__m256i numers, const struct libdivide_u64_t *denom);
+static inline __m256i libdivide_s64_do_vector(__m256i numers, const struct libdivide_s64_t *denom);
+
+static inline __m256i libdivide_u32_branchfree_do_vector(__m256i numers, const struct libdivide_u32_branchfree_t *denom);
+static inline __m256i libdivide_s32_branchfree_do_vector(__m256i numers, const struct libdivide_s32_branchfree_t *denom);
+static inline __m256i libdivide_u64_branchfree_do_vector(__m256i numers, const struct libdivide_u64_branchfree_t *denom);
+static inline __m256i libdivide_s64_branchfree_do_vector(__m256i numers, const struct libdivide_s64_branchfree_t *denom);
+
+//////// Internal Utility Functions
+
+// Implementation of _mm256_srai_epi64(v, 63) (from AVX512).
+static inline __m256i libdivide_s64_signbits(__m256i v) {
+ __m256i hiBitsDuped = _mm256_shuffle_epi32(v, _MM_SHUFFLE(3, 3, 1, 1));
+ __m256i signBits = _mm256_srai_epi32(hiBitsDuped, 31);
+ return signBits;
+}
+
+// Implementation of _mm256_srai_epi64 (from AVX512).
+static inline __m256i libdivide_s64_shift_right_vector(__m256i v, int amt) {
+ const int b = 64 - amt;
+ __m256i m = _mm256_set1_epi64x(1ULL << (b - 1));
+ __m256i x = _mm256_srli_epi64(v, amt);
+ __m256i result = _mm256_sub_epi64(_mm256_xor_si256(x, m), m);
+ return result;
+}
+
+// Here, b is assumed to contain one 32-bit value repeated.
+static inline __m256i libdivide_mullhi_u32_vector(__m256i a, __m256i b) {
+ __m256i hi_product_0Z2Z = _mm256_srli_epi64(_mm256_mul_epu32(a, b), 32);
+ __m256i a1X3X = _mm256_srli_epi64(a, 32);
+ __m256i mask = _mm256_set_epi32(-1, 0, -1, 0, -1, 0, -1, 0);
+ __m256i hi_product_Z1Z3 = _mm256_and_si256(_mm256_mul_epu32(a1X3X, b), mask);
+ return _mm256_or_si256(hi_product_0Z2Z, hi_product_Z1Z3);
+}
+
+// b is one 32-bit value repeated.
+static inline __m256i libdivide_mullhi_s32_vector(__m256i a, __m256i b) {
+ __m256i hi_product_0Z2Z = _mm256_srli_epi64(_mm256_mul_epi32(a, b), 32);
+ __m256i a1X3X = _mm256_srli_epi64(a, 32);
+ __m256i mask = _mm256_set_epi32(-1, 0, -1, 0, -1, 0, -1, 0);
+ __m256i hi_product_Z1Z3 = _mm256_and_si256(_mm256_mul_epi32(a1X3X, b), mask);
+ return _mm256_or_si256(hi_product_0Z2Z, hi_product_Z1Z3);
+}
+
+// Here, y is assumed to contain one 64-bit value repeated.
+// https://stackoverflow.com/a/28827013
+static inline __m256i libdivide_mullhi_u64_vector(__m256i x, __m256i y) {
+ __m256i lomask = _mm256_set1_epi64x(0xffffffff);
+ __m256i xh = _mm256_shuffle_epi32(x, 0xB1); // x0l, x0h, x1l, x1h
+ __m256i yh = _mm256_shuffle_epi32(y, 0xB1); // y0l, y0h, y1l, y1h
+ __m256i w0 = _mm256_mul_epu32(x, y); // x0l*y0l, x1l*y1l
+ __m256i w1 = _mm256_mul_epu32(x, yh); // x0l*y0h, x1l*y1h
+ __m256i w2 = _mm256_mul_epu32(xh, y); // x0h*y0l, x1h*y0l
+ __m256i w3 = _mm256_mul_epu32(xh, yh); // x0h*y0h, x1h*y1h
+ __m256i w0h = _mm256_srli_epi64(w0, 32);
+ __m256i s1 = _mm256_add_epi64(w1, w0h);
+ __m256i s1l = _mm256_and_si256(s1, lomask);
+ __m256i s1h = _mm256_srli_epi64(s1, 32);
+ __m256i s2 = _mm256_add_epi64(w2, s1l);
+ __m256i s2h = _mm256_srli_epi64(s2, 32);
+ __m256i hi = _mm256_add_epi64(w3, s1h);
+ hi = _mm256_add_epi64(hi, s2h);
+
+ return hi;
+}
+
+// y is one 64-bit value repeated.
+static inline __m256i libdivide_mullhi_s64_vector(__m256i x, __m256i y) {
+ __m256i p = libdivide_mullhi_u64_vector(x, y);
+ __m256i t1 = _mm256_and_si256(libdivide_s64_signbits(x), y);
+ __m256i t2 = _mm256_and_si256(libdivide_s64_signbits(y), x);
+ p = _mm256_sub_epi64(p, t1);
+ p = _mm256_sub_epi64(p, t2);
+ return p;
+}
+
+////////// UINT32
+
+__m256i libdivide_u32_do_vector(__m256i numers, const struct libdivide_u32_t *denom) {
+ uint8_t more = denom->more;
+ if (!denom->magic) {
+ return _mm256_srli_epi32(numers, more);
+ }
+ else {
+ __m256i q = libdivide_mullhi_u32_vector(numers, _mm256_set1_epi32(denom->magic));
+ if (more & LIBDIVIDE_ADD_MARKER) {
+ // uint32_t t = ((numer - q) >> 1) + q;
+ // return t >> denom->shift;
+ uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
+ __m256i t = _mm256_add_epi32(_mm256_srli_epi32(_mm256_sub_epi32(numers, q), 1), q);
+ return _mm256_srli_epi32(t, shift);
+ }
+ else {
+ return _mm256_srli_epi32(q, more);
+ }
+ }
+}
+
+__m256i libdivide_u32_branchfree_do_vector(__m256i numers, const struct libdivide_u32_branchfree_t *denom) {
+ __m256i q = libdivide_mullhi_u32_vector(numers, _mm256_set1_epi32(denom->magic));
+ __m256i t = _mm256_add_epi32(_mm256_srli_epi32(_mm256_sub_epi32(numers, q), 1), q);
+ return _mm256_srli_epi32(t, denom->more);
+}
+
+////////// UINT64
+
+__m256i libdivide_u64_do_vector(__m256i numers, const struct libdivide_u64_t *denom) {
+ uint8_t more = denom->more;
+ if (!denom->magic) {
+ return _mm256_srli_epi64(numers, more);
+ }
+ else {
+ __m256i q = libdivide_mullhi_u64_vector(numers, _mm256_set1_epi64x(denom->magic));
+ if (more & LIBDIVIDE_ADD_MARKER) {
+ // uint32_t t = ((numer - q) >> 1) + q;
+ // return t >> denom->shift;
+ uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
+ __m256i t = _mm256_add_epi64(_mm256_srli_epi64(_mm256_sub_epi64(numers, q), 1), q);
+ return _mm256_srli_epi64(t, shift);
+ }
+ else {
+ return _mm256_srli_epi64(q, more);
+ }
+ }
+}
+
+__m256i libdivide_u64_branchfree_do_vector(__m256i numers, const struct libdivide_u64_branchfree_t *denom) {
+ __m256i q = libdivide_mullhi_u64_vector(numers, _mm256_set1_epi64x(denom->magic));
+ __m256i t = _mm256_add_epi64(_mm256_srli_epi64(_mm256_sub_epi64(numers, q), 1), q);
+ return _mm256_srli_epi64(t, denom->more);
+}
+
+////////// SINT32
+
+__m256i libdivide_s32_do_vector(__m256i numers, const struct libdivide_s32_t *denom) {
+ uint8_t more = denom->more;
+ if (!denom->magic) {
+ uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
+ uint32_t mask = (1U << shift) - 1;
+ __m256i roundToZeroTweak = _mm256_set1_epi32(mask);
+ // q = numer + ((numer >> 31) & roundToZeroTweak);
+ __m256i q = _mm256_add_epi32(numers, _mm256_and_si256(_mm256_srai_epi32(numers, 31), roundToZeroTweak));
+ q = _mm256_srai_epi32(q, shift);
+ __m256i sign = _mm256_set1_epi32((int8_t)more >> 7);
+ // q = (q ^ sign) - sign;
+ q = _mm256_sub_epi32(_mm256_xor_si256(q, sign), sign);
+ return q;
+ }
+ else {
+ __m256i q = libdivide_mullhi_s32_vector(numers, _mm256_set1_epi32(denom->magic));
+ if (more & LIBDIVIDE_ADD_MARKER) {
+ // must be arithmetic shift
+ __m256i sign = _mm256_set1_epi32((int8_t)more >> 7);
+ // q += ((numer ^ sign) - sign);
+ q = _mm256_add_epi32(q, _mm256_sub_epi32(_mm256_xor_si256(numers, sign), sign));
+ }
+ // q >>= shift
+ q = _mm256_srai_epi32(q, more & LIBDIVIDE_32_SHIFT_MASK);
+ q = _mm256_add_epi32(q, _mm256_srli_epi32(q, 31)); // q += (q < 0)
+ return q;
+ }
+}
+
+__m256i libdivide_s32_branchfree_do_vector(__m256i numers, const struct libdivide_s32_branchfree_t *denom) {
+ int32_t magic = denom->magic;
+ uint8_t more = denom->more;
+ uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
+ // must be arithmetic shift
+ __m256i sign = _mm256_set1_epi32((int8_t)more >> 7);
+ __m256i q = libdivide_mullhi_s32_vector(numers, _mm256_set1_epi32(magic));
+ q = _mm256_add_epi32(q, numers); // q += numers
+
+ // If q is non-negative, we have nothing to do
+ // If q is negative, we want to add either (2**shift)-1 if d is
+ // a power of 2, or (2**shift) if it is not a power of 2
+ uint32_t is_power_of_2 = (magic == 0);
+ __m256i q_sign = _mm256_srai_epi32(q, 31); // q_sign = q >> 31
+ __m256i mask = _mm256_set1_epi32((1U << shift) - is_power_of_2);
+ q = _mm256_add_epi32(q, _mm256_and_si256(q_sign, mask)); // q = q + (q_sign & mask)
+ q = _mm256_srai_epi32(q, shift); // q >>= shift
+ q = _mm256_sub_epi32(_mm256_xor_si256(q, sign), sign); // q = (q ^ sign) - sign
+ return q;
+}
+
+////////// SINT64
+
+__m256i libdivide_s64_do_vector(__m256i numers, const struct libdivide_s64_t *denom) {
+ uint8_t more = denom->more;
+ int64_t magic = denom->magic;
+ if (magic == 0) { // shift path
+ uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
+ uint64_t mask = (1ULL << shift) - 1;
+ __m256i roundToZeroTweak = _mm256_set1_epi64x(mask);
+ // q = numer + ((numer >> 63) & roundToZeroTweak);
+ __m256i q = _mm256_add_epi64(numers, _mm256_and_si256(libdivide_s64_signbits(numers), roundToZeroTweak));
+ q = libdivide_s64_shift_right_vector(q, shift);
+ __m256i sign = _mm256_set1_epi32((int8_t)more >> 7);
+ // q = (q ^ sign) - sign;
+ q = _mm256_sub_epi64(_mm256_xor_si256(q, sign), sign);
+ return q;
+ }
+ else {
+ __m256i q = libdivide_mullhi_s64_vector(numers, _mm256_set1_epi64x(magic));
+ if (more & LIBDIVIDE_ADD_MARKER) {
+ // must be arithmetic shift
+ __m256i sign = _mm256_set1_epi32((int8_t)more >> 7);
+ // q += ((numer ^ sign) - sign);
+ q = _mm256_add_epi64(q, _mm256_sub_epi64(_mm256_xor_si256(numers, sign), sign));
+ }
+ // q >>= denom->mult_path.shift
+ q = libdivide_s64_shift_right_vector(q, more & LIBDIVIDE_64_SHIFT_MASK);
+ q = _mm256_add_epi64(q, _mm256_srli_epi64(q, 63)); // q += (q < 0)
+ return q;
+ }
+}
+
+__m256i libdivide_s64_branchfree_do_vector(__m256i numers, const struct libdivide_s64_branchfree_t *denom) {
+ int64_t magic = denom->magic;
+ uint8_t more = denom->more;
+ uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
+ // must be arithmetic shift
+ __m256i sign = _mm256_set1_epi32((int8_t)more >> 7);
+
+ // libdivide_mullhi_s64(numers, magic);
+ __m256i q = libdivide_mullhi_s64_vector(numers, _mm256_set1_epi64x(magic));
+ q = _mm256_add_epi64(q, numers); // q += numers
+
+ // If q is non-negative, we have nothing to do.
+ // If q is negative, we want to add either (2**shift)-1 if d is
+ // a power of 2, or (2**shift) if it is not a power of 2.
+ uint32_t is_power_of_2 = (magic == 0);
+ __m256i q_sign = libdivide_s64_signbits(q); // q_sign = q >> 63
+ __m256i mask = _mm256_set1_epi64x((1ULL << shift) - is_power_of_2);
+ q = _mm256_add_epi64(q, _mm256_and_si256(q_sign, mask)); // q = q + (q_sign & mask)
+ q = libdivide_s64_shift_right_vector(q, shift); // q >>= shift
+ q = _mm256_sub_epi64(_mm256_xor_si256(q, sign), sign); // q = (q ^ sign) - sign
+ return q;
+}
+
+#elif defined(LIBDIVIDE_SSE2)
+
+static inline __m128i libdivide_u32_do_vector(__m128i numers, const struct libdivide_u32_t *denom);
+static inline __m128i libdivide_s32_do_vector(__m128i numers, const struct libdivide_s32_t *denom);
+static inline __m128i libdivide_u64_do_vector(__m128i numers, const struct libdivide_u64_t *denom);
+static inline __m128i libdivide_s64_do_vector(__m128i numers, const struct libdivide_s64_t *denom);
+
+static inline __m128i libdivide_u32_branchfree_do_vector(__m128i numers, const struct libdivide_u32_branchfree_t *denom);
+static inline __m128i libdivide_s32_branchfree_do_vector(__m128i numers, const struct libdivide_s32_branchfree_t *denom);
+static inline __m128i libdivide_u64_branchfree_do_vector(__m128i numers, const struct libdivide_u64_branchfree_t *denom);
+static inline __m128i libdivide_s64_branchfree_do_vector(__m128i numers, const struct libdivide_s64_branchfree_t *denom);
+
+//////// Internal Utility Functions
+
+// Implementation of _mm_srai_epi64(v, 63) (from AVX512).
+static inline __m128i libdivide_s64_signbits(__m128i v) {
+ __m128i hiBitsDuped = _mm_shuffle_epi32(v, _MM_SHUFFLE(3, 3, 1, 1));
+ __m128i signBits = _mm_srai_epi32(hiBitsDuped, 31);
+ return signBits;
+}
+
+// Implementation of _mm_srai_epi64 (from AVX512).
+static inline __m128i libdivide_s64_shift_right_vector(__m128i v, int amt) {
+ const int b = 64 - amt;
+ __m128i m = _mm_set1_epi64x(1ULL << (b - 1));
+ __m128i x = _mm_srli_epi64(v, amt);
+ __m128i result = _mm_sub_epi64(_mm_xor_si128(x, m), m);
+ return result;
+}
+
+// Here, b is assumed to contain one 32-bit value repeated.
+static inline __m128i libdivide_mullhi_u32_vector(__m128i a, __m128i b) {
+ __m128i hi_product_0Z2Z = _mm_srli_epi64(_mm_mul_epu32(a, b), 32);
+ __m128i a1X3X = _mm_srli_epi64(a, 32);
+ __m128i mask = _mm_set_epi32(-1, 0, -1, 0);
+ __m128i hi_product_Z1Z3 = _mm_and_si128(_mm_mul_epu32(a1X3X, b), mask);
+ return _mm_or_si128(hi_product_0Z2Z, hi_product_Z1Z3);
+}
+
+// SSE2 does not have a signed multiplication instruction, but we can convert
+// unsigned to signed pretty efficiently. Again, b is just a 32 bit value
+// repeated four times.
+static inline __m128i libdivide_mullhi_s32_vector(__m128i a, __m128i b) {
+ __m128i p = libdivide_mullhi_u32_vector(a, b);
+ // t1 = (a >> 31) & y, arithmetic shift
+ __m128i t1 = _mm_and_si128(_mm_srai_epi32(a, 31), b);
+ __m128i t2 = _mm_and_si128(_mm_srai_epi32(b, 31), a);
+ p = _mm_sub_epi32(p, t1);
+ p = _mm_sub_epi32(p, t2);
+ return p;
+}
+
+// Here, y is assumed to contain one 64-bit value repeated.
+// https://stackoverflow.com/a/28827013
+static inline __m128i libdivide_mullhi_u64_vector(__m128i x, __m128i y) {
+ __m128i lomask = _mm_set1_epi64x(0xffffffff);
+ __m128i xh = _mm_shuffle_epi32(x, 0xB1); // x0l, x0h, x1l, x1h
+ __m128i yh = _mm_shuffle_epi32(y, 0xB1); // y0l, y0h, y1l, y1h
+ __m128i w0 = _mm_mul_epu32(x, y); // x0l*y0l, x1l*y1l
+ __m128i w1 = _mm_mul_epu32(x, yh); // x0l*y0h, x1l*y1h
+ __m128i w2 = _mm_mul_epu32(xh, y); // x0h*y0l, x1h*y0l
+ __m128i w3 = _mm_mul_epu32(xh, yh); // x0h*y0h, x1h*y1h
+ __m128i w0h = _mm_srli_epi64(w0, 32);
+ __m128i s1 = _mm_add_epi64(w1, w0h);
+ __m128i s1l = _mm_and_si128(s1, lomask);
+ __m128i s1h = _mm_srli_epi64(s1, 32);
+ __m128i s2 = _mm_add_epi64(w2, s1l);
+ __m128i s2h = _mm_srli_epi64(s2, 32);
+ __m128i hi = _mm_add_epi64(w3, s1h);
+ hi = _mm_add_epi64(hi, s2h);
+
+ return hi;
+}
+
+// y is one 64-bit value repeated.
+static inline __m128i libdivide_mullhi_s64_vector(__m128i x, __m128i y) {
+ __m128i p = libdivide_mullhi_u64_vector(x, y);
+ __m128i t1 = _mm_and_si128(libdivide_s64_signbits(x), y);
+ __m128i t2 = _mm_and_si128(libdivide_s64_signbits(y), x);
+ p = _mm_sub_epi64(p, t1);
+ p = _mm_sub_epi64(p, t2);
+ return p;
+}
+
+////////// UINT32
+
+__m128i libdivide_u32_do_vector(__m128i numers, const struct libdivide_u32_t *denom) {
+ uint8_t more = denom->more;
+ if (!denom->magic) {
+ return _mm_srli_epi32(numers, more);
+ }
+ else {
+ __m128i q = libdivide_mullhi_u32_vector(numers, _mm_set1_epi32(denom->magic));
+ if (more & LIBDIVIDE_ADD_MARKER) {
+ // uint32_t t = ((numer - q) >> 1) + q;
+ // return t >> denom->shift;
+ uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
+ __m128i t = _mm_add_epi32(_mm_srli_epi32(_mm_sub_epi32(numers, q), 1), q);
+ return _mm_srli_epi32(t, shift);
+ }
+ else {
+ return _mm_srli_epi32(q, more);
+ }
+ }
+}
+
+__m128i libdivide_u32_branchfree_do_vector(__m128i numers, const struct libdivide_u32_branchfree_t *denom) {
+ __m128i q = libdivide_mullhi_u32_vector(numers, _mm_set1_epi32(denom->magic));
+ __m128i t = _mm_add_epi32(_mm_srli_epi32(_mm_sub_epi32(numers, q), 1), q);
+ return _mm_srli_epi32(t, denom->more);
+}
+
+////////// UINT64
+
+__m128i libdivide_u64_do_vector(__m128i numers, const struct libdivide_u64_t *denom) {
+ uint8_t more = denom->more;
+ if (!denom->magic) {
+ return _mm_srli_epi64(numers, more);
+ }
+ else {
+ __m128i q = libdivide_mullhi_u64_vector(numers, _mm_set1_epi64x(denom->magic));
+ if (more & LIBDIVIDE_ADD_MARKER) {
+ // uint32_t t = ((numer - q) >> 1) + q;
+ // return t >> denom->shift;
+ uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
+ __m128i t = _mm_add_epi64(_mm_srli_epi64(_mm_sub_epi64(numers, q), 1), q);
+ return _mm_srli_epi64(t, shift);
+ }
+ else {
+ return _mm_srli_epi64(q, more);
+ }
+ }
+}
+
+__m128i libdivide_u64_branchfree_do_vector(__m128i numers, const struct libdivide_u64_branchfree_t *denom) {
+ __m128i q = libdivide_mullhi_u64_vector(numers, _mm_set1_epi64x(denom->magic));
+ __m128i t = _mm_add_epi64(_mm_srli_epi64(_mm_sub_epi64(numers, q), 1), q);
+ return _mm_srli_epi64(t, denom->more);
+}
+
+////////// SINT32
+
+__m128i libdivide_s32_do_vector(__m128i numers, const struct libdivide_s32_t *denom) {
+ uint8_t more = denom->more;
+ if (!denom->magic) {
+ uint32_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
+ uint32_t mask = (1U << shift) - 1;
+ __m128i roundToZeroTweak = _mm_set1_epi32(mask);
+ // q = numer + ((numer >> 31) & roundToZeroTweak);
+ __m128i q = _mm_add_epi32(numers, _mm_and_si128(_mm_srai_epi32(numers, 31), roundToZeroTweak));
+ q = _mm_srai_epi32(q, shift);
+ __m128i sign = _mm_set1_epi32((int8_t)more >> 7);
+ // q = (q ^ sign) - sign;
+ q = _mm_sub_epi32(_mm_xor_si128(q, sign), sign);
+ return q;
+ }
+ else {
+ __m128i q = libdivide_mullhi_s32_vector(numers, _mm_set1_epi32(denom->magic));
+ if (more & LIBDIVIDE_ADD_MARKER) {
+ // must be arithmetic shift
+ __m128i sign = _mm_set1_epi32((int8_t)more >> 7);
+ // q += ((numer ^ sign) - sign);
+ q = _mm_add_epi32(q, _mm_sub_epi32(_mm_xor_si128(numers, sign), sign));
+ }
+ // q >>= shift
+ q = _mm_srai_epi32(q, more & LIBDIVIDE_32_SHIFT_MASK);
+ q = _mm_add_epi32(q, _mm_srli_epi32(q, 31)); // q += (q < 0)
+ return q;
+ }
+}
+
+__m128i libdivide_s32_branchfree_do_vector(__m128i numers, const struct libdivide_s32_branchfree_t *denom) {
+ int32_t magic = denom->magic;
+ uint8_t more = denom->more;
+ uint8_t shift = more & LIBDIVIDE_32_SHIFT_MASK;
+ // must be arithmetic shift
+ __m128i sign = _mm_set1_epi32((int8_t)more >> 7);
+ __m128i q = libdivide_mullhi_s32_vector(numers, _mm_set1_epi32(magic));
+ q = _mm_add_epi32(q, numers); // q += numers
+
+ // If q is non-negative, we have nothing to do
+ // If q is negative, we want to add either (2**shift)-1 if d is
+ // a power of 2, or (2**shift) if it is not a power of 2
+ uint32_t is_power_of_2 = (magic == 0);
+ __m128i q_sign = _mm_srai_epi32(q, 31); // q_sign = q >> 31
+ __m128i mask = _mm_set1_epi32((1U << shift) - is_power_of_2);
+ q = _mm_add_epi32(q, _mm_and_si128(q_sign, mask)); // q = q + (q_sign & mask)
+ q = _mm_srai_epi32(q, shift); // q >>= shift
+ q = _mm_sub_epi32(_mm_xor_si128(q, sign), sign); // q = (q ^ sign) - sign
+ return q;
+}
+
+////////// SINT64
+
+__m128i libdivide_s64_do_vector(__m128i numers, const struct libdivide_s64_t *denom) {
+ uint8_t more = denom->more;
+ int64_t magic = denom->magic;
+ if (magic == 0) { // shift path
+ uint32_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
+ uint64_t mask = (1ULL << shift) - 1;
+ __m128i roundToZeroTweak = _mm_set1_epi64x(mask);
+ // q = numer + ((numer >> 63) & roundToZeroTweak);
+ __m128i q = _mm_add_epi64(numers, _mm_and_si128(libdivide_s64_signbits(numers), roundToZeroTweak));
+ q = libdivide_s64_shift_right_vector(q, shift);
+ __m128i sign = _mm_set1_epi32((int8_t)more >> 7);
+ // q = (q ^ sign) - sign;
+ q = _mm_sub_epi64(_mm_xor_si128(q, sign), sign);
+ return q;
+ }
+ else {
+ __m128i q = libdivide_mullhi_s64_vector(numers, _mm_set1_epi64x(magic));
+ if (more & LIBDIVIDE_ADD_MARKER) {
+ // must be arithmetic shift
+ __m128i sign = _mm_set1_epi32((int8_t)more >> 7);
+ // q += ((numer ^ sign) - sign);
+ q = _mm_add_epi64(q, _mm_sub_epi64(_mm_xor_si128(numers, sign), sign));
+ }
+ // q >>= denom->mult_path.shift
+ q = libdivide_s64_shift_right_vector(q, more & LIBDIVIDE_64_SHIFT_MASK);
+ q = _mm_add_epi64(q, _mm_srli_epi64(q, 63)); // q += (q < 0)
+ return q;
+ }
+}
+
+__m128i libdivide_s64_branchfree_do_vector(__m128i numers, const struct libdivide_s64_branchfree_t *denom) {
+ int64_t magic = denom->magic;
+ uint8_t more = denom->more;
+ uint8_t shift = more & LIBDIVIDE_64_SHIFT_MASK;
+ // must be arithmetic shift
+ __m128i sign = _mm_set1_epi32((int8_t)more >> 7);
+
+ // libdivide_mullhi_s64(numers, magic);
+ __m128i q = libdivide_mullhi_s64_vector(numers, _mm_set1_epi64x(magic));
+ q = _mm_add_epi64(q, numers); // q += numers
+
+ // If q is non-negative, we have nothing to do.
+ // If q is negative, we want to add either (2**shift)-1 if d is
+ // a power of 2, or (2**shift) if it is not a power of 2.
+ uint32_t is_power_of_2 = (magic == 0);
+ __m128i q_sign = libdivide_s64_signbits(q); // q_sign = q >> 63
+ __m128i mask = _mm_set1_epi64x((1ULL << shift) - is_power_of_2);
+ q = _mm_add_epi64(q, _mm_and_si128(q_sign, mask)); // q = q + (q_sign & mask)
+ q = libdivide_s64_shift_right_vector(q, shift); // q >>= shift
+ q = _mm_sub_epi64(_mm_xor_si128(q, sign), sign); // q = (q ^ sign) - sign
+ return q;
+}
+
+#endif
+
+/////////// C++ stuff
+
+#ifdef __cplusplus
+
+// The C++ divider class is templated on both an integer type
+// (like uint64_t) and an algorithm type.
+// * BRANCHFULL is the default algorithm type.
+// * BRANCHFREE is the branchfree algorithm type.
+enum {
+ BRANCHFULL,
+ BRANCHFREE
+};
+
+#if defined(LIBDIVIDE_AVX512)
+ #define LIBDIVIDE_VECTOR_TYPE __m512i
+#elif defined(LIBDIVIDE_AVX2)
+ #define LIBDIVIDE_VECTOR_TYPE __m256i
+#elif defined(LIBDIVIDE_SSE2)
+ #define LIBDIVIDE_VECTOR_TYPE __m128i
+#endif
+
+#if !defined(LIBDIVIDE_VECTOR_TYPE)
+ #define LIBDIVIDE_DIVIDE_VECTOR(ALGO)
+#else
+ #define LIBDIVIDE_DIVIDE_VECTOR(ALGO) \
+ LIBDIVIDE_VECTOR_TYPE divide(LIBDIVIDE_VECTOR_TYPE n) const { \
+ return libdivide_##ALGO##_do_vector(n, &denom); \
+ }
+#endif
+
+// The DISPATCHER_GEN() macro generates C++ methods (for the given integer
+// and algorithm types) that redirect to libdivide's C API.
+#define DISPATCHER_GEN(T, ALGO) \
+ libdivide_##ALGO##_t denom; \
+ dispatcher() { } \
+ dispatcher(T d) \
+ : denom(libdivide_##ALGO##_gen(d)) \
+ { } \
+ T divide(T n) const { \
+ return libdivide_##ALGO##_do(n, &denom); \
+ } \
+ LIBDIVIDE_DIVIDE_VECTOR(ALGO) \
+ T recover() const { \
+ return libdivide_##ALGO##_recover(&denom); \
+ }
+
+// The dispatcher selects a specific division algorithm for a given
+// type and ALGO using partial template specialization.
+template<bool IS_INTEGRAL, bool IS_SIGNED, int SIZEOF, int ALGO> struct dispatcher { };
+
+template<> struct dispatcher<true, true, sizeof(int32_t), BRANCHFULL> { DISPATCHER_GEN(int32_t, s32) };
+template<> struct dispatcher<true, true, sizeof(int32_t), BRANCHFREE> { DISPATCHER_GEN(int32_t, s32_branchfree) };
+template<> struct dispatcher<true, false, sizeof(uint32_t), BRANCHFULL> { DISPATCHER_GEN(uint32_t, u32) };
+template<> struct dispatcher<true, false, sizeof(uint32_t), BRANCHFREE> { DISPATCHER_GEN(uint32_t, u32_branchfree) };
+template<> struct dispatcher<true, true, sizeof(int64_t), BRANCHFULL> { DISPATCHER_GEN(int64_t, s64) };
+template<> struct dispatcher<true, true, sizeof(int64_t), BRANCHFREE> { DISPATCHER_GEN(int64_t, s64_branchfree) };
+template<> struct dispatcher<true, false, sizeof(uint64_t), BRANCHFULL> { DISPATCHER_GEN(uint64_t, u64) };
+template<> struct dispatcher<true, false, sizeof(uint64_t), BRANCHFREE> { DISPATCHER_GEN(uint64_t, u64_branchfree) };
+
+// This is the main divider class for use by the user (C++ API).
+// The actual division algorithm is selected using the dispatcher struct
+// based on the integer and algorithm template parameters.
+template<typename T, int ALGO = BRANCHFULL>
+class divider {
+public:
+ // We leave the default constructor empty so that creating
+ // an array of dividers and then initializing them
+ // later doesn't slow us down.
+ divider() { }
+
+ // Constructor that takes the divisor as a parameter
+ divider(T d) : div(d) { }
+
+ // Divides n by the divisor
+ T divide(T n) const {
+ return div.divide(n);
+ }
+
+ // Recovers the divisor, returns the value that was
+ // used to initialize this divider object.
+ T recover() const {
+ return div.recover();
+ }
+
+ bool operator==(const divider<T, ALGO>& other) const {
+ return div.denom.magic == other.denom.magic &&
+ div.denom.more == other.denom.more;
+ }
+
+ bool operator!=(const divider<T, ALGO>& other) const {
+ return !(*this == other);
+ }
+
+#if defined(LIBDIVIDE_VECTOR_TYPE)
+ // Treats the vector as packed integer values with the same type as
+ // the divider (e.g. s32, u32, s64, u64) and divides each of
+ // them by the divider, returning the packed quotients.
+ LIBDIVIDE_VECTOR_TYPE divide(LIBDIVIDE_VECTOR_TYPE n) const {
+ return div.divide(n);
+ }
+#endif
+
+private:
+ // Storage for the actual divisor
+ dispatcher<std::is_integral<T>::value,
+ std::is_signed<T>::value, sizeof(T), ALGO> div;
+};
+
+// Overload of operator / for scalar division
+template<typename T, int ALGO>
+T operator/(T n, const divider<T, ALGO>& div) {
+ return div.divide(n);
+}
+
+// Overload of operator /= for scalar division
+template<typename T, int ALGO>
+T& operator/=(T& n, const divider<T, ALGO>& div) {
+ n = div.divide(n);
+ return n;
+}
+
+#if defined(LIBDIVIDE_VECTOR_TYPE)
+ // Overload of operator / for vector division
+ template<typename T, int ALGO>
+ LIBDIVIDE_VECTOR_TYPE operator/(LIBDIVIDE_VECTOR_TYPE n, const divider<T, ALGO>& div) {
+ return div.divide(n);
+ }
+ // Overload of operator /= for vector division
+ template<typename T, int ALGO>
+ LIBDIVIDE_VECTOR_TYPE& operator/=(LIBDIVIDE_VECTOR_TYPE& n, const divider<T, ALGO>& div) {
+ n = div.divide(n);
+ return n;
+ }
+#endif
+
+// libdivdie::branchfree_divider<T>
+template <typename T>
+using branchfree_divider = divider<T, BRANCHFREE>;
+
+} // namespace libdivide
+
+#endif // __cplusplus
+
+#endif // LIBDIVIDE_H
diff --git a/numpy/core/include/numpy/ndarraytypes.h b/numpy/core/include/numpy/ndarraytypes.h
index 63e8bf974..84441e641 100644
--- a/numpy/core/include/numpy/ndarraytypes.h
+++ b/numpy/core/include/numpy/ndarraytypes.h
@@ -236,6 +236,12 @@ typedef enum {
NPY_RAISE=2
} NPY_CLIPMODE;
+typedef enum {
+ NPY_VALID=0,
+ NPY_SAME=1,
+ NPY_FULL=2
+} NPY_CORRELATEMODE;
+
/* The special not-a-time (NaT) value */
#define NPY_DATETIME_NAT NPY_MIN_INT64
@@ -850,6 +856,17 @@ typedef int (PyArray_FinalizeFunc)(PyArrayObject *, PyObject *);
*/
#define NPY_ARRAY_ENSUREARRAY 0x0040
+#if defined(NPY_INTERNAL_BUILD) && NPY_INTERNAL_BUILD
+ /*
+ * Dual use of the ENSUREARRAY flag, to indicate that this was converted
+ * from a python float, int, or complex.
+ * An array using this flag must be a temporary array that can never
+ * leave the C internals of NumPy. Even if it does, ENSUREARRAY is
+ * absolutely safe to abuse, since it already is a base class array :).
+ */
+ #define _NPY_ARRAY_WAS_PYSCALAR 0x0040
+#endif /* NPY_INTERNAL_BUILD */
+
/*
* Make sure that the strides are in units of the element size Needed
* for some operations with record-arrays.
@@ -1219,6 +1236,8 @@ struct PyArrayIterObject_tag {
_PyAIT(it)->dataptr = PyArray_BYTES(_PyAIT(it)->ao); \
for (__npy_i = 0; __npy_i<=_PyAIT(it)->nd_m1; \
__npy_i++) { \
+ _PyAIT(it)->coordinates[__npy_i] = \
+ (__npy_ind / _PyAIT(it)->factors[__npy_i]); \
_PyAIT(it)->dataptr += \
(__npy_ind / _PyAIT(it)->factors[__npy_i]) \
* _PyAIT(it)->strides[__npy_i]; \
@@ -1289,7 +1308,6 @@ typedef struct {
#define PyArray_MultiIter_NOTDONE(multi) \
(_PyMIT(multi)->index < _PyMIT(multi)->size)
-
/*
* Store the information needed for fancy-indexing over an array. The
* fields are slightly unordered to keep consec, dataptr and subspace
@@ -1883,49 +1901,25 @@ typedef void (PyDataMem_EventHookFunc)(void *inp, void *outp, size_t size,
* may be a pointer to the *prototype* instance?
*/
PyArray_Descr *singleton;
- /*
- * Is this DType created using the old API? This exists mainly to
- * allow for assertions in paths specific to wrapping legacy types.
- */
- npy_bool legacy;
- /* The values stored by a parametric datatype depend on its instance */
- npy_bool parametric;
- /* whether the DType can be instantiated (i.e. np.dtype cannot) */
- npy_bool abstract;
+ /* Copy of the legacy DTypes type number, usually invalid. */
+ int type_num;
- /*
- * The following fields replicate the most important dtype information.
- * In the legacy implementation most of these are stored in the
- * PyArray_Descr struct.
- */
/* The type object of the scalar instances (may be NULL?) */
PyTypeObject *scalar_type;
- /* kind for this type */
- char kind;
- /* unique-character representing this type */
- char type;
- /* flags describing data type */
- char flags;
- /* number representing this type */
- int type_num;
/*
- * Point to the original ArrFuncs.
- * NOTE: We could make a copy to detect changes to `f`.
+ * DType flags to signal legacy, parametric, or
+ * abstract. But plenty of space for additional information/flags.
*/
- PyArray_ArrFuncs *f;
+ npy_uint64 flags;
- /* DType methods, these could be moved into its own struct */
- discover_descr_from_pyobject_function *discover_descr_from_pyobject;
- is_known_scalar_type_function *is_known_scalar_type;
- default_descr_function *default_descr;
- common_dtype_function *common_dtype;
- common_instance_function *common_instance;
/*
- * Dictionary of ArrayMethods representing most possible casts
- * (structured and object are exceptions).
- * This should potentially become a weak mapping in the future.
+ * Use indirection in order to allow a fixed size for this struct.
+ * A stable ABI size makes creating a static DType less painful
+ * while also ensuring flexibility for all opaque API (with one
+ * indirection due the pointer lookup).
*/
- PyObject *castingimpls;
+ void *dt_slots;
+ void *reserved[3];
};
#endif /* NPY_INTERNAL_BUILD */
diff --git a/numpy/core/include/numpy/npy_3kcompat.h b/numpy/core/include/numpy/npy_3kcompat.h
index 191cd244f..551ec6be8 100644
--- a/numpy/core/include/numpy/npy_3kcompat.h
+++ b/numpy/core/include/numpy/npy_3kcompat.h
@@ -216,6 +216,7 @@ static NPY_INLINE FILE*
npy_PyFile_Dup2(PyObject *file, char *mode, npy_off_t *orig_pos)
{
int fd, fd2, unbuf;
+ Py_ssize_t fd2_tmp;
PyObject *ret, *os, *io, *io_raw;
npy_off_t pos;
FILE *handle;
@@ -251,8 +252,17 @@ npy_PyFile_Dup2(PyObject *file, char *mode, npy_off_t *orig_pos)
if (ret == NULL) {
return NULL;
}
- fd2 = PyNumber_AsSsize_t(ret, NULL);
+ fd2_tmp = PyNumber_AsSsize_t(ret, PyExc_IOError);
Py_DECREF(ret);
+ if (fd2_tmp == -1 && PyErr_Occurred()) {
+ return NULL;
+ }
+ if (fd2_tmp < INT_MIN || fd2_tmp > INT_MAX) {
+ PyErr_SetString(PyExc_IOError,
+ "Getting an 'int' from os.dup() failed");
+ return NULL;
+ }
+ fd2 = (int)fd2_tmp;
/* Convert to FILE* handle */
#ifdef _WIN32
diff --git a/numpy/core/include/numpy/npy_common.h b/numpy/core/include/numpy/npy_common.h
index 78d6d3120..d5f329b66 100644
--- a/numpy/core/include/numpy/npy_common.h
+++ b/numpy/core/include/numpy/npy_common.h
@@ -14,9 +14,11 @@
* using static inline modifiers when defining npy_math functions
* allows the compiler to make optimizations when possible
*/
-#if defined(NPY_INTERNAL_BUILD) && NPY_INTERNAL_BUILD
#ifndef NPY_INLINE_MATH
-#define NPY_INLINE_MATH 1
+#if defined(NPY_INTERNAL_BUILD) && NPY_INTERNAL_BUILD
+ #define NPY_INLINE_MATH 1
+#else
+ #define NPY_INLINE_MATH 0
#endif
#endif
diff --git a/numpy/core/include/numpy/npy_cpu.h b/numpy/core/include/numpy/npy_cpu.h
index 4dbf9d84e..bc1fad72f 100644
--- a/numpy/core/include/numpy/npy_cpu.h
+++ b/numpy/core/include/numpy/npy_cpu.h
@@ -63,7 +63,8 @@
#define NPY_CPU_HPPA
#elif defined(__alpha__)
#define NPY_CPU_ALPHA
-#elif defined(__arm__) || defined(__aarch64__)
+#elif defined(__arm__) || defined(__aarch64__) || defined(_M_ARM64)
+ /* _M_ARM64 is defined in MSVC for ARM64 compilation on Windows */
#if defined(__ARMEB__) || defined(__AARCH64EB__)
#if defined(__ARM_32BIT_STATE)
#define NPY_CPU_ARMEB_AARCH32
@@ -72,10 +73,10 @@
#else
#define NPY_CPU_ARMEB
#endif
- #elif defined(__ARMEL__) || defined(__AARCH64EL__)
+ #elif defined(__ARMEL__) || defined(__AARCH64EL__) || defined(_M_ARM64)
#if defined(__ARM_32BIT_STATE)
#define NPY_CPU_ARMEL_AARCH32
- #elif defined(__ARM_64BIT_STATE)
+ #elif defined(__ARM_64BIT_STATE) || defined(_M_ARM64)
#define NPY_CPU_ARMEL_AARCH64
#else
#define NPY_CPU_ARMEL
@@ -110,10 +111,16 @@
information about your platform (OS, CPU and compiler)
#endif
-#if (defined(NPY_CPU_X86) || defined(NPY_CPU_AMD64))
-#define NPY_CPU_HAVE_UNALIGNED_ACCESS 1
-#else
-#define NPY_CPU_HAVE_UNALIGNED_ACCESS 0
+/*
+ * Except for the following architectures, memory access is limited to the natural
+ * alignment of data types otherwise it may lead to bus error or performance regression.
+ * For more details about unaligned access, see https://www.kernel.org/doc/Documentation/unaligned-memory-access.txt.
+*/
+#if defined(NPY_CPU_X86) || defined(NPY_CPU_AMD64) || defined(__aarch64__) || defined(__powerpc64__)
+ #define NPY_ALIGNMENT_REQUIRED 0
+#endif
+#ifndef NPY_ALIGNMENT_REQUIRED
+ #define NPY_ALIGNMENT_REQUIRED 1
#endif
#endif
diff --git a/numpy/core/include/numpy/npy_math.h b/numpy/core/include/numpy/npy_math.h
index dbade058f..f32e298f0 100644
--- a/numpy/core/include/numpy/npy_math.h
+++ b/numpy/core/include/numpy/npy_math.h
@@ -151,15 +151,6 @@ NPY_INPLACE npy_longlong npy_rshiftll(npy_longlong a, npy_longlong b);
NPY_INPLACE npy_longlong npy_lshiftll(npy_longlong a, npy_longlong b);
/*
- * avx function has a common API for both sin & cos. This enum is used to
- * distinguish between the two
- */
-typedef enum {
- npy_compute_sin,
- npy_compute_cos
-} NPY_TRIG_OP;
-
-/*
* C99 double math funcs
*/
NPY_INPLACE double npy_sin(double x);
@@ -211,7 +202,7 @@ double npy_spacing(double x);
/* use builtins to avoid function calls in tight loops
* only available if npy_config.h is available (= numpys own build) */
-#if HAVE___BUILTIN_ISNAN
+#ifdef HAVE___BUILTIN_ISNAN
#define npy_isnan(x) __builtin_isnan(x)
#else
#ifndef NPY_HAVE_DECL_ISNAN
@@ -227,7 +218,7 @@ double npy_spacing(double x);
/* only available if npy_config.h is available (= numpys own build) */
-#if HAVE___BUILTIN_ISFINITE
+#ifdef HAVE___BUILTIN_ISFINITE
#define npy_isfinite(x) __builtin_isfinite(x)
#else
#ifndef NPY_HAVE_DECL_ISFINITE
@@ -242,7 +233,7 @@ double npy_spacing(double x);
#endif
/* only available if npy_config.h is available (= numpys own build) */
-#if HAVE___BUILTIN_ISINF
+#ifdef HAVE___BUILTIN_ISINF
#define npy_isinf(x) __builtin_isinf(x)
#else
#ifndef NPY_HAVE_DECL_ISINF
diff --git a/numpy/core/include/numpy/numpyconfig.h b/numpy/core/include/numpy/numpyconfig.h
index a1b1de0ef..726f1dfac 100644
--- a/numpy/core/include/numpy/numpyconfig.h
+++ b/numpy/core/include/numpy/numpyconfig.h
@@ -43,5 +43,6 @@
#define NPY_1_19_API_VERSION 0x00000008
#define NPY_1_20_API_VERSION 0x0000000e
#define NPY_1_21_API_VERSION 0x0000000e
+#define NPY_1_22_API_VERSION 0x0000000e
#endif
diff --git a/numpy/core/include/numpy/random/distributions.h b/numpy/core/include/numpy/random/distributions.h
index c474c4d14..554198174 100644
--- a/numpy/core/include/numpy/random/distributions.h
+++ b/numpy/core/include/numpy/random/distributions.h
@@ -1,6 +1,10 @@
#ifndef _RANDOMDGEN__DISTRIBUTIONS_H_
#define _RANDOMDGEN__DISTRIBUTIONS_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include "Python.h"
#include "numpy/npy_common.h"
#include <stddef.h>
@@ -24,7 +28,7 @@
#define RAND_INT_MAX INT64_MAX
#endif
-#ifdef _MSC_VER
+#if defined(_MSC_VER) || defined(__CYGWIN__)
#define DECLDIR __declspec(dllexport)
#else
#define DECLDIR extern
@@ -119,8 +123,9 @@ DECLDIR RAND_INT_TYPE random_negative_binomial(bitgen_t *bitgen_state, double n,
DECLDIR int64_t random_binomial(bitgen_t *bitgen_state, double p,
int64_t n, binomial_t *binomial);
-DECLDIR RAND_INT_TYPE random_logseries(bitgen_t *bitgen_state, double p);
-DECLDIR RAND_INT_TYPE random_geometric(bitgen_t *bitgen_state, double p);
+DECLDIR int64_t random_logseries(bitgen_t *bitgen_state, double p);
+DECLDIR int64_t random_geometric(bitgen_t *bitgen_state, double p);
+DECLDIR RAND_INT_TYPE random_geometric_search(bitgen_t *bitgen_state, double p);
DECLDIR RAND_INT_TYPE random_zipf(bitgen_t *bitgen_state, double a);
DECLDIR int64_t random_hypergeometric(bitgen_t *bitgen_state,
int64_t good, int64_t bad, int64_t sample);
@@ -197,4 +202,8 @@ static NPY_INLINE double next_double(bitgen_t *bitgen_state) {
return bitgen_state->next_double(bitgen_state->state);
}
+#ifdef __cplusplus
+}
+#endif
+
#endif
diff --git a/numpy/core/include/numpy/ufuncobject.h b/numpy/core/include/numpy/ufuncobject.h
index e5d845842..fd7307703 100644
--- a/numpy/core/include/numpy/ufuncobject.h
+++ b/numpy/core/include/numpy/ufuncobject.h
@@ -66,27 +66,14 @@ typedef int (PyUFunc_TypeResolutionFunc)(
PyArray_Descr **out_dtypes);
/*
- * Given an array of DTypes as returned by the PyUFunc_TypeResolutionFunc,
- * and an array of fixed strides (the array will contain NPY_MAX_INTP for
- * strides which are not necessarily fixed), returns an inner loop
- * with associated auxiliary data.
- *
- * For backwards compatibility, there is a variant of the inner loop
- * selection which returns an inner loop irrespective of the strides,
- * and with a void* static auxiliary data instead of an NpyAuxData *
- * dynamically allocatable auxiliary data.
+ * Legacy loop selector. (This should NOT normally be used and we can expect
+ * that only the `PyUFunc_DefaultLegacyInnerLoopSelector` is ever set).
+ * However, unlike the masked version, it probably still works.
*
* ufunc: The ufunc object.
* dtypes: An array which has been populated with dtypes,
* in most cases by the type resolution function
* for the same ufunc.
- * fixed_strides: For each input/output, either the stride that
- * will be used every time the function is called
- * or NPY_MAX_INTP if the stride might change or
- * is not known ahead of time. The loop selection
- * function may use this stride to pick inner loops
- * which are optimized for contiguous or 0-stride
- * cases.
* out_innerloop: Should be populated with the correct ufunc inner
* loop for the given type.
* out_innerloopdata: Should be populated with the void* data to
@@ -101,15 +88,7 @@ typedef int (PyUFunc_LegacyInnerLoopSelectionFunc)(
PyUFuncGenericFunction *out_innerloop,
void **out_innerloopdata,
int *out_needs_api);
-typedef int (PyUFunc_MaskedInnerLoopSelectionFunc)(
- struct _tagPyUFuncObject *ufunc,
- PyArray_Descr **dtypes,
- PyArray_Descr *mask_dtype,
- npy_intp *fixed_strides,
- npy_intp fixed_mask_stride,
- PyUFunc_MaskedStridedInnerLoopFunc **out_innerloop,
- NpyAuxData **out_innerloopdata,
- int *out_needs_api);
+
typedef struct _tagPyUFuncObject {
PyObject_HEAD
@@ -194,11 +173,13 @@ typedef struct _tagPyUFuncObject {
* but this was never implemented. (This is also why the above
* selector is called the "legacy" selector.)
*/
+ #if PY_VERSION_HEX >= 0x03080000
+ vectorcallfunc vectorcall;
+ #else
void *reserved2;
- /*
- * A function which returns a masked inner loop for the ufunc.
- */
- PyUFunc_MaskedInnerLoopSelectionFunc *masked_inner_loop_selector;
+ #endif
+ /* Was previously the `PyUFunc_MaskedInnerLoopSelectionFunc` */
+ void *_always_null_previously_masked_innerloop_selector;
/*
* List of flags for each operand when ufunc is called by nditer object.
@@ -230,6 +211,12 @@ typedef struct _tagPyUFuncObject {
/* Identity for reduction, when identity == PyUFunc_IdentityValue */
PyObject *identity_value;
+ /* New in NPY_API_VERSION 0x0000000F and above */
+
+ /* New private fields related to dispatching */
+ void *_dispatch_cache;
+ /* A PyListObject of `(tuple of DTypes, ArrayMethod/Promoter)` */
+ PyObject *_loops;
} PyUFuncObject;
#include "arrayobject.h"
diff --git a/numpy/core/machar.py b/numpy/core/machar.py
index 55285fe59..04dad4d77 100644
--- a/numpy/core/machar.py
+++ b/numpy/core/machar.py
@@ -56,13 +56,19 @@ class MachAr:
epsilon : float
Same as `eps`.
tiny : float
- Same as `xmin`.
+ An alias for `smallest_normal`, kept for backwards compatibility.
huge : float
Same as `xmax`.
precision : float
``- int(-log10(eps))``
resolution : float
``- 10**(-precision)``
+ smallest_normal : float
+ The smallest positive floating point number with 1 as leading bit in
+ the mantissa following IEEE-754. Same as `xmin`.
+ smallest_subnormal : float
+ The smallest positive floating point number with 0 as leading bit in
+ the mantissa following IEEE-754.
Parameters
----------
@@ -293,6 +299,8 @@ class MachAr:
else:
xmax = xmax * beta
+ smallest_subnormal = abs(xmin / beta ** (it))
+
self.ibeta = ibeta
self.it = it
self.negep = negep
@@ -316,6 +324,8 @@ class MachAr:
self.epsilon = self.eps
self.tiny = self.xmin
self.huge = self.xmax
+ self.smallest_normal = self.xmin
+ self.smallest_subnormal = float_to_float(smallest_subnormal)
import math
self.precision = int(-math.log10(float_to_float(self.eps)))
@@ -333,6 +343,8 @@ class MachAr:
'negep =%(negep)s epsneg=%(_str_epsneg)s (beta**epsneg)\n'
'minexp=%(minexp)s xmin=%(_str_xmin)s (beta**minexp == tiny)\n'
'maxexp=%(maxexp)s xmax=%(_str_xmax)s ((1-epsneg)*beta**maxexp == huge)\n'
+ 'smallest_normal=%(smallest_normal)s '
+ 'smallest_subnormal=%(smallest_subnormal)s\n'
'---------------------------------------------------------------------\n'
)
return fmt % self.__dict__
diff --git a/numpy/core/memmap.py b/numpy/core/memmap.py
index 66653c0c1..b0d9cb3af 100644
--- a/numpy/core/memmap.py
+++ b/numpy/core/memmap.py
@@ -1,8 +1,8 @@
+from contextlib import nullcontext
+
import numpy as np
from .numeric import uint8, ndarray, dtype
-from numpy.compat import (
- os_fspath, contextlib_nullcontext, is_pathlib_path
-)
+from numpy.compat import os_fspath, is_pathlib_path
from numpy.core.overrides import set_module
__all__ = ['memmap']
@@ -38,7 +38,7 @@ class memmap(ndarray):
which returns a view into an mmap buffer.
Flush the memmap instance to write the changes to the file. Currently there
- is no API to close the underlying ``mmap``. It is tricky to ensure the
+ is no API to close the underlying ``mmap``. It is tricky to ensure the
resource is actually closed, since it may be shared between different
memmap instances.
@@ -112,7 +112,7 @@ class memmap(ndarray):
The memmap object can be used anywhere an ndarray is accepted.
Given a memmap ``fp``, ``isinstance(fp, numpy.ndarray)`` returns
``True``.
-
+
Memory-mapped files cannot be larger than 2GB on 32-bit systems.
When a memmap causes a file to be created or extended beyond its
@@ -223,7 +223,7 @@ class memmap(ndarray):
raise ValueError("shape must be given")
if hasattr(filename, 'read'):
- f_ctx = contextlib_nullcontext(filename)
+ f_ctx = nullcontext(filename)
else:
f_ctx = open(os_fspath(filename), ('r' if mode == 'c' else mode)+'b')
@@ -316,7 +316,7 @@ class memmap(ndarray):
self.base.flush()
def __array_wrap__(self, arr, context=None):
- arr = super(memmap, self).__array_wrap__(arr, context)
+ arr = super().__array_wrap__(arr, context)
# Return a memmap if a memmap was given as the output of the
# ufunc. Leave the arr class unchanged if self is not a memmap
@@ -331,7 +331,7 @@ class memmap(ndarray):
return arr.view(np.ndarray)
def __getitem__(self, index):
- res = super(memmap, self).__getitem__(index)
+ res = super().__getitem__(index)
if type(res) is memmap and res._mmap is None:
return res.view(type=ndarray)
return res
diff --git a/numpy/core/multiarray.py b/numpy/core/multiarray.py
index f311fad8d..154df6f4d 100644
--- a/numpy/core/multiarray.py
+++ b/numpy/core/multiarray.py
@@ -7,8 +7,6 @@ by importing from the extension module.
"""
import functools
-import warnings
-
from . import overrides
from . import _multiarray_umath
from ._multiarray_umath import * # noqa: F403
@@ -26,11 +24,12 @@ __all__ = [
'MAY_SHARE_BOUNDS', 'MAY_SHARE_EXACT', 'NEEDS_INIT', 'NEEDS_PYAPI',
'RAISE', 'USE_GETITEM', 'USE_SETITEM', 'WRAP', '_fastCopyAndTranspose',
'_flagdict', '_insert', '_reconstruct', '_vec_string', '_monotonicity',
- 'add_docstring', 'arange', 'array', 'bincount', 'broadcast',
+ 'add_docstring', 'arange', 'array', 'asarray', 'asanyarray',
+ 'ascontiguousarray', 'asfortranarray', 'bincount', 'broadcast',
'busday_count', 'busday_offset', 'busdaycalendar', 'can_cast',
'compare_chararrays', 'concatenate', 'copyto', 'correlate', 'correlate2',
'count_nonzero', 'c_einsum', 'datetime_as_string', 'datetime_data',
- 'digitize', 'dot', 'dragon4_positional', 'dragon4_scientific', 'dtype',
+ 'dot', 'dragon4_positional', 'dragon4_scientific', 'dtype',
'empty', 'empty_like', 'error', 'flagsobj', 'flatiter', 'format_longfloat',
'frombuffer', 'fromfile', 'fromiter', 'fromstring', 'inner',
'interp', 'interp_complex', 'is_busday', 'lexsort',
@@ -49,6 +48,10 @@ scalar.__module__ = 'numpy.core.multiarray'
arange.__module__ = 'numpy'
array.__module__ = 'numpy'
+asarray.__module__ = 'numpy'
+asanyarray.__module__ = 'numpy'
+ascontiguousarray.__module__ = 'numpy'
+asfortranarray.__module__ = 'numpy'
datetime_data.__module__ = 'numpy'
empty.__module__ = 'numpy'
frombuffer.__module__ = 'numpy'
@@ -244,7 +247,7 @@ def concatenate(arrays, axis=None, out=None, *, dtype=None, casting=None):
@array_function_from_c_func_and_dispatcher(_multiarray_umath.inner)
def inner(a, b):
"""
- inner(a, b)
+ inner(a, b, /)
Inner product of two arrays.
@@ -259,12 +262,16 @@ def inner(a, b):
Returns
-------
out : ndarray
- `out.shape = a.shape[:-1] + b.shape[:-1]`
+ If `a` and `b` are both
+ scalars or both 1-D arrays then a scalar is returned; otherwise
+ an array is returned.
+ ``out.shape = (*a.shape[:-1], *b.shape[:-1])``
Raises
------
ValueError
- If the last dimension of `a` and `b` has different size.
+ If both `a` and `b` are nonscalar and their last dimensions have
+ different sizes.
See Also
--------
@@ -284,8 +291,8 @@ def inner(a, b):
or explicitly::
- np.inner(a, b)[i0,...,ir-1,j0,...,js-1]
- = sum(a[i0,...,ir-1,:]*b[j0,...,js-1,:])
+ np.inner(a, b)[i0,...,ir-2,j0,...,js-2]
+ = sum(a[i0,...,ir-2,:]*b[j0,...,js-2,:])
In addition `a` or `b` may be scalars, in which case::
@@ -300,14 +307,25 @@ def inner(a, b):
>>> np.inner(a, b)
2
- A multidimensional example:
+ Some multidimensional examples:
>>> a = np.arange(24).reshape((2,3,4))
>>> b = np.arange(4)
- >>> np.inner(a, b)
+ >>> c = np.inner(a, b)
+ >>> c.shape
+ (2, 3)
+ >>> c
array([[ 14, 38, 62],
[ 86, 110, 134]])
+ >>> a = np.arange(2).reshape((1,1,2))
+ >>> b = np.arange(6).reshape((3,2))
+ >>> c = np.inner(a, b)
+ >>> c.shape
+ (1, 1, 3)
+ >>> c
+ array([[[1, 3, 5]]])
+
An example where `b` is a scalar:
>>> np.inner(np.eye(2), 7)
@@ -321,7 +339,7 @@ def inner(a, b):
@array_function_from_c_func_and_dispatcher(_multiarray_umath.where)
def where(condition, x=None, y=None):
"""
- where(condition, [x, y])
+ where(condition, [x, y], /)
Return elements chosen from `x` or `y` depending on `condition`.
@@ -593,7 +611,7 @@ def can_cast(from_, to, casting=None):
@array_function_from_c_func_and_dispatcher(_multiarray_umath.min_scalar_type)
def min_scalar_type(a):
"""
- min_scalar_type(a)
+ min_scalar_type(a, /)
For scalar ``a``, returns the data type with the smallest size
and smallest scalar kind which can hold its value. For non-scalar
@@ -805,7 +823,7 @@ def dot(a, b, out=None):
@array_function_from_c_func_and_dispatcher(_multiarray_umath.vdot)
def vdot(a, b):
"""
- vdot(a, b)
+ vdot(a, b, /)
Return the dot product of two vectors.
@@ -863,7 +881,7 @@ def vdot(a, b):
@array_function_from_c_func_and_dispatcher(_multiarray_umath.bincount)
def bincount(x, weights=None, minlength=None):
"""
- bincount(x, weights=None, minlength=0)
+ bincount(x, /, weights=None, minlength=0)
Count number of occurrences of each value in array of non-negative ints.
@@ -999,7 +1017,7 @@ def ravel_multi_index(multi_index, dims, mode=None, order=None):
@array_function_from_c_func_and_dispatcher(_multiarray_umath.unravel_index)
-def unravel_index(indices, shape=None, order=None, dims=None):
+def unravel_index(indices, shape=None, order=None):
"""
unravel_index(indices, shape, order='C')
@@ -1045,9 +1063,6 @@ def unravel_index(indices, shape=None, order=None, dims=None):
(3, 1, 4, 1)
"""
- if dims is not None:
- warnings.warn("'shape' argument should be used instead of 'dims'",
- DeprecationWarning, stacklevel=3)
return (indices,)
@@ -1134,7 +1149,7 @@ def putmask(a, mask, values):
@array_function_from_c_func_and_dispatcher(_multiarray_umath.packbits)
def packbits(a, axis=None, bitorder='big'):
"""
- packbits(a, axis=None, bitorder='big')
+ packbits(a, /, axis=None, bitorder='big')
Packs the elements of a binary-valued array into bits in a uint8 array.
@@ -1192,7 +1207,7 @@ def packbits(a, axis=None, bitorder='big'):
@array_function_from_c_func_and_dispatcher(_multiarray_umath.unpackbits)
def unpackbits(a, axis=None, count=None, bitorder='big'):
"""
- unpackbits(a, axis=None, count=None, bitorder='big')
+ unpackbits(a, /, axis=None, count=None, bitorder='big')
Unpacks elements of a uint8 array into a binary-valued output array.
@@ -1276,7 +1291,7 @@ def unpackbits(a, axis=None, count=None, bitorder='big'):
@array_function_from_c_func_and_dispatcher(_multiarray_umath.shares_memory)
def shares_memory(a, b, max_work=None):
"""
- shares_memory(a, b, max_work=None)
+ shares_memory(a, b, /, max_work=None)
Determine if two arrays share memory.
@@ -1351,7 +1366,7 @@ def shares_memory(a, b, max_work=None):
@array_function_from_c_func_and_dispatcher(_multiarray_umath.may_share_memory)
def may_share_memory(a, b, max_work=None):
"""
- may_share_memory(a, b, max_work=None)
+ may_share_memory(a, b, /, max_work=None)
Determine if two arrays might share memory
@@ -1429,7 +1444,7 @@ def is_busday(dates, weekmask=None, holidays=None, busdaycal=None, out=None):
See Also
--------
- busdaycalendar: An object that specifies a custom set of valid days.
+ busdaycalendar : An object that specifies a custom set of valid days.
busday_offset : Applies an offset counted in valid days.
busday_count : Counts how many valid days are in a half-open date range.
@@ -1504,7 +1519,7 @@ def busday_offset(dates, offsets, roll=None, weekmask=None, holidays=None,
See Also
--------
- busdaycalendar: An object that specifies a custom set of valid days.
+ busdaycalendar : An object that specifies a custom set of valid days.
is_busday : Returns a boolean array indicating valid days.
busday_count : Counts how many valid days are in a half-open date range.
@@ -1586,7 +1601,7 @@ def busday_count(begindates, enddates, weekmask=None, holidays=None,
See Also
--------
- busdaycalendar: An object that specifies a custom set of valid days.
+ busdaycalendar : An object that specifies a custom set of valid days.
is_busday : Returns a boolean array indicating valid days.
busday_offset : Applies an offset counted in valid days.
diff --git a/numpy/core/multiarray.pyi b/numpy/core/multiarray.pyi
new file mode 100644
index 000000000..a7d2e6bbf
--- /dev/null
+++ b/numpy/core/multiarray.pyi
@@ -0,0 +1,1002 @@
+# TODO: Sort out any and all missing functions in this namespace
+
+import os
+import sys
+import datetime as dt
+from typing import (
+ Any,
+ Callable,
+ IO,
+ Iterable,
+ Optional,
+ overload,
+ TypeVar,
+ List,
+ Type,
+ Union,
+ Sequence,
+ Tuple,
+)
+
+from numpy import (
+ # Re-exports
+ busdaycalendar as busdaycalendar,
+ broadcast as broadcast,
+ dtype as dtype,
+ ndarray as ndarray,
+ nditer as nditer,
+
+ # The rest
+ nditer,
+ ufunc,
+ str_,
+ bool_,
+ uint8,
+ intp,
+ int_,
+ float64,
+ timedelta64,
+ datetime64,
+ generic,
+ unsignedinteger,
+ signedinteger,
+ floating,
+ complexfloating,
+ _OrderKACF,
+ _OrderCF,
+ _CastingKind,
+ _ModeKind,
+ _SupportsBuffer,
+)
+
+from numpy.typing import (
+ # Shapes
+ _ShapeLike,
+
+ # DTypes
+ DTypeLike,
+ _SupportsDType,
+
+ # Arrays
+ NDArray,
+ ArrayLike,
+ _SupportsArray,
+ _NestedSequence,
+ _ArrayLikeBool_co,
+ _ArrayLikeUInt_co,
+ _ArrayLikeInt_co,
+ _ArrayLikeFloat_co,
+ _ArrayLikeComplex_co,
+ _ArrayLikeTD64_co,
+ _ArrayLikeDT64_co,
+ _ArrayLikeObject_co,
+ _ArrayLikeStr_co,
+ _ArrayLikeBytes_co,
+ _ScalarLike_co,
+ _IntLike_co,
+ _FloatLike_co,
+ _TD64Like_co,
+)
+
+if sys.version_info >= (3, 8):
+ from typing import SupportsIndex, final, Final, Literal as L
+else:
+ from typing_extensions import SupportsIndex, final, Final, Literal as L
+
+_SCT = TypeVar("_SCT", bound=generic)
+_ArrayType = TypeVar("_ArrayType", bound=NDArray[Any])
+
+# Subscriptable subsets of `npt.DTypeLike` and `npt.ArrayLike`
+_DTypeLike = Union[
+ dtype[_SCT],
+ Type[_SCT],
+ _SupportsDType[dtype[_SCT]],
+]
+_ArrayLike = _NestedSequence[_SupportsArray[dtype[_SCT]]]
+
+# Valid time units
+_UnitKind = L[
+ "Y",
+ "M",
+ "D",
+ "h",
+ "m",
+ "s",
+ "ms",
+ "us", "μs",
+ "ns",
+ "ps",
+ "fs",
+ "as",
+]
+_RollKind = L[ # `raise` is deliberately excluded
+ "nat",
+ "forward",
+ "following",
+ "backward",
+ "preceding",
+ "modifiedfollowing",
+ "modifiedpreceding",
+]
+
+__all__: List[str]
+
+ALLOW_THREADS: Final[int] # 0 or 1 (system-specific)
+BUFSIZE: L[8192]
+CLIP: L[0]
+WRAP: L[1]
+RAISE: L[2]
+MAXDIMS: L[32]
+MAY_SHARE_BOUNDS: L[0]
+MAY_SHARE_EXACT: L[-1]
+tracemalloc_domain: L[389047]
+
+@overload
+def empty_like(
+ prototype: _ArrayType,
+ dtype: None = ...,
+ order: _OrderKACF = ...,
+ subok: bool = ...,
+ shape: Optional[_ShapeLike] = ...,
+) -> _ArrayType: ...
+@overload
+def empty_like(
+ prototype: _ArrayLike[_SCT],
+ dtype: None = ...,
+ order: _OrderKACF = ...,
+ subok: bool = ...,
+ shape: Optional[_ShapeLike] = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def empty_like(
+ prototype: object,
+ dtype: None = ...,
+ order: _OrderKACF = ...,
+ subok: bool = ...,
+ shape: Optional[_ShapeLike] = ...,
+) -> NDArray[Any]: ...
+@overload
+def empty_like(
+ prototype: Any,
+ dtype: _DTypeLike[_SCT],
+ order: _OrderKACF = ...,
+ subok: bool = ...,
+ shape: Optional[_ShapeLike] = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def empty_like(
+ prototype: Any,
+ dtype: DTypeLike,
+ order: _OrderKACF = ...,
+ subok: bool = ...,
+ shape: Optional[_ShapeLike] = ...,
+) -> NDArray[Any]: ...
+
+@overload
+def array(
+ object: _ArrayType,
+ dtype: None = ...,
+ *,
+ copy: bool = ...,
+ order: _OrderKACF = ...,
+ subok: L[True],
+ ndmin: int = ...,
+ like: ArrayLike = ...,
+) -> _ArrayType: ...
+@overload
+def array(
+ object: _ArrayLike[_SCT],
+ dtype: None = ...,
+ *,
+ copy: bool = ...,
+ order: _OrderKACF = ...,
+ subok: bool = ...,
+ ndmin: int = ...,
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def array(
+ object: object,
+ dtype: None = ...,
+ *,
+ copy: bool = ...,
+ order: _OrderKACF = ...,
+ subok: bool = ...,
+ ndmin: int = ...,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+@overload
+def array(
+ object: Any,
+ dtype: _DTypeLike[_SCT],
+ *,
+ copy: bool = ...,
+ order: _OrderKACF = ...,
+ subok: bool = ...,
+ ndmin: int = ...,
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def array(
+ object: Any,
+ dtype: DTypeLike,
+ *,
+ copy: bool = ...,
+ order: _OrderKACF = ...,
+ subok: bool = ...,
+ ndmin: int = ...,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+
+@overload
+def zeros(
+ shape: _ShapeLike,
+ dtype: None = ...,
+ order: _OrderCF = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[float64]: ...
+@overload
+def zeros(
+ shape: _ShapeLike,
+ dtype: _DTypeLike[_SCT],
+ order: _OrderCF = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def zeros(
+ shape: _ShapeLike,
+ dtype: DTypeLike,
+ order: _OrderCF = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+
+@overload
+def empty(
+ shape: _ShapeLike,
+ dtype: None = ...,
+ order: _OrderCF = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[float64]: ...
+@overload
+def empty(
+ shape: _ShapeLike,
+ dtype: _DTypeLike[_SCT],
+ order: _OrderCF = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def empty(
+ shape: _ShapeLike,
+ dtype: DTypeLike,
+ order: _OrderCF = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+
+@overload
+def unravel_index( # type: ignore[misc]
+ indices: _IntLike_co,
+ shape: _ShapeLike,
+ order: _OrderCF = ...,
+) -> Tuple[intp, ...]: ...
+@overload
+def unravel_index(
+ indices: _ArrayLikeInt_co,
+ shape: _ShapeLike,
+ order: _OrderCF = ...,
+) -> Tuple[NDArray[intp], ...]: ...
+
+@overload
+def ravel_multi_index( # type: ignore[misc]
+ multi_index: Sequence[_IntLike_co],
+ dims: Sequence[SupportsIndex],
+ mode: Union[_ModeKind, Tuple[_ModeKind, ...]] = ...,
+ order: _OrderCF = ...,
+) -> intp: ...
+@overload
+def ravel_multi_index(
+ multi_index: Sequence[_ArrayLikeInt_co],
+ dims: Sequence[SupportsIndex],
+ mode: Union[_ModeKind, Tuple[_ModeKind, ...]] = ...,
+ order: _OrderCF = ...,
+) -> NDArray[intp]: ...
+
+@overload
+def concatenate( # type: ignore[misc]
+ __arrays: _ArrayLike[_SCT],
+ axis: Optional[SupportsIndex] = ...,
+ out: None = ...,
+ *,
+ dtype: None = ...,
+ casting: Optional[_CastingKind] = ...
+) -> NDArray[_SCT]: ...
+@overload
+def concatenate( # type: ignore[misc]
+ __arrays: ArrayLike,
+ axis: Optional[SupportsIndex] = ...,
+ out: None = ...,
+ *,
+ dtype: None = ...,
+ casting: Optional[_CastingKind] = ...
+) -> NDArray[Any]: ...
+@overload
+def concatenate( # type: ignore[misc]
+ __arrays: ArrayLike,
+ axis: Optional[SupportsIndex] = ...,
+ out: None = ...,
+ *,
+ dtype: _DTypeLike[_SCT],
+ casting: Optional[_CastingKind] = ...
+) -> NDArray[_SCT]: ...
+@overload
+def concatenate( # type: ignore[misc]
+ __arrays: ArrayLike,
+ axis: Optional[SupportsIndex] = ...,
+ out: None = ...,
+ *,
+ dtype: DTypeLike,
+ casting: Optional[_CastingKind] = ...
+) -> NDArray[Any]: ...
+@overload
+def concatenate(
+ __arrays: ArrayLike,
+ axis: Optional[SupportsIndex] = ...,
+ out: _ArrayType = ...,
+ *,
+ dtype: DTypeLike = ...,
+ casting: Optional[_CastingKind] = ...
+) -> _ArrayType: ...
+
+def inner(
+ __a: ArrayLike,
+ __b: ArrayLike,
+) -> Any: ...
+
+@overload
+def where(
+ __condition: ArrayLike,
+) -> Tuple[NDArray[intp], ...]: ...
+@overload
+def where(
+ __condition: ArrayLike,
+ __x: ArrayLike,
+ __y: ArrayLike,
+) -> NDArray[Any]: ...
+
+def lexsort(
+ keys: ArrayLike,
+ axis: Optional[SupportsIndex] = ...,
+) -> Any: ...
+
+def can_cast(
+ from_: Union[ArrayLike, DTypeLike],
+ to: DTypeLike,
+ casting: Optional[_CastingKind] = ...,
+) -> bool: ...
+
+def min_scalar_type(
+ __a: ArrayLike,
+) -> dtype[Any]: ...
+
+def result_type(
+ *arrays_and_dtypes: Union[ArrayLike, DTypeLike],
+) -> dtype[Any]: ...
+
+@overload
+def dot(a: ArrayLike, b: ArrayLike, out: None = ...) -> Any: ...
+@overload
+def dot(a: ArrayLike, b: ArrayLike, out: _ArrayType) -> _ArrayType: ...
+
+@overload
+def vdot(__a: _ArrayLikeBool_co, __b: _ArrayLikeBool_co) -> bool_: ... # type: ignore[misc]
+@overload
+def vdot(__a: _ArrayLikeUInt_co, __b: _ArrayLikeUInt_co) -> unsignedinteger[Any]: ... # type: ignore[misc]
+@overload
+def vdot(__a: _ArrayLikeInt_co, __b: _ArrayLikeInt_co) -> signedinteger[Any]: ... # type: ignore[misc]
+@overload
+def vdot(__a: _ArrayLikeFloat_co, __b: _ArrayLikeFloat_co) -> floating[Any]: ... # type: ignore[misc]
+@overload
+def vdot(__a: _ArrayLikeComplex_co, __b: _ArrayLikeComplex_co) -> complexfloating[Any, Any]: ... # type: ignore[misc]
+@overload
+def vdot(__a: _ArrayLikeTD64_co, __b: _ArrayLikeTD64_co) -> timedelta64: ...
+@overload
+def vdot(__a: _ArrayLikeObject_co, __b: Any) -> Any: ...
+@overload
+def vdot(__a: Any, __b: _ArrayLikeObject_co) -> Any: ...
+
+def bincount(
+ __x: ArrayLike,
+ weights: Optional[ArrayLike] = ...,
+ minlength: SupportsIndex = ...,
+) -> NDArray[intp]: ...
+
+def copyto(
+ dst: NDArray[Any],
+ src: ArrayLike,
+ casting: Optional[_CastingKind] = ...,
+ where: Optional[_ArrayLikeBool_co] = ...,
+) -> None: ...
+
+def putmask(
+ a: NDArray[Any],
+ mask: _ArrayLikeBool_co,
+ values: ArrayLike,
+) -> None: ...
+
+def packbits(
+ __a: _ArrayLikeInt_co,
+ axis: Optional[SupportsIndex] = ...,
+ bitorder: L["big", "little"] = ...,
+) -> NDArray[uint8]: ...
+
+def unpackbits(
+ __a: _ArrayLike[uint8],
+ axis: Optional[SupportsIndex] = ...,
+ count: Optional[SupportsIndex] = ...,
+ bitorder: L["big", "little"] = ...,
+) -> NDArray[uint8]: ...
+
+def shares_memory(
+ __a: object,
+ __b: object,
+ max_work: Optional[int] = ...,
+) -> bool: ...
+
+def may_share_memory(
+ __a: object,
+ __b: object,
+ max_work: Optional[int] = ...,
+) -> bool: ...
+
+@overload
+def asarray(
+ a: _ArrayLike[_SCT],
+ dtype: None = ...,
+ order: _OrderKACF = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def asarray(
+ a: object,
+ dtype: None = ...,
+ order: _OrderKACF = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+@overload
+def asarray(
+ a: Any,
+ dtype: _DTypeLike[_SCT],
+ order: _OrderKACF = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def asarray(
+ a: Any,
+ dtype: DTypeLike,
+ order: _OrderKACF = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+
+@overload
+def asanyarray(
+ a: _ArrayType, # Preserve subclass-information
+ dtype: None = ...,
+ order: _OrderKACF = ...,
+ *,
+ like: ArrayLike = ...,
+) -> _ArrayType: ...
+@overload
+def asanyarray(
+ a: _ArrayLike[_SCT],
+ dtype: None = ...,
+ order: _OrderKACF = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def asanyarray(
+ a: object,
+ dtype: None = ...,
+ order: _OrderKACF = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+@overload
+def asanyarray(
+ a: Any,
+ dtype: _DTypeLike[_SCT],
+ order: _OrderKACF = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def asanyarray(
+ a: Any,
+ dtype: DTypeLike,
+ order: _OrderKACF = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+
+@overload
+def ascontiguousarray(
+ a: _ArrayLike[_SCT],
+ dtype: None = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def ascontiguousarray(
+ a: object,
+ dtype: None = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+@overload
+def ascontiguousarray(
+ a: Any,
+ dtype: _DTypeLike[_SCT],
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def ascontiguousarray(
+ a: Any,
+ dtype: DTypeLike,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+
+@overload
+def asfortranarray(
+ a: _ArrayLike[_SCT],
+ dtype: None = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def asfortranarray(
+ a: object,
+ dtype: None = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+@overload
+def asfortranarray(
+ a: Any,
+ dtype: _DTypeLike[_SCT],
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def asfortranarray(
+ a: Any,
+ dtype: DTypeLike,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+
+# In practice `List[Any]` is list with an int, int and a valid
+# `np.seterrcall()` object
+def geterrobj() -> List[Any]: ...
+def seterrobj(__errobj: List[Any]) -> None: ...
+
+def promote_types(__type1: DTypeLike, __type2: DTypeLike) -> dtype[Any]: ...
+
+# `sep` is a de facto mandatory argument, as its default value is deprecated
+@overload
+def fromstring(
+ string: str | bytes,
+ dtype: None = ...,
+ count: SupportsIndex = ...,
+ *,
+ sep: str,
+ like: ArrayLike = ...,
+) -> NDArray[float64]: ...
+@overload
+def fromstring(
+ string: str | bytes,
+ dtype: _DTypeLike[_SCT],
+ count: SupportsIndex = ...,
+ *,
+ sep: str,
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def fromstring(
+ string: str | bytes,
+ dtype: DTypeLike,
+ count: SupportsIndex = ...,
+ *,
+ sep: str,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+
+def frompyfunc(
+ __func: Callable[..., Any],
+ nin: SupportsIndex,
+ nout: SupportsIndex,
+ *,
+ identity: Any = ...,
+) -> ufunc: ...
+
+@overload
+def fromfile(
+ file: str | bytes | os.PathLike[Any] | IO[Any],
+ dtype: None = ...,
+ count: SupportsIndex = ...,
+ sep: str = ...,
+ offset: SupportsIndex = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[float64]: ...
+@overload
+def fromfile(
+ file: str | bytes | os.PathLike[Any] | IO[Any],
+ dtype: _DTypeLike[_SCT],
+ count: SupportsIndex = ...,
+ sep: str = ...,
+ offset: SupportsIndex = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def fromfile(
+ file: str | bytes | os.PathLike[Any] | IO[Any],
+ dtype: DTypeLike,
+ count: SupportsIndex = ...,
+ sep: str = ...,
+ offset: SupportsIndex = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+
+@overload
+def fromiter(
+ iter: Iterable[Any],
+ dtype: _DTypeLike[_SCT],
+ count: SupportsIndex = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def fromiter(
+ iter: Iterable[Any],
+ dtype: DTypeLike,
+ count: SupportsIndex = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+
+@overload
+def frombuffer(
+ buffer: _SupportsBuffer,
+ dtype: None = ...,
+ count: SupportsIndex = ...,
+ offset: SupportsIndex = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[float64]: ...
+@overload
+def frombuffer(
+ buffer: _SupportsBuffer,
+ dtype: _DTypeLike[_SCT],
+ count: SupportsIndex = ...,
+ offset: SupportsIndex = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def frombuffer(
+ buffer: _SupportsBuffer,
+ dtype: DTypeLike,
+ count: SupportsIndex = ...,
+ offset: SupportsIndex = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+
+@overload
+def arange( # type: ignore[misc]
+ __stop: _IntLike_co,
+ *,
+ dtype: None = ...,
+ like: ArrayLike = ...,
+) -> NDArray[signedinteger[Any]]: ...
+@overload
+def arange( # type: ignore[misc]
+ start: _IntLike_co,
+ stop: _IntLike_co,
+ step: _IntLike_co = ...,
+ dtype: None = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[signedinteger[Any]]: ...
+@overload
+def arange( # type: ignore[misc]
+ __stop: _FloatLike_co,
+ *,
+ dtype: None = ...,
+ like: ArrayLike = ...,
+) -> NDArray[floating[Any]]: ...
+@overload
+def arange( # type: ignore[misc]
+ start: _FloatLike_co,
+ stop: _FloatLike_co,
+ step: _FloatLike_co = ...,
+ dtype: None = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[floating[Any]]: ...
+@overload
+def arange(
+ __stop: _TD64Like_co,
+ *,
+ dtype: None = ...,
+ like: ArrayLike = ...,
+) -> NDArray[timedelta64]: ...
+@overload
+def arange(
+ start: _TD64Like_co,
+ stop: _TD64Like_co,
+ step: _TD64Like_co = ...,
+ dtype: None = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[timedelta64]: ...
+@overload
+def arange( # both start and stop must always be specified for datetime64
+ start: datetime64,
+ stop: datetime64,
+ step: datetime64 = ...,
+ dtype: None = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[datetime64]: ...
+@overload
+def arange(
+ __stop: Any,
+ *,
+ dtype: _DTypeLike[_SCT],
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def arange(
+ start: Any,
+ stop: Any,
+ step: Any = ...,
+ dtype: _DTypeLike[_SCT] = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def arange(
+ __stop: Any,
+ *,
+ dtype: DTypeLike,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+@overload
+def arange(
+ start: Any,
+ stop: Any,
+ step: Any = ...,
+ dtype: DTypeLike = ...,
+ *,
+ like: ArrayLike = ...,
+) -> NDArray[Any]: ...
+
+def datetime_data(
+ __dtype: str | _DTypeLike[datetime64] | _DTypeLike[timedelta64],
+) -> Tuple[str, int]: ...
+
+# The datetime functions perform unsafe casts to `datetime64[D]`,
+# so a lot of different argument types are allowed here
+
+@overload
+def busday_count( # type: ignore[misc]
+ begindates: _ScalarLike_co,
+ enddates: _ScalarLike_co,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: None = ...,
+) -> int_: ...
+@overload
+def busday_count( # type: ignore[misc]
+ begindates: ArrayLike,
+ enddates: ArrayLike,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: None = ...,
+) -> NDArray[int_]: ...
+@overload
+def busday_count(
+ begindates: ArrayLike,
+ enddates: ArrayLike,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: _ArrayType = ...,
+) -> _ArrayType: ...
+
+# `roll="raise"` is (more or less?) equivalent to `casting="safe"`
+@overload
+def busday_offset( # type: ignore[misc]
+ dates: datetime64,
+ offsets: _TD64Like_co,
+ roll: L["raise"] = ...,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: None = ...,
+) -> datetime64: ...
+@overload
+def busday_offset( # type: ignore[misc]
+ dates: _ArrayLike[datetime64],
+ offsets: _ArrayLikeTD64_co,
+ roll: L["raise"] = ...,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: None = ...,
+) -> NDArray[datetime64]: ...
+@overload
+def busday_offset( # type: ignore[misc]
+ dates: _ArrayLike[datetime64],
+ offsets: _ArrayLike[timedelta64],
+ roll: L["raise"] = ...,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: _ArrayType = ...,
+) -> _ArrayType: ...
+@overload
+def busday_offset( # type: ignore[misc]
+ dates: _ScalarLike_co,
+ offsets: _ScalarLike_co,
+ roll: _RollKind,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: None = ...,
+) -> datetime64: ...
+@overload
+def busday_offset( # type: ignore[misc]
+ dates: ArrayLike,
+ offsets: ArrayLike,
+ roll: _RollKind,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: None = ...,
+) -> NDArray[datetime64]: ...
+@overload
+def busday_offset(
+ dates: ArrayLike,
+ offsets: ArrayLike,
+ roll: _RollKind,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: _ArrayType = ...,
+) -> _ArrayType: ...
+
+@overload
+def is_busday( # type: ignore[misc]
+ dates: _ScalarLike_co,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: None = ...,
+) -> bool_: ...
+@overload
+def is_busday( # type: ignore[misc]
+ dates: ArrayLike,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: None = ...,
+) -> NDArray[bool_]: ...
+@overload
+def is_busday(
+ dates: ArrayLike,
+ weekmask: ArrayLike = ...,
+ holidays: None | ArrayLike = ...,
+ busdaycal: None | busdaycalendar = ...,
+ out: _ArrayType = ...,
+) -> _ArrayType: ...
+
+@overload
+def datetime_as_string( # type: ignore[misc]
+ arr: datetime64,
+ unit: None | L["auto"] | _UnitKind = ...,
+ timezone: L["naive", "UTC", "local"] | dt.tzinfo = ...,
+ casting: _CastingKind = ...,
+) -> str_: ...
+@overload
+def datetime_as_string(
+ arr: _ArrayLikeDT64_co,
+ unit: None | L["auto"] | _UnitKind = ...,
+ timezone: L["naive", "UTC", "local"] | dt.tzinfo = ...,
+ casting: _CastingKind = ...,
+) -> NDArray[str_]: ...
+
+@overload
+def compare_chararrays(
+ a1: _ArrayLikeStr_co,
+ a2: _ArrayLikeStr_co,
+ cmp: L["<", "<=", "==", ">=", ">", "!="],
+ rstrip: bool,
+) -> NDArray[bool_]: ...
+@overload
+def compare_chararrays(
+ a1: _ArrayLikeBytes_co,
+ a2: _ArrayLikeBytes_co,
+ cmp: L["<", "<=", "==", ">=", ">", "!="],
+ rstrip: bool,
+) -> NDArray[bool_]: ...
+
+def add_docstring(__obj: Callable[..., Any], __docstring: str) -> None: ...
+
+_GetItemKeys = L[
+ "C", "CONTIGUOUS", "C_CONTIGUOUS",
+ "F", "FORTRAN", "F_CONTIGUOUS",
+ "W", "WRITEABLE",
+ "B", "BEHAVED",
+ "O", "OWNDATA",
+ "A", "ALIGNED",
+ "X", "WRITEBACKIFCOPY",
+ "CA", "CARRAY",
+ "FA", "FARRAY",
+ "FNC",
+ "FORC",
+]
+_SetItemKeys = L[
+ "A", "ALIGNED",
+ "W", "WRITABLE",
+ "X", "WRITEBACKIFCOPY",
+]
+
+@final
+class flagsobj:
+ __hash__: None # type: ignore[assignment]
+ aligned: bool
+ # NOTE: deprecated
+ # updateifcopy: bool
+ writeable: bool
+ writebackifcopy: bool
+ @property
+ def behaved(self) -> bool: ...
+ @property
+ def c_contiguous(self) -> bool: ...
+ @property
+ def carray(self) -> bool: ...
+ @property
+ def contiguous(self) -> bool: ...
+ @property
+ def f_contiguous(self) -> bool: ...
+ @property
+ def farray(self) -> bool: ...
+ @property
+ def fnc(self) -> bool: ...
+ @property
+ def forc(self) -> bool: ...
+ @property
+ def fortran(self) -> bool: ...
+ @property
+ def num(self) -> int: ...
+ @property
+ def owndata(self) -> bool: ...
+ def __getitem__(self, key: _GetItemKeys) -> bool: ...
+ def __setitem__(self, key: _SetItemKeys, value: bool) -> None: ...
diff --git a/numpy/core/numeric.py b/numpy/core/numeric.py
index c95c48d71..813063adb 100644
--- a/numpy/core/numeric.py
+++ b/numpy/core/numeric.py
@@ -10,7 +10,8 @@ from . import multiarray
from .multiarray import (
_fastCopyAndTranspose as fastCopyAndTranspose, ALLOW_THREADS,
BUFSIZE, CLIP, MAXDIMS, MAY_SHARE_BOUNDS, MAY_SHARE_EXACT, RAISE,
- WRAP, arange, array, broadcast, can_cast, compare_chararrays,
+ WRAP, arange, array, asarray, asanyarray, ascontiguousarray,
+ asfortranarray, broadcast, can_cast, compare_chararrays,
concatenate, copyto, dot, dtype, empty,
empty_like, flatiter, frombuffer, fromfile, fromiter, fromstring,
inner, lexsort, matmul, may_share_memory,
@@ -26,7 +27,6 @@ from .umath import (multiply, invert, sin, PINF, NAN)
from . import numerictypes
from .numerictypes import longlong, intc, int_, float_, complex_, bool_
from ._exceptions import TooHardError, AxisError
-from ._asarray import asarray, asanyarray
from ._ufunc_config import errstate
bitwise_not = invert
@@ -39,7 +39,8 @@ array_function_dispatch = functools.partial(
__all__ = [
'newaxis', 'ndarray', 'flatiter', 'nditer', 'nested_iters', 'ufunc',
- 'arange', 'array', 'zeros', 'count_nonzero', 'empty', 'broadcast', 'dtype',
+ 'arange', 'array', 'asarray', 'asanyarray', 'ascontiguousarray',
+ 'asfortranarray', 'zeros', 'count_nonzero', 'empty', 'broadcast', 'dtype',
'fromstring', 'fromfile', 'frombuffer', 'where',
'argwhere', 'copyto', 'concatenate', 'fastCopyAndTranspose', 'lexsort',
'set_numeric_ops', 'can_cast', 'promote_types', 'min_scalar_type',
@@ -299,7 +300,7 @@ def full(shape, fill_value, dtype=None, order='C', *, like=None):
Fill value.
dtype : data-type, optional
The desired data-type for the array The default, None, means
- `np.array(fill_value).dtype`.
+ ``np.array(fill_value).dtype``.
order : {'C', 'F'}, optional
Whether to store multidimensional data in C- or Fortran-contiguous
(row- or column-wise) order in memory.
@@ -662,17 +663,6 @@ def flatnonzero(a):
return np.nonzero(np.ravel(a))[0]
-_mode_from_name_dict = {'v': 0,
- 's': 1,
- 'f': 2}
-
-
-def _mode_from_name(mode):
- if isinstance(mode, str):
- return _mode_from_name_dict[mode.lower()[0]]
- return mode
-
-
def _correlate_dispatcher(a, v, mode=None):
return (a, v)
@@ -710,6 +700,7 @@ def correlate(a, v, mode='valid'):
--------
convolve : Discrete, linear convolution of two one-dimensional sequences.
multiarray.correlate : Old, no conjugate, version of correlate.
+ scipy.signal.correlate : uses FFT which has superior performance on large arrays.
Notes
-----
@@ -720,6 +711,11 @@ def correlate(a, v, mode='valid'):
which is related to ``c_{av}[k]`` by ``c'_{av}[k] = c_{av}[-k]``.
+ `numpy.correlate` may perform slowly in large arrays (i.e. n = 1e5) because it does
+ not use the FFT to compute the convolution; in that case, `scipy.signal.correlate` might
+ be preferable.
+
+
Examples
--------
>>> np.correlate([1, 2, 3], [0, 1, 0.5])
@@ -742,7 +738,6 @@ def correlate(a, v, mode='valid'):
array([ 0.0+0.j , 3.0+1.j , 1.5+1.5j, 1.0+0.j , 0.5+0.5j])
"""
- mode = _mode_from_name(mode)
return multiarray.correlate2(a, v, mode)
@@ -846,7 +841,6 @@ def convolve(a, v, mode='full'):
raise ValueError('a cannot be empty')
if len(v) == 0:
raise ValueError('v cannot be empty')
- mode = _mode_from_name(mode)
return multiarray.correlate(a, v[::-1], mode)
@@ -1427,12 +1421,11 @@ def moveaxis(a, source, destination):
See Also
--------
- transpose: Permute the dimensions of an array.
- swapaxes: Interchange two axes of an array.
+ transpose : Permute the dimensions of an array.
+ swapaxes : Interchange two axes of an array.
Examples
--------
-
>>> x = np.zeros((3, 4, 5))
>>> np.moveaxis(x, 0, -1).shape
(4, 5, 3)
@@ -1473,11 +1466,6 @@ def moveaxis(a, source, destination):
return result
-# fix hack in scipy which imports this function
-def _move_axis_to_0(a, axis):
- return moveaxis(a, axis, 0)
-
-
def _cross_dispatcher(a, b, axisa=None, axisb=None, axisc=None, axis=None):
return (a, b)
@@ -2351,8 +2339,13 @@ def isclose(a, b, rtol=1.e-5, atol=1.e-8, equal_nan=False):
# Make sure y is an inexact type to avoid bad behavior on abs(MIN_INT).
# This will cause casting of x later. Also, make sure to allow subclasses
# (e.g., for numpy.ma).
- dt = multiarray.result_type(y, 1.)
- y = array(y, dtype=dt, copy=False, subok=True)
+ # NOTE: We explicitly allow timedelta, which used to work. This could
+ # possibly be deprecated. See also gh-18286.
+ # timedelta works if `atol` is an integer or also a timedelta.
+ # Although, the default tolerances are unlikely to be useful
+ if y.dtype.kind != "m":
+ dt = multiarray.result_type(y, 1.)
+ y = asanyarray(y, dtype=dt)
xfin = isfinite(x)
yfin = isfinite(y)
diff --git a/numpy/core/numeric.pyi b/numpy/core/numeric.pyi
index d91cb31c2..3c2b553ec 100644
--- a/numpy/core/numeric.pyi
+++ b/numpy/core/numeric.pyi
@@ -41,6 +41,7 @@ def zeros_like(
subok: bool = ...,
shape: Optional[_ShapeLike] = ...,
) -> ndarray: ...
+
def ones(
shape: _ShapeLike,
dtype: DTypeLike = ...,
@@ -48,6 +49,7 @@ def ones(
*,
like: ArrayLike = ...,
) -> ndarray: ...
+
@overload
def ones_like(
a: _ArrayType,
@@ -64,22 +66,7 @@ def ones_like(
subok: bool = ...,
shape: Optional[_ShapeLike] = ...,
) -> ndarray: ...
-@overload
-def empty_like(
- a: _ArrayType,
- dtype: None = ...,
- order: _OrderKACF = ...,
- subok: Literal[True] = ...,
- shape: None = ...,
-) -> _ArrayType: ...
-@overload
-def empty_like(
- a: ArrayLike,
- dtype: DTypeLike = ...,
- order: _OrderKACF = ...,
- subok: bool = ...,
- shape: Optional[_ShapeLike] = ...,
-) -> ndarray: ...
+
def full(
shape: _ShapeLike,
fill_value: Any,
@@ -88,6 +75,7 @@ def full(
*,
like: ArrayLike = ...,
) -> ndarray: ...
+
@overload
def full_like(
a: _ArrayType,
@@ -106,39 +94,73 @@ def full_like(
subok: bool = ...,
shape: Optional[_ShapeLike] = ...,
) -> ndarray: ...
+
@overload
def count_nonzero(
- a: ArrayLike, axis: None = ..., *, keepdims: Literal[False] = ...
+ a: ArrayLike,
+ axis: None = ...,
+ *,
+ keepdims: Literal[False] = ...,
) -> int: ...
@overload
def count_nonzero(
- a: ArrayLike, axis: _ShapeLike = ..., *, keepdims: bool = ...
-) -> Union[signedinteger[Any], ndarray]: ... # TODO: np.intp
+ a: ArrayLike,
+ axis: _ShapeLike = ...,
+ *,
+ keepdims: bool = ...,
+) -> Any: ... # TODO: np.intp or ndarray[np.intp]
+
def isfortran(a: Union[ndarray, generic]) -> bool: ...
+
def argwhere(a: ArrayLike) -> ndarray: ...
+
def flatnonzero(a: ArrayLike) -> ndarray: ...
-def correlate(a: ArrayLike, v: ArrayLike, mode: _CorrelateMode = ...) -> ndarray: ...
-def convolve(a: ArrayLike, v: ArrayLike, mode: _CorrelateMode = ...) -> ndarray: ...
+
+def correlate(
+ a: ArrayLike,
+ v: ArrayLike,
+ mode: _CorrelateMode = ...,
+) -> ndarray: ...
+
+def convolve(
+ a: ArrayLike,
+ v: ArrayLike,
+ mode: _CorrelateMode = ...,
+) -> ndarray: ...
+
@overload
-def outer(a: ArrayLike, b: ArrayLike, out: None = ...) -> ndarray: ...
+def outer(
+ a: ArrayLike,
+ b: ArrayLike,
+ out: None = ...,
+) -> ndarray: ...
@overload
-def outer(a: ArrayLike, b: ArrayLike, out: _ArrayType = ...) -> _ArrayType: ...
+def outer(
+ a: ArrayLike,
+ b: ArrayLike,
+ out: _ArrayType = ...,
+) -> _ArrayType: ...
+
def tensordot(
a: ArrayLike,
b: ArrayLike,
axes: Union[int, Tuple[_ShapeLike, _ShapeLike]] = ...,
) -> ndarray: ...
+
def roll(
a: ArrayLike,
shift: _ShapeLike,
axis: Optional[_ShapeLike] = ...,
) -> ndarray: ...
+
def rollaxis(a: ndarray, axis: int, start: int = ...) -> ndarray: ...
+
def moveaxis(
a: ndarray,
source: _ShapeLike,
destination: _ShapeLike,
) -> ndarray: ...
+
def cross(
a: ArrayLike,
b: ArrayLike,
@@ -147,6 +169,7 @@ def cross(
axisc: int = ...,
axis: Optional[int] = ...,
) -> ndarray: ...
+
@overload
def indices(
dimensions: Sequence[int],
@@ -159,6 +182,7 @@ def indices(
dtype: DTypeLike = ...,
sparse: Literal[True] = ...,
) -> Tuple[ndarray, ...]: ...
+
def fromfunction(
function: Callable[..., _T],
shape: Sequence[int],
@@ -167,10 +191,20 @@ def fromfunction(
like: ArrayLike = ...,
**kwargs: Any,
) -> _T: ...
+
def isscalar(element: Any) -> bool: ...
+
def binary_repr(num: int, width: Optional[int] = ...) -> str: ...
+
def base_repr(number: int, base: int = ..., padding: int = ...) -> str: ...
-def identity(n: int, dtype: DTypeLike = ..., *, like: ArrayLike = ...) -> ndarray: ...
+
+def identity(
+ n: int,
+ dtype: DTypeLike = ...,
+ *,
+ like: ArrayLike = ...,
+) -> ndarray: ...
+
def allclose(
a: ArrayLike,
b: ArrayLike,
@@ -178,12 +212,15 @@ def allclose(
atol: float = ...,
equal_nan: bool = ...,
) -> bool: ...
+
def isclose(
a: ArrayLike,
b: ArrayLike,
rtol: float = ...,
atol: float = ...,
equal_nan: bool = ...,
-) -> Union[bool_, ndarray]: ...
-def array_equal(a1: ArrayLike, a2: ArrayLike) -> bool: ...
+) -> Any: ...
+
+def array_equal(a1: ArrayLike, a2: ArrayLike, equal_nan: bool = ...) -> bool: ...
+
def array_equiv(a1: ArrayLike, a2: ArrayLike) -> bool: ...
diff --git a/numpy/core/numerictypes.py b/numpy/core/numerictypes.py
index e705dd3ea..12f424fd4 100644
--- a/numpy/core/numerictypes.py
+++ b/numpy/core/numerictypes.py
@@ -5,7 +5,7 @@ This module is designed so "from numerictypes import \\*" is safe.
Exported symbols include:
Dictionary with all registered number types (including aliases):
- typeDict
+ sctypeDict
Type objects (not all will be available, depends on platform):
see variable sctypes for which ones you have
@@ -79,7 +79,6 @@ Exported symbols include:
\\-> object_ (not used much) (kind=O)
"""
-import types as _types
import numbers
import warnings
@@ -91,7 +90,7 @@ from numpy.core.multiarray import (
from numpy.core.overrides import set_module
# we add more at the bottom
-__all__ = ['sctypeDict', 'typeDict', 'sctypes',
+__all__ = ['sctypeDict', 'sctypes',
'ScalarType', 'obj2sctype', 'cast', 'nbytes', 'sctype2char',
'maximum_sctype', 'issctype', 'typecodes', 'find_common_type',
'issubdtype', 'datetime_data', 'datetime_as_string',
@@ -512,15 +511,15 @@ cast = _typedict()
for key in _concrete_types:
cast[key] = lambda x, k=key: array(x, copy=False).astype(k)
-try:
- ScalarType = [_types.IntType, _types.FloatType, _types.ComplexType,
- _types.LongType, _types.BooleanType,
- _types.StringType, _types.UnicodeType, _types.BufferType]
-except AttributeError:
- # Py3K
- ScalarType = [int, float, complex, int, bool, bytes, str, memoryview]
-ScalarType.extend(_concrete_types)
+def _scalar_type_key(typ):
+ """A ``key`` function for `sorted`."""
+ dt = dtype(typ)
+ return (dt.kind.lower(), dt.itemsize)
+
+
+ScalarType = [int, float, complex, int, bool, bytes, str, memoryview]
+ScalarType += sorted(_concrete_types, key=_scalar_type_key)
ScalarType = tuple(ScalarType)
@@ -542,6 +541,7 @@ typecodes = {'Character':'c',
'All':'?bhilqpBHILQPefdgFDGSUVOMm'}
# backwards compatibility --- deprecated name
+# Formal deprecation: Numpy 1.20.0, 2020-10-19 (see numpy/__init__.py)
typeDict = sctypeDict
# b -> boolean
diff --git a/numpy/core/numerictypes.pyi b/numpy/core/numerictypes.pyi
index 192015ff1..e99e1c500 100644
--- a/numpy/core/numerictypes.pyi
+++ b/numpy/core/numerictypes.pyi
@@ -1,29 +1,175 @@
-from typing import TypeVar, Optional, Type, Union, Tuple, Sequence, overload, Any
+import sys
+import types
+from typing import (
+ Type,
+ Union,
+ Tuple,
+ overload,
+ Any,
+ TypeVar,
+ Dict,
+ List,
+ Iterable,
+)
-from numpy import generic, ndarray, dtype
-from numpy.typing import DTypeLike
+from numpy import (
+ ndarray,
+ dtype,
+ generic,
+ bool_,
+ ubyte,
+ ushort,
+ uintc,
+ uint,
+ ulonglong,
+ byte,
+ short,
+ intc,
+ int_,
+ longlong,
+ half,
+ single,
+ double,
+ longdouble,
+ csingle,
+ cdouble,
+ clongdouble,
+ datetime64,
+ timedelta64,
+ object_,
+ str_,
+ bytes_,
+ void,
+)
-_DefaultType = TypeVar("_DefaultType")
+from numpy.core._type_aliases import (
+ sctypeDict as sctypeDict,
+ sctypes as sctypes,
+)
-def maximum_sctype(t: DTypeLike) -> dtype: ...
-def issctype(rep: object) -> bool: ...
+from numpy.typing import DTypeLike, ArrayLike, _SupportsDType
+
+if sys.version_info >= (3, 8):
+ from typing import Literal as L, Protocol, TypedDict
+else:
+ from typing_extensions import Literal as L, Protocol, TypedDict
+
+_T = TypeVar("_T")
+_SCT = TypeVar("_SCT", bound=generic)
+
+# A paramtrizable subset of `npt.DTypeLike`
+_DTypeLike = Union[
+ Type[_SCT],
+ dtype[_SCT],
+ _SupportsDType[dtype[_SCT]],
+]
+
+class _CastFunc(Protocol):
+ def __call__(
+ self, x: ArrayLike, k: DTypeLike = ...
+ ) -> ndarray[Any, dtype[Any]]: ...
+
+class _TypeCodes(TypedDict):
+ Character: L['c']
+ Integer: L['bhilqp']
+ UnsignedInteger: L['BHILQP']
+ Float: L['efdg']
+ Complex: L['FDG']
+ AllInteger: L['bBhHiIlLqQpP']
+ AllFloat: L['efdgFDG']
+ Datetime: L['Mm']
+ All: L['?bhilqpBHILQPefdgFDGSUVOMm']
+
+class _typedict(Dict[Type[generic], _T]):
+ def __getitem__(self, key: DTypeLike) -> _T: ...
+
+if sys.version_info >= (3, 10):
+ _TypeTuple = Union[
+ Type[Any],
+ types.Union,
+ Tuple[Union[Type[Any], types.Union, Tuple[Any, ...]], ...],
+ ]
+else:
+ _TypeTuple = Union[
+ Type[Any],
+ Tuple[Union[Type[Any], Tuple[Any, ...]], ...],
+ ]
+
+__all__: List[str]
+
+@overload
+def maximum_sctype(t: _DTypeLike[_SCT]) -> Type[_SCT]: ...
@overload
-def obj2sctype(rep: object) -> Optional[generic]: ...
+def maximum_sctype(t: DTypeLike) -> Type[Any]: ...
+
+@overload
+def issctype(rep: dtype[Any] | Type[Any]) -> bool: ...
@overload
-def obj2sctype(rep: object, default: None) -> Optional[generic]: ...
+def issctype(rep: object) -> L[False]: ...
+
@overload
-def obj2sctype(
- rep: object, default: Type[_DefaultType]
-) -> Union[generic, Type[_DefaultType]]: ...
-def issubclass_(arg1: object, arg2: Union[object, Tuple[object, ...]]) -> bool: ...
-def issubsctype(
- arg1: Union[ndarray, DTypeLike], arg2: Union[ndarray, DTypeLike]
-) -> bool: ...
+def obj2sctype(rep: _DTypeLike[_SCT], default: None = ...) -> None | Type[_SCT]: ...
+@overload
+def obj2sctype(rep: _DTypeLike[_SCT], default: _T) -> _T | Type[_SCT]: ...
+@overload
+def obj2sctype(rep: DTypeLike, default: None = ...) -> None | Type[Any]: ...
+@overload
+def obj2sctype(rep: DTypeLike, default: _T) -> _T | Type[Any]: ...
+@overload
+def obj2sctype(rep: object, default: None = ...) -> None: ...
+@overload
+def obj2sctype(rep: object, default: _T) -> _T: ...
+
+@overload
+def issubclass_(arg1: Type[Any], arg2: _TypeTuple) -> bool: ...
+@overload
+def issubclass_(arg1: object, arg2: object) -> L[False]: ...
+
+def issubsctype(arg1: DTypeLike, arg2: DTypeLike) -> bool: ...
+
def issubdtype(arg1: DTypeLike, arg2: DTypeLike) -> bool: ...
-def sctype2char(sctype: object) -> str: ...
+
+def sctype2char(sctype: DTypeLike) -> str: ...
+
def find_common_type(
- array_types: Sequence[DTypeLike], scalar_types: Sequence[DTypeLike]
-) -> dtype: ...
+ array_types: Iterable[DTypeLike],
+ scalar_types: Iterable[DTypeLike],
+) -> dtype[Any]: ...
-# TODO: Add annotations for the following objects:
-# typeDict, nbytes, cast, ScalarType & typecodes
+cast: _typedict[_CastFunc]
+nbytes: _typedict[int]
+typecodes: _TypeCodes
+ScalarType: Tuple[
+ Type[int],
+ Type[float],
+ Type[complex],
+ Type[int],
+ Type[bool],
+ Type[bytes],
+ Type[str],
+ Type[memoryview],
+ Type[bool_],
+ Type[csingle],
+ Type[cdouble],
+ Type[clongdouble],
+ Type[half],
+ Type[single],
+ Type[double],
+ Type[longdouble],
+ Type[byte],
+ Type[short],
+ Type[intc],
+ Type[int_],
+ Type[longlong],
+ Type[timedelta64],
+ Type[datetime64],
+ Type[object_],
+ Type[bytes_],
+ Type[str_],
+ Type[ubyte],
+ Type[ushort],
+ Type[uintc],
+ Type[uint],
+ Type[ulonglong],
+ Type[void],
+]
diff --git a/numpy/core/overrides.py b/numpy/core/overrides.py
index c2b5fb7fa..70085d896 100644
--- a/numpy/core/overrides.py
+++ b/numpy/core/overrides.py
@@ -18,11 +18,7 @@ array_function_like_doc = (
NumPy arrays. If an array-like passed in as ``like`` supports
the ``__array_function__`` protocol, the result will be defined
by it. In this case, it ensures the creation of an array object
- compatible with that passed in via this argument.
-
- .. note::
- The ``like`` keyword is an experimental feature pending on
- acceptance of :ref:`NEP 35 <NEP35>`."""
+ compatible with that passed in via this argument."""
)
def set_array_function_like_doc(public_api):
diff --git a/numpy/core/records.py b/numpy/core/records.py
index c2f6c6965..b3474ad01 100644
--- a/numpy/core/records.py
+++ b/numpy/core/records.py
@@ -33,20 +33,21 @@ Record arrays allow us to access fields as properties::
array([2., 2.])
"""
-import os
import warnings
-from collections import Counter, OrderedDict
+from collections import Counter
+from contextlib import nullcontext
from . import numeric as sb
from . import numerictypes as nt
-from numpy.compat import (
- os_fspath, contextlib_nullcontext
-)
+from numpy.compat import os_fspath
from numpy.core.overrides import set_module
from .arrayprint import get_printoptions
# All of the functions allow formats to be a dtype
-__all__ = ['record', 'recarray', 'format_parser']
+__all__ = [
+ 'record', 'recarray', 'format_parser',
+ 'fromarrays', 'fromrecords', 'fromstring', 'fromfile', 'array',
+]
ndarray = sb.ndarray
@@ -71,25 +72,14 @@ _byteorderconv = {'b':'>',
# of the letter code '(2,3)f4' and ' ( 2 , 3 ) f4 '
# are equally allowed
-numfmt = nt.typeDict
-
-# taken from OrderedDict recipes in the Python documentation
-# https://docs.python.org/3.3/library/collections.html#ordereddict-examples-and-recipes
-class _OrderedCounter(Counter, OrderedDict):
- """Counter that remembers the order elements are first encountered"""
-
- def __repr__(self):
- return '%s(%r)' % (self.__class__.__name__, OrderedDict(self))
-
- def __reduce__(self):
- return self.__class__, (OrderedDict(self),)
+numfmt = nt.sctypeDict
def find_duplicate(list):
"""Find duplication in a list, return a list of duplicated elements"""
return [
item
- for item, counts in _OrderedCounter(list).items()
+ for item, counts in Counter(list).items()
if counts > 1
]
@@ -242,12 +232,12 @@ class record(nt.void):
def __repr__(self):
if get_printoptions()['legacy'] == '1.13':
return self.__str__()
- return super(record, self).__repr__()
+ return super().__repr__()
def __str__(self):
if get_printoptions()['legacy'] == '1.13':
return str(self.item())
- return super(record, self).__str__()
+ return super().__str__()
def __getattribute__(self, attr):
if attr in ('setfield', 'getfield', 'dtype'):
@@ -516,7 +506,7 @@ class recarray(ndarray):
return self.setfield(val, *res)
def __getitem__(self, indx):
- obj = super(recarray, self).__getitem__(indx)
+ obj = super().__getitem__(indx)
# copy behavior of getattr, except that here
# we might also be returning a single element
@@ -914,7 +904,7 @@ def fromfile(fd, dtype=None, shape=None, offset=0, formats=None,
# GH issue 2504. fd supports io.RawIOBase or io.BufferedIOBase interface.
# Example of fd: gzip, BytesIO, BufferedReader
# file already opened
- ctx = contextlib_nullcontext(fd)
+ ctx = nullcontext(fd)
else:
# open file
ctx = open(os_fspath(fd), 'rb')
@@ -963,16 +953,16 @@ def array(obj, dtype=None, shape=None, offset=0, strides=None, formats=None,
Parameters
----------
- obj: any
+ obj : any
Input object. See Notes for details on how various input types are
treated.
- dtype: data-type, optional
+ dtype : data-type, optional
Valid dtype for array.
- shape: int or tuple of ints, optional
+ shape : int or tuple of ints, optional
Shape of each array.
- offset: int, optional
+ offset : int, optional
Position in the file or buffer to start reading from.
- strides: tuple of ints, optional
+ strides : tuple of ints, optional
Buffer (`buf`) is interpreted according to these strides (strides
define how many bytes each array element, row, column, etc.
occupy in memory).
@@ -980,7 +970,7 @@ def array(obj, dtype=None, shape=None, offset=0, strides=None, formats=None,
If `dtype` is ``None``, these arguments are passed to
`numpy.format_parser` to construct a dtype. See that function for
detailed documentation.
- copy: bool, optional
+ copy : bool, optional
Whether to copy the input object (True), or to use a reference instead.
This option only applies when the input is an ndarray or recarray.
Defaults to True.
diff --git a/numpy/core/setup.py b/numpy/core/setup.py
index 2ec5e1a64..c20320910 100644
--- a/numpy/core/setup.py
+++ b/numpy/core/setup.py
@@ -23,11 +23,6 @@ NPY_RELAXED_STRIDES_CHECKING = (os.environ.get('NPY_RELAXED_STRIDES_CHECKING', "
NPY_RELAXED_STRIDES_DEBUG = (os.environ.get('NPY_RELAXED_STRIDES_DEBUG', "0") != "0")
NPY_RELAXED_STRIDES_DEBUG = NPY_RELAXED_STRIDES_DEBUG and NPY_RELAXED_STRIDES_CHECKING
-# Set to True to use the new casting implementation as much as implemented.
-# Allows running the full test suit to exercise the new machinery until
-# it is used as default and the old version is eventually deleted.
-NPY_USE_NEW_CASTINGIMPL = os.environ.get('NPY_USE_NEW_CASTINGIMPL', "0") != "0"
-
# XXX: ugly, we use a class to avoid calling twice some expensive functions in
# config.h/numpyconfig.h. I don't see a better way because distutils force
# config.h generation inside an Extension class, and as such sharing
@@ -405,11 +400,6 @@ def configuration(parent_package='',top_path=None):
from numpy.distutils.system_info import (get_info, blas_opt_info,
lapack_opt_info)
- # Accelerate is buggy, disallow it. See also numpy/linalg/setup.py
- for opt_order in (blas_opt_info.blas_order, lapack_opt_info.lapack_order):
- if 'accelerate' in opt_order:
- opt_order.remove('accelerate')
-
config = Configuration('core', parent_package, top_path)
local_dir = config.local_path
codegen_dir = join(local_dir, 'code_generators')
@@ -468,14 +458,14 @@ def configuration(parent_package='',top_path=None):
# Use relaxed stride checking
if NPY_RELAXED_STRIDES_CHECKING:
moredefs.append(('NPY_RELAXED_STRIDES_CHECKING', 1))
+ else:
+ moredefs.append(('NPY_RELAXED_STRIDES_CHECKING', 0))
# Use bogus stride debug aid when relaxed strides are enabled
if NPY_RELAXED_STRIDES_DEBUG:
moredefs.append(('NPY_RELAXED_STRIDES_DEBUG', 1))
-
- # Use the new experimental casting implementation in NumPy 1.20:
- if NPY_USE_NEW_CASTINGIMPL:
- moredefs.append(('NPY_USE_NEW_CASTINGIMPL', 1))
+ else:
+ moredefs.append(('NPY_RELAXED_STRIDES_DEBUG', 0))
# Get long double representation
rep = check_long_double_representation(config_cmd)
@@ -710,8 +700,12 @@ def configuration(parent_package='',top_path=None):
config.add_extension('_multiarray_tests',
sources=[join('src', 'multiarray', '_multiarray_tests.c.src'),
- join('src', 'common', 'mem_overlap.c')],
+ join('src', 'common', 'mem_overlap.c'),
+ join('src', 'common', 'npy_argparse.c'),
+ join('src', 'common', 'npy_hashtable.c')],
depends=[join('src', 'common', 'mem_overlap.h'),
+ join('src', 'common', 'npy_argparse.h'),
+ join('src', 'common', 'npy_hashtable.h'),
join('src', 'common', 'npy_extint128.h')],
libraries=['npymath'])
@@ -725,11 +719,13 @@ def configuration(parent_package='',top_path=None):
join('src', 'common', 'cblasfuncs.h'),
join('src', 'common', 'lowlevel_strided_loops.h'),
join('src', 'common', 'mem_overlap.h'),
+ join('src', 'common', 'npy_argparse.h'),
join('src', 'common', 'npy_cblas.h'),
join('src', 'common', 'npy_config.h'),
join('src', 'common', 'npy_ctypes.h'),
join('src', 'common', 'npy_extint128.h'),
join('src', 'common', 'npy_import.h'),
+ join('src', 'common', 'npy_hashtable.h'),
join('src', 'common', 'npy_longdouble.h'),
join('src', 'common', 'templ_common.h.src'),
join('src', 'common', 'ucsnarrow.h'),
@@ -743,6 +739,8 @@ def configuration(parent_package='',top_path=None):
common_src = [
join('src', 'common', 'array_assign.c'),
join('src', 'common', 'mem_overlap.c'),
+ join('src', 'common', 'npy_argparse.c'),
+ join('src', 'common', 'npy_hashtable.c'),
join('src', 'common', 'npy_longdouble.c'),
join('src', 'common', 'templ_common.h.src'),
join('src', 'common', 'ucsnarrow.c'),
@@ -782,12 +780,14 @@ def configuration(parent_package='',top_path=None):
join('src', 'multiarray', 'npy_buffer.h'),
join('src', 'multiarray', 'calculation.h'),
join('src', 'multiarray', 'common.h'),
+ join('src', 'multiarray', 'common_dtype.h'),
join('src', 'multiarray', 'convert_datatype.h'),
join('src', 'multiarray', 'convert.h'),
join('src', 'multiarray', 'conversion_utils.h'),
join('src', 'multiarray', 'ctors.h'),
join('src', 'multiarray', 'descriptor.h'),
join('src', 'multiarray', 'dtypemeta.h'),
+ join('src', 'multiarray', 'dtype_transfer.h'),
join('src', 'multiarray', 'dragon4.h'),
join('src', 'multiarray', 'einsum_debug.h'),
join('src', 'multiarray', 'einsum_sumprod.h'),
@@ -843,6 +843,7 @@ def configuration(parent_package='',top_path=None):
join('src', 'multiarray', 'calculation.c'),
join('src', 'multiarray', 'compiled_base.c'),
join('src', 'multiarray', 'common.c'),
+ join('src', 'multiarray', 'common_dtype.c'),
join('src', 'multiarray', 'convert.c'),
join('src', 'multiarray', 'convert_datatype.c'),
join('src', 'multiarray', 'conversion_utils.c'),
@@ -916,17 +917,26 @@ def configuration(parent_package='',top_path=None):
join('src', 'umath', 'funcs.inc.src'),
join('src', 'umath', 'simd.inc.src'),
join('src', 'umath', 'loops.h.src'),
+ join('src', 'umath', 'loops_utils.h.src'),
join('src', 'umath', 'loops.c.src'),
join('src', 'umath', 'loops_unary_fp.dispatch.c.src'),
+ join('src', 'umath', 'loops_arithm_fp.dispatch.c.src'),
+ join('src', 'umath', 'loops_arithmetic.dispatch.c.src'),
+ join('src', 'umath', 'loops_trigonometric.dispatch.c.src'),
+ join('src', 'umath', 'loops_exponent_log.dispatch.c.src'),
join('src', 'umath', 'matmul.h.src'),
join('src', 'umath', 'matmul.c.src'),
join('src', 'umath', 'clip.h.src'),
join('src', 'umath', 'clip.c.src'),
+ join('src', 'umath', 'dispatching.c'),
+ join('src', 'umath', 'legacy_array_method.c'),
join('src', 'umath', 'ufunc_object.c'),
join('src', 'umath', 'extobj.c'),
join('src', 'umath', 'scalarmath.c.src'),
join('src', 'umath', 'ufunc_type_resolution.c'),
join('src', 'umath', 'override.c'),
+ # For testing. Eventually, should use public API and be separate:
+ join('src', 'umath', '_scaled_float_dtype.c'),
]
umath_deps = [
diff --git a/numpy/core/setup_common.py b/numpy/core/setup_common.py
index ba3e215b3..85c8f16d1 100644
--- a/numpy/core/setup_common.py
+++ b/numpy/core/setup_common.py
@@ -42,6 +42,8 @@ C_ABI_VERSION = 0x01000009
# 0x0000000d - 1.16.x
# 0x0000000d - 1.19.x
# 0x0000000e - 1.20.x
+# 0x0000000e - 1.21.x
+# 0x0000000e - 1.22.x
C_API_VERSION = 0x0000000e
class MismatchCAPIWarning(Warning):
@@ -51,7 +53,7 @@ def is_released(config):
"""Return True if a released version of numpy is detected."""
from distutils.version import LooseVersion
- v = config.get_version('../version.py')
+ v = config.get_version('../_version.py')
if v is None:
raise ValueError("Could not get version")
pv = LooseVersion(vstring=v).version
@@ -194,7 +196,8 @@ OPTIONAL_FUNCTION_ATTRIBUTES_WITH_INTRINSICS = [('__attribute__((target("avx2,fm
('__attribute__((target ("avx512f,avx512dq,avx512bw,avx512vl,avx512cd")))',
'attribute_target_avx512_skx_with_intrinsics',
'__mmask8 temp = _mm512_fpclass_pd_mask(_mm512_set1_pd(1.0), 0x01);\
- __m512i temp = _mm512_castps_si512(_mm512_set1_ps(1.0));\
+ __m512i unused_temp = \
+ _mm512_castps_si512(_mm512_set1_ps(1.0));\
_mm_mask_storeu_epi8(NULL, 0xFF, _mm_broadcastmb_epi64(temp))',
'immintrin.h'),
]
@@ -317,8 +320,8 @@ def pyod(filename):
out : seq
list of lines of od output
- Note
- ----
+ Notes
+ -----
We only implement enough to get the necessary information for long double
representation, this is not intended as a compatible replacement for od.
"""
diff --git a/numpy/core/shape_base.py b/numpy/core/shape_base.py
index e4dc30d4c..a81a04f7f 100644
--- a/numpy/core/shape_base.py
+++ b/numpy/core/shape_base.py
@@ -8,8 +8,7 @@ import warnings
from . import numeric as _nx
from . import overrides
-from ._asarray import array, asanyarray
-from .multiarray import normalize_axis_index
+from .multiarray import array, asanyarray, normalize_axis_index
from . import fromnumeric as _from_nx
@@ -258,20 +257,20 @@ def vstack(tup):
Examples
--------
>>> a = np.array([1, 2, 3])
- >>> b = np.array([2, 3, 4])
+ >>> b = np.array([4, 5, 6])
>>> np.vstack((a,b))
array([[1, 2, 3],
- [2, 3, 4]])
+ [4, 5, 6]])
>>> a = np.array([[1], [2], [3]])
- >>> b = np.array([[2], [3], [4]])
+ >>> b = np.array([[4], [5], [6]])
>>> np.vstack((a,b))
array([[1],
[2],
[3],
- [2],
- [3],
- [4]])
+ [4],
+ [5],
+ [6]])
"""
if not overrides.ARRAY_FUNCTION_ENABLED:
@@ -321,15 +320,15 @@ def hstack(tup):
Examples
--------
>>> a = np.array((1,2,3))
- >>> b = np.array((2,3,4))
+ >>> b = np.array((4,5,6))
>>> np.hstack((a,b))
- array([1, 2, 3, 2, 3, 4])
+ array([1, 2, 3, 4, 5, 6])
>>> a = np.array([[1],[2],[3]])
- >>> b = np.array([[2],[3],[4]])
+ >>> b = np.array([[4],[5],[6]])
>>> np.hstack((a,b))
- array([[1, 2],
- [2, 3],
- [3, 4]])
+ array([[1, 4],
+ [2, 5],
+ [3, 6]])
"""
if not overrides.ARRAY_FUNCTION_ENABLED:
@@ -403,15 +402,15 @@ def stack(arrays, axis=0, out=None):
(3, 4, 10)
>>> a = np.array([1, 2, 3])
- >>> b = np.array([2, 3, 4])
+ >>> b = np.array([4, 5, 6])
>>> np.stack((a, b))
array([[1, 2, 3],
- [2, 3, 4]])
+ [4, 5, 6]])
>>> np.stack((a, b), axis=-1)
- array([[1, 2],
- [2, 3],
- [3, 4]])
+ array([[1, 4],
+ [2, 5],
+ [3, 6]])
"""
if not overrides.ARRAY_FUNCTION_ENABLED:
@@ -607,7 +606,7 @@ def _block_info_recursion(arrays, max_depth, result_ndim, depth=0):
The arrays to check
max_depth : list of int
The number of nested lists
- result_ndim: int
+ result_ndim : int
The number of dimensions in thefinal array.
Returns
@@ -786,9 +785,9 @@ def block(arrays):
array([1, 2, 3])
>>> a = np.array([1, 2, 3])
- >>> b = np.array([2, 3, 4])
+ >>> b = np.array([4, 5, 6])
>>> np.block([a, b, 10]) # hstack([a, b, 10])
- array([ 1, 2, 3, 2, 3, 4, 10])
+ array([ 1, 2, 3, 4, 5, 6, 10])
>>> A = np.ones((2, 2), int)
>>> B = 2 * A
@@ -799,10 +798,10 @@ def block(arrays):
With a list of depth 2, `block` can be used in place of `vstack`:
>>> a = np.array([1, 2, 3])
- >>> b = np.array([2, 3, 4])
+ >>> b = np.array([4, 5, 6])
>>> np.block([[a], [b]]) # vstack([a, b])
array([[1, 2, 3],
- [2, 3, 4]])
+ [4, 5, 6]])
>>> A = np.ones((2, 2), int)
>>> B = 2 * A
diff --git a/numpy/core/shape_base.pyi b/numpy/core/shape_base.pyi
index b20598b1a..9aaeceed7 100644
--- a/numpy/core/shape_base.pyi
+++ b/numpy/core/shape_base.pyi
@@ -1,41 +1,72 @@
import sys
-from typing import TypeVar, overload, List, Sequence
+from typing import TypeVar, overload, List, Sequence, Any
-from numpy import ndarray
-from numpy.typing import ArrayLike
+from numpy import generic, dtype
+from numpy.typing import ArrayLike, NDArray, _NestedSequence, _SupportsArray
if sys.version_info >= (3, 8):
from typing import SupportsIndex
else:
- from typing_extensions import Protocol
- class SupportsIndex(Protocol):
- def __index__(self) -> int: ...
+ from typing_extensions import SupportsIndex
-_ArrayType = TypeVar("_ArrayType", bound=ndarray)
+_SCT = TypeVar("_SCT", bound=generic)
+_ArrayType = TypeVar("_ArrayType", bound=NDArray[Any])
+_ArrayLike = _NestedSequence[_SupportsArray[dtype[_SCT]]]
+
+__all__: List[str]
+
+@overload
+def atleast_1d(__arys: _ArrayLike[_SCT]) -> NDArray[_SCT]: ...
+@overload
+def atleast_1d(__arys: ArrayLike) -> NDArray[Any]: ...
+@overload
+def atleast_1d(*arys: ArrayLike) -> List[NDArray[Any]]: ...
+
+@overload
+def atleast_2d(__arys: _ArrayLike[_SCT]) -> NDArray[_SCT]: ...
+@overload
+def atleast_2d(__arys: ArrayLike) -> NDArray[Any]: ...
@overload
-def atleast_1d(__arys: ArrayLike) -> ndarray: ...
+def atleast_2d(*arys: ArrayLike) -> List[NDArray[Any]]: ...
+
+@overload
+def atleast_3d(__arys: _ArrayLike[_SCT]) -> NDArray[_SCT]: ...
@overload
-def atleast_1d(*arys: ArrayLike) -> List[ndarray]: ...
+def atleast_3d(__arys: ArrayLike) -> NDArray[Any]: ...
+@overload
+def atleast_3d(*arys: ArrayLike) -> List[NDArray[Any]]: ...
@overload
-def atleast_2d(__arys: ArrayLike) -> ndarray: ...
+def vstack(tup: Sequence[_ArrayLike[_SCT]]) -> NDArray[_SCT]: ...
@overload
-def atleast_2d(*arys: ArrayLike) -> List[ndarray]: ...
+def vstack(tup: Sequence[ArrayLike]) -> NDArray[Any]: ...
@overload
-def atleast_3d(__arys: ArrayLike) -> ndarray: ...
+def hstack(tup: Sequence[_ArrayLike[_SCT]]) -> NDArray[_SCT]: ...
@overload
-def atleast_3d(*arys: ArrayLike) -> List[ndarray]: ...
+def hstack(tup: Sequence[ArrayLike]) -> NDArray[Any]: ...
-def vstack(tup: Sequence[ArrayLike]) -> ndarray: ...
-def hstack(tup: Sequence[ArrayLike]) -> ndarray: ...
@overload
def stack(
- arrays: Sequence[ArrayLike], axis: SupportsIndex = ..., out: None = ...
-) -> ndarray: ...
+ arrays: Sequence[_ArrayLike[_SCT]],
+ axis: SupportsIndex = ...,
+ out: None = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def stack(
+ arrays: Sequence[ArrayLike],
+ axis: SupportsIndex = ...,
+ out: None = ...,
+) -> NDArray[Any]: ...
@overload
def stack(
- arrays: Sequence[ArrayLike], axis: SupportsIndex = ..., out: _ArrayType = ...
+ arrays: Sequence[ArrayLike],
+ axis: SupportsIndex = ...,
+ out: _ArrayType = ...,
) -> _ArrayType: ...
-def block(arrays: ArrayLike) -> ndarray: ...
+
+@overload
+def block(arrays: _ArrayLike[_SCT]) -> NDArray[_SCT]: ...
+@overload
+def block(arrays: ArrayLike) -> NDArray[Any]: ...
diff --git a/numpy/core/src/_simd/_simd.dispatch.c.src b/numpy/core/src/_simd/_simd.dispatch.c.src
index 18c383871..54770959c 100644
--- a/numpy/core/src/_simd/_simd.dispatch.c.src
+++ b/numpy/core/src/_simd/_simd.dispatch.c.src
@@ -1,4 +1,4 @@
-/*@targets $werror #simd_test*/
+/*@targets #simd_test*/
#include "_simd.h"
#include "_simd_inc.h"
@@ -9,20 +9,25 @@
#include "_simd_arg.inc"
#include "_simd_easyintrin.inc"
-/*************************************************************************
- * Defining NPYV intrinsics as module functions
- *************************************************************************/
+//#########################################################################
+//## Defining NPYV intrinsics as module functions
+//#########################################################################
/**begin repeat
* #sfx = u8, s8, u16, s16, u32, s32, u64, s64, f32, f64#
* #bsfx = b8, b8, b16, b16, b32, b32, b64, b64, b32, b64#
+ * #esfx = u16, s8, u32,s16, u32, s32, u64, s64, f32, f64#
+ * #expand_sup= 1, 0, 1, 0, 0, 0, 0, 0, 0, 0#
* #simd_sup = 1, 1, 1, 1, 1, 1, 1, 1, 1, NPY_SIMD_F64#
* #fp_only = 0, 0, 0, 0, 0, 0, 0, 0, 1, 1#
* #sat_sup = 1, 1, 1, 1, 0, 0, 0, 0, 0, 0#
* #mul_sup = 1, 1, 1, 1, 1, 1, 0, 0, 1, 1#
* #div_sup = 0, 0, 0, 0, 0, 0, 0, 0, 1, 1#
* #fused_sup = 0, 0, 0, 0, 0, 0, 0, 0, 1, 1#
- * #sum_sup = 0, 0, 0, 0, 0, 0, 0, 0, 1, 1#
+ * #sumup_sup = 1, 0, 1, 0, 0, 0, 0, 0, 0, 0#
+ * #sum_sup = 0, 0, 0, 0, 1, 0, 1, 0, 1, 1#
+ * #rev64_sup = 1, 1, 1, 1, 1, 1, 0, 0, 1, 0#
* #ncont_sup = 0, 0, 0, 0, 1, 1, 1, 1, 1, 1#
+ * #intdiv_sup= 1, 1, 1, 1, 1, 1, 1, 1, 0, 0#
* #shl_imm = 0, 0, 15, 15, 31, 31, 63, 63, 0, 0#
* #shr_imm = 0, 0, 16, 16, 32, 32, 64, 64, 0, 0#
*/
@@ -227,7 +232,6 @@ err:
/**end repeat1**/
#endif // @ncont_sup@
-
/***************************
* Misc
***************************/
@@ -289,6 +293,10 @@ SIMD_IMPL_INTRIN_2(@intrin@_@sfx@, v@sfx@, v@sfx@, v@sfx@)
SIMD_IMPL_INTRIN_2(@intrin@_@sfx@, v@sfx@x2, v@sfx@, v@sfx@)
/**end repeat1**/
+#if @rev64_sup@
+SIMD_IMPL_INTRIN_1(rev64_@sfx@, v@sfx@, v@sfx@)
+#endif
+
/***************************
* Operators
***************************/
@@ -301,7 +309,7 @@ SIMD_IMPL_INTRIN_2IMM(shri_@sfx@, v@sfx@, v@sfx@, @shr_imm@)
#endif // shl_imm
/**begin repeat1
- * #intrin = and, or, xor#
+ * #intrin = and, or, xor#
*/
SIMD_IMPL_INTRIN_2(@intrin@_@sfx@, v@sfx@, v@sfx@, v@sfx@)
/**end repeat1**/
@@ -309,7 +317,7 @@ SIMD_IMPL_INTRIN_2(@intrin@_@sfx@, v@sfx@, v@sfx@, v@sfx@)
SIMD_IMPL_INTRIN_1(not_@sfx@, v@sfx@, v@sfx@)
/**begin repeat1
- * #intrin = cmpeq, cmpneq, cmpgt, cmpge, cmplt, cmple#
+ * #intrin = cmpeq, cmpneq, cmpgt, cmpge, cmplt, cmple#
*/
SIMD_IMPL_INTRIN_2(@intrin@_@sfx@, v@bsfx@, v@sfx@, v@sfx@)
/**end repeat1**/
@@ -319,19 +327,21 @@ SIMD_IMPL_INTRIN_2(@intrin@_@sfx@, v@bsfx@, v@sfx@, v@sfx@)
***************************/
SIMD_IMPL_INTRIN_1(cvt_@sfx@_@bsfx@, v@sfx@, v@bsfx@)
SIMD_IMPL_INTRIN_1(cvt_@bsfx@_@sfx@, v@bsfx@, v@sfx@)
-
+#if @expand_sup@
+SIMD_IMPL_INTRIN_1(expand_@esfx@_@sfx@, v@esfx@x2, v@sfx@)
+#endif // expand_sup
/***************************
* Arithmetic
***************************/
/**begin repeat1
- * #intrin = add, sub#
+ * #intrin = add, sub#
*/
SIMD_IMPL_INTRIN_2(@intrin@_@sfx@, v@sfx@, v@sfx@, v@sfx@)
/**end repeat1**/
#if @sat_sup@
/**begin repeat1
- * #intrin = adds, subs#
+ * #intrin = adds, subs#
*/
SIMD_IMPL_INTRIN_2(@intrin@_@sfx@, v@sfx@, v@sfx@, v@sfx@)
/**end repeat1**/
@@ -345,9 +355,14 @@ SIMD_IMPL_INTRIN_2(mul_@sfx@, v@sfx@, v@sfx@, v@sfx@)
SIMD_IMPL_INTRIN_2(div_@sfx@, v@sfx@, v@sfx@, v@sfx@)
#endif // div_sup
+#if @intdiv_sup@
+SIMD_IMPL_INTRIN_1(divisor_@sfx@, v@sfx@x3, @sfx@)
+SIMD_IMPL_INTRIN_2(divc_@sfx@, v@sfx@, v@sfx@, v@sfx@x3)
+#endif // intdiv_sup
+
#if @fused_sup@
/**begin repeat1
- * #intrin = muladd, mulsub, nmuladd, nmulsub#
+ * #intrin = muladd, mulsub, nmuladd, nmulsub#
*/
SIMD_IMPL_INTRIN_3(@intrin@_@sfx@, v@sfx@, v@sfx@, v@sfx@, v@sfx@)
/**end repeat1**/
@@ -357,39 +372,117 @@ SIMD_IMPL_INTRIN_3(@intrin@_@sfx@, v@sfx@, v@sfx@, v@sfx@, v@sfx@)
SIMD_IMPL_INTRIN_1(sum_@sfx@, @sfx@, v@sfx@)
#endif // sum_sup
+#if @sumup_sup@
+SIMD_IMPL_INTRIN_1(sumup_@sfx@, @esfx@, v@sfx@)
+#endif // sumup_sup
+
/***************************
* Math
***************************/
#if @fp_only@
/**begin repeat1
- * #intrin = sqrt, recip, abs, square#
+ * #intrin = sqrt, recip, abs, square#
*/
SIMD_IMPL_INTRIN_1(@intrin@_@sfx@, v@sfx@, v@sfx@)
/**end repeat1**/
#endif
+/**begin repeat1
+ * #intrin = max, min#
+ */
+SIMD_IMPL_INTRIN_2(@intrin@_@sfx@, v@sfx@, v@sfx@, v@sfx@)
+/**end repeat1**/
+
+#if @fp_only@
+/**begin repeat1
+ * #intrin = maxp, minp#
+ */
+SIMD_IMPL_INTRIN_2(@intrin@_@sfx@, v@sfx@, v@sfx@, v@sfx@)
+/**end repeat1**/
+#endif
+
+/***************************
+ * Mask operations
+ ***************************/
+/**begin repeat1
+ * #intrin = ifadd, ifsub#
+ */
+ SIMD_IMPL_INTRIN_4(@intrin@_@sfx@, v@sfx@, v@bsfx@, v@sfx@, v@sfx@, v@sfx@)
+/**end repeat1**/
+
#endif // simd_sup
/**end repeat**/
-/***************************
+/*************************************************************************
* Variant
- ***************************/
+ ************************************************************************/
SIMD_IMPL_INTRIN_0N(cleanup)
/*************************************************************************
- * Attach module functions
- *************************************************************************/
+ * A special section for f32/f64 intrinsics outside the main repeater
+ ************************************************************************/
+/***************************
+ * Operators
+ ***************************/
+// check special cases
+SIMD_IMPL_INTRIN_1(notnan_f32, vb32, vf32)
+#if NPY_SIMD_F64
+ SIMD_IMPL_INTRIN_1(notnan_f64, vb64, vf64)
+#endif
+/***************************
+ * Conversions
+ ***************************/
+// round to nearest integer (assume even)
+SIMD_IMPL_INTRIN_1(round_s32_f32, vs32, vf32)
+#if NPY_SIMD_F64
+ SIMD_IMPL_INTRIN_2(round_s32_f64, vs32, vf64, vf64)
+#endif
+
+/*************************************************************************
+ * A special section for boolean intrinsics outside the main repeater
+ ************************************************************************/
+/***************************
+ * Operators
+ ***************************/
+// Logical
+/**begin repeat
+ * #bsfx = b8, b16, b32, b64#
+ */
+SIMD_IMPL_INTRIN_2(and_@bsfx@, v@bsfx@, v@bsfx@, v@bsfx@)
+SIMD_IMPL_INTRIN_2(or_@bsfx@, v@bsfx@, v@bsfx@, v@bsfx@)
+SIMD_IMPL_INTRIN_2(xor_@bsfx@, v@bsfx@, v@bsfx@, v@bsfx@)
+SIMD_IMPL_INTRIN_1(not_@bsfx@, v@bsfx@, v@bsfx@)
+/**end repeat**/
+/***************************
+ * Conversions
+ ***************************/
+// Convert mask vector to integer bitfield
+/**begin repeat
+ * #bsfx = b8, b16, b32, b64#
+ */
+SIMD_IMPL_INTRIN_1(tobits_@bsfx@, u64, v@bsfx@)
+/**end repeat**/
+
+
+//#########################################################################
+//## Attach module functions
+//#########################################################################
static PyMethodDef simd__intrinsics_methods[] = {
/**begin repeat
* #sfx = u8, s8, u16, s16, u32, s32, u64, s64, f32, f64#
* #bsfx = b8, b8, b16, b16, b32, b32, b64, b64, b32, b64#
+ * #esfx = u16, s8, u32,s16, u32, s32, u64, s64, f32, f64#
+ * #expand_sup =1, 0, 1, 0, 0, 0, 0, 0, 0, 0#
* #simd_sup = 1, 1, 1, 1, 1, 1, 1, 1, 1, NPY_SIMD_F64#
* #fp_only = 0, 0, 0, 0, 0, 0, 0, 0, 1, 1#
* #sat_sup = 1, 1, 1, 1, 0, 0, 0, 0, 0, 0#
* #mul_sup = 1, 1, 1, 1, 1, 1, 0, 0, 1, 1#
* #div_sup = 0, 0, 0, 0, 0, 0, 0, 0, 1, 1#
* #fused_sup = 0, 0, 0, 0, 0, 0, 0, 0, 1, 1#
- * #sum_sup = 0, 0, 0, 0, 0, 0, 0, 0, 1, 1#
+ * #sumup_sup = 1, 0, 1, 0, 0, 0, 0, 0, 0, 0#
+ * #sum_sup = 0, 0, 0, 0, 1, 0, 1, 0, 1, 1#
+ * #rev64_sup = 1, 1, 1, 1, 1, 1, 0, 0, 1, 0#
* #ncont_sup = 0, 0, 0, 0, 1, 1, 1, 1, 1, 1#
+ * #intdiv_sup= 1, 1, 1, 1, 1, 1, 1, 1, 0, 0#
* #shl_imm = 0, 0, 15, 15, 31, 31, 63, 63, 0, 0#
* #shr_imm = 0, 0, 16, 16, 32, 32, 64, 64, 0, 0#
*/
@@ -416,7 +509,6 @@ SIMD_INTRIN_DEF(@intrin@_@sfx@)
/**end repeat1**/
#endif // ncont_sup
-
/***************************
* Misc
***************************/
@@ -444,8 +536,9 @@ SIMD_INTRIN_DEF(@intrin@_@sfx@)
SIMD_INTRIN_DEF(@intrin@_@sfx@)
/**end repeat1**/
-SIMD_INTRIN_DEF(cvt_@sfx@_@bsfx@)
-SIMD_INTRIN_DEF(cvt_@bsfx@_@sfx@)
+#if @rev64_sup@
+SIMD_INTRIN_DEF(rev64_@sfx@)
+#endif
/***************************
* Operators
@@ -459,7 +552,7 @@ SIMD_INTRIN_DEF(@intrin@_@sfx@)
#endif // shl_imm
/**begin repeat1
- * #intrin = and, or, xor, not, cmpeq, cmpneq, cmpgt, cmpge, cmplt, cmple#
+ * #intrin = and, or, xor, not, cmpeq, cmpneq, cmpgt, cmpge, cmplt, cmple#
*/
SIMD_INTRIN_DEF(@intrin@_@sfx@)
/**end repeat1**/
@@ -469,19 +562,21 @@ SIMD_INTRIN_DEF(@intrin@_@sfx@)
***************************/
SIMD_INTRIN_DEF(cvt_@sfx@_@bsfx@)
SIMD_INTRIN_DEF(cvt_@bsfx@_@sfx@)
-
+#if @expand_sup@
+SIMD_INTRIN_DEF(expand_@esfx@_@sfx@)
+#endif // expand_sup
/***************************
* Arithmetic
***************************/
/**begin repeat1
- * #intrin = add, sub#
+ * #intrin = add, sub#
*/
SIMD_INTRIN_DEF(@intrin@_@sfx@)
/**end repeat1**/
#if @sat_sup@
/**begin repeat1
- * #intrin = adds, subs#
+ * #intrin = adds, subs#
*/
SIMD_INTRIN_DEF(@intrin@_@sfx@)
/**end repeat1**/
@@ -495,9 +590,14 @@ SIMD_INTRIN_DEF(mul_@sfx@)
SIMD_INTRIN_DEF(div_@sfx@)
#endif // div_sup
+#if @intdiv_sup@
+SIMD_INTRIN_DEF(divisor_@sfx@)
+SIMD_INTRIN_DEF(divc_@sfx@)
+#endif // intdiv_sup
+
#if @fused_sup@
/**begin repeat1
- * #intrin = muladd, mulsub, nmuladd, nmulsub#
+ * #intrin = muladd, mulsub, nmuladd, nmulsub#
*/
SIMD_INTRIN_DEF(@intrin@_@sfx@)
/**end repeat1**/
@@ -507,33 +607,104 @@ SIMD_INTRIN_DEF(@intrin@_@sfx@)
SIMD_INTRIN_DEF(sum_@sfx@)
#endif // sum_sup
+#if @sumup_sup@
+SIMD_INTRIN_DEF(sumup_@sfx@)
+#endif // sumup_sup
/***************************
* Math
***************************/
#if @fp_only@
/**begin repeat1
- * #intrin = sqrt, recip, abs, square#
+ * #intrin = sqrt, recip, abs, square#
+ */
+SIMD_INTRIN_DEF(@intrin@_@sfx@)
+/**end repeat1**/
+#endif
+
+/**begin repeat1
+ * #intrin = max, min#
+ */
+SIMD_INTRIN_DEF(@intrin@_@sfx@)
+/**end repeat1**/
+
+#if @fp_only@
+/**begin repeat1
+ * #intrin = maxp, minp#
*/
SIMD_INTRIN_DEF(@intrin@_@sfx@)
/**end repeat1**/
#endif
+/***************************
+ * Mask operations
+ ***************************/
+/**begin repeat1
+ * #intrin = ifadd, ifsub#
+ */
+ SIMD_INTRIN_DEF(@intrin@_@sfx@)
+/**end repeat1**/
+
#endif // simd_sup
/**end repeat**/
+/*************************************************************************
+ * Variant
+ ************************************************************************/
+SIMD_INTRIN_DEF(cleanup)
+/*************************************************************************
+ * A special section for f32/f64 intrinsics outside the main repeater
+ ************************************************************************/
/***************************
- * Variant
+ * Operators
***************************/
-SIMD_INTRIN_DEF(cleanup)
-/***************************/
+// check special cases
+SIMD_INTRIN_DEF(notnan_f32)
+#if NPY_SIMD_F64
+ SIMD_INTRIN_DEF(notnan_f64)
+#endif
+/***************************
+ * Conversions
+ ***************************/
+// round to nearest integer (assume even)
+SIMD_INTRIN_DEF(round_s32_f32)
+#if NPY_SIMD_F64
+ SIMD_INTRIN_DEF(round_s32_f64)
+#endif
+
+/*************************************************************************
+ * A special section for boolean intrinsics outside the main repeater
+ ************************************************************************/
+/***************************
+ * Operators
+ ***************************/
+// Logical
+/**begin repeat
+ * #bsfx = b8, b16, b32, b64#
+ */
+SIMD_INTRIN_DEF(and_@bsfx@)
+SIMD_INTRIN_DEF(or_@bsfx@)
+SIMD_INTRIN_DEF(xor_@bsfx@)
+SIMD_INTRIN_DEF(not_@bsfx@)
+/**end repeat**/
+/***************************
+ * Conversions
+ ***************************/
+// Convert mask vector to integer bitfield
+/**begin repeat
+ * #bsfx = b8, b16, b32, b64#
+ */
+SIMD_INTRIN_DEF(tobits_@bsfx@)
+/**end repeat**/
+
+/************************************************************************/
{NULL, NULL, 0, NULL}
}; // PyMethodDef
#endif // NPY_SIMD
-/*************************************************************************
- * Defining a separate module for each target
- *************************************************************************/
+//#########################################################################
+//## Defining a separate module for each target
+//#########################################################################
NPY_VISIBILITY_HIDDEN PyObject *
NPY_CPU_DISPATCH_CURFX(simd_create_module)(void)
{
@@ -561,6 +732,9 @@ NPY_CPU_DISPATCH_CURFX(simd_create_module)(void)
if (PyModule_AddIntConstant(m, "simd_f64", NPY_SIMD_F64)) {
goto err;
}
+ if (PyModule_AddIntConstant(m, "simd_fma3", NPY_SIMD_FMA3)) {
+ goto err;
+ }
if (PyModule_AddIntConstant(m, "simd_width", NPY_SIMD_WIDTH)) {
goto err;
}
diff --git a/numpy/core/src/_simd/_simd_easyintrin.inc b/numpy/core/src/_simd/_simd_easyintrin.inc
index 54e7ccf01..4521b2d87 100644
--- a/numpy/core/src/_simd/_simd_easyintrin.inc
+++ b/numpy/core/src/_simd/_simd_easyintrin.inc
@@ -87,10 +87,10 @@
simd_arg_converter, &arg1, \
simd_arg_converter, &arg2 \
)) return NULL; \
- simd_data data; \
+ simd_data data = {.u64 = 0}; \
data.RET = NPY_CAT(SIMD__IMPL_COUNT_, CONST_RNG)( \
SIMD__REPEAT_2IMM, NAME, IN0 \
- ) npyv_##NAME(arg1.data.IN0, 0); \
+ ) data.RET; \
simd_arg_free(&arg1); \
simd_arg ret = { \
.data = data, .dtype = simd_data_##RET \
@@ -123,6 +123,36 @@
}; \
return simd_arg_to_obj(&ret); \
}
+
+#define SIMD_IMPL_INTRIN_4(NAME, RET, IN0, IN1, IN2, IN3) \
+ static PyObject *simd__intrin_##NAME \
+ (PyObject* NPY_UNUSED(self), PyObject *args) \
+ { \
+ simd_arg arg1 = {.dtype = simd_data_##IN0}; \
+ simd_arg arg2 = {.dtype = simd_data_##IN1}; \
+ simd_arg arg3 = {.dtype = simd_data_##IN2}; \
+ simd_arg arg4 = {.dtype = simd_data_##IN3}; \
+ if (!PyArg_ParseTuple( \
+ args, "O&O&O&O&:"NPY_TOSTRING(NAME), \
+ simd_arg_converter, &arg1, \
+ simd_arg_converter, &arg2, \
+ simd_arg_converter, &arg3, \
+ simd_arg_converter, &arg4 \
+ )) return NULL; \
+ simd_data data = {.RET = npyv_##NAME( \
+ arg1.data.IN0, arg2.data.IN1, \
+ arg3.data.IN2, arg4.data.IN3 \
+ )}; \
+ simd_arg_free(&arg1); \
+ simd_arg_free(&arg2); \
+ simd_arg_free(&arg3); \
+ simd_arg_free(&arg4); \
+ simd_arg ret = { \
+ .data = data, .dtype = simd_data_##RET \
+ }; \
+ return simd_arg_to_obj(&ret); \
+ }
+
/**
* Helper macros for repeating and expand a certain macro.
* Mainly used for converting a scalar to an immediate constant.
diff --git a/numpy/core/src/_simd/_simd_vector.inc b/numpy/core/src/_simd/_simd_vector.inc
index 2a1378f22..3d0c15375 100644
--- a/numpy/core/src/_simd/_simd_vector.inc
+++ b/numpy/core/src/_simd/_simd_vector.inc
@@ -33,7 +33,7 @@ static PySequenceMethods simd__vector_as_sequence = {
};
static PyObject *
-simd__vector_name(PySIMDVectorObject *self)
+simd__vector_name(PySIMDVectorObject *self, void *NPY_UNUSED(ignored))
{
return PyUnicode_FromString(simd_data_getinfo(self->dtype)->pyname);
}
@@ -86,7 +86,22 @@ static PyTypeObject PySIMDVectorType = {
/************************************
** Protected Definitions
************************************/
-static PySIMDVectorObject *
+/*
+ * Force inlining the following functions on CYGWIN to avoid spilling vector
+ * registers into the stack to workaround GCC/WIN64 bug that performs
+ * miss-align load variable of 256/512-bit vector from non-aligned
+ * 256/512-bit stack pointer.
+ *
+ * check the following links for more clearification:
+ * https://github.com/numpy/numpy/pull/18330#issuecomment-821539919
+ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=49001
+ */
+#if defined(__CYGWIN__) || (defined(__GNUC__) && defined(_WIN64))
+ #define CYG_FINLINE NPY_FINLINE
+#else
+ #define CYG_FINLINE static
+#endif
+CYG_FINLINE PySIMDVectorObject *
PySIMDVector_FromData(simd_data data, simd_data_type dtype)
{
const simd_data_info *info = simd_data_getinfo(dtype);
@@ -118,7 +133,7 @@ PySIMDVector_FromData(simd_data data, simd_data_type dtype)
return vec;
}
-static simd_data
+CYG_FINLINE simd_data
PySIMDVector_AsData(PySIMDVectorObject *vec, simd_data_type dtype)
{
const simd_data_info *info = simd_data_getinfo(dtype);
diff --git a/numpy/core/src/common/lowlevel_strided_loops.h b/numpy/core/src/common/lowlevel_strided_loops.h
index 12aa61822..3df054b40 100644
--- a/numpy/core/src/common/lowlevel_strided_loops.h
+++ b/numpy/core/src/common/lowlevel_strided_loops.h
@@ -2,6 +2,8 @@
#define __LOWLEVEL_STRIDED_LOOPS_H
#include "common.h"
#include <npy_config.h>
+#include <array_method.h>
+#include "dtype_transfer.h"
#include "mem_overlap.h"
/* For PyArray_ macros used below */
@@ -30,22 +32,26 @@
* Use NPY_AUXDATA_CLONE and NPY_AUXDATA_FREE to deal with this data.
*
*/
-typedef int (PyArray_StridedUnaryOp)(
- char *dst, npy_intp dst_stride, char *src, npy_intp src_stride,
- npy_intp N, npy_intp src_itemsize, NpyAuxData *transferdata);
+// TODO: FIX! That comment belongs to something now in array-method
/*
* This is for pointers to functions which behave exactly as
- * for PyArray_StridedUnaryOp, but with an additional mask controlling
+ * for PyArrayMethod_StridedLoop, but with an additional mask controlling
* which values are transformed.
*
+ * TODO: We should move this mask "capability" to the ArrayMethod itself
+ * probably. Although for NumPy internal things this works decently,
+ * and exposing it there should be well thought out to be useful beyond
+ * NumPy if possible.
+ *
* In particular, the 'i'-th element is operated on if and only if
* mask[i*mask_stride] is true.
*/
typedef int (PyArray_MaskedStridedUnaryOp)(
- char *dst, npy_intp dst_stride, char *src, npy_intp src_stride,
+ PyArrayMethod_Context *context, char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
npy_bool *mask, npy_intp mask_stride,
- npy_intp N, npy_intp src_itemsize, NpyAuxData *transferdata);
+ NpyAuxData *auxdata);
/*
* Gives back a function pointer to a specialized function for copying
@@ -65,7 +71,7 @@ typedef int (PyArray_MaskedStridedUnaryOp)(
* Should be the item size if it will always be the same, 0 otherwise.
*
*/
-NPY_NO_EXPORT PyArray_StridedUnaryOp *
+NPY_NO_EXPORT PyArrayMethod_StridedLoop *
PyArray_GetStridedCopyFn(int aligned,
npy_intp src_stride, npy_intp dst_stride,
npy_intp itemsize);
@@ -80,7 +86,7 @@ PyArray_GetStridedCopyFn(int aligned,
*
* Parameters are as for PyArray_GetStridedCopyFn.
*/
-NPY_NO_EXPORT PyArray_StridedUnaryOp *
+NPY_NO_EXPORT PyArrayMethod_StridedLoop *
PyArray_GetStridedCopySwapFn(int aligned,
npy_intp src_stride, npy_intp dst_stride,
npy_intp itemsize);
@@ -95,7 +101,7 @@ PyArray_GetStridedCopySwapFn(int aligned,
*
* Parameters are as for PyArray_GetStridedCopyFn.
*/
-NPY_NO_EXPORT PyArray_StridedUnaryOp *
+NPY_NO_EXPORT PyArrayMethod_StridedLoop *
PyArray_GetStridedCopySwapPairFn(int aligned,
npy_intp src_stride, npy_intp dst_stride,
npy_intp itemsize);
@@ -114,7 +120,7 @@ NPY_NO_EXPORT int
PyArray_GetStridedZeroPadCopyFn(int aligned, int unicode_swap,
npy_intp src_stride, npy_intp dst_stride,
npy_intp src_itemsize, npy_intp dst_itemsize,
- PyArray_StridedUnaryOp **outstransfer,
+ PyArrayMethod_StridedLoop **outstransfer,
NpyAuxData **outtransferdata);
/*
@@ -123,7 +129,7 @@ PyArray_GetStridedZeroPadCopyFn(int aligned, int unicode_swap,
* to dst_type_num. If a conversion is unsupported, returns NULL
* without setting a Python exception.
*/
-NPY_NO_EXPORT PyArray_StridedUnaryOp *
+NPY_NO_EXPORT PyArrayMethod_StridedLoop *
PyArray_GetStridedNumericCastFn(int aligned,
npy_intp src_stride, npy_intp dst_stride,
int src_type_num, int dst_type_num);
@@ -138,7 +144,7 @@ NPY_NO_EXPORT int
PyArray_GetDTypeCopySwapFn(int aligned,
npy_intp src_stride, npy_intp dst_stride,
PyArray_Descr *dtype,
- PyArray_StridedUnaryOp **outstransfer,
+ PyArrayMethod_StridedLoop **outstransfer,
NpyAuxData **outtransferdata);
/*
@@ -159,8 +165,7 @@ PyArray_GetDTypeCopySwapFn(int aligned,
* Should be the dst stride if it will always be the same,
* NPY_MAX_INTP otherwise.
* src_dtype:
- * The data type of source data. If this is NULL, a transfer
- * function which sets the destination to zeros is produced.
+ * The data type of source data. Must not be NULL.
* dst_dtype:
* The data type of destination data. If this is NULL and
* move_references is 1, a transfer function which decrements
@@ -169,12 +174,10 @@ PyArray_GetDTypeCopySwapFn(int aligned,
* If 0, the destination data gets new reference ownership.
* If 1, the references from the source data are moved to
* the destination data.
- * out_stransfer:
- * The resulting transfer function is placed here.
- * out_transferdata:
- * The auxiliary data for the transfer function is placed here.
- * When finished with the transfer function, the caller must call
- * NPY_AUXDATA_FREE on this data.
+ * cast_info:
+ * A pointer to an (uninitialized) `NPY_cast_info` struct, the caller
+ * must call `NPY_cast_info_xfree` on it (except on error) and handle
+ * its memory livespan.
* out_needs_api:
* If this is non-NULL, and the transfer function produced needs
* to call into the (Python) API, this gets set to 1. This
@@ -192,10 +195,27 @@ PyArray_GetDTypeTransferFunction(int aligned,
npy_intp src_stride, npy_intp dst_stride,
PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
int move_references,
- PyArray_StridedUnaryOp **out_stransfer,
- NpyAuxData **out_transferdata,
+ NPY_cast_info *cast_info,
int *out_needs_api);
+NPY_NO_EXPORT int
+get_fields_transfer_function(int aligned,
+ npy_intp src_stride, npy_intp dst_stride,
+ PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
+ int move_references,
+ PyArrayMethod_StridedLoop **out_stransfer,
+ NpyAuxData **out_transferdata,
+ int *out_needs_api);
+
+NPY_NO_EXPORT int
+get_subarray_transfer_function(int aligned,
+ npy_intp src_stride, npy_intp dst_stride,
+ PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
+ int move_references,
+ PyArrayMethod_StridedLoop **out_stransfer,
+ NpyAuxData **out_transferdata,
+ int *out_needs_api);
+
/*
* This is identical to PyArray_GetDTypeTransferFunction, but returns a
* transfer function which also takes a mask as a parameter. The mask is used
@@ -220,8 +240,7 @@ PyArray_GetMaskedDTypeTransferFunction(int aligned,
PyArray_Descr *dst_dtype,
PyArray_Descr *mask_dtype,
int move_references,
- PyArray_MaskedStridedUnaryOp **out_stransfer,
- NpyAuxData **out_transferdata,
+ NPY_cast_info *cast_info,
int *out_needs_api);
/*
@@ -276,11 +295,9 @@ PyArray_CastRawArrays(npy_intp count,
* sizes, for example a casting operation, the 'stransfer' function
* should be specialized for that, in which case 'stransfer' will use
* this parameter as the source item size.
- * stransfer:
- * The strided transfer function.
- * transferdata:
- * An auxiliary data pointer passed to the strided transfer function.
- * This follows the conventions of NpyAuxData objects.
+ * cast_info:
+ * Pointer to the NPY_cast_info struct which summarizes all information
+ * necessary to perform a cast.
*/
NPY_NO_EXPORT npy_intp
PyArray_TransferNDimToStrided(npy_intp ndim,
@@ -289,8 +306,7 @@ PyArray_TransferNDimToStrided(npy_intp ndim,
npy_intp const *coords, npy_intp coords_inc,
npy_intp const *shape, npy_intp shape_inc,
npy_intp count, npy_intp src_itemsize,
- PyArray_StridedUnaryOp *stransfer,
- NpyAuxData *transferdata);
+ NPY_cast_info *cast_info);
NPY_NO_EXPORT npy_intp
PyArray_TransferStridedToNDim(npy_intp ndim,
@@ -299,8 +315,7 @@ PyArray_TransferStridedToNDim(npy_intp ndim,
npy_intp const *coords, npy_intp coords_inc,
npy_intp const *shape, npy_intp shape_inc,
npy_intp count, npy_intp src_itemsize,
- PyArray_StridedUnaryOp *stransfer,
- NpyAuxData *transferdata);
+ NPY_cast_info *cast_info);
NPY_NO_EXPORT npy_intp
PyArray_TransferMaskedStridedToNDim(npy_intp ndim,
@@ -310,8 +325,7 @@ PyArray_TransferMaskedStridedToNDim(npy_intp ndim,
npy_intp const *coords, npy_intp coords_inc,
npy_intp const *shape, npy_intp shape_inc,
npy_intp count, npy_intp src_itemsize,
- PyArray_MaskedStridedUnaryOp *stransfer,
- NpyAuxData *data);
+ NPY_cast_info *cast_info);
NPY_NO_EXPORT int
mapiter_trivial_get(PyArrayObject *self, PyArrayObject *ind,
@@ -633,25 +647,6 @@ npy_bswap8_unaligned(char * x)
* // Create iterator, etc...
* }
*
- * Here is example code for a pair of arrays:
- *
- * if (PyArray_TRIVIALLY_ITERABLE_PAIR(a1, a2)) {
- * char *data1, *data2;
- * npy_intp count, stride1, stride2;
- *
- * PyArray_PREPARE_TRIVIAL_PAIR_ITERATION(a1, a2, count,
- * data1, data2, stride1, stride2);
- *
- * while (count--) {
- * // Use the data1 and data2 pointers
- *
- * data1 += stride1;
- * data2 += stride2;
- * }
- * }
- * else {
- * // Create iterator, etc...
- * }
*/
/*
@@ -762,16 +757,6 @@ PyArray_EQUIVALENTLY_ITERABLE_OVERLAP_OK(PyArrayObject *arr1, PyArrayObject *arr
PyArray_STRIDE(arr, 0) : \
PyArray_ITEMSIZE(arr)));
-#define PyArray_TRIVIALLY_ITERABLE_PAIR(arr1, arr2, arr1_read, arr2_read) ( \
- PyArray_TRIVIALLY_ITERABLE(arr1) && \
- (PyArray_NDIM(arr2) == 0 || \
- PyArray_EQUIVALENTLY_ITERABLE_BASE(arr1, arr2) || \
- (PyArray_NDIM(arr1) == 0 && \
- PyArray_TRIVIALLY_ITERABLE(arr2) \
- ) \
- ) && \
- PyArray_EQUIVALENTLY_ITERABLE_OVERLAP_OK(arr1, arr2, arr1_read, arr2_read) \
- )
#define PyArray_PREPARE_TRIVIAL_PAIR_ITERATION(arr1, arr2, \
count, \
data1, data2, \
@@ -785,45 +770,4 @@ PyArray_EQUIVALENTLY_ITERABLE_OVERLAP_OK(PyArrayObject *arr1, PyArrayObject *arr
stride2 = PyArray_TRIVIAL_PAIR_ITERATION_STRIDE(size2, arr2); \
}
-#define PyArray_TRIVIALLY_ITERABLE_TRIPLE(arr1, arr2, arr3, arr1_read, arr2_read, arr3_read) ( \
- PyArray_TRIVIALLY_ITERABLE(arr1) && \
- ((PyArray_NDIM(arr2) == 0 && \
- (PyArray_NDIM(arr3) == 0 || \
- PyArray_EQUIVALENTLY_ITERABLE_BASE(arr1, arr3) \
- ) \
- ) || \
- (PyArray_EQUIVALENTLY_ITERABLE_BASE(arr1, arr2) && \
- (PyArray_NDIM(arr3) == 0 || \
- PyArray_EQUIVALENTLY_ITERABLE_BASE(arr1, arr3) \
- ) \
- ) || \
- (PyArray_NDIM(arr1) == 0 && \
- PyArray_TRIVIALLY_ITERABLE(arr2) && \
- (PyArray_NDIM(arr3) == 0 || \
- PyArray_EQUIVALENTLY_ITERABLE_BASE(arr2, arr3) \
- ) \
- ) \
- ) && \
- PyArray_EQUIVALENTLY_ITERABLE_OVERLAP_OK(arr1, arr2, arr1_read, arr2_read) && \
- PyArray_EQUIVALENTLY_ITERABLE_OVERLAP_OK(arr1, arr3, arr1_read, arr3_read) && \
- PyArray_EQUIVALENTLY_ITERABLE_OVERLAP_OK(arr2, arr3, arr2_read, arr3_read) \
- )
-
-#define PyArray_PREPARE_TRIVIAL_TRIPLE_ITERATION(arr1, arr2, arr3, \
- count, \
- data1, data2, data3, \
- stride1, stride2, stride3) { \
- npy_intp size1 = PyArray_SIZE(arr1); \
- npy_intp size2 = PyArray_SIZE(arr2); \
- npy_intp size3 = PyArray_SIZE(arr3); \
- count = ((size1 > size2) || size1 == 0) ? size1 : size2; \
- count = ((size3 > count) || size3 == 0) ? size3 : count; \
- data1 = PyArray_BYTES(arr1); \
- data2 = PyArray_BYTES(arr2); \
- data3 = PyArray_BYTES(arr3); \
- stride1 = PyArray_TRIVIAL_PAIR_ITERATION_STRIDE(size1, arr1); \
- stride2 = PyArray_TRIVIAL_PAIR_ITERATION_STRIDE(size2, arr2); \
- stride3 = PyArray_TRIVIAL_PAIR_ITERATION_STRIDE(size3, arr3); \
- }
-
#endif
diff --git a/numpy/core/src/common/npy_argparse.c b/numpy/core/src/common/npy_argparse.c
new file mode 100644
index 000000000..8460a38e6
--- /dev/null
+++ b/numpy/core/src/common/npy_argparse.c
@@ -0,0 +1,421 @@
+#include "Python.h"
+
+#define NPY_NO_DEPRECATED_API NPY_API_VERSION
+#define _MULTIARRAYMODULE
+
+#include "numpy/ndarraytypes.h"
+#include "npy_argparse.h"
+#include "npy_pycompat.h"
+#include "npy_import.h"
+
+#include "arrayfunction_override.h"
+
+
+/**
+ * Small wrapper converting to array just like CPython does.
+ *
+ * We could use our own PyArray_PyIntAsInt function, but it handles floats
+ * differently.
+ * A disadvantage of this function compared to ``PyArg_*("i")`` code is that
+ * it will not say which parameter is wrong.
+ *
+ * @param obj The python object to convert
+ * @param value The output value
+ *
+ * @returns 0 on failure and 1 on success (`NPY_FAIL`, `NPY_SUCCEED`)
+ */
+NPY_NO_EXPORT int
+PyArray_PythonPyIntFromInt(PyObject *obj, int *value)
+{
+ /* Pythons behaviour is to check only for float explicitly... */
+ if (NPY_UNLIKELY(PyFloat_Check(obj))) {
+ PyErr_SetString(PyExc_TypeError,
+ "integer argument expected, got float");
+ return NPY_FAIL;
+ }
+
+ long result = PyLong_AsLong(obj);
+ if (NPY_UNLIKELY((result == -1) && PyErr_Occurred())) {
+ return NPY_FAIL;
+ }
+ if (NPY_UNLIKELY((result > INT_MAX) || (result < INT_MIN))) {
+ PyErr_SetString(PyExc_OverflowError,
+ "Python int too large to convert to C int");
+ return NPY_FAIL;
+ }
+ else {
+ *value = (int)result;
+ return NPY_SUCCEED;
+ }
+}
+
+
+typedef int convert(PyObject *, void *);
+
+/**
+ * Internal function to initialize keyword argument parsing.
+ *
+ * This does a few simple jobs:
+ *
+ * * Check the input for consistency to find coding errors, for example
+ * a parameter not marked with | after one marked with | (optional).
+ * 2. Find the number of positional-only arguments, the number of
+ * total, required, and keyword arguments.
+ * 3. Intern all keyword arguments strings to allow fast, identity based
+ * parsing and avoid string creation overhead on each call.
+ *
+ * @param funcname Name of the function, mainly used for errors.
+ * @param cache A cache object stored statically in the parsing function
+ * @param va_orig Argument list to npy_parse_arguments
+ * @return 0 on success, -1 on failure
+ */
+static int
+initialize_keywords(const char *funcname,
+ _NpyArgParserCache *cache, va_list va_orig) {
+ va_list va;
+ int nargs = 0;
+ int nkwargs = 0;
+ int npositional_only = 0;
+ int nrequired = 0;
+ int npositional = 0;
+ char state = '\0';
+
+ va_copy(va, va_orig);
+ while (1) {
+ /* Count length first: */
+ char *name = va_arg(va, char *);
+ convert *converter = va_arg(va, convert *);
+ void *data = va_arg(va, void *);
+
+ /* Check if this is the sentinel, only converter may be NULL */
+ if ((name == NULL) && (converter == NULL) && (data == NULL)) {
+ break;
+ }
+
+ if (name == NULL) {
+ PyErr_Format(PyExc_SystemError,
+ "NumPy internal error: name is NULL in %s() at "
+ "argument %d.", funcname, nargs);
+ va_end(va);
+ return -1;
+ }
+ if (data == NULL) {
+ PyErr_Format(PyExc_SystemError,
+ "NumPy internal error: data is NULL in %s() at "
+ "argument %d.", funcname, nargs);
+ va_end(va);
+ return -1;
+ }
+
+ nargs += 1;
+ if (*name == '|') {
+ if (state == '$') {
+ PyErr_Format(PyExc_SystemError,
+ "NumPy internal error: positional argument `|` "
+ "after keyword only `$` one to %s() at argument %d.",
+ funcname, nargs);
+ va_end(va);
+ return -1;
+ }
+ state = '|';
+ name++; /* advance to actual name. */
+ npositional += 1;
+ }
+ else if (*name == '$') {
+ state = '$';
+ name++; /* advance to actual name. */
+ }
+ else {
+ if (state != '\0') {
+ PyErr_Format(PyExc_SystemError,
+ "NumPy internal error: non-required argument after "
+ "required | or $ one to %s() at argument %d.",
+ funcname, nargs);
+ va_end(va);
+ return -1;
+ }
+
+ nrequired += 1;
+ npositional += 1;
+ }
+
+ if (*name == '\0') {
+ /* Empty string signals positional only */
+ if (state != '\0') {
+ PyErr_Format(PyExc_SystemError,
+ "NumPy internal error: non-kwarg marked with | or $ "
+ "to %s() at argument %d.", funcname, nargs);
+ va_end(va);
+ return -1;
+ }
+ npositional_only += 1;
+ }
+ else {
+ nkwargs += 1;
+ }
+ }
+ va_end(va);
+
+ if (npositional == -1) {
+ npositional = nargs;
+ }
+
+ if (nargs > _NPY_MAX_KWARGS) {
+ PyErr_Format(PyExc_SystemError,
+ "NumPy internal error: function %s() has %d arguments, but "
+ "the maximum is currently limited to %d for easier parsing; "
+ "it can be increased by modifying `_NPY_MAX_KWARGS`.",
+ funcname, nargs, _NPY_MAX_KWARGS);
+ return -1;
+ }
+
+ /*
+ * Do any necessary string allocation and interning,
+ * creating a caching object.
+ */
+ cache->nargs = nargs;
+ cache->npositional_only = npositional_only;
+ cache->npositional = npositional;
+ cache->nrequired = nrequired;
+
+ /* NULL kw_strings for easier cleanup (and NULL termination) */
+ memset(cache->kw_strings, 0, sizeof(PyObject *) * (nkwargs + 1));
+
+ va_copy(va, va_orig);
+ for (int i = 0; i < nargs; i++) {
+ /* Advance through non-kwargs, which do not require setup. */
+ char *name = va_arg(va, char *);
+ va_arg(va, convert *);
+ va_arg(va, void *);
+
+ if (*name == '|' || *name == '$') {
+ name++; /* ignore | and $ */
+ }
+ if (i >= npositional_only) {
+ int i_kwarg = i - npositional_only;
+ cache->kw_strings[i_kwarg] = PyUString_InternFromString(name);
+ if (cache->kw_strings[i_kwarg] == NULL) {
+ va_end(va);
+ goto error;
+ }
+ }
+ }
+
+ va_end(va);
+ return 0;
+
+error:
+ for (int i = 0; i < nkwargs; i++) {
+ Py_XDECREF(cache->kw_strings[i]);
+ }
+ cache->npositional = -1; /* not initialized */
+ return -1;
+}
+
+
+static int
+raise_incorrect_number_of_positional_args(const char *funcname,
+ const _NpyArgParserCache *cache, Py_ssize_t len_args)
+{
+ if (cache->npositional == cache->nrequired) {
+ PyErr_Format(PyExc_TypeError,
+ "%s() takes %d positional arguments but %zd were given",
+ funcname, cache->npositional, len_args);
+ }
+ else {
+ PyErr_Format(PyExc_TypeError,
+ "%s() takes from %d to %d positional arguments but "
+ "%zd were given",
+ funcname, cache->nrequired, cache->npositional, len_args);
+ }
+ return -1;
+}
+
+static void
+raise_missing_argument(const char *funcname,
+ const _NpyArgParserCache *cache, int i)
+{
+ if (i < cache->npositional_only) {
+ PyErr_Format(PyExc_TypeError,
+ "%s() missing required positional argument %d",
+ funcname, i);
+ }
+ else {
+ PyObject *kw = cache->kw_strings[i - cache->npositional_only];
+ PyErr_Format(PyExc_TypeError,
+ "%s() missing required argument '%S' (pos %d)",
+ funcname, kw, i);
+ }
+}
+
+
+/**
+ * Generic helper for argument parsing
+ *
+ * See macro version for an example pattern of how to use this function.
+ *
+ * @param funcname
+ * @param cache
+ * @param args Python passed args (METH_FASTCALL)
+ * @param len_args
+ * @param kwnames
+ * @param ... List of arguments (see macro version).
+ *
+ * @return Returns 0 on success and -1 on failure.
+ */
+NPY_NO_EXPORT int
+_npy_parse_arguments(const char *funcname,
+ /* cache_ptr is a NULL initialized persistent storage for data */
+ _NpyArgParserCache *cache,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames,
+ /* ... is NULL, NULL, NULL terminated: name, converter, value */
+ ...)
+{
+ if (NPY_UNLIKELY(cache->npositional == -1)) {
+ va_list va;
+ va_start(va, kwnames);
+
+ int res = initialize_keywords(funcname, cache, va);
+ va_end(va);
+ if (res < 0) {
+ return -1;
+ }
+ }
+
+ if (NPY_UNLIKELY(len_args > cache->npositional)) {
+ return raise_incorrect_number_of_positional_args(
+ funcname, cache, len_args);
+ }
+
+ /* NOTE: Could remove the limit but too many kwargs are slow anyway. */
+ PyObject *all_arguments[NPY_MAXARGS];
+
+ for (Py_ssize_t i = 0; i < len_args; i++) {
+ all_arguments[i] = args[i];
+ }
+
+ /* Without kwargs, do not iterate all converters. */
+ int max_nargs = (int)len_args;
+ Py_ssize_t len_kwargs = 0;
+
+ /* If there are any kwargs, first handle them */
+ if (NPY_LIKELY(kwnames != NULL)) {
+ len_kwargs = PyTuple_GET_SIZE(kwnames);
+ max_nargs = cache->nargs;
+
+ for (int i = len_args; i < cache->nargs; i++) {
+ all_arguments[i] = NULL;
+ }
+
+ for (Py_ssize_t i = 0; i < len_kwargs; i++) {
+ PyObject *key = PyTuple_GET_ITEM(kwnames, i);
+ PyObject *value = args[i + len_args];
+ PyObject *const *name;
+
+ /* Super-fast path, check identity: */
+ for (name = cache->kw_strings; *name != NULL; name++) {
+ if (*name == key) {
+ break;
+ }
+ }
+ if (NPY_UNLIKELY(*name == NULL)) {
+ /* Slow fallback, if identity checks failed for some reason */
+ for (name = cache->kw_strings; *name != NULL; name++) {
+ int eq = PyObject_RichCompareBool(*name, key, Py_EQ);
+ if (eq == -1) {
+ return -1;
+ }
+ else if (eq) {
+ break;
+ }
+ }
+ if (NPY_UNLIKELY(*name == NULL)) {
+ /* Invalid keyword argument. */
+ PyErr_Format(PyExc_TypeError,
+ "%s() got an unexpected keyword argument '%S'",
+ funcname, key);
+ return -1;
+ }
+ }
+
+ Py_ssize_t param_pos = (
+ (name - cache->kw_strings) + cache->npositional_only);
+
+ /* There could be an identical positional argument */
+ if (NPY_UNLIKELY(all_arguments[param_pos] != NULL)) {
+ PyErr_Format(PyExc_TypeError,
+ "argument for %s() given by name ('%S') and position "
+ "(position %zd)", funcname, key, param_pos);
+ return -1;
+ }
+
+ all_arguments[param_pos] = value;
+ }
+ }
+
+ /*
+ * There cannot be too many args, too many kwargs would find an
+ * incorrect one above.
+ */
+ assert(len_args + len_kwargs <= cache->nargs);
+
+ /* At this time `all_arguments` holds either NULLs or the objects */
+ va_list va;
+ va_start(va, kwnames);
+
+ for (int i = 0; i < max_nargs; i++) {
+ va_arg(va, char *);
+ convert *converter = va_arg(va, convert *);
+ void *data = va_arg(va, void *);
+
+ if (all_arguments[i] == NULL) {
+ continue;
+ }
+
+ int res;
+ if (converter == NULL) {
+ *((PyObject **) data) = all_arguments[i];
+ continue;
+ }
+ res = converter(all_arguments[i], data);
+
+ if (NPY_UNLIKELY(res == NPY_SUCCEED)) {
+ continue;
+ }
+ else if (NPY_UNLIKELY(res == NPY_FAIL)) {
+ /* It is usually the users responsibility to clean up. */
+ goto converting_failed;
+ }
+ else if (NPY_UNLIKELY(res == Py_CLEANUP_SUPPORTED)) {
+ /* TODO: Implementing cleanup if/when needed should not be hard */
+ PyErr_Format(PyExc_SystemError,
+ "converter cleanup of parameter %d to %s() not supported.",
+ i, funcname);
+ goto converting_failed;
+ }
+ assert(0);
+ }
+
+ /* Required arguments are typically not passed as keyword arguments */
+ if (NPY_UNLIKELY(len_args < cache->nrequired)) {
+ /* (PyArg_* also does this after the actual parsing is finished) */
+ if (NPY_UNLIKELY(max_nargs < cache->nrequired)) {
+ raise_missing_argument(funcname, cache, max_nargs);
+ goto converting_failed;
+ }
+ for (int i = 0; i < cache->nrequired; i++) {
+ if (NPY_UNLIKELY(all_arguments[i] == NULL)) {
+ raise_missing_argument(funcname, cache, i);
+ goto converting_failed;
+ }
+ }
+ }
+
+ va_end(va);
+ return 0;
+
+converting_failed:
+ va_end(va);
+ return -1;
+
+}
diff --git a/numpy/core/src/common/npy_argparse.h b/numpy/core/src/common/npy_argparse.h
new file mode 100644
index 000000000..5da535c91
--- /dev/null
+++ b/numpy/core/src/common/npy_argparse.h
@@ -0,0 +1,96 @@
+#ifndef _NPY_ARGPARSE_H
+#define _NPY_ARGPARSE_H
+
+#include "Python.h"
+#include "numpy/ndarraytypes.h"
+
+/*
+ * This file defines macros to help with keyword argument parsing.
+ * This solves two issues as of now:
+ * 1. Pythons C-API PyArg_* keyword argument parsers are slow, due to
+ * not caching the strings they use.
+ * 2. It allows the use of METH_ARGPARSE (and `tp_vectorcall`)
+ * when available in Python, which removes a large chunk of overhead.
+ *
+ * Internally CPython achieves similar things by using a code generator
+ * argument clinic. NumPy may well decide to use argument clinic or a different
+ * solution in the future.
+ */
+
+NPY_NO_EXPORT int
+PyArray_PythonPyIntFromInt(PyObject *obj, int *value);
+
+
+#define _NPY_MAX_KWARGS 15
+
+typedef struct {
+ int npositional;
+ int nargs;
+ int npositional_only;
+ int nrequired;
+ /* Null terminated list of keyword argument name strings */
+ PyObject *kw_strings[_NPY_MAX_KWARGS+1];
+} _NpyArgParserCache;
+
+
+/*
+ * The sole purpose of this macro is to hide the argument parsing cache.
+ * Since this cache must be static, this also removes a source of error.
+ */
+#define NPY_PREPARE_ARGPARSER static _NpyArgParserCache __argparse_cache = {-1}
+
+/**
+ * Macro to help with argument parsing.
+ *
+ * The pattern for using this macro is by defining the method as:
+ *
+ * @code
+ * static PyObject *
+ * my_method(PyObject *self,
+ * PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
+ * {
+ * NPY_PREPARE_ARGPARSER;
+ *
+ * PyObject *argument1, *argument3;
+ * int argument2 = -1;
+ * if (npy_parse_arguments("method", args, len_args, kwnames),
+ * "argument1", NULL, &argument1,
+ * "|argument2", &PyArray_PythonPyIntFromInt, &argument2,
+ * "$argument3", NULL, &argument3,
+ * NULL, NULL, NULL) < 0) {
+ * return NULL;
+ * }
+ * }
+ * @endcode
+ *
+ * The `NPY_PREPARE_ARGPARSER` macro sets up a static cache variable necessary
+ * to hold data for speeding up the parsing. `npy_parse_arguments` must be
+ * used in cunjunction with the macro defined in the same scope.
+ * (No two `npy_parse_arguments` may share a single `NPY_PREPARE_ARGPARSER`.)
+ *
+ * @param funcname
+ * @param args Python passed args (METH_FASTCALL)
+ * @param len_args Number of arguments (not flagged)
+ * @param kwnames Tuple as passed by METH_FASTCALL or NULL.
+ * @param ... List of arguments must be param1_name, param1_converter,
+ * *param1_outvalue, param2_name, ..., NULL, NULL, NULL.
+ * Where name is ``char *``, ``converter`` a python converter
+ * function or NULL and ``outvalue`` is the ``void *`` passed to
+ * the converter (holding the converted data or a borrowed
+ * reference if converter is NULL).
+ *
+ * @return Returns 0 on success and -1 on failure.
+ */
+NPY_NO_EXPORT int
+_npy_parse_arguments(const char *funcname,
+ /* cache_ptr is a NULL initialized persistent storage for data */
+ _NpyArgParserCache *cache_ptr,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames,
+ /* va_list is NULL, NULL, NULL terminated: name, converter, value */
+ ...) NPY_GCC_NONNULL(1);
+
+#define npy_parse_arguments(funcname, args, len_args, kwnames, ...) \
+ _npy_parse_arguments(funcname, &__argparse_cache, \
+ args, len_args, kwnames, __VA_ARGS__)
+
+#endif /* _NPY_ARGPARSE_H */
diff --git a/numpy/core/src/common/npy_config.h b/numpy/core/src/common/npy_config.h
index 61cc3c7f1..c6de0cd30 100644
--- a/numpy/core/src/common/npy_config.h
+++ b/numpy/core/src/common/npy_config.h
@@ -96,6 +96,51 @@
#undef HAVE_POWL
#endif
+#ifdef __CYGWIN__
+/* Loss of precision */
+#undef HAVE_CASINHL
+#undef HAVE_CASINH
+#undef HAVE_CASINHF
+
+/* Loss of precision */
+#undef HAVE_CATANHL
+#undef HAVE_CATANH
+#undef HAVE_CATANHF
+
+/* Loss of precision and branch cuts */
+#undef HAVE_CATANL
+#undef HAVE_CATAN
+#undef HAVE_CATANF
+
+/* Branch cuts */
+#undef HAVE_CACOSHF
+#undef HAVE_CACOSH
+
+/* Branch cuts */
+#undef HAVE_CSQRTF
+#undef HAVE_CSQRT
+
+/* Branch cuts and loss of precision */
+#undef HAVE_CASINF
+#undef HAVE_CASIN
+#undef HAVE_CASINL
+
+/* Branch cuts */
+#undef HAVE_CACOSF
+#undef HAVE_CACOS
+
+/* log2(exp2(i)) off by a few eps */
+#undef HAVE_LOG2
+
+/* np.power(..., dtype=np.complex256) doesn't report overflow */
+#undef HAVE_CPOWL
+#undef HAVE_CEXPL
+
+/* Builtin abs reports overflow */
+#undef HAVE_CABSL
+#undef HAVE_HYPOTL
+#endif
+
/* Disable broken gnu trig functions */
#if defined(HAVE_FEATURES_H)
#include <features.h>
diff --git a/numpy/core/src/common/npy_cpu_dispatch.h b/numpy/core/src/common/npy_cpu_dispatch.h
index a0f82fa3d..c8411104a 100644
--- a/numpy/core/src/common/npy_cpu_dispatch.h
+++ b/numpy/core/src/common/npy_cpu_dispatch.h
@@ -7,10 +7,10 @@
#include "npy_cpu_features.h" // NPY_CPU_HAVE
#include "numpy/utils.h" // NPY_EXPAND, NPY_CAT
/**
- * Bringing the main configration header '_cpu_dispatch.h'.
+ * Including the main configuration header 'npy_cpu_dispatch_config.h'.
*
* This header is generated by the distutils module 'ccompiler_opt',
- * and contains all the #definitions and headers of instruction-sets,
+ * and contains all the #definitions and headers for platform-specific instruction-sets
* that had been configured through command arguments '--cpu-baseline' and '--cpu-dispatch'.
*
* It also contains extra C #definitions and macros that are used for implementing
@@ -33,7 +33,7 @@
#define NPY__DISPATCH_DEFBOOL
typedef bool npy__dispatch_bkbool;
#endif
- #include "_cpu_dispatch.h"
+ #include "npy_cpu_dispatch_config.h"
#ifdef NPY_HAVE_VSX
#undef bool
#undef vector
diff --git a/numpy/core/src/common/npy_cpu_features.c.src b/numpy/core/src/common/npy_cpu_features.c.src
index 69bbc83a2..1e0f4a571 100644
--- a/numpy/core/src/common/npy_cpu_features.c.src
+++ b/numpy/core/src/common/npy_cpu_features.c.src
@@ -394,8 +394,30 @@ npy__cpu_init_features(void)
npy__cpu_have[NPY_CPU_FEATURE_FMA] = npy__cpu_have[NPY_CPU_FEATURE_FMA3];
// check AVX512 OS support
- if ((xcr & 0xe6) != 0xe6)
+ int avx512_os = (xcr & 0xe6) == 0xe6;
+#if defined(__APPLE__) && defined(__x86_64__)
+ /**
+ * On darwin, machines with AVX512 support, by default, threads are created with
+ * AVX512 masked off in XCR0 and an AVX-sized savearea is used.
+ * However, AVX512 capabilities are advertised in the commpage and via sysctl.
+ * for more information, check:
+ * - https://github.com/apple/darwin-xnu/blob/0a798f6738bc1db01281fc08ae024145e84df927/osfmk/i386/fpu.c#L175-L201
+ * - https://github.com/golang/go/issues/43089
+ * - https://github.com/numpy/numpy/issues/19319
+ */
+ if (!avx512_os) {
+ npy_uintp commpage64_addr = 0x00007fffffe00000ULL;
+ npy_uint16 commpage64_ver = *((npy_uint16*)(commpage64_addr + 0x01E));
+ // cpu_capabilities64 undefined in versions < 13
+ if (commpage64_ver > 12) {
+ npy_uint64 commpage64_cap = *((npy_uint64*)(commpage64_addr + 0x010));
+ avx512_os = (commpage64_cap & 0x0000004000000000ULL) != 0;
+ }
+ }
+#endif
+ if (!avx512_os) {
return;
+ }
npy__cpu_have[NPY_CPU_FEATURE_AVX512F] = (reg[1] & (1 << 16)) != 0;
npy__cpu_have[NPY_CPU_FEATURE_AVX512CD] = (reg[1] & (1 << 28)) != 0;
if (npy__cpu_have[NPY_CPU_FEATURE_AVX512F] && npy__cpu_have[NPY_CPU_FEATURE_AVX512CD]) {
@@ -500,7 +522,7 @@ npy__cpu_init_features_arm8(void)
npy__cpu_have[NPY_CPU_FEATURE_ASIMD] = 1;
}
-#ifdef __linux__
+#if defined(__linux__) || defined(__FreeBSD__)
/*
* we aren't sure of what kind kernel or clib we deal with
* so we play it safe
@@ -509,10 +531,23 @@ npy__cpu_init_features_arm8(void)
#include "npy_cpuinfo_parser.h"
__attribute__((weak)) unsigned long getauxval(unsigned long); // linker should handle it
+#ifdef __FreeBSD__
+__attribute__((weak)) int elf_aux_info(int, void *, int); // linker should handle it
+
+static unsigned long getauxval(unsigned long k)
+{
+ unsigned long val = 0ul;
+ if (elf_aux_info == 0 || elf_aux_info((int)k, (void *)&val, (int)sizeof(val)) != 0) {
+ return 0ul;
+ }
+ return val;
+}
+#endif
static int
npy__cpu_init_features_linux(void)
{
unsigned long hwcap = 0, hwcap2 = 0;
+ #ifdef __linux__
if (getauxval != 0) {
hwcap = getauxval(NPY__HWCAP);
#ifdef __arm__
@@ -539,7 +574,14 @@ npy__cpu_init_features_linux(void)
close(fd);
}
}
+ #else
+ hwcap = getauxval(NPY__HWCAP);
+ #ifdef __arm__
+ hwcap2 = getauxval(NPY__HWCAP2);
+ #endif
+ #endif
if (hwcap == 0 && hwcap2 == 0) {
+ #ifdef __linux__
/*
* try parsing with /proc/cpuinfo, if sandboxed
* failback to compiler definitions
@@ -547,6 +589,9 @@ npy__cpu_init_features_linux(void)
if(!get_feature_from_proc_cpuinfo(&hwcap, &hwcap2)) {
return 0;
}
+ #else
+ return 0;
+ #endif
}
#ifdef __arm__
// Detect Arm8 (aarch32 state)
diff --git a/numpy/core/src/common/npy_cpuinfo_parser.h b/numpy/core/src/common/npy_cpuinfo_parser.h
index 4c00c847b..f4540f6ab 100644
--- a/numpy/core/src/common/npy_cpuinfo_parser.h
+++ b/numpy/core/src/common/npy_cpuinfo_parser.h
@@ -1,262 +1,262 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * * Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-#ifndef __NPY_CPUINFO_PARSER_H__
-#define __NPY_CPUINFO_PARSER_H__
-#include <errno.h>
-#include <stdio.h>
-#include <fcntl.h>
-#include <string.h>
-#include <stddef.h>
-
-#define NPY__HWCAP 16
-#define NPY__HWCAP2 26
-
-// arch/arm/include/uapi/asm/hwcap.h
-#define NPY__HWCAP_HALF (1 << 1)
-#define NPY__HWCAP_NEON (1 << 12)
-#define NPY__HWCAP_VFPv3 (1 << 13)
-#define NPY__HWCAP_VFPv4 (1 << 16)
-#define NPY__HWCAP2_AES (1 << 0)
-#define NPY__HWCAP2_PMULL (1 << 1)
-#define NPY__HWCAP2_SHA1 (1 << 2)
-#define NPY__HWCAP2_SHA2 (1 << 3)
-#define NPY__HWCAP2_CRC32 (1 << 4)
-// arch/arm64/include/uapi/asm/hwcap.h
-#define NPY__HWCAP_FP (1 << 0)
-#define NPY__HWCAP_ASIMD (1 << 1)
-#define NPY__HWCAP_FPHP (1 << 9)
-#define NPY__HWCAP_ASIMDHP (1 << 10)
-#define NPY__HWCAP_ASIMDDP (1 << 20)
-#define NPY__HWCAP_ASIMDFHM (1 << 23)
-/*
- * Get the size of a file by reading it until the end. This is needed
- * because files under /proc do not always return a valid size when
- * using fseek(0, SEEK_END) + ftell(). Nor can they be mmap()-ed.
- */
-static int
-get_file_size(const char* pathname)
-{
- int fd, result = 0;
- char buffer[256];
-
- fd = open(pathname, O_RDONLY);
- if (fd < 0) {
- return -1;
- }
-
- for (;;) {
- int ret = read(fd, buffer, sizeof buffer);
- if (ret < 0) {
- if (errno == EINTR) {
- continue;
- }
- break;
- }
- if (ret == 0) {
- break;
- }
- result += ret;
- }
- close(fd);
- return result;
-}
-
-/*
- * Read the content of /proc/cpuinfo into a user-provided buffer.
- * Return the length of the data, or -1 on error. Does *not*
- * zero-terminate the content. Will not read more
- * than 'buffsize' bytes.
- */
-static int
-read_file(const char* pathname, char* buffer, size_t buffsize)
-{
- int fd, count;
-
- fd = open(pathname, O_RDONLY);
- if (fd < 0) {
- return -1;
- }
- count = 0;
- while (count < (int)buffsize) {
- int ret = read(fd, buffer + count, buffsize - count);
- if (ret < 0) {
- if (errno == EINTR) {
- continue;
- }
- if (count == 0) {
- count = -1;
- }
- break;
- }
- if (ret == 0) {
- break;
- }
- count += ret;
- }
- close(fd);
- return count;
-}
-
-/*
- * Extract the content of a the first occurence of a given field in
- * the content of /proc/cpuinfo and return it as a heap-allocated
- * string that must be freed by the caller.
- *
- * Return NULL if not found
- */
-static char*
-extract_cpuinfo_field(const char* buffer, int buflen, const char* field)
-{
- int fieldlen = strlen(field);
- const char* bufend = buffer + buflen;
- char* result = NULL;
- int len;
- const char *p, *q;
-
- /* Look for first field occurence, and ensures it starts the line. */
- p = buffer;
- for (;;) {
- p = memmem(p, bufend-p, field, fieldlen);
- if (p == NULL) {
- goto EXIT;
- }
-
- if (p == buffer || p[-1] == '\n') {
- break;
- }
-
- p += fieldlen;
- }
-
- /* Skip to the first column followed by a space */
- p += fieldlen;
- p = memchr(p, ':', bufend-p);
- if (p == NULL || p[1] != ' ') {
- goto EXIT;
- }
-
- /* Find the end of the line */
- p += 2;
- q = memchr(p, '\n', bufend-p);
- if (q == NULL) {
- q = bufend;
- }
-
- /* Copy the line into a heap-allocated buffer */
- len = q - p;
- result = malloc(len + 1);
- if (result == NULL) {
- goto EXIT;
- }
-
- memcpy(result, p, len);
- result[len] = '\0';
-
-EXIT:
- return result;
-}
-
-/*
- * Checks that a space-separated list of items contains one given 'item'.
- * Returns 1 if found, 0 otherwise.
- */
-static int
-has_list_item(const char* list, const char* item)
-{
- const char* p = list;
- int itemlen = strlen(item);
-
- if (list == NULL) {
- return 0;
- }
-
- while (*p) {
- const char* q;
-
- /* skip spaces */
- while (*p == ' ' || *p == '\t') {
- p++;
- }
-
- /* find end of current list item */
- q = p;
- while (*q && *q != ' ' && *q != '\t') {
- q++;
- }
-
- if (itemlen == q-p && !memcmp(p, item, itemlen)) {
- return 1;
- }
-
- /* skip to next item */
- p = q;
- }
- return 0;
-}
-
-static void setHwcap(char* cpuFeatures, unsigned long* hwcap) {
- *hwcap |= has_list_item(cpuFeatures, "neon") ? NPY__HWCAP_NEON : 0;
- *hwcap |= has_list_item(cpuFeatures, "half") ? NPY__HWCAP_HALF : 0;
- *hwcap |= has_list_item(cpuFeatures, "vfpv3") ? NPY__HWCAP_VFPv3 : 0;
- *hwcap |= has_list_item(cpuFeatures, "vfpv4") ? NPY__HWCAP_VFPv4 : 0;
-
- *hwcap |= has_list_item(cpuFeatures, "asimd") ? NPY__HWCAP_ASIMD : 0;
- *hwcap |= has_list_item(cpuFeatures, "fp") ? NPY__HWCAP_FP : 0;
- *hwcap |= has_list_item(cpuFeatures, "fphp") ? NPY__HWCAP_FPHP : 0;
- *hwcap |= has_list_item(cpuFeatures, "asimdhp") ? NPY__HWCAP_ASIMDHP : 0;
- *hwcap |= has_list_item(cpuFeatures, "asimddp") ? NPY__HWCAP_ASIMDDP : 0;
- *hwcap |= has_list_item(cpuFeatures, "asimdfhm") ? NPY__HWCAP_ASIMDFHM : 0;
-}
-
-static int
-get_feature_from_proc_cpuinfo(unsigned long *hwcap, unsigned long *hwcap2) {
- char* cpuinfo = NULL;
- int cpuinfo_len;
- cpuinfo_len = get_file_size("/proc/cpuinfo");
- if (cpuinfo_len < 0) {
- return 0;
- }
- cpuinfo = malloc(cpuinfo_len);
- if (cpuinfo == NULL) {
- return 0;
- }
- cpuinfo_len = read_file("/proc/cpuinfo", cpuinfo, cpuinfo_len);
- char* cpuFeatures = extract_cpuinfo_field(cpuinfo, cpuinfo_len, "Features");
- if(cpuFeatures == NULL) {
- return 0;
- }
- setHwcap(cpuFeatures, hwcap);
- *hwcap2 |= *hwcap;
- *hwcap2 |= has_list_item(cpuFeatures, "aes") ? NPY__HWCAP2_AES : 0;
- *hwcap2 |= has_list_item(cpuFeatures, "pmull") ? NPY__HWCAP2_PMULL : 0;
- *hwcap2 |= has_list_item(cpuFeatures, "sha1") ? NPY__HWCAP2_SHA1 : 0;
- *hwcap2 |= has_list_item(cpuFeatures, "sha2") ? NPY__HWCAP2_SHA2 : 0;
- *hwcap2 |= has_list_item(cpuFeatures, "crc32") ? NPY__HWCAP2_CRC32 : 0;
- return 1;
-}
-#endif
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
+ * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+#ifndef __NPY_CPUINFO_PARSER_H__
+#define __NPY_CPUINFO_PARSER_H__
+#include <errno.h>
+#include <stdio.h>
+#include <fcntl.h>
+#include <string.h>
+#include <stddef.h>
+
+#define NPY__HWCAP 16
+#define NPY__HWCAP2 26
+
+// arch/arm/include/uapi/asm/hwcap.h
+#define NPY__HWCAP_HALF (1 << 1)
+#define NPY__HWCAP_NEON (1 << 12)
+#define NPY__HWCAP_VFPv3 (1 << 13)
+#define NPY__HWCAP_VFPv4 (1 << 16)
+#define NPY__HWCAP2_AES (1 << 0)
+#define NPY__HWCAP2_PMULL (1 << 1)
+#define NPY__HWCAP2_SHA1 (1 << 2)
+#define NPY__HWCAP2_SHA2 (1 << 3)
+#define NPY__HWCAP2_CRC32 (1 << 4)
+// arch/arm64/include/uapi/asm/hwcap.h
+#define NPY__HWCAP_FP (1 << 0)
+#define NPY__HWCAP_ASIMD (1 << 1)
+#define NPY__HWCAP_FPHP (1 << 9)
+#define NPY__HWCAP_ASIMDHP (1 << 10)
+#define NPY__HWCAP_ASIMDDP (1 << 20)
+#define NPY__HWCAP_ASIMDFHM (1 << 23)
+/*
+ * Get the size of a file by reading it until the end. This is needed
+ * because files under /proc do not always return a valid size when
+ * using fseek(0, SEEK_END) + ftell(). Nor can they be mmap()-ed.
+ */
+static int
+get_file_size(const char* pathname)
+{
+ int fd, result = 0;
+ char buffer[256];
+
+ fd = open(pathname, O_RDONLY);
+ if (fd < 0) {
+ return -1;
+ }
+
+ for (;;) {
+ int ret = read(fd, buffer, sizeof buffer);
+ if (ret < 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+ break;
+ }
+ if (ret == 0) {
+ break;
+ }
+ result += ret;
+ }
+ close(fd);
+ return result;
+}
+
+/*
+ * Read the content of /proc/cpuinfo into a user-provided buffer.
+ * Return the length of the data, or -1 on error. Does *not*
+ * zero-terminate the content. Will not read more
+ * than 'buffsize' bytes.
+ */
+static int
+read_file(const char* pathname, char* buffer, size_t buffsize)
+{
+ int fd, count;
+
+ fd = open(pathname, O_RDONLY);
+ if (fd < 0) {
+ return -1;
+ }
+ count = 0;
+ while (count < (int)buffsize) {
+ int ret = read(fd, buffer + count, buffsize - count);
+ if (ret < 0) {
+ if (errno == EINTR) {
+ continue;
+ }
+ if (count == 0) {
+ count = -1;
+ }
+ break;
+ }
+ if (ret == 0) {
+ break;
+ }
+ count += ret;
+ }
+ close(fd);
+ return count;
+}
+
+/*
+ * Extract the content of a the first occurence of a given field in
+ * the content of /proc/cpuinfo and return it as a heap-allocated
+ * string that must be freed by the caller.
+ *
+ * Return NULL if not found
+ */
+static char*
+extract_cpuinfo_field(const char* buffer, int buflen, const char* field)
+{
+ int fieldlen = strlen(field);
+ const char* bufend = buffer + buflen;
+ char* result = NULL;
+ int len;
+ const char *p, *q;
+
+ /* Look for first field occurence, and ensures it starts the line. */
+ p = buffer;
+ for (;;) {
+ p = memmem(p, bufend-p, field, fieldlen);
+ if (p == NULL) {
+ goto EXIT;
+ }
+
+ if (p == buffer || p[-1] == '\n') {
+ break;
+ }
+
+ p += fieldlen;
+ }
+
+ /* Skip to the first column followed by a space */
+ p += fieldlen;
+ p = memchr(p, ':', bufend-p);
+ if (p == NULL || p[1] != ' ') {
+ goto EXIT;
+ }
+
+ /* Find the end of the line */
+ p += 2;
+ q = memchr(p, '\n', bufend-p);
+ if (q == NULL) {
+ q = bufend;
+ }
+
+ /* Copy the line into a heap-allocated buffer */
+ len = q - p;
+ result = malloc(len + 1);
+ if (result == NULL) {
+ goto EXIT;
+ }
+
+ memcpy(result, p, len);
+ result[len] = '\0';
+
+EXIT:
+ return result;
+}
+
+/*
+ * Checks that a space-separated list of items contains one given 'item'.
+ * Returns 1 if found, 0 otherwise.
+ */
+static int
+has_list_item(const char* list, const char* item)
+{
+ const char* p = list;
+ int itemlen = strlen(item);
+
+ if (list == NULL) {
+ return 0;
+ }
+
+ while (*p) {
+ const char* q;
+
+ /* skip spaces */
+ while (*p == ' ' || *p == '\t') {
+ p++;
+ }
+
+ /* find end of current list item */
+ q = p;
+ while (*q && *q != ' ' && *q != '\t') {
+ q++;
+ }
+
+ if (itemlen == q-p && !memcmp(p, item, itemlen)) {
+ return 1;
+ }
+
+ /* skip to next item */
+ p = q;
+ }
+ return 0;
+}
+
+static void setHwcap(char* cpuFeatures, unsigned long* hwcap) {
+ *hwcap |= has_list_item(cpuFeatures, "neon") ? NPY__HWCAP_NEON : 0;
+ *hwcap |= has_list_item(cpuFeatures, "half") ? NPY__HWCAP_HALF : 0;
+ *hwcap |= has_list_item(cpuFeatures, "vfpv3") ? NPY__HWCAP_VFPv3 : 0;
+ *hwcap |= has_list_item(cpuFeatures, "vfpv4") ? NPY__HWCAP_VFPv4 : 0;
+
+ *hwcap |= has_list_item(cpuFeatures, "asimd") ? NPY__HWCAP_ASIMD : 0;
+ *hwcap |= has_list_item(cpuFeatures, "fp") ? NPY__HWCAP_FP : 0;
+ *hwcap |= has_list_item(cpuFeatures, "fphp") ? NPY__HWCAP_FPHP : 0;
+ *hwcap |= has_list_item(cpuFeatures, "asimdhp") ? NPY__HWCAP_ASIMDHP : 0;
+ *hwcap |= has_list_item(cpuFeatures, "asimddp") ? NPY__HWCAP_ASIMDDP : 0;
+ *hwcap |= has_list_item(cpuFeatures, "asimdfhm") ? NPY__HWCAP_ASIMDFHM : 0;
+}
+
+static int
+get_feature_from_proc_cpuinfo(unsigned long *hwcap, unsigned long *hwcap2) {
+ char* cpuinfo = NULL;
+ int cpuinfo_len;
+ cpuinfo_len = get_file_size("/proc/cpuinfo");
+ if (cpuinfo_len < 0) {
+ return 0;
+ }
+ cpuinfo = malloc(cpuinfo_len);
+ if (cpuinfo == NULL) {
+ return 0;
+ }
+ cpuinfo_len = read_file("/proc/cpuinfo", cpuinfo, cpuinfo_len);
+ char* cpuFeatures = extract_cpuinfo_field(cpuinfo, cpuinfo_len, "Features");
+ if(cpuFeatures == NULL) {
+ return 0;
+ }
+ setHwcap(cpuFeatures, hwcap);
+ *hwcap2 |= *hwcap;
+ *hwcap2 |= has_list_item(cpuFeatures, "aes") ? NPY__HWCAP2_AES : 0;
+ *hwcap2 |= has_list_item(cpuFeatures, "pmull") ? NPY__HWCAP2_PMULL : 0;
+ *hwcap2 |= has_list_item(cpuFeatures, "sha1") ? NPY__HWCAP2_SHA1 : 0;
+ *hwcap2 |= has_list_item(cpuFeatures, "sha2") ? NPY__HWCAP2_SHA2 : 0;
+ *hwcap2 |= has_list_item(cpuFeatures, "crc32") ? NPY__HWCAP2_CRC32 : 0;
+ return 1;
+}
+#endif
diff --git a/numpy/core/src/common/npy_hashtable.c b/numpy/core/src/common/npy_hashtable.c
new file mode 100644
index 000000000..af9e2df43
--- /dev/null
+++ b/numpy/core/src/common/npy_hashtable.c
@@ -0,0 +1,220 @@
+/*
+ * This functionality is designed specifically for the ufunc machinery to
+ * dispatch based on multiple DTypes. Since this is designed to be used
+ * as purely a cache, it currently does no reference counting.
+ * Even though this is a cache, there is currently no maximum size. It may
+ * make sense to limit the size, or count collisions: If too many collisions
+ * occur, we could grow the cache, otherwise, just replace an old item that
+ * was presumably not used for a long time.
+ *
+ * If a different part of NumPy requires a custom hashtable, the code should
+ * be reused with care since specializing it more for the ufunc dispatching
+ * case is likely desired.
+ */
+
+#include "templ_common.h"
+#include "npy_hashtable.h"
+
+
+
+#if SIZEOF_PY_UHASH_T > 4
+#define _NpyHASH_XXPRIME_1 ((Py_uhash_t)11400714785074694791ULL)
+#define _NpyHASH_XXPRIME_2 ((Py_uhash_t)14029467366897019727ULL)
+#define _NpyHASH_XXPRIME_5 ((Py_uhash_t)2870177450012600261ULL)
+#define _NpyHASH_XXROTATE(x) ((x << 31) | (x >> 33)) /* Rotate left 31 bits */
+#else
+#define _NpyHASH_XXPRIME_1 ((Py_uhash_t)2654435761UL)
+#define _NpyHASH_XXPRIME_2 ((Py_uhash_t)2246822519UL)
+#define _NpyHASH_XXPRIME_5 ((Py_uhash_t)374761393UL)
+#define _NpyHASH_XXROTATE(x) ((x << 13) | (x >> 19)) /* Rotate left 13 bits */
+#endif
+
+/*
+ * This hashing function is basically the Python tuple hash with the type
+ * identity hash inlined. The tuple hash itself is a reduced version of xxHash.
+ *
+ * Users cannot control pointers, so we do not have to worry about DoS attacks?
+ */
+static NPY_INLINE Py_hash_t
+identity_list_hash(PyObject *const *v, int len)
+{
+ Py_uhash_t acc = _NpyHASH_XXPRIME_5;
+ for (int i = 0; i < len; i++) {
+ /*
+ * Lane is the single item hash, which for us is the rotated pointer.
+ * Identical to the python type hash (pointers end with 0s normally).
+ */
+ size_t y = (size_t)v[i];
+ Py_uhash_t lane = (y >> 4) | (y << (8 * SIZEOF_VOID_P - 4));
+ acc += lane * _NpyHASH_XXPRIME_2;
+ acc = _NpyHASH_XXROTATE(acc);
+ acc *= _NpyHASH_XXPRIME_1;
+ }
+ return acc;
+}
+#undef _NpyHASH_XXPRIME_1
+#undef _NpyHASH_XXPRIME_2
+#undef _NpyHASH_XXPRIME_5
+#undef _NpyHASH_XXROTATE
+
+
+static NPY_INLINE PyObject **
+find_item(PyArrayIdentityHash const *tb, PyObject *const *key)
+{
+ Py_hash_t hash = identity_list_hash(key, tb->key_len);
+ npy_uintp perturb = (npy_uintp)hash;
+ npy_intp bucket;
+ npy_intp mask = tb->size - 1 ;
+ PyObject **item;
+
+ bucket = (npy_intp)hash & mask;
+ while (1) {
+ item = &(tb->buckets[bucket * (tb->key_len + 1)]);
+
+ if (item[0] == NULL) {
+ /* The item is not in the cache; return the empty bucket */
+ return item;
+ }
+ if (memcmp(item+1, key, tb->key_len * sizeof(PyObject *)) == 0) {
+ /* This is a match, so return the item/bucket */
+ return item;
+ }
+ /* Hash collision, perturb like Python (must happen rarely!) */
+ perturb >>= 5; /* Python uses the macro PERTURB_SHIFT == 5 */
+ bucket = mask & (bucket * 5 + perturb + 1);
+ }
+}
+
+
+NPY_NO_EXPORT PyArrayIdentityHash *
+PyArrayIdentityHash_New(int key_len)
+{
+ PyArrayIdentityHash *res = PyMem_Malloc(sizeof(PyArrayIdentityHash));
+ if (res == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+
+ assert(key_len > 0);
+ res->key_len = key_len;
+ res->size = 4; /* Start with a size of 4 */
+ res->nelem = 0;
+
+ res->buckets = PyMem_Calloc(4 * (key_len + 1), sizeof(PyObject *));
+ if (res->buckets == NULL) {
+ PyErr_NoMemory();
+ PyMem_Free(res);
+ return NULL;
+ }
+ return res;
+}
+
+
+NPY_NO_EXPORT void
+PyArrayIdentityHash_Dealloc(PyArrayIdentityHash *tb)
+{
+ PyMem_Free(tb->buckets);
+ PyMem_Free(tb);
+}
+
+
+static int
+_resize_if_necessary(PyArrayIdentityHash *tb)
+{
+ npy_intp new_size, prev_size = tb->size;
+ PyObject **old_table = tb->buckets;
+ assert(prev_size > 0);
+
+ if ((tb->nelem + 1) * 2 > prev_size) {
+ /* Double in size */
+ new_size = prev_size * 2;
+ }
+ else {
+ new_size = prev_size;
+ while ((tb->nelem + 8) * 2 < new_size / 2) {
+ /*
+ * Should possibly be improved. However, we assume that we
+ * almost never shrink. Still if we do, do not shrink as much
+ * as possible to avoid growing right away.
+ */
+ new_size /= 2;
+ }
+ assert(new_size >= 4);
+ }
+ if (new_size == prev_size) {
+ return 0;
+ }
+
+ npy_intp alloc_size;
+ if (npy_mul_with_overflow_intp(&alloc_size, new_size, tb->key_len + 1)) {
+ return -1;
+ }
+ tb->buckets = PyMem_Calloc(alloc_size, sizeof(PyObject *));
+ if (tb->buckets == NULL) {
+ tb->buckets = old_table;
+ PyErr_NoMemory();
+ return -1;
+ }
+
+ tb->size = new_size;
+ for (npy_intp i = 0; i < prev_size; i++) {
+ PyObject **item = &old_table[i * (tb->key_len + 1)];
+ if (item[0] != NULL) {
+ tb->nelem -= 1; /* Decrement, setitem will increment again */
+ PyArrayIdentityHash_SetItem(tb, item+1, item[0], 1);
+ }
+ }
+ PyMem_Free(old_table);
+ return 0;
+}
+
+
+/**
+ * Add an item to the identity cache. The storage location must not change
+ * unless the cache is cleared.
+ *
+ * @param tb The mapping.
+ * @param key The key, must be a C-array of pointers of the length
+ * corresponding to the mapping.
+ * @param value Normally a Python object, no reference counting is done.
+ * use NULL to clear an item. If the item does not exist, no
+ * action is performed for NULL.
+ * @param replace If 1, allow replacements.
+ * @returns 0 on success, -1 with a MemoryError or RuntimeError (if an item
+ * is added which is already in the cache). The caller should avoid
+ * the RuntimeError.
+ */
+NPY_NO_EXPORT int
+PyArrayIdentityHash_SetItem(PyArrayIdentityHash *tb,
+ PyObject *const *key, PyObject *value, int replace)
+{
+ if (value != NULL && _resize_if_necessary(tb) < 0) {
+ /* Shrink, only if a new value is added. */
+ return -1;
+ }
+
+ PyObject **tb_item = find_item(tb, key);
+ if (value != NULL) {
+ if (tb_item[0] != NULL && !replace) {
+ PyErr_SetString(PyExc_RuntimeError,
+ "Identity cache already includes the item.");
+ return -1;
+ }
+ tb_item[0] = value;
+ memcpy(tb_item+1, key, tb->key_len * sizeof(PyObject *));
+ tb->nelem += 1;
+ }
+ else {
+ /* Clear the bucket -- just the value should be enough though. */
+ memset(tb_item, 0, (tb->key_len + 1) * sizeof(PyObject *));
+ }
+
+ return 0;
+}
+
+
+NPY_NO_EXPORT PyObject *
+PyArrayIdentityHash_GetItem(PyArrayIdentityHash const *tb, PyObject *const *key)
+{
+ return find_item(tb, key)[0];
+}
diff --git a/numpy/core/src/common/npy_hashtable.h b/numpy/core/src/common/npy_hashtable.h
new file mode 100644
index 000000000..5f11d2c1d
--- /dev/null
+++ b/numpy/core/src/common/npy_hashtable.h
@@ -0,0 +1,32 @@
+#ifndef _NPY_NPY_HASHTABLE_H
+#define _NPY_NPY_HASHTABLE_H
+
+#include <Python.h>
+
+#define NPY_NO_DEPRECATED_API NPY_API_VERSION
+#include "numpy/ndarraytypes.h"
+
+
+typedef struct {
+ int key_len; /* number of identities used */
+ /* Buckets stores: val1, key1[0], key1[1], ..., val2, key2[0], ... */
+ PyObject **buckets;
+ npy_intp size; /* current size */
+ npy_intp nelem; /* number of elements */
+} PyArrayIdentityHash;
+
+
+NPY_NO_EXPORT int
+PyArrayIdentityHash_SetItem(PyArrayIdentityHash *tb,
+ PyObject *const *key, PyObject *value, int replace);
+
+NPY_NO_EXPORT PyObject *
+PyArrayIdentityHash_GetItem(PyArrayIdentityHash const *tb, PyObject *const *key);
+
+NPY_NO_EXPORT PyArrayIdentityHash *
+PyArrayIdentityHash_New(int key_len);
+
+NPY_NO_EXPORT void
+PyArrayIdentityHash_Dealloc(PyArrayIdentityHash *tb);
+
+#endif /* _NPY_NPY_HASHTABLE_H */
diff --git a/numpy/core/src/common/npy_pycompat.h b/numpy/core/src/common/npy_pycompat.h
index aa0b5c122..9e94a9710 100644
--- a/numpy/core/src/common/npy_pycompat.h
+++ b/numpy/core/src/common/npy_pycompat.h
@@ -3,4 +3,20 @@
#include "numpy/npy_3kcompat.h"
+
+/*
+ * In Python 3.10a7 (or b1), python started using the identity for the hash
+ * when a value is NaN. See https://bugs.python.org/issue43475
+ */
+#if PY_VERSION_HEX > 0x030a00a6
+#define Npy_HashDouble _Py_HashDouble
+#else
+static NPY_INLINE Py_hash_t
+Npy_HashDouble(PyObject *NPY_UNUSED(identity), double val)
+{
+ return _Py_HashDouble(val);
+}
+#endif
+
+
#endif /* _NPY_COMPAT_H_ */
diff --git a/numpy/core/src/common/simd/avx2/arithmetic.h b/numpy/core/src/common/simd/avx2/arithmetic.h
index 3a6dc9535..e1b170863 100644
--- a/numpy/core/src/common/simd/avx2/arithmetic.h
+++ b/numpy/core/src/common/simd/avx2/arithmetic.h
@@ -5,6 +5,7 @@
#ifndef _NPY_SIMD_AVX2_ARITHMETIC_H
#define _NPY_SIMD_AVX2_ARITHMETIC_H
+#include "../sse/utils.h"
/***************************
* Addition
***************************/
@@ -25,7 +26,7 @@
#define npyv_adds_s8 _mm256_adds_epi8
#define npyv_adds_u16 _mm256_adds_epu16
#define npyv_adds_s16 _mm256_adds_epi16
-// TODO: rest, after implment Packs intrins
+// TODO: rest, after implement Packs intrins
/***************************
* Subtraction
@@ -47,7 +48,7 @@
#define npyv_subs_s8 _mm256_subs_epi8
#define npyv_subs_u16 _mm256_subs_epu16
#define npyv_subs_s16 _mm256_subs_epi16
-// TODO: rest, after implment Packs intrins
+// TODO: rest, after implement Packs intrins
/***************************
* Multiplication
@@ -63,9 +64,167 @@
#define npyv_mul_f64 _mm256_mul_pd
// saturated
-// TODO: after implment Packs intrins
+// TODO: after implement Packs intrins
/***************************
+ * Integer Division
+ ***************************/
+// See simd/intdiv.h for more clarification
+// divide each unsigned 8-bit element by a precomputed divisor
+NPY_FINLINE npyv_u8 npyv_divc_u8(npyv_u8 a, const npyv_u8x3 divisor)
+{
+ const __m256i bmask = _mm256_set1_epi32(0x00FF00FF);
+ const __m128i shf1 = _mm256_castsi256_si128(divisor.val[1]);
+ const __m128i shf2 = _mm256_castsi256_si128(divisor.val[2]);
+ const __m256i shf1b = _mm256_set1_epi8(0xFFU >> _mm_cvtsi128_si32(shf1));
+ const __m256i shf2b = _mm256_set1_epi8(0xFFU >> _mm_cvtsi128_si32(shf2));
+ // high part of unsigned multiplication
+ __m256i mulhi_even = _mm256_mullo_epi16(_mm256_and_si256(a, bmask), divisor.val[0]);
+ mulhi_even = _mm256_srli_epi16(mulhi_even, 8);
+ __m256i mulhi_odd = _mm256_mullo_epi16(_mm256_srli_epi16(a, 8), divisor.val[0]);
+ __m256i mulhi = _mm256_blendv_epi8(mulhi_odd, mulhi_even, bmask);
+ // floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
+ __m256i q = _mm256_sub_epi8(a, mulhi);
+ q = _mm256_and_si256(_mm256_srl_epi16(q, shf1), shf1b);
+ q = _mm256_add_epi8(mulhi, q);
+ q = _mm256_and_si256(_mm256_srl_epi16(q, shf2), shf2b);
+ return q;
+}
+// divide each signed 8-bit element by a precomputed divisor (round towards zero)
+NPY_FINLINE npyv_s16 npyv_divc_s16(npyv_s16 a, const npyv_s16x3 divisor);
+NPY_FINLINE npyv_s8 npyv_divc_s8(npyv_s8 a, const npyv_s8x3 divisor)
+{
+ const __m256i bmask = _mm256_set1_epi32(0x00FF00FF);
+ // instead of _mm256_cvtepi8_epi16/_mm256_packs_epi16 to wrap around overflow
+ __m256i divc_even = npyv_divc_s16(_mm256_srai_epi16(_mm256_slli_epi16(a, 8), 8), divisor);
+ __m256i divc_odd = npyv_divc_s16(_mm256_srai_epi16(a, 8), divisor);
+ divc_odd = _mm256_slli_epi16(divc_odd, 8);
+ return _mm256_blendv_epi8(divc_odd, divc_even, bmask);
+}
+// divide each unsigned 16-bit element by a precomputed divisor
+NPY_FINLINE npyv_u16 npyv_divc_u16(npyv_u16 a, const npyv_u16x3 divisor)
+{
+ const __m128i shf1 = _mm256_castsi256_si128(divisor.val[1]);
+ const __m128i shf2 = _mm256_castsi256_si128(divisor.val[2]);
+ // high part of unsigned multiplication
+ __m256i mulhi = _mm256_mulhi_epu16(a, divisor.val[0]);
+ // floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
+ __m256i q = _mm256_sub_epi16(a, mulhi);
+ q = _mm256_srl_epi16(q, shf1);
+ q = _mm256_add_epi16(mulhi, q);
+ q = _mm256_srl_epi16(q, shf2);
+ return q;
+}
+// divide each signed 16-bit element by a precomputed divisor (round towards zero)
+NPY_FINLINE npyv_s16 npyv_divc_s16(npyv_s16 a, const npyv_s16x3 divisor)
+{
+ const __m128i shf1 = _mm256_castsi256_si128(divisor.val[1]);
+ // high part of signed multiplication
+ __m256i mulhi = _mm256_mulhi_epi16(a, divisor.val[0]);
+ // q = ((a + mulhi) >> sh1) - XSIGN(a)
+ // trunc(a/d) = (q ^ dsign) - dsign
+ __m256i q = _mm256_sra_epi16(_mm256_add_epi16(a, mulhi), shf1);
+ q = _mm256_sub_epi16(q, _mm256_srai_epi16(a, 15));
+ q = _mm256_sub_epi16(_mm256_xor_si256(q, divisor.val[2]), divisor.val[2]);
+ return q;
+}
+// divide each unsigned 32-bit element by a precomputed divisor
+NPY_FINLINE npyv_u32 npyv_divc_u32(npyv_u32 a, const npyv_u32x3 divisor)
+{
+ const __m128i shf1 = _mm256_castsi256_si128(divisor.val[1]);
+ const __m128i shf2 = _mm256_castsi256_si128(divisor.val[2]);
+ // high part of unsigned multiplication
+ __m256i mulhi_even = _mm256_srli_epi64(_mm256_mul_epu32(a, divisor.val[0]), 32);
+ __m256i mulhi_odd = _mm256_mul_epu32(_mm256_srli_epi64(a, 32), divisor.val[0]);
+ __m256i mulhi = _mm256_blend_epi32(mulhi_even, mulhi_odd, 0xAA);
+ // floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
+ __m256i q = _mm256_sub_epi32(a, mulhi);
+ q = _mm256_srl_epi32(q, shf1);
+ q = _mm256_add_epi32(mulhi, q);
+ q = _mm256_srl_epi32(q, shf2);
+ return q;
+}
+// divide each signed 32-bit element by a precomputed divisor (round towards zero)
+NPY_FINLINE npyv_s32 npyv_divc_s32(npyv_s32 a, const npyv_s32x3 divisor)
+{
+ const __m128i shf1 = _mm256_castsi256_si128(divisor.val[1]);
+ // high part of signed multiplication
+ __m256i mulhi_even = _mm256_srli_epi64(_mm256_mul_epi32(a, divisor.val[0]), 32);
+ __m256i mulhi_odd = _mm256_mul_epi32(_mm256_srli_epi64(a, 32), divisor.val[0]);
+ __m256i mulhi = _mm256_blend_epi32(mulhi_even, mulhi_odd, 0xAA);
+ // q = ((a + mulhi) >> sh1) - XSIGN(a)
+ // trunc(a/d) = (q ^ dsign) - dsign
+ __m256i q = _mm256_sra_epi32(_mm256_add_epi32(a, mulhi), shf1);
+ q = _mm256_sub_epi32(q, _mm256_srai_epi32(a, 31));
+ q = _mm256_sub_epi32(_mm256_xor_si256(q, divisor.val[2]), divisor.val[2]);
+ return q;
+}
+// returns the high 64 bits of unsigned 64-bit multiplication
+// xref https://stackoverflow.com/a/28827013
+NPY_FINLINE npyv_u64 npyv__mullhi_u64(npyv_u64 a, npyv_u64 b)
+{
+ __m256i lomask = npyv_setall_s64(0xffffffff);
+ __m256i a_hi = _mm256_srli_epi64(a, 32); // a0l, a0h, a1l, a1h
+ __m256i b_hi = _mm256_srli_epi64(b, 32); // b0l, b0h, b1l, b1h
+ // compute partial products
+ __m256i w0 = _mm256_mul_epu32(a, b); // a0l*b0l, a1l*b1l
+ __m256i w1 = _mm256_mul_epu32(a, b_hi); // a0l*b0h, a1l*b1h
+ __m256i w2 = _mm256_mul_epu32(a_hi, b); // a0h*b0l, a1h*b0l
+ __m256i w3 = _mm256_mul_epu32(a_hi, b_hi); // a0h*b0h, a1h*b1h
+ // sum partial products
+ __m256i w0h = _mm256_srli_epi64(w0, 32);
+ __m256i s1 = _mm256_add_epi64(w1, w0h);
+ __m256i s1l = _mm256_and_si256(s1, lomask);
+ __m256i s1h = _mm256_srli_epi64(s1, 32);
+
+ __m256i s2 = _mm256_add_epi64(w2, s1l);
+ __m256i s2h = _mm256_srli_epi64(s2, 32);
+
+ __m256i hi = _mm256_add_epi64(w3, s1h);
+ hi = _mm256_add_epi64(hi, s2h);
+ return hi;
+}
+// divide each unsigned 64-bit element by a divisor
+NPY_FINLINE npyv_u64 npyv_divc_u64(npyv_u64 a, const npyv_u64x3 divisor)
+{
+ const __m128i shf1 = _mm256_castsi256_si128(divisor.val[1]);
+ const __m128i shf2 = _mm256_castsi256_si128(divisor.val[2]);
+ // high part of unsigned multiplication
+ __m256i mulhi = npyv__mullhi_u64(a, divisor.val[0]);
+ // floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
+ __m256i q = _mm256_sub_epi64(a, mulhi);
+ q = _mm256_srl_epi64(q, shf1);
+ q = _mm256_add_epi64(mulhi, q);
+ q = _mm256_srl_epi64(q, shf2);
+ return q;
+}
+// divide each unsigned 64-bit element by a divisor (round towards zero)
+NPY_FINLINE npyv_s64 npyv_divc_s64(npyv_s64 a, const npyv_s64x3 divisor)
+{
+ const __m128i shf1 = _mm256_castsi256_si128(divisor.val[1]);
+ // high part of unsigned multiplication
+ __m256i mulhi = npyv__mullhi_u64(a, divisor.val[0]);
+ // convert unsigned to signed high multiplication
+ // mulhi - ((a < 0) ? m : 0) - ((m < 0) ? a : 0);
+ __m256i asign = _mm256_cmpgt_epi64(_mm256_setzero_si256(), a);
+ __m256i msign = _mm256_cmpgt_epi64(_mm256_setzero_si256(), divisor.val[0]);
+ __m256i m_asign = _mm256_and_si256(divisor.val[0], asign);
+ __m256i a_msign = _mm256_and_si256(a, msign);
+ mulhi = _mm256_sub_epi64(mulhi, m_asign);
+ mulhi = _mm256_sub_epi64(mulhi, a_msign);
+ // q = (a + mulhi) >> sh
+ __m256i q = _mm256_add_epi64(a, mulhi);
+ // emulate arithmetic right shift
+ const __m256i sigb = npyv_setall_s64(1LL << 63);
+ q = _mm256_srl_epi64(_mm256_add_epi64(q, sigb), shf1);
+ q = _mm256_sub_epi64(q, _mm256_srl_epi64(sigb, shf1));
+ // q = q - XSIGN(a)
+ // trunc(a/d) = (q ^ dsign) - dsign
+ q = _mm256_sub_epi64(q, asign);
+ q = _mm256_sub_epi64(_mm256_xor_si256(q, divisor.val[2]), divisor.val[2]);
+ return q;
+}
+/***************************
* Division
***************************/
// TODO: emulate integer division
@@ -117,8 +276,27 @@
}
#endif // !NPY_HAVE_FMA3
-// Horizontal add: Calculates the sum of all vector elements.
-NPY_FINLINE float npyv_sum_f32(__m256 a)
+/***************************
+ * Summation
+ ***************************/
+// reduce sum across vector
+NPY_FINLINE npy_uint32 npyv_sum_u32(npyv_u32 a)
+{
+ __m256i s0 = _mm256_hadd_epi32(a, a);
+ s0 = _mm256_hadd_epi32(s0, s0);
+ __m128i s1 = _mm256_extracti128_si256(s0, 1);;
+ s1 = _mm_add_epi32(_mm256_castsi256_si128(s0), s1);
+ return _mm_cvtsi128_si32(s1);
+}
+
+NPY_FINLINE npy_uint64 npyv_sum_u64(npyv_u64 a)
+{
+ __m256i two = _mm256_add_epi64(a, _mm256_shuffle_epi32(a, _MM_SHUFFLE(1, 0, 3, 2)));
+ __m128i one = _mm_add_epi64(_mm256_castsi256_si128(two), _mm256_extracti128_si256(two, 1));
+ return (npy_uint64)npyv128_cvtsi128_si64(one);
+}
+
+NPY_FINLINE float npyv_sum_f32(npyv_f32 a)
{
__m256 sum_halves = _mm256_hadd_ps(a, a);
sum_halves = _mm256_hadd_ps(sum_halves, sum_halves);
@@ -128,7 +306,7 @@ NPY_FINLINE float npyv_sum_f32(__m256 a)
return _mm_cvtss_f32(sum);
}
-NPY_FINLINE double npyv_sum_f64(__m256d a)
+NPY_FINLINE double npyv_sum_f64(npyv_f64 a)
{
__m256d sum_halves = _mm256_hadd_pd(a, a);
__m128d lo = _mm256_castpd256_pd128(sum_halves);
@@ -137,6 +315,22 @@ NPY_FINLINE double npyv_sum_f64(__m256d a)
return _mm_cvtsd_f64(sum);
}
-#endif // _NPY_SIMD_AVX2_ARITHMETIC_H
+// expand the source vector and performs sum reduce
+NPY_FINLINE npy_uint16 npyv_sumup_u8(npyv_u8 a)
+{
+ __m256i four = _mm256_sad_epu8(a, _mm256_setzero_si256());
+ __m128i two = _mm_add_epi16(_mm256_castsi256_si128(four), _mm256_extracti128_si256(four, 1));
+ __m128i one = _mm_add_epi16(two, _mm_unpackhi_epi64(two, two));
+ return (npy_uint16)_mm_cvtsi128_si32(one);
+}
+NPY_FINLINE npy_uint32 npyv_sumup_u16(npyv_u16 a)
+{
+ const npyv_u16 even_mask = _mm256_set1_epi32(0x0000FFFF);
+ __m256i even = _mm256_and_si256(a, even_mask);
+ __m256i odd = _mm256_srli_epi32(a, 16);
+ __m256i eight = _mm256_add_epi32(even, odd);
+ return npyv_sum_u32(eight);
+}
+#endif // _NPY_SIMD_AVX2_ARITHMETIC_H
diff --git a/numpy/core/src/common/simd/avx2/avx2.h b/numpy/core/src/common/simd/avx2/avx2.h
index 6f0d3c0d9..02ff536fb 100644
--- a/numpy/core/src/common/simd/avx2/avx2.h
+++ b/numpy/core/src/common/simd/avx2/avx2.h
@@ -1,10 +1,14 @@
#ifndef _NPY_SIMD_H_
#error "Not a standalone header"
#endif
-
#define NPY_SIMD 256
#define NPY_SIMD_WIDTH 32
#define NPY_SIMD_F64 1
+#ifdef NPY_HAVE_FMA3
+ #define NPY_SIMD_FMA3 1 // native support
+#else
+ #define NPY_SIMD_FMA3 0 // fast emulated
+#endif
// Enough limit to allow us to use _mm256_i32gather_*
#define NPY_SIMD_MAXLOAD_STRIDE32 (0x7fffffff / 8)
diff --git a/numpy/core/src/common/simd/avx2/conversion.h b/numpy/core/src/common/simd/avx2/conversion.h
index 9fd86016d..64e051686 100644
--- a/numpy/core/src/common/simd/avx2/conversion.h
+++ b/numpy/core/src/common/simd/avx2/conversion.h
@@ -14,8 +14,8 @@
#define npyv_cvt_s32_b32(A) A
#define npyv_cvt_u64_b64(A) A
#define npyv_cvt_s64_b64(A) A
-#define npyv_cvt_f32_b32(A) _mm256_castsi256_ps(A)
-#define npyv_cvt_f64_b64(A) _mm256_castsi256_pd(A)
+#define npyv_cvt_f32_b32 _mm256_castsi256_ps
+#define npyv_cvt_f64_b64 _mm256_castsi256_pd
// convert integer types to mask types
#define npyv_cvt_b8_u8(BL) BL
@@ -26,7 +26,44 @@
#define npyv_cvt_b32_s32(BL) BL
#define npyv_cvt_b64_u64(BL) BL
#define npyv_cvt_b64_s64(BL) BL
-#define npyv_cvt_b32_f32(BL) _mm256_castps_si256(BL)
-#define npyv_cvt_b64_f64(BL) _mm256_castpd_si256(BL)
+#define npyv_cvt_b32_f32 _mm256_castps_si256
+#define npyv_cvt_b64_f64 _mm256_castpd_si256
+
+// convert boolean vector to integer bitfield
+NPY_FINLINE npy_uint64 npyv_tobits_b8(npyv_b8 a)
+{ return (npy_uint32)_mm256_movemask_epi8(a); }
+
+NPY_FINLINE npy_uint64 npyv_tobits_b16(npyv_b16 a)
+{
+ __m128i pack = _mm_packs_epi16(_mm256_castsi256_si128(a), _mm256_extracti128_si256(a, 1));
+ return (npy_uint16)_mm_movemask_epi8(pack);
+}
+NPY_FINLINE npy_uint64 npyv_tobits_b32(npyv_b32 a)
+{ return (npy_uint8)_mm256_movemask_ps(_mm256_castsi256_ps(a)); }
+NPY_FINLINE npy_uint64 npyv_tobits_b64(npyv_b64 a)
+{ return (npy_uint8)_mm256_movemask_pd(_mm256_castsi256_pd(a)); }
+
+// expand
+NPY_FINLINE npyv_u16x2 npyv_expand_u16_u8(npyv_u8 data) {
+ npyv_u16x2 r;
+ r.val[0] = _mm256_cvtepu8_epi16(_mm256_castsi256_si128(data));
+ r.val[1] = _mm256_cvtepu8_epi16(_mm256_extracti128_si256(data, 1));
+ return r;
+}
+
+NPY_FINLINE npyv_u32x2 npyv_expand_u32_u16(npyv_u16 data) {
+ npyv_u32x2 r;
+ r.val[0] = _mm256_cvtepu16_epi32(_mm256_castsi256_si128(data));
+ r.val[1] = _mm256_cvtepu16_epi32(_mm256_extracti128_si256(data, 1));
+ return r;
+}
+
+// round to nearest integer (assuming even)
+#define npyv_round_s32_f32 _mm256_cvtps_epi32
+NPY_FINLINE npyv_s32 npyv_round_s32_f64(npyv_f64 a, npyv_f64 b)
+{
+ __m128i lo = _mm256_cvtpd_epi32(a), hi = _mm256_cvtpd_epi32(b);
+ return _mm256_inserti128_si256(_mm256_castsi128_si256(lo), hi, 1);
+}
#endif // _NPY_SIMD_AVX2_CVT_H
diff --git a/numpy/core/src/common/simd/avx2/math.h b/numpy/core/src/common/simd/avx2/math.h
index b3eba6f5f..9460183df 100644
--- a/numpy/core/src/common/simd/avx2/math.h
+++ b/numpy/core/src/common/simd/avx2/math.h
@@ -37,4 +37,72 @@ NPY_FINLINE npyv_f32 npyv_square_f32(npyv_f32 a)
NPY_FINLINE npyv_f64 npyv_square_f64(npyv_f64 a)
{ return _mm256_mul_pd(a, a); }
-#endif
+// Maximum, natively mapping with no guarantees to handle NaN.
+#define npyv_max_f32 _mm256_max_ps
+#define npyv_max_f64 _mm256_max_pd
+// Maximum, supports IEEE floating-point arithmetic (IEC 60559),
+// - If one of the two vectors contains NaN, the equivalent element of the other vector is set
+// - Only if both corresponded elements are NaN, NaN is set.
+NPY_FINLINE npyv_f32 npyv_maxp_f32(npyv_f32 a, npyv_f32 b)
+{
+ __m256 nn = _mm256_cmp_ps(b, b, _CMP_ORD_Q);
+ __m256 max = _mm256_max_ps(a, b);
+ return _mm256_blendv_ps(a, max, nn);
+}
+NPY_FINLINE npyv_f64 npyv_maxp_f64(npyv_f64 a, npyv_f64 b)
+{
+ __m256d nn = _mm256_cmp_pd(b, b, _CMP_ORD_Q);
+ __m256d max = _mm256_max_pd(a, b);
+ return _mm256_blendv_pd(a, max, nn);
+}
+// Maximum, integer operations
+#define npyv_max_u8 _mm256_max_epu8
+#define npyv_max_s8 _mm256_max_epi8
+#define npyv_max_u16 _mm256_max_epu16
+#define npyv_max_s16 _mm256_max_epi16
+#define npyv_max_u32 _mm256_max_epu32
+#define npyv_max_s32 _mm256_max_epi32
+NPY_FINLINE npyv_u64 npyv_max_u64(npyv_u64 a, npyv_u64 b)
+{
+ return _mm256_blendv_epi8(b, a, npyv_cmpgt_u64(a, b));
+}
+NPY_FINLINE npyv_s64 npyv_max_s64(npyv_s64 a, npyv_s64 b)
+{
+ return _mm256_blendv_epi8(b, a, _mm256_cmpgt_epi64(a, b));
+}
+
+// Minimum, natively mapping with no guarantees to handle NaN.
+#define npyv_min_f32 _mm256_min_ps
+#define npyv_min_f64 _mm256_min_pd
+// Minimum, supports IEEE floating-point arithmetic (IEC 60559),
+// - If one of the two vectors contains NaN, the equivalent element of the other vector is set
+// - Only if both corresponded elements are NaN, NaN is set.
+NPY_FINLINE npyv_f32 npyv_minp_f32(npyv_f32 a, npyv_f32 b)
+{
+ __m256 nn = _mm256_cmp_ps(b, b, _CMP_ORD_Q);
+ __m256 min = _mm256_min_ps(a, b);
+ return _mm256_blendv_ps(a, min, nn);
+}
+NPY_FINLINE npyv_f64 npyv_minp_f64(npyv_f64 a, npyv_f64 b)
+{
+ __m256d nn = _mm256_cmp_pd(b, b, _CMP_ORD_Q);
+ __m256d min = _mm256_min_pd(a, b);
+ return _mm256_blendv_pd(a, min, nn);
+}
+// Minimum, integer operations
+#define npyv_min_u8 _mm256_min_epu8
+#define npyv_min_s8 _mm256_min_epi8
+#define npyv_min_u16 _mm256_min_epu16
+#define npyv_min_s16 _mm256_min_epi16
+#define npyv_min_u32 _mm256_min_epu32
+#define npyv_min_s32 _mm256_min_epi32
+NPY_FINLINE npyv_u64 npyv_min_u64(npyv_u64 a, npyv_u64 b)
+{
+ return _mm256_blendv_epi8(b, a, npyv_cmplt_u64(a, b));
+}
+NPY_FINLINE npyv_s64 npyv_min_s64(npyv_s64 a, npyv_s64 b)
+{
+ return _mm256_blendv_epi8(a, b, _mm256_cmpgt_epi64(a, b));
+}
+
+#endif // _NPY_SIMD_AVX2_MATH_H
diff --git a/numpy/core/src/common/simd/avx2/operators.h b/numpy/core/src/common/simd/avx2/operators.h
index c1d30413f..5fc7719e9 100644
--- a/numpy/core/src/common/simd/avx2/operators.h
+++ b/numpy/core/src/common/simd/avx2/operators.h
@@ -61,6 +61,10 @@ NPY_FINLINE __m256i npyv_shr_s64(__m256i a, int c)
#define npyv_and_s64 _mm256_and_si256
#define npyv_and_f32 _mm256_and_ps
#define npyv_and_f64 _mm256_and_pd
+#define npyv_and_b8 _mm256_and_si256
+#define npyv_and_b16 _mm256_and_si256
+#define npyv_and_b32 _mm256_and_si256
+#define npyv_and_b64 _mm256_and_si256
// OR
#define npyv_or_u8 _mm256_or_si256
@@ -73,6 +77,10 @@ NPY_FINLINE __m256i npyv_shr_s64(__m256i a, int c)
#define npyv_or_s64 _mm256_or_si256
#define npyv_or_f32 _mm256_or_ps
#define npyv_or_f64 _mm256_or_pd
+#define npyv_or_b8 _mm256_or_si256
+#define npyv_or_b16 _mm256_or_si256
+#define npyv_or_b32 _mm256_or_si256
+#define npyv_or_b64 _mm256_or_si256
// XOR
#define npyv_xor_u8 _mm256_xor_si256
@@ -85,6 +93,10 @@ NPY_FINLINE __m256i npyv_shr_s64(__m256i a, int c)
#define npyv_xor_s64 _mm256_xor_si256
#define npyv_xor_f32 _mm256_xor_ps
#define npyv_xor_f64 _mm256_xor_pd
+#define npyv_xor_b8 _mm256_xor_si256
+#define npyv_xor_b16 _mm256_xor_si256
+#define npyv_xor_b32 _mm256_xor_si256
+#define npyv_xor_b64 _mm256_xor_si256
// NOT
#define npyv_not_u8(A) _mm256_xor_si256(A, _mm256_set1_epi32(-1))
@@ -97,6 +109,10 @@ NPY_FINLINE __m256i npyv_shr_s64(__m256i a, int c)
#define npyv_not_s64 npyv_not_u8
#define npyv_not_f32(A) _mm256_xor_ps(A, _mm256_castsi256_ps(_mm256_set1_epi32(-1)))
#define npyv_not_f64(A) _mm256_xor_pd(A, _mm256_castsi256_pd(_mm256_set1_epi32(-1)))
+#define npyv_not_b8 npyv_not_u8
+#define npyv_not_b16 npyv_not_u8
+#define npyv_not_b32 npyv_not_u8
+#define npyv_not_b64 npyv_not_u8
/***************************
* Comparison
@@ -197,4 +213,10 @@ NPY_FINLINE __m256i npyv_cmpge_u32(__m256i a, __m256i b)
#define npyv_cmpge_f32(A, B) _mm256_castps_si256(_mm256_cmp_ps(A, B, _CMP_GE_OQ))
#define npyv_cmpge_f64(A, B) _mm256_castpd_si256(_mm256_cmp_pd(A, B, _CMP_GE_OQ))
+// check special cases
+NPY_FINLINE npyv_b32 npyv_notnan_f32(npyv_f32 a)
+{ return _mm256_castps_si256(_mm256_cmp_ps(a, a, _CMP_ORD_Q)); }
+NPY_FINLINE npyv_b64 npyv_notnan_f64(npyv_f64 a)
+{ return _mm256_castpd_si256(_mm256_cmp_pd(a, a, _CMP_ORD_Q)); }
+
#endif // _NPY_SIMD_AVX2_OPERATORS_H
diff --git a/numpy/core/src/common/simd/avx2/reorder.h b/numpy/core/src/common/simd/avx2/reorder.h
index 5a9e68e32..4d6ec8f75 100644
--- a/numpy/core/src/common/simd/avx2/reorder.h
+++ b/numpy/core/src/common/simd/avx2/reorder.h
@@ -94,4 +94,36 @@ NPY_FINLINE npyv_f64x2 npyv_zip_f64(__m256d a, __m256d b)
return npyv_combine_f64(ab0, ab1);
}
+// Reverse elements of each 64-bit lane
+NPY_FINLINE npyv_u8 npyv_rev64_u8(npyv_u8 a)
+{
+ const __m256i idx = _mm256_setr_epi8(
+ 7, 6, 5, 4, 3, 2, 1, 0,/*64*/15, 14, 13, 12, 11, 10, 9, 8,
+ 7, 6, 5, 4, 3, 2, 1, 0,/*64*/15, 14, 13, 12, 11, 10, 9, 8
+ );
+ return _mm256_shuffle_epi8(a, idx);
+}
+#define npyv_rev64_s8 npyv_rev64_u8
+
+NPY_FINLINE npyv_u16 npyv_rev64_u16(npyv_u16 a)
+{
+ const __m256i idx = _mm256_setr_epi8(
+ 6, 7, 4, 5, 2, 3, 0, 1,/*64*/14, 15, 12, 13, 10, 11, 8, 9,
+ 6, 7, 4, 5, 2, 3, 0, 1,/*64*/14, 15, 12, 13, 10, 11, 8, 9
+ );
+ return _mm256_shuffle_epi8(a, idx);
+}
+#define npyv_rev64_s16 npyv_rev64_u16
+
+NPY_FINLINE npyv_u32 npyv_rev64_u32(npyv_u32 a)
+{
+ return _mm256_shuffle_epi32(a, _MM_SHUFFLE(2, 3, 0, 1));
+}
+#define npyv_rev64_s32 npyv_rev64_u32
+
+NPY_FINLINE npyv_f32 npyv_rev64_f32(npyv_f32 a)
+{
+ return _mm256_shuffle_ps(a, a, _MM_SHUFFLE(2, 3, 0, 1));
+}
+
#endif // _NPY_SIMD_AVX2_REORDER_H
diff --git a/numpy/core/src/common/simd/avx512/arithmetic.h b/numpy/core/src/common/simd/avx512/arithmetic.h
index 7372ca29e..f8632e701 100644
--- a/numpy/core/src/common/simd/avx512/arithmetic.h
+++ b/numpy/core/src/common/simd/avx512/arithmetic.h
@@ -6,7 +6,7 @@
#define _NPY_SIMD_AVX512_ARITHMETIC_H
#include "../avx2/utils.h"
-
+#include "../sse/utils.h"
/***************************
* Addition
***************************/
@@ -39,7 +39,7 @@
NPYV_IMPL_AVX512_FROM_AVX2_2ARG(npyv_adds_u16, _mm256_adds_epu16)
NPYV_IMPL_AVX512_FROM_AVX2_2ARG(npyv_adds_s16, _mm256_adds_epi16)
#endif
-// TODO: rest, after implment Packs intrins
+// TODO: rest, after implement Packs intrins
/***************************
* Subtraction
@@ -73,7 +73,7 @@
NPYV_IMPL_AVX512_FROM_AVX2_2ARG(npyv_subs_u16, _mm256_subs_epu16)
NPYV_IMPL_AVX512_FROM_AVX2_2ARG(npyv_subs_s16, _mm256_subs_epi16)
#endif
-// TODO: rest, after implment Packs intrins
+// TODO: rest, after implement Packs intrins
/***************************
* Multiplication
@@ -104,8 +104,229 @@ NPY_FINLINE __m512i npyv_mul_u8(__m512i a, __m512i b)
#define npyv_mul_f64 _mm512_mul_pd
// saturated
-// TODO: after implment Packs intrins
+// TODO: after implement Packs intrins
+
+/***************************
+ * Integer Division
+ ***************************/
+// See simd/intdiv.h for more clarification
+// divide each unsigned 8-bit element by divisor
+NPY_FINLINE npyv_u8 npyv_divc_u8(npyv_u8 a, const npyv_u8x3 divisor)
+{
+ const __m128i shf1 = _mm512_castsi512_si128(divisor.val[1]);
+ const __m128i shf2 = _mm512_castsi512_si128(divisor.val[2]);
+#ifdef NPY_HAVE_AVX512BW
+ const __m512i bmask = _mm512_set1_epi32(0x00FF00FF);
+ const __m512i shf1b = _mm512_set1_epi8(0xFFU >> _mm_cvtsi128_si32(shf1));
+ const __m512i shf2b = _mm512_set1_epi8(0xFFU >> _mm_cvtsi128_si32(shf2));
+ // high part of unsigned multiplication
+ __m512i mulhi_even = _mm512_mullo_epi16(_mm512_and_si512(a, bmask), divisor.val[0]);
+ mulhi_even = _mm512_srli_epi16(mulhi_even, 8);
+ __m512i mulhi_odd = _mm512_mullo_epi16(_mm512_srli_epi16(a, 8), divisor.val[0]);
+ __m512i mulhi = _mm512_mask_mov_epi8(mulhi_even, 0xAAAAAAAAAAAAAAAA, mulhi_odd);
+ // floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
+ __m512i q = _mm512_sub_epi8(a, mulhi);
+ q = _mm512_and_si512(_mm512_srl_epi16(q, shf1), shf1b);
+ q = _mm512_add_epi8(mulhi, q);
+ q = _mm512_and_si512(_mm512_srl_epi16(q, shf2), shf2b);
+ return q;
+#else
+ const __m256i bmask = _mm256_set1_epi32(0x00FF00FF);
+ const __m256i shf1b = _mm256_set1_epi8(0xFFU >> _mm_cvtsi128_si32(shf1));
+ const __m256i shf2b = _mm256_set1_epi8(0xFFU >> _mm_cvtsi128_si32(shf2));
+ const __m512i shf2bw= npyv512_combine_si256(shf2b, shf2b);
+ const __m256i mulc = npyv512_lower_si256(divisor.val[0]);
+ //// lower 256-bit
+ __m256i lo_a = npyv512_lower_si256(a);
+ // high part of unsigned multiplication
+ __m256i mulhi_even = _mm256_mullo_epi16(_mm256_and_si256(lo_a, bmask), mulc);
+ mulhi_even = _mm256_srli_epi16(mulhi_even, 8);
+ __m256i mulhi_odd = _mm256_mullo_epi16(_mm256_srli_epi16(lo_a, 8), mulc);
+ __m256i mulhi = _mm256_blendv_epi8(mulhi_odd, mulhi_even, bmask);
+ // floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
+ __m256i lo_q = _mm256_sub_epi8(lo_a, mulhi);
+ lo_q = _mm256_and_si256(_mm256_srl_epi16(lo_q, shf1), shf1b);
+ lo_q = _mm256_add_epi8(mulhi, lo_q);
+ lo_q = _mm256_srl_epi16(lo_q, shf2); // no sign extend
+
+ //// higher 256-bit
+ __m256i hi_a = npyv512_higher_si256(a);
+ // high part of unsigned multiplication
+ mulhi_even = _mm256_mullo_epi16(_mm256_and_si256(hi_a, bmask), mulc);
+ mulhi_even = _mm256_srli_epi16(mulhi_even, 8);
+ mulhi_odd = _mm256_mullo_epi16(_mm256_srli_epi16(hi_a, 8), mulc);
+ mulhi = _mm256_blendv_epi8(mulhi_odd, mulhi_even, bmask);
+ // floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
+ __m256i hi_q = _mm256_sub_epi8(hi_a, mulhi);
+ hi_q = _mm256_and_si256(_mm256_srl_epi16(hi_q, shf1), shf1b);
+ hi_q = _mm256_add_epi8(mulhi, hi_q);
+ hi_q = _mm256_srl_epi16(hi_q, shf2); // no sign extend
+ return _mm512_and_si512(npyv512_combine_si256(lo_q, hi_q), shf2bw); // extend sign
+#endif
+}
+// divide each signed 8-bit element by divisor (round towards zero)
+NPY_FINLINE npyv_s16 npyv_divc_s16(npyv_s16 a, const npyv_s16x3 divisor);
+NPY_FINLINE npyv_s8 npyv_divc_s8(npyv_s8 a, const npyv_s8x3 divisor)
+{
+ __m512i divc_even = npyv_divc_s16(npyv_shri_s16(npyv_shli_s16(a, 8), 8), divisor);
+ __m512i divc_odd = npyv_divc_s16(npyv_shri_s16(a, 8), divisor);
+ divc_odd = npyv_shli_s16(divc_odd, 8);
+#ifdef NPY_HAVE_AVX512BW
+ return _mm512_mask_mov_epi8(divc_even, 0xAAAAAAAAAAAAAAAA, divc_odd);
+#else
+ const __m512i bmask = _mm512_set1_epi32(0x00FF00FF);
+ return npyv_select_u8(bmask, divc_even, divc_odd);
+#endif
+}
+// divide each unsigned 16-bit element by divisor
+NPY_FINLINE npyv_u16 npyv_divc_u16(npyv_u16 a, const npyv_u16x3 divisor)
+{
+ const __m128i shf1 = _mm512_castsi512_si128(divisor.val[1]);
+ const __m128i shf2 = _mm512_castsi512_si128(divisor.val[2]);
+ // floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
+ #define NPYV__DIVC_U16(RLEN, A, MULC, R) \
+ mulhi = _mm##RLEN##_mulhi_epu16(A, MULC); \
+ R = _mm##RLEN##_sub_epi16(A, mulhi); \
+ R = _mm##RLEN##_srl_epi16(R, shf1); \
+ R = _mm##RLEN##_add_epi16(mulhi, R); \
+ R = _mm##RLEN##_srl_epi16(R, shf2);
+
+#ifdef NPY_HAVE_AVX512BW
+ __m512i mulhi, q;
+ NPYV__DIVC_U16(512, a, divisor.val[0], q)
+ return q;
+#else
+ const __m256i m = npyv512_lower_si256(divisor.val[0]);
+ __m256i lo_a = npyv512_lower_si256(a);
+ __m256i hi_a = npyv512_higher_si256(a);
+
+ __m256i mulhi, lo_q, hi_q;
+ NPYV__DIVC_U16(256, lo_a, m, lo_q)
+ NPYV__DIVC_U16(256, hi_a, m, hi_q)
+ return npyv512_combine_si256(lo_q, hi_q);
+#endif
+ #undef NPYV__DIVC_U16
+}
+// divide each signed 16-bit element by divisor (round towards zero)
+NPY_FINLINE npyv_s16 npyv_divc_s16(npyv_s16 a, const npyv_s16x3 divisor)
+{
+ const __m128i shf1 = _mm512_castsi512_si128(divisor.val[1]);
+ // q = ((a + mulhi) >> sh1) - XSIGN(a)
+ // trunc(a/d) = (q ^ dsign) - dsign
+ #define NPYV__DIVC_S16(RLEN, A, MULC, DSIGN, R) \
+ mulhi = _mm##RLEN##_mulhi_epi16(A, MULC); \
+ R = _mm##RLEN##_sra_epi16(_mm##RLEN##_add_epi16(A, mulhi), shf1); \
+ R = _mm##RLEN##_sub_epi16(R, _mm##RLEN##_srai_epi16(A, 15)); \
+ R = _mm##RLEN##_sub_epi16(_mm##RLEN##_xor_si##RLEN(R, DSIGN), DSIGN);
+
+#ifdef NPY_HAVE_AVX512BW
+ __m512i mulhi, q;
+ NPYV__DIVC_S16(512, a, divisor.val[0], divisor.val[2], q)
+ return q;
+#else
+ const __m256i m = npyv512_lower_si256(divisor.val[0]);
+ const __m256i dsign = npyv512_lower_si256(divisor.val[2]);
+ __m256i lo_a = npyv512_lower_si256(a);
+ __m256i hi_a = npyv512_higher_si256(a);
+
+ __m256i mulhi, lo_q, hi_q;
+ NPYV__DIVC_S16(256, lo_a, m, dsign, lo_q)
+ NPYV__DIVC_S16(256, hi_a, m, dsign, hi_q)
+ return npyv512_combine_si256(lo_q, hi_q);
+#endif
+ #undef NPYV__DIVC_S16
+}
+// divide each unsigned 32-bit element by divisor
+NPY_FINLINE npyv_u32 npyv_divc_u32(npyv_u32 a, const npyv_u32x3 divisor)
+{
+ const __m128i shf1 = _mm512_castsi512_si128(divisor.val[1]);
+ const __m128i shf2 = _mm512_castsi512_si128(divisor.val[2]);
+ // high part of unsigned multiplication
+ __m512i mulhi_even = _mm512_srli_epi64(_mm512_mul_epu32(a, divisor.val[0]), 32);
+ __m512i mulhi_odd = _mm512_mul_epu32(_mm512_srli_epi64(a, 32), divisor.val[0]);
+ __m512i mulhi = _mm512_mask_mov_epi32(mulhi_even, 0xAAAA, mulhi_odd);
+ // floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
+ __m512i q = _mm512_sub_epi32(a, mulhi);
+ q = _mm512_srl_epi32(q, shf1);
+ q = _mm512_add_epi32(mulhi, q);
+ q = _mm512_srl_epi32(q, shf2);
+ return q;
+}
+// divide each signed 32-bit element by divisor (round towards zero)
+NPY_FINLINE npyv_s32 npyv_divc_s32(npyv_s32 a, const npyv_s32x3 divisor)
+{
+ const __m128i shf1 = _mm512_castsi512_si128(divisor.val[1]);
+ // high part of signed multiplication
+ __m512i mulhi_even = _mm512_srli_epi64(_mm512_mul_epi32(a, divisor.val[0]), 32);
+ __m512i mulhi_odd = _mm512_mul_epi32(_mm512_srli_epi64(a, 32), divisor.val[0]);
+ __m512i mulhi = _mm512_mask_mov_epi32(mulhi_even, 0xAAAA, mulhi_odd);
+ // q = ((a + mulhi) >> sh1) - XSIGN(a)
+ // trunc(a/d) = (q ^ dsign) - dsign
+ __m512i q = _mm512_sra_epi32(_mm512_add_epi32(a, mulhi), shf1);
+ q = _mm512_sub_epi32(q, _mm512_srai_epi32(a, 31));
+ q = _mm512_sub_epi32(_mm512_xor_si512(q, divisor.val[2]), divisor.val[2]);
+ return q;
+}
+// returns the high 64 bits of unsigned 64-bit multiplication
+// xref https://stackoverflow.com/a/28827013
+NPY_FINLINE npyv_u64 npyv__mullhi_u64(npyv_u64 a, npyv_u64 b)
+{
+ __m512i lomask = npyv_setall_s64(0xffffffff);
+ __m512i a_hi = _mm512_srli_epi64(a, 32); // a0l, a0h, a1l, a1h
+ __m512i b_hi = _mm512_srli_epi64(b, 32); // b0l, b0h, b1l, b1h
+ // compute partial products
+ __m512i w0 = _mm512_mul_epu32(a, b); // a0l*b0l, a1l*b1l
+ __m512i w1 = _mm512_mul_epu32(a, b_hi); // a0l*b0h, a1l*b1h
+ __m512i w2 = _mm512_mul_epu32(a_hi, b); // a0h*b0l, a1h*b0l
+ __m512i w3 = _mm512_mul_epu32(a_hi, b_hi); // a0h*b0h, a1h*b1h
+ // sum partial products
+ __m512i w0h = _mm512_srli_epi64(w0, 32);
+ __m512i s1 = _mm512_add_epi64(w1, w0h);
+ __m512i s1l = _mm512_and_si512(s1, lomask);
+ __m512i s1h = _mm512_srli_epi64(s1, 32);
+
+ __m512i s2 = _mm512_add_epi64(w2, s1l);
+ __m512i s2h = _mm512_srli_epi64(s2, 32);
+ __m512i hi = _mm512_add_epi64(w3, s1h);
+ hi = _mm512_add_epi64(hi, s2h);
+ return hi;
+}
+// divide each unsigned 64-bit element by a divisor
+NPY_FINLINE npyv_u64 npyv_divc_u64(npyv_u64 a, const npyv_u64x3 divisor)
+{
+ const __m128i shf1 = _mm512_castsi512_si128(divisor.val[1]);
+ const __m128i shf2 = _mm512_castsi512_si128(divisor.val[2]);
+ // high part of unsigned multiplication
+ __m512i mulhi = npyv__mullhi_u64(a, divisor.val[0]);
+ // floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
+ __m512i q = _mm512_sub_epi64(a, mulhi);
+ q = _mm512_srl_epi64(q, shf1);
+ q = _mm512_add_epi64(mulhi, q);
+ q = _mm512_srl_epi64(q, shf2);
+ return q;
+}
+// divide each unsigned 64-bit element by a divisor (round towards zero)
+NPY_FINLINE npyv_s64 npyv_divc_s64(npyv_s64 a, const npyv_s64x3 divisor)
+{
+ const __m128i shf1 = _mm512_castsi512_si128(divisor.val[1]);
+ // high part of unsigned multiplication
+ __m512i mulhi = npyv__mullhi_u64(a, divisor.val[0]);
+ // convert unsigned to signed high multiplication
+ // mulhi - ((a < 0) ? m : 0) - ((m < 0) ? a : 0);
+ __m512i asign = _mm512_srai_epi64(a, 63);
+ __m512i msign = _mm512_srai_epi64(divisor.val[0], 63);
+ __m512i m_asign = _mm512_and_si512(divisor.val[0], asign);
+ __m512i a_msign = _mm512_and_si512(a, msign);
+ mulhi = _mm512_sub_epi64(mulhi, m_asign);
+ mulhi = _mm512_sub_epi64(mulhi, a_msign);
+ // q = ((a + mulhi) >> sh1) - XSIGN(a)
+ // trunc(a/d) = (q ^ dsign) - dsign
+ __m512i q = _mm512_sra_epi64(_mm512_add_epi64(a, mulhi), shf1);
+ q = _mm512_sub_epi64(q, asign);
+ q = _mm512_sub_epi64(_mm512_xor_si512(q, divisor.val[2]), divisor.val[2]);
+ return q;
+}
/***************************
* Division
***************************/
@@ -130,24 +351,43 @@ NPY_FINLINE __m512i npyv_mul_u8(__m512i a, __m512i b)
#define npyv_nmulsub_f64 _mm512_fnmsub_pd
/***************************
- * Reduce Sum
+ * Summation: Calculates the sum of all vector elements.
* there are three ways to implement reduce sum for AVX512:
* 1- split(256) /add /split(128) /add /hadd /hadd /extract
* 2- shuff(cross) /add /shuff(cross) /add /shuff /add /shuff /add /extract
* 3- _mm512_reduce_add_ps/pd
* The first one is been widely used by many projects
- *
+ *
* the second one is used by Intel Compiler, maybe because the
* latency of hadd increased by (2-3) starting from Skylake-X which makes two
* extra shuffles(non-cross) cheaper. check https://godbolt.org/z/s3G9Er for more info.
- *
+ *
* The third one is almost the same as the second one but only works for
* intel compiler/GCC 7.1/Clang 4, we still need to support older GCC.
***************************/
+// reduce sum across vector
#ifdef NPY_HAVE_AVX512F_REDUCE
+ #define npyv_sum_u32 _mm512_reduce_add_epi32
+ #define npyv_sum_u64 _mm512_reduce_add_epi64
#define npyv_sum_f32 _mm512_reduce_add_ps
#define npyv_sum_f64 _mm512_reduce_add_pd
#else
+ NPY_FINLINE npy_uint32 npyv_sum_u32(npyv_u32 a)
+ {
+ __m256i half = _mm256_add_epi32(npyv512_lower_si256(a), npyv512_higher_si256(a));
+ __m128i quarter = _mm_add_epi32(_mm256_castsi256_si128(half), _mm256_extracti128_si256(half, 1));
+ quarter = _mm_hadd_epi32(quarter, quarter);
+ return _mm_cvtsi128_si32(_mm_hadd_epi32(quarter, quarter));
+ }
+
+ NPY_FINLINE npy_uint64 npyv_sum_u64(npyv_u64 a)
+ {
+ __m256i four = _mm256_add_epi64(npyv512_lower_si256(a), npyv512_higher_si256(a));
+ __m256i two = _mm256_add_epi64(four, _mm256_shuffle_epi32(four, _MM_SHUFFLE(1, 0, 3, 2)));
+ __m128i one = _mm_add_epi64(_mm256_castsi256_si128(two), _mm256_extracti128_si256(two, 1));
+ return (npy_uint64)npyv128_cvtsi128_si64(one);
+ }
+
NPY_FINLINE float npyv_sum_f32(npyv_f32 a)
{
__m512 h64 = _mm512_shuffle_f32x4(a, a, _MM_SHUFFLE(3, 2, 3, 2));
@@ -160,6 +400,7 @@ NPY_FINLINE __m512i npyv_mul_u8(__m512i a, __m512i b)
__m512 sum4 = _mm512_add_ps(sum8, h4);
return _mm_cvtss_f32(_mm512_castps512_ps128(sum4));
}
+
NPY_FINLINE double npyv_sum_f64(npyv_f64 a)
{
__m512d h64 = _mm512_shuffle_f64x2(a, a, _MM_SHUFFLE(3, 2, 3, 2));
@@ -172,4 +413,29 @@ NPY_FINLINE __m512i npyv_mul_u8(__m512i a, __m512i b)
}
#endif
+// expand the source vector and performs sum reduce
+NPY_FINLINE npy_uint16 npyv_sumup_u8(npyv_u8 a)
+{
+#ifdef NPY_HAVE_AVX512BW
+ __m512i eight = _mm512_sad_epu8(a, _mm512_setzero_si512());
+ __m256i four = _mm256_add_epi16(npyv512_lower_si256(eight), npyv512_higher_si256(eight));
+#else
+ __m256i lo_four = _mm256_sad_epu8(npyv512_lower_si256(a), _mm256_setzero_si256());
+ __m256i hi_four = _mm256_sad_epu8(npyv512_higher_si256(a), _mm256_setzero_si256());
+ __m256i four = _mm256_add_epi16(lo_four, hi_four);
+#endif
+ __m128i two = _mm_add_epi16(_mm256_castsi256_si128(four), _mm256_extracti128_si256(four, 1));
+ __m128i one = _mm_add_epi16(two, _mm_unpackhi_epi64(two, two));
+ return (npy_uint16)_mm_cvtsi128_si32(one);
+}
+
+NPY_FINLINE npy_uint32 npyv_sumup_u16(npyv_u16 a)
+{
+ const npyv_u16 even_mask = _mm512_set1_epi32(0x0000FFFF);
+ __m512i even = _mm512_and_si512(a, even_mask);
+ __m512i odd = _mm512_srli_epi32(a, 16);
+ __m512i ff = _mm512_add_epi32(even, odd);
+ return npyv_sum_u32(ff);
+}
+
#endif // _NPY_SIMD_AVX512_ARITHMETIC_H
diff --git a/numpy/core/src/common/simd/avx512/avx512.h b/numpy/core/src/common/simd/avx512/avx512.h
index 2de33765a..f38686834 100644
--- a/numpy/core/src/common/simd/avx512/avx512.h
+++ b/numpy/core/src/common/simd/avx512/avx512.h
@@ -4,6 +4,7 @@
#define NPY_SIMD 512
#define NPY_SIMD_WIDTH 64
#define NPY_SIMD_F64 1
+#define NPY_SIMD_FMA3 1 // native support
// Enough limit to allow us to use _mm512_i32gather_* and _mm512_i32scatter_*
#define NPY_SIMD_MAXLOAD_STRIDE32 (0x7fffffff / 16)
#define NPY_SIMD_MAXSTORE_STRIDE32 (0x7fffffff / 16)
@@ -73,3 +74,4 @@ typedef struct { __m512d val[3]; } npyv_f64x3;
#include "conversion.h"
#include "arithmetic.h"
#include "math.h"
+#include "maskop.h"
diff --git a/numpy/core/src/common/simd/avx512/conversion.h b/numpy/core/src/common/simd/avx512/conversion.h
index 0f7e27de3..0bd44179b 100644
--- a/numpy/core/src/common/simd/avx512/conversion.h
+++ b/numpy/core/src/common/simd/avx512/conversion.h
@@ -51,4 +51,88 @@
#define npyv_cvt_b32_f32(A) npyv_cvt_b32_u32(_mm512_castps_si512(A))
#define npyv_cvt_b64_f64(A) npyv_cvt_b64_u64(_mm512_castpd_si512(A))
+// expand
+NPY_FINLINE npyv_u16x2 npyv_expand_u16_u8(npyv_u8 data)
+{
+ npyv_u16x2 r;
+ __m256i lo = npyv512_lower_si256(data);
+ __m256i hi = npyv512_higher_si256(data);
+#ifdef NPY_HAVE_AVX512BW
+ r.val[0] = _mm512_cvtepu8_epi16(lo);
+ r.val[1] = _mm512_cvtepu8_epi16(hi);
+#else
+ __m256i loelo = _mm256_cvtepu8_epi16(_mm256_castsi256_si128(lo));
+ __m256i loehi = _mm256_cvtepu8_epi16(_mm256_extracti128_si256(lo, 1));
+ __m256i hielo = _mm256_cvtepu8_epi16(_mm256_castsi256_si128(hi));
+ __m256i hiehi = _mm256_cvtepu8_epi16(_mm256_extracti128_si256(hi, 1));
+ r.val[0] = npyv512_combine_si256(loelo, loehi);
+ r.val[1] = npyv512_combine_si256(hielo, hiehi);
+#endif
+ return r;
+}
+
+NPY_FINLINE npyv_u32x2 npyv_expand_u32_u16(npyv_u16 data)
+{
+ npyv_u32x2 r;
+ __m256i lo = npyv512_lower_si256(data);
+ __m256i hi = npyv512_higher_si256(data);
+#ifdef NPY_HAVE_AVX512BW
+ r.val[0] = _mm512_cvtepu16_epi32(lo);
+ r.val[1] = _mm512_cvtepu16_epi32(hi);
+#else
+ __m256i loelo = _mm256_cvtepu16_epi32(_mm256_castsi256_si128(lo));
+ __m256i loehi = _mm256_cvtepu16_epi32(_mm256_extracti128_si256(lo, 1));
+ __m256i hielo = _mm256_cvtepu16_epi32(_mm256_castsi256_si128(hi));
+ __m256i hiehi = _mm256_cvtepu16_epi32(_mm256_extracti128_si256(hi, 1));
+ r.val[0] = npyv512_combine_si256(loelo, loehi);
+ r.val[1] = npyv512_combine_si256(hielo, hiehi);
+#endif
+ return r;
+}
+
+// convert boolean vectors to integer bitfield
+NPY_FINLINE npy_uint64 npyv_tobits_b8(npyv_b8 a)
+{
+#ifdef NPY_HAVE_AVX512BW_MASK
+ return (npy_uint64)_cvtmask64_u64(a);
+#elif defined(NPY_HAVE_AVX512BW)
+ return (npy_uint64)a;
+#else
+ int mask_lo = _mm256_movemask_epi8(npyv512_lower_si256(a));
+ int mask_hi = _mm256_movemask_epi8(npyv512_higher_si256(a));
+ return (unsigned)mask_lo | ((npy_uint64)(unsigned)mask_hi << 32);
+#endif
+}
+NPY_FINLINE npy_uint64 npyv_tobits_b16(npyv_b16 a)
+{
+#ifdef NPY_HAVE_AVX512BW_MASK
+ return (npy_uint32)_cvtmask32_u32(a);
+#elif defined(NPY_HAVE_AVX512BW)
+ return (npy_uint32)a;
+#else
+ __m256i pack = _mm256_packs_epi16(
+ npyv512_lower_si256(a), npyv512_higher_si256(a)
+ );
+ return (npy_uint32)_mm256_movemask_epi8(_mm256_permute4x64_epi64(pack, _MM_SHUFFLE(3, 1, 2, 0)));
+#endif
+}
+NPY_FINLINE npy_uint64 npyv_tobits_b32(npyv_b32 a)
+{ return (npy_uint16)a; }
+NPY_FINLINE npy_uint64 npyv_tobits_b64(npyv_b64 a)
+{
+#ifdef NPY_HAVE_AVX512DQ_MASK
+ return _cvtmask8_u32(a);
+#else
+ return (npy_uint8)a;
+#endif
+}
+
+// round to nearest integer (assuming even)
+#define npyv_round_s32_f32 _mm512_cvtps_epi32
+NPY_FINLINE npyv_s32 npyv_round_s32_f64(npyv_f64 a, npyv_f64 b)
+{
+ __m256i lo = _mm512_cvtpd_epi32(a), hi = _mm512_cvtpd_epi32(b);
+ return npyv512_combine_si256(lo, hi);
+}
+
#endif // _NPY_SIMD_AVX512_CVT_H
diff --git a/numpy/core/src/common/simd/avx512/maskop.h b/numpy/core/src/common/simd/avx512/maskop.h
new file mode 100644
index 000000000..d1c188390
--- /dev/null
+++ b/numpy/core/src/common/simd/avx512/maskop.h
@@ -0,0 +1,54 @@
+#ifndef NPY_SIMD
+ #error "Not a standalone header, use simd/simd.h instead"
+#endif
+
+#ifndef _NPY_SIMD_AVX512_MASKOP_H
+#define _NPY_SIMD_AVX512_MASKOP_H
+
+/**
+ * Implements conditional addition and subtraction.
+ * e.g. npyv_ifadd_f32(m, a, b, c) -> m ? a + b : c
+ * e.g. npyv_ifsub_f32(m, a, b, c) -> m ? a - b : c
+ */
+#define NPYV_IMPL_AVX512_EMULATE_MASK_ADDSUB(SFX, BSFX) \
+ NPY_FINLINE npyv_##SFX npyv_ifadd_##SFX \
+ (npyv_##BSFX m, npyv_##SFX a, npyv_##SFX b, npyv_##SFX c) \
+ { \
+ npyv_##SFX add = npyv_add_##SFX(a, b); \
+ return npyv_select_##SFX(m, add, c); \
+ } \
+ NPY_FINLINE npyv_##SFX npyv_ifsub_##SFX \
+ (npyv_##BSFX m, npyv_##SFX a, npyv_##SFX b, npyv_##SFX c) \
+ { \
+ npyv_##SFX sub = npyv_sub_##SFX(a, b); \
+ return npyv_select_##SFX(m, sub, c); \
+ }
+
+#define NPYV_IMPL_AVX512_MASK_ADDSUB(SFX, BSFX, ZSFX) \
+ NPY_FINLINE npyv_##SFX npyv_ifadd_##SFX \
+ (npyv_##BSFX m, npyv_##SFX a, npyv_##SFX b, npyv_##SFX c) \
+ { return _mm512_mask_add_##ZSFX(c, m, a, b); } \
+ NPY_FINLINE npyv_##SFX npyv_ifsub_##SFX \
+ (npyv_##BSFX m, npyv_##SFX a, npyv_##SFX b, npyv_##SFX c) \
+ { return _mm512_mask_sub_##ZSFX(c, m, a, b); }
+
+#ifdef NPY_HAVE_AVX512BW
+ NPYV_IMPL_AVX512_MASK_ADDSUB(u8, b8, epi8)
+ NPYV_IMPL_AVX512_MASK_ADDSUB(s8, b8, epi8)
+ NPYV_IMPL_AVX512_MASK_ADDSUB(u16, b16, epi16)
+ NPYV_IMPL_AVX512_MASK_ADDSUB(s16, b16, epi16)
+#else
+ NPYV_IMPL_AVX512_EMULATE_MASK_ADDSUB(u8, b8)
+ NPYV_IMPL_AVX512_EMULATE_MASK_ADDSUB(s8, b8)
+ NPYV_IMPL_AVX512_EMULATE_MASK_ADDSUB(u16, b16)
+ NPYV_IMPL_AVX512_EMULATE_MASK_ADDSUB(s16, b16)
+#endif
+
+NPYV_IMPL_AVX512_MASK_ADDSUB(u32, b32, epi32)
+NPYV_IMPL_AVX512_MASK_ADDSUB(s32, b32, epi32)
+NPYV_IMPL_AVX512_MASK_ADDSUB(u64, b64, epi64)
+NPYV_IMPL_AVX512_MASK_ADDSUB(s64, b64, epi64)
+NPYV_IMPL_AVX512_MASK_ADDSUB(f32, b32, ps)
+NPYV_IMPL_AVX512_MASK_ADDSUB(f64, b64, pd)
+
+#endif // _NPY_SIMD_AVX512_MASKOP_H
diff --git a/numpy/core/src/common/simd/avx512/math.h b/numpy/core/src/common/simd/avx512/math.h
index 1db710670..0141396d0 100644
--- a/numpy/core/src/common/simd/avx512/math.h
+++ b/numpy/core/src/common/simd/avx512/math.h
@@ -46,4 +46,70 @@ NPY_FINLINE npyv_f32 npyv_square_f32(npyv_f32 a)
NPY_FINLINE npyv_f64 npyv_square_f64(npyv_f64 a)
{ return _mm512_mul_pd(a, a); }
+// Maximum, natively mapping with no guarantees to handle NaN.
+#define npyv_max_f32 _mm512_max_ps
+#define npyv_max_f64 _mm512_max_pd
+// Maximum, supports IEEE floating-point arithmetic (IEC 60559),
+// - If one of the two vectors contains NaN, the equivalent element of the other vector is set
+// - Only if both corresponded elements are NaN, NaN is set.
+NPY_FINLINE npyv_f32 npyv_maxp_f32(npyv_f32 a, npyv_f32 b)
+{
+ __mmask16 nn = _mm512_cmp_ps_mask(b, b, _CMP_ORD_Q);
+ return _mm512_mask_max_ps(a, nn, a, b);
+}
+NPY_FINLINE npyv_f64 npyv_maxp_f64(npyv_f64 a, npyv_f64 b)
+{
+ __mmask8 nn = _mm512_cmp_pd_mask(b, b, _CMP_ORD_Q);
+ return _mm512_mask_max_pd(a, nn, a, b);
+}
+// Maximum, integer operations
+#ifdef NPY_HAVE_AVX512BW
+ #define npyv_max_u8 _mm512_max_epu8
+ #define npyv_max_s8 _mm512_max_epi8
+ #define npyv_max_u16 _mm512_max_epu16
+ #define npyv_max_s16 _mm512_max_epi16
+#else
+ NPYV_IMPL_AVX512_FROM_AVX2_2ARG(npyv_max_u8, _mm256_max_epu8)
+ NPYV_IMPL_AVX512_FROM_AVX2_2ARG(npyv_max_s8, _mm256_max_epi8)
+ NPYV_IMPL_AVX512_FROM_AVX2_2ARG(npyv_max_u16, _mm256_max_epu16)
+ NPYV_IMPL_AVX512_FROM_AVX2_2ARG(npyv_max_s16, _mm256_max_epi16)
#endif
+#define npyv_max_u32 _mm512_max_epu32
+#define npyv_max_s32 _mm512_max_epi32
+#define npyv_max_u64 _mm512_max_epu64
+#define npyv_max_s64 _mm512_max_epi64
+
+// Minimum, natively mapping with no guarantees to handle NaN.
+#define npyv_min_f32 _mm512_min_ps
+#define npyv_min_f64 _mm512_min_pd
+// Minimum, supports IEEE floating-point arithmetic (IEC 60559),
+// - If one of the two vectors contains NaN, the equivalent element of the other vector is set
+// - Only if both corresponded elements are NaN, NaN is set.
+NPY_FINLINE npyv_f32 npyv_minp_f32(npyv_f32 a, npyv_f32 b)
+{
+ __mmask16 nn = _mm512_cmp_ps_mask(b, b, _CMP_ORD_Q);
+ return _mm512_mask_min_ps(a, nn, a, b);
+}
+NPY_FINLINE npyv_f64 npyv_minp_f64(npyv_f64 a, npyv_f64 b)
+{
+ __mmask8 nn = _mm512_cmp_pd_mask(b, b, _CMP_ORD_Q);
+ return _mm512_mask_min_pd(a, nn, a, b);
+}
+// Minimum, integer operations
+#ifdef NPY_HAVE_AVX512BW
+ #define npyv_min_u8 _mm512_min_epu8
+ #define npyv_min_s8 _mm512_min_epi8
+ #define npyv_min_u16 _mm512_min_epu16
+ #define npyv_min_s16 _mm512_min_epi16
+#else
+ NPYV_IMPL_AVX512_FROM_AVX2_2ARG(npyv_min_u8, _mm256_min_epu8)
+ NPYV_IMPL_AVX512_FROM_AVX2_2ARG(npyv_min_s8, _mm256_min_epi8)
+ NPYV_IMPL_AVX512_FROM_AVX2_2ARG(npyv_min_u16, _mm256_min_epu16)
+ NPYV_IMPL_AVX512_FROM_AVX2_2ARG(npyv_min_s16, _mm256_min_epi16)
+#endif
+#define npyv_min_u32 _mm512_min_epu32
+#define npyv_min_s32 _mm512_min_epi32
+#define npyv_min_u64 _mm512_min_epu64
+#define npyv_min_s64 _mm512_min_epi64
+
+#endif // _NPY_SIMD_AVX512_MATH_H
diff --git a/numpy/core/src/common/simd/avx512/operators.h b/numpy/core/src/common/simd/avx512/operators.h
index f76ea5e2d..d53932fa8 100644
--- a/numpy/core/src/common/simd/avx512/operators.h
+++ b/numpy/core/src/common/simd/avx512/operators.h
@@ -90,7 +90,6 @@
NPYV_IMPL_AVX512_FROM_SI512_PS_2ARG(npyv_and_f32, _mm512_and_si512)
NPYV_IMPL_AVX512_FROM_SI512_PD_2ARG(npyv_and_f64, _mm512_and_si512)
#endif
-
// OR
#define npyv_or_u8 _mm512_or_si512
#define npyv_or_s8 _mm512_or_si512
@@ -124,7 +123,6 @@
NPYV_IMPL_AVX512_FROM_SI512_PS_2ARG(npyv_xor_f32, _mm512_xor_si512)
NPYV_IMPL_AVX512_FROM_SI512_PD_2ARG(npyv_xor_f64, _mm512_xor_si512)
#endif
-
// NOT
#define npyv_not_u8(A) _mm512_xor_si512(A, _mm512_set1_epi32(-1))
#define npyv_not_s8 npyv_not_u8
@@ -143,6 +141,67 @@
#endif
/***************************
+ * Logical (boolean)
+ ***************************/
+#ifdef NPY_HAVE_AVX512BW_MASK
+ #define npyv_and_b8 _kand_mask64
+ #define npyv_and_b16 _kand_mask32
+ #define npyv_or_b8 _kor_mask64
+ #define npyv_or_b16 _kor_mask32
+ #define npyv_xor_b8 _kxor_mask64
+ #define npyv_xor_b16 _kxor_mask32
+ #define npyv_not_b8 _knot_mask64
+ #define npyv_not_b16 _knot_mask32
+#elif defined(NPY_HAVE_AVX512BW)
+ NPY_FINLINE npyv_b8 npyv_and_b8(npyv_b8 a, npyv_b8 b)
+ { return a & b; }
+ NPY_FINLINE npyv_b16 npyv_and_b16(npyv_b16 a, npyv_b16 b)
+ { return a & b; }
+ NPY_FINLINE npyv_b8 npyv_or_b8(npyv_b8 a, npyv_b8 b)
+ { return a | b; }
+ NPY_FINLINE npyv_b16 npyv_or_b16(npyv_b16 a, npyv_b16 b)
+ { return a | b; }
+ NPY_FINLINE npyv_b8 npyv_xor_b8(npyv_b8 a, npyv_b8 b)
+ { return a ^ b; }
+ NPY_FINLINE npyv_b16 npyv_xor_b16(npyv_b16 a, npyv_b16 b)
+ { return a ^ b; }
+ NPY_FINLINE npyv_b8 npyv_not_b8(npyv_b8 a)
+ { return ~a; }
+ NPY_FINLINE npyv_b16 npyv_not_b16(npyv_b16 a)
+ { return ~a; }
+#else
+ #define npyv_and_b8 _mm512_and_si512
+ #define npyv_and_b16 _mm512_and_si512
+ #define npyv_or_b8 _mm512_or_si512
+ #define npyv_or_b16 _mm512_or_si512
+ #define npyv_xor_b8 _mm512_xor_si512
+ #define npyv_xor_b16 _mm512_xor_si512
+ #define npyv_not_b8 npyv_not_u8
+ #define npyv_not_b16 npyv_not_u8
+#endif
+
+#define npyv_and_b32 _mm512_kand
+#define npyv_or_b32 _mm512_kor
+#define npyv_xor_b32 _mm512_kxor
+#define npyv_not_b32 _mm512_knot
+
+#ifdef NPY_HAVE_AVX512DQ_MASK
+ #define npyv_and_b64 _kand_mask8
+ #define npyv_or_b64 _kor_mask8
+ #define npyv_xor_b64 _kxor_mask8
+ #define npyv_not_b64 _knot_mask8
+#else
+ NPY_FINLINE npyv_b64 npyv_and_b64(npyv_b64 a, npyv_b64 b)
+ { return (npyv_b64)_mm512_kand((npyv_b32)a, (npyv_b32)b); }
+ NPY_FINLINE npyv_b64 npyv_or_b64(npyv_b64 a, npyv_b64 b)
+ { return (npyv_b64)_mm512_kor((npyv_b32)a, (npyv_b32)b); }
+ NPY_FINLINE npyv_b64 npyv_xor_b64(npyv_b64 a, npyv_b64 b)
+ { return (npyv_b64)_mm512_kxor((npyv_b32)a, (npyv_b32)b); }
+ NPY_FINLINE npyv_b64 npyv_not_b64(npyv_b64 a)
+ { return (npyv_b64)_mm512_knot((npyv_b32)a); }
+#endif
+
+/***************************
* Comparison
***************************/
@@ -256,4 +315,10 @@
#define npyv_cmpge_f32(A, B) _mm512_cmp_ps_mask(A, B, _CMP_GE_OQ)
#define npyv_cmpge_f64(A, B) _mm512_cmp_pd_mask(A, B, _CMP_GE_OQ)
+// check special cases
+NPY_FINLINE npyv_b32 npyv_notnan_f32(npyv_f32 a)
+{ return _mm512_cmp_ps_mask(a, a, _CMP_ORD_Q); }
+NPY_FINLINE npyv_b64 npyv_notnan_f64(npyv_f64 a)
+{ return _mm512_cmp_pd_mask(a, a, _CMP_ORD_Q); }
+
#endif // _NPY_SIMD_AVX512_OPERATORS_H
diff --git a/numpy/core/src/common/simd/avx512/reorder.h b/numpy/core/src/common/simd/avx512/reorder.h
index cdbae7aac..f043004ec 100644
--- a/numpy/core/src/common/simd/avx512/reorder.h
+++ b/numpy/core/src/common/simd/avx512/reorder.h
@@ -167,4 +167,60 @@ NPY_FINLINE npyv_f64x2 npyv_zip_f64(__m512d a, __m512d b)
return r;
}
+// Reverse elements of each 64-bit lane
+NPY_FINLINE npyv_u8 npyv_rev64_u8(npyv_u8 a)
+{
+#ifdef NPY_HAVE_AVX512BW
+ const __m512i idx = npyv_set_u8(
+ 7, 6, 5, 4, 3, 2, 1, 0,/*64*/15, 14, 13, 12, 11, 10, 9, 8,
+ 7, 6, 5, 4, 3, 2, 1, 0,/*64*/15, 14, 13, 12, 11, 10, 9, 8,
+ 7, 6, 5, 4, 3, 2, 1, 0,/*64*/15, 14, 13, 12, 11, 10, 9, 8,
+ 7, 6, 5, 4, 3, 2, 1, 0,/*64*/15, 14, 13, 12, 11, 10, 9, 8
+ );
+ return _mm512_shuffle_epi8(a, idx);
+#else
+ const __m256i idx = _mm256_setr_epi8(
+ 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8,
+ 7, 6, 5, 4, 3, 2, 1, 0, 15, 14, 13, 12, 11, 10, 9, 8
+ );
+ __m256i lo = _mm256_shuffle_epi8(npyv512_lower_si256(a), idx);
+ __m256i hi = _mm256_shuffle_epi8(npyv512_higher_si256(a), idx);
+ return npyv512_combine_si256(lo, hi);
+#endif
+}
+#define npyv_rev64_s8 npyv_rev64_u8
+
+NPY_FINLINE npyv_u16 npyv_rev64_u16(npyv_u16 a)
+{
+#ifdef NPY_HAVE_AVX512BW
+ const __m512i idx = npyv_set_u8(
+ 6, 7, 4, 5, 2, 3, 0, 1,/*64*/14, 15, 12, 13, 10, 11, 8, 9,
+ 6, 7, 4, 5, 2, 3, 0, 1,/*64*/14, 15, 12, 13, 10, 11, 8, 9,
+ 6, 7, 4, 5, 2, 3, 0, 1,/*64*/14, 15, 12, 13, 10, 11, 8, 9,
+ 6, 7, 4, 5, 2, 3, 0, 1,/*64*/14, 15, 12, 13, 10, 11, 8, 9
+ );
+ return _mm512_shuffle_epi8(a, idx);
+#else
+ const __m256i idx = _mm256_setr_epi8(
+ 6, 7, 4, 5, 2, 3, 0, 1,/*64*/14, 15, 12, 13, 10, 11, 8, 9,
+ 6, 7, 4, 5, 2, 3, 0, 1,/*64*/14, 15, 12, 13, 10, 11, 8, 9
+ );
+ __m256i lo = _mm256_shuffle_epi8(npyv512_lower_si256(a), idx);
+ __m256i hi = _mm256_shuffle_epi8(npyv512_higher_si256(a), idx);
+ return npyv512_combine_si256(lo, hi);
+#endif
+}
+#define npyv_rev64_s16 npyv_rev64_u16
+
+NPY_FINLINE npyv_u32 npyv_rev64_u32(npyv_u32 a)
+{
+ return _mm512_shuffle_epi32(a, _MM_SHUFFLE(2, 3, 0, 1));
+}
+#define npyv_rev64_s32 npyv_rev64_u32
+
+NPY_FINLINE npyv_f32 npyv_rev64_f32(npyv_f32 a)
+{
+ return _mm512_shuffle_ps(a, a, _MM_SHUFFLE(2, 3, 0, 1));
+}
+
#endif // _NPY_SIMD_AVX512_REORDER_H
diff --git a/numpy/core/src/common/simd/emulate_maskop.h b/numpy/core/src/common/simd/emulate_maskop.h
new file mode 100644
index 000000000..7e7446bc5
--- /dev/null
+++ b/numpy/core/src/common/simd/emulate_maskop.h
@@ -0,0 +1,44 @@
+/**
+ * This header is used internaly by all current supported SIMD extention,
+ * execpt for AVX512.
+ */
+#ifndef NPY_SIMD
+ #error "Not a standalone header, use simd/simd.h instead"
+#endif
+
+#ifndef _NPY_SIMD_EMULATE_MASKOP_H
+#define _NPY_SIMD_EMULATE_MASKOP_H
+
+/**
+ * Implements conditional addition and subtraction.
+ * e.g. npyv_ifadd_f32(mask, a, b, c) -> mask ? a + b : c
+ * e.g. npyv_ifsub_f32(mask, a, b, c) -> mask ? a - b : c
+ */
+#define NPYV_IMPL_EMULATE_MASK_ADDSUB(SFX, BSFX) \
+ NPY_FINLINE npyv_##SFX npyv_ifadd_##SFX \
+ (npyv_##BSFX m, npyv_##SFX a, npyv_##SFX b, npyv_##SFX c) \
+ { \
+ npyv_##SFX add = npyv_add_##SFX(a, b); \
+ return npyv_select_##SFX(m, add, c); \
+ } \
+ NPY_FINLINE npyv_##SFX npyv_ifsub_##SFX \
+ (npyv_##BSFX m, npyv_##SFX a, npyv_##SFX b, npyv_##SFX c) \
+ { \
+ npyv_##SFX sub = npyv_sub_##SFX(a, b); \
+ return npyv_select_##SFX(m, sub, c); \
+ }
+
+NPYV_IMPL_EMULATE_MASK_ADDSUB(u8, b8)
+NPYV_IMPL_EMULATE_MASK_ADDSUB(s8, b8)
+NPYV_IMPL_EMULATE_MASK_ADDSUB(u16, b16)
+NPYV_IMPL_EMULATE_MASK_ADDSUB(s16, b16)
+NPYV_IMPL_EMULATE_MASK_ADDSUB(u32, b32)
+NPYV_IMPL_EMULATE_MASK_ADDSUB(s32, b32)
+NPYV_IMPL_EMULATE_MASK_ADDSUB(u64, b64)
+NPYV_IMPL_EMULATE_MASK_ADDSUB(s64, b64)
+NPYV_IMPL_EMULATE_MASK_ADDSUB(f32, b32)
+#if NPY_SIMD_F64
+ NPYV_IMPL_EMULATE_MASK_ADDSUB(f64, b64)
+#endif
+
+#endif // _NPY_SIMD_EMULATE_MASKOP_H
diff --git a/numpy/core/src/common/simd/intdiv.h b/numpy/core/src/common/simd/intdiv.h
new file mode 100644
index 000000000..f6ea9abf2
--- /dev/null
+++ b/numpy/core/src/common/simd/intdiv.h
@@ -0,0 +1,475 @@
+/**
+ * This header implements `npyv_divisor_*` intrinsics used for computing the parameters
+ * of fast integer division, while division intrinsics `npyv_divc_*` are defined in
+ * {extension}/arithmetic.h.
+ */
+#ifndef NPY_SIMD
+ #error "Not a standalone header, use simd/simd.h instead"
+#endif
+#ifndef _NPY_SIMD_INTDIV_H
+#define _NPY_SIMD_INTDIV_H
+/**********************************************************************************
+ ** Integer division
+ **********************************************************************************
+ * Almost all architecture (except Power10) doesn't support integer vector division,
+ * also the cost of scalar division in architectures like x86 is too high it can take
+ * 30 to 40 cycles on modern chips and up to 100 on old ones.
+ *
+ * Therefore we are using division by multiplying with precomputed reciprocal technique,
+ * the method that been used in this implementation is based on T. Granlund and P. L. Montgomery
+ * “Division by invariant integers using multiplication(see [Figure 4.1, 5.1]
+ * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.1.2556)
+ *
+ * It shows a good impact for all architectures especially on X86,
+ * however computing divisor parameters is kind of expensive so this implementation
+ * should only works when divisor is a scalar and used multiple of times.
+ *
+ * The division process is separated into two intrinsics for each data type
+ *
+ * 1- npyv_{dtype}x3 npyv_divisor_{dtype} ({dtype} divisor);
+ * For computing the divisor parameters (multiplier + shifters + sign of divisor(signed only))
+ *
+ * 2- npyv_{dtype} npyv_divisor_{dtype} (npyv_{dtype} dividend, npyv_{dtype}x3 divisor_parms);
+ * For performing the final division.
+ *
+ ** For example:
+ * int vstep = npyv_nlanes_s32; // number of lanes
+ * int x = 0x6e70;
+ * npyv_s32x3 divisor = npyv_divisor_s32(x); // init divisor params
+ * for (; len >= vstep; src += vstep, dst += vstep, len -= vstep) {
+ * npyv_s32 a = npyv_load_s32(*src); // load s32 vector from memory
+ * a = npyv_divc_s32(a, divisor); // divide all elements by x
+ * npyv_store_s32(dst, a); // store s32 vector into memroy
+ * }
+ *
+ ** NOTES:
+ * - For 64-bit division on Aarch64 and IBM/Power, we fall-back to the scalar division
+ * since emulating multiply-high is expensive and both architectures have very fast dividers.
+ *
+ ** TODO:
+ * - Add support for Power10(VSX4)
+ *
+ ***************************************************************
+ ** Figure 4.1: Unsigned division by run–time invariant divisor
+ ***************************************************************
+ * Initialization (given uword d with 1 ≤ d < 2^N):
+ * int l = ceil(log2(d));
+ * uword m = 2^N * (2^l− d) / d + 1;
+ * int sh1 = min(l, 1);
+ * int sh2 = max(l − 1, 0);
+ *
+ * For q = FLOOR(a/d), all uword:
+ * uword t1 = MULUH(m, a);
+ * q = SRL(t1 + SRL(a − t1, sh1), sh2);
+ *
+ ************************************************************************************
+ ** Figure 5.1: Signed division by run–time invariant divisor, rounded towards zero
+ ************************************************************************************
+ * Initialization (given constant sword d with d !=0):
+ * int l = max(ceil(log2(abs(d))), 1);
+ * udword m0 = 1 + (2^(N+l-1)) / abs(d);
+ * sword m = m0 − 2^N;
+ * sword dsign = XSIGN(d);
+ * int sh = l − 1;
+ *
+ * For q = TRUNC(a/d), all sword:
+ * sword q0 = a + MULSH(m, a);
+ * q0 = SRA(q0, sh) − XSIGN(a);
+ * q = EOR(q0, dsign) − dsign;
+ */
+/**
+ * bit-scan reverse for non-zeros. returns the index of the highest set bit.
+ * equivalent to floor(log2(a))
+ */
+#ifdef _MSC_VER
+ #include <intrin.h> // _BitScanReverse
+#endif
+NPY_FINLINE unsigned npyv__bitscan_revnz_u32(npy_uint32 a)
+{
+ assert(a > 0); // due to use __builtin_clz
+ unsigned r;
+#if defined(NPY_HAVE_SSE2) && defined(_MSC_VER)
+ unsigned long rl;
+ (void)_BitScanReverse(&rl, (unsigned long)a);
+ r = (unsigned)rl;
+#elif defined(NPY_HAVE_SSE2) && (defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER))
+ __asm__("bsr %1, %0" : "=r" (r) : "r"(a));
+#elif defined(__GNUC__) || defined(__clang__)
+ r = 31 - __builtin_clz(a); // performs on arm -> clz, ppc -> cntlzw
+#else
+ r = 0;
+ while (a >>= 1) {
+ r++;
+ }
+#endif
+ return r;
+}
+NPY_FINLINE unsigned npyv__bitscan_revnz_u64(npy_uint64 a)
+{
+ assert(a > 0); // due to use __builtin_clzll
+#if defined(_M_AMD64) && defined(_MSC_VER)
+ unsigned long rl;
+ (void)_BitScanReverse64(&rl, a);
+ return (unsigned)rl;
+#elif defined(__x86_64__) && (defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER))
+ npy_uint64 r;
+ __asm__("bsrq %1, %0" : "=r"(r) : "r"(a));
+ return (unsigned)r;
+#elif defined(__GNUC__) || defined(__clang__)
+ return 63 - __builtin_clzll(a);
+#else
+ npy_uint64 a_hi = a >> 32;
+ if (a_hi == 0) {
+ return npyv__bitscan_revnz_u32((npy_uint32)a);
+ }
+ return 32 + npyv__bitscan_revnz_u32((npy_uint32)a_hi);
+#endif
+}
+/**
+ * Divides 128-bit unsigned integer by a 64-bit when the lower
+ * 64-bit of the dividend is zero.
+ *
+ * This function is needed to calculate the multiplier of 64-bit integer division
+ * see npyv_divisor_u64/npyv_divisor_s64.
+ */
+NPY_FINLINE npy_uint64 npyv__divh128_u64(npy_uint64 high, npy_uint64 divisor)
+{
+ assert(divisor > 1);
+ npy_uint64 quotient;
+#if defined(_M_X64) && defined(_MSC_VER) && _MSC_VER >= 1920
+ npy_uint64 remainder;
+ quotient = _udiv128(high, 0, divisor, &remainder);
+ (void)remainder;
+#elif defined(__x86_64__) && (defined(__GNUC__) || defined(__clang__) || defined(__INTEL_COMPILER))
+ __asm__("divq %[d]" : "=a"(quotient) : [d] "r"(divisor), "a"(0), "d"(high));
+#elif defined(__SIZEOF_INT128__)
+ quotient = (npy_uint64)((((__uint128_t)high) << 64) / divisor);
+#else
+ /**
+ * Minified version based on Donald Knuth’s Algorithm D (Division of nonnegative integers),
+ * and Generic implementation in Hacker’s Delight.
+ *
+ * See https://skanthak.homepage.t-online.de/division.html
+ * with respect to the license of the Hacker's Delight book
+ * (https://web.archive.org/web/20190408122508/http://www.hackersdelight.org/permissions.htm)
+ */
+ // shift amount for normalize
+ unsigned ldz = 63 - npyv__bitscan_revnz_u64(divisor);
+ // normalize divisor
+ divisor <<= ldz;
+ high <<= ldz;
+ // break divisor up into two 32-bit digits
+ npy_uint32 divisor_hi = divisor >> 32;
+ npy_uint32 divisor_lo = divisor & 0xFFFFFFFF;
+ // compute high quotient digit
+ npy_uint32 quotient_hi = (npy_uint32)(high / divisor_hi);
+ npy_uint64 remainder = high - divisor_hi * quotient_hi;
+ npy_uint64 base32 = 1ULL << 32;
+ while (quotient_hi >= base32 || quotient_hi*divisor_lo > base32*remainder) {
+ remainder += --divisor_hi;
+ if (remainder >= base32) {
+ break;
+ }
+ }
+ // compute dividend digit pairs
+ npy_uint64 dividend_pairs = base32*high - divisor*quotient_hi;
+ // compute second quotient digit for lower zeros
+ npy_uint32 quotient_lo = (npy_uint32)(dividend_pairs / divisor_hi);
+ quotient = base32*quotient_hi + quotient_lo;
+#endif
+ return quotient;
+}
+// Initializing divisor parameters for unsigned 8-bit division
+NPY_FINLINE npyv_u8x3 npyv_divisor_u8(npy_uint8 d)
+{
+ unsigned l, l2, sh1, sh2, m;
+ switch (d) {
+ case 0: // LCOV_EXCL_LINE
+ // for potential divide by zero, On x86 GCC inserts `ud2` instruction
+ // instead of letting the HW/CPU trap it which leads to illegal instruction exception.
+ // 'volatile' should suppress this behavior and allow us to raise HW/CPU
+ // arithmetic exception.
+ m = sh1 = sh2 = 1 / ((npy_uint8 volatile *)&d)[0];
+ break;
+ case 1:
+ m = 1; sh1 = sh2 = 0;
+ break;
+ case 2:
+ m = 1; sh1 = 1; sh2 = 0;
+ break;
+ default:
+ l = npyv__bitscan_revnz_u32(d - 1) + 1; // ceil(log2(d))
+ l2 = (npy_uint8)(1 << l); // 2^l, overflow to 0 if l = 8
+ m = ((l2 - d) << 8) / d + 1; // multiplier
+ sh1 = 1; sh2 = l - 1; // shift counts
+ }
+ npyv_u8x3 divisor;
+#ifdef NPY_HAVE_SSE2 // SSE/AVX2/AVX512
+ divisor.val[0] = npyv_setall_u16(m);
+ divisor.val[1] = npyv_set_u8(sh1);
+ divisor.val[2] = npyv_set_u8(sh2);
+#elif defined(NPY_HAVE_VSX2)
+ divisor.val[0] = npyv_setall_u8(m);
+ divisor.val[1] = npyv_setall_u8(sh1);
+ divisor.val[2] = npyv_setall_u8(sh2);
+#elif defined(NPY_HAVE_NEON)
+ divisor.val[0] = npyv_setall_u8(m);
+ divisor.val[1] = npyv_reinterpret_u8_s8(npyv_setall_s8(-sh1));
+ divisor.val[2] = npyv_reinterpret_u8_s8(npyv_setall_s8(-sh2));
+#else
+ #error "please initialize the shifting operand for the new architecture"
+#endif
+ return divisor;
+}
+// Initializing divisor parameters for signed 8-bit division
+NPY_FINLINE npyv_s16x3 npyv_divisor_s16(npy_int16 d);
+NPY_FINLINE npyv_s8x3 npyv_divisor_s8(npy_int8 d)
+{
+#ifdef NPY_HAVE_SSE2 // SSE/AVX2/AVX512
+ npyv_s16x3 p = npyv_divisor_s16(d);
+ npyv_s8x3 r;
+ r.val[0] = npyv_reinterpret_s8_s16(p.val[0]);
+ r.val[1] = npyv_reinterpret_s8_s16(p.val[1]);
+ r.val[2] = npyv_reinterpret_s8_s16(p.val[2]);
+ return r;
+#else
+ int d1 = abs(d);
+ int sh, m;
+ if (d1 > 1) {
+ sh = (int)npyv__bitscan_revnz_u32(d1-1); // ceil(log2(abs(d))) - 1
+ m = (1 << (8 + sh)) / d1 + 1; // multiplier
+ }
+ else if (d1 == 1) {
+ sh = 0; m = 1;
+ }
+ else {
+ // raise arithmetic exception for d == 0
+ sh = m = 1 / ((npy_int8 volatile *)&d)[0]; // LCOV_EXCL_LINE
+ }
+ npyv_s8x3 divisor;
+ divisor.val[0] = npyv_setall_s8(m);
+ divisor.val[2] = npyv_setall_s8(d < 0 ? -1 : 0);
+ #ifdef NPY_HAVE_VSX2
+ divisor.val[1] = npyv_setall_s8(sh);
+ #elif defined(NPY_HAVE_NEON)
+ divisor.val[1] = npyv_setall_s8(-sh);
+ #else
+ #error "please initialize the shifting operand for the new architecture"
+ #endif
+ return divisor;
+#endif
+}
+// Initializing divisor parameters for unsigned 16-bit division
+NPY_FINLINE npyv_u16x3 npyv_divisor_u16(npy_uint16 d)
+{
+ unsigned l, l2, sh1, sh2, m;
+ switch (d) {
+ case 0: // LCOV_EXCL_LINE
+ // raise arithmetic exception for d == 0
+ m = sh1 = sh2 = 1 / ((npy_uint16 volatile *)&d)[0];
+ break;
+ case 1:
+ m = 1; sh1 = sh2 = 0;
+ break;
+ case 2:
+ m = 1; sh1 = 1; sh2 = 0;
+ break;
+ default:
+ l = npyv__bitscan_revnz_u32(d - 1) + 1; // ceil(log2(d))
+ l2 = (npy_uint16)(1 << l); // 2^l, overflow to 0 if l = 16
+ m = ((l2 - d) << 16) / d + 1; // multiplier
+ sh1 = 1; sh2 = l - 1; // shift counts
+ }
+ npyv_u16x3 divisor;
+ divisor.val[0] = npyv_setall_u16(m);
+#ifdef NPY_HAVE_SSE2 // SSE/AVX2/AVX512
+ divisor.val[1] = npyv_set_u16(sh1);
+ divisor.val[2] = npyv_set_u16(sh2);
+#elif defined(NPY_HAVE_VSX2)
+ divisor.val[1] = npyv_setall_u16(sh1);
+ divisor.val[2] = npyv_setall_u16(sh2);
+#elif defined(NPY_HAVE_NEON)
+ divisor.val[1] = npyv_reinterpret_u16_s16(npyv_setall_s16(-sh1));
+ divisor.val[2] = npyv_reinterpret_u16_s16(npyv_setall_s16(-sh2));
+#else
+ #error "please initialize the shifting operand for the new architecture"
+#endif
+ return divisor;
+}
+// Initializing divisor parameters for signed 16-bit division
+NPY_FINLINE npyv_s16x3 npyv_divisor_s16(npy_int16 d)
+{
+ int d1 = abs(d);
+ int sh, m;
+ if (d1 > 1) {
+ sh = (int)npyv__bitscan_revnz_u32(d1 - 1); // ceil(log2(abs(d))) - 1
+ m = (1 << (16 + sh)) / d1 + 1; // multiplier
+ }
+ else if (d1 == 1) {
+ sh = 0; m = 1;
+ }
+ else {
+ // raise arithmetic exception for d == 0
+ sh = m = 1 / ((npy_int16 volatile *)&d)[0]; // LCOV_EXCL_LINE
+ }
+ npyv_s16x3 divisor;
+ divisor.val[0] = npyv_setall_s16(m);
+ divisor.val[2] = npyv_setall_s16(d < 0 ? -1 : 0); // sign of divisor
+#ifdef NPY_HAVE_SSE2 // SSE/AVX2/AVX512
+ divisor.val[1] = npyv_set_s16(sh);
+#elif defined(NPY_HAVE_VSX2)
+ divisor.val[1] = npyv_setall_s16(sh);
+#elif defined(NPY_HAVE_NEON)
+ divisor.val[1] = npyv_setall_s16(-sh);
+#else
+ #error "please initialize the shifting operand for the new architecture"
+#endif
+ return divisor;
+}
+// Initializing divisor parameters for unsigned 32-bit division
+NPY_FINLINE npyv_u32x3 npyv_divisor_u32(npy_uint32 d)
+{
+ npy_uint32 l, l2, sh1, sh2, m;
+ switch (d) {
+ case 0: // LCOV_EXCL_LINE
+ // raise arithmetic exception for d == 0
+ m = sh1 = sh2 = 1 / ((npy_uint32 volatile *)&d)[0]; // LCOV_EXCL_LINE
+ break;
+ case 1:
+ m = 1; sh1 = sh2 = 0;
+ break;
+ case 2:
+ m = 1; sh1 = 1; sh2 = 0;
+ break;
+ default:
+ l = npyv__bitscan_revnz_u32(d - 1) + 1; // ceil(log2(d))
+ l2 = (npy_uint32)(1ULL << l); // 2^l, overflow to 0 if l = 32
+ m = ((npy_uint64)(l2 - d) << 32) / d + 1; // multiplier
+ sh1 = 1; sh2 = l - 1; // shift counts
+ }
+ npyv_u32x3 divisor;
+ divisor.val[0] = npyv_setall_u32(m);
+#ifdef NPY_HAVE_SSE2 // SSE/AVX2/AVX512
+ divisor.val[1] = npyv_set_u32(sh1);
+ divisor.val[2] = npyv_set_u32(sh2);
+#elif defined(NPY_HAVE_VSX2)
+ divisor.val[1] = npyv_setall_u32(sh1);
+ divisor.val[2] = npyv_setall_u32(sh2);
+#elif defined(NPY_HAVE_NEON)
+ divisor.val[1] = npyv_reinterpret_u32_s32(npyv_setall_s32(-sh1));
+ divisor.val[2] = npyv_reinterpret_u32_s32(npyv_setall_s32(-sh2));
+#else
+ #error "please initialize the shifting operand for the new architecture"
+#endif
+ return divisor;
+}
+// Initializing divisor parameters for signed 32-bit division
+NPY_FINLINE npyv_s32x3 npyv_divisor_s32(npy_int32 d)
+{
+ npy_int32 d1 = abs(d);
+ npy_int32 sh, m;
+ // Handel abs overflow
+ if ((npy_uint32)d == 0x80000000U) {
+ m = 0x80000001;
+ sh = 30;
+ }
+ else if (d1 > 1) {
+ sh = npyv__bitscan_revnz_u32(d1 - 1); // ceil(log2(abs(d))) - 1
+ m = (1ULL << (32 + sh)) / d1 + 1; // multiplier
+ }
+ else if (d1 == 1) {
+ sh = 0; m = 1;
+ }
+ else {
+ // raise arithmetic exception for d == 0
+ sh = m = 1 / ((npy_int32 volatile *)&d)[0]; // LCOV_EXCL_LINE
+ }
+ npyv_s32x3 divisor;
+ divisor.val[0] = npyv_setall_s32(m);
+ divisor.val[2] = npyv_setall_s32(d < 0 ? -1 : 0); // sign of divisor
+#ifdef NPY_HAVE_SSE2 // SSE/AVX2/AVX512
+ divisor.val[1] = npyv_set_s32(sh);
+#elif defined(NPY_HAVE_VSX2)
+ divisor.val[1] = npyv_setall_s32(sh);
+#elif defined(NPY_HAVE_NEON)
+ divisor.val[1] = npyv_setall_s32(-sh);
+#else
+ #error "please initialize the shifting operand for the new architecture"
+#endif
+ return divisor;
+}
+// Initializing divisor parameters for unsigned 64-bit division
+NPY_FINLINE npyv_u64x3 npyv_divisor_u64(npy_uint64 d)
+{
+ npyv_u64x3 divisor;
+#if defined(NPY_HAVE_VSX2) || defined(NPY_HAVE_NEON)
+ divisor.val[0] = npyv_setall_u64(d);
+#else
+ npy_uint64 l, l2, sh1, sh2, m;
+ switch (d) {
+ case 0: // LCOV_EXCL_LINE
+ // raise arithmetic exception for d == 0
+ m = sh1 = sh2 = 1 / ((npy_uint64 volatile *)&d)[0]; // LCOV_EXCL_LINE
+ break;
+ case 1:
+ m = 1; sh1 = sh2 = 0;
+ break;
+ case 2:
+ m = 1; sh1 = 1; sh2 = 0;
+ break;
+ default:
+ l = npyv__bitscan_revnz_u64(d - 1) + 1; // ceil(log2(d))
+ l2 = l < 64 ? 1ULL << l : 0; // 2^l
+ m = npyv__divh128_u64(l2 - d, d) + 1; // multiplier
+ sh1 = 1; sh2 = l - 1; // shift counts
+ }
+ divisor.val[0] = npyv_setall_u64(m);
+ #ifdef NPY_HAVE_SSE2 // SSE/AVX2/AVX512
+ divisor.val[1] = npyv_set_u64(sh1);
+ divisor.val[2] = npyv_set_u64(sh2);
+ #else
+ #error "please initialize the shifting operand for the new architecture"
+ #endif
+#endif
+ return divisor;
+}
+// Initializing divisor parameters for signed 64-bit division
+NPY_FINLINE npyv_s64x3 npyv_divisor_s64(npy_int64 d)
+{
+ npyv_s64x3 divisor;
+#if defined(NPY_HAVE_VSX2) || defined(NPY_HAVE_NEON)
+ divisor.val[0] = npyv_setall_s64(d);
+ divisor.val[1] = npyv_cvt_s64_b64(
+ npyv_cmpeq_s64(npyv_setall_s64(-1), divisor.val[0])
+ );
+#else
+ npy_int64 d1 = llabs(d);
+ npy_int64 sh, m;
+ // Handel abs overflow
+ if ((npy_uint64)d == 0x8000000000000000ULL) {
+ m = 0x8000000000000001LL;
+ sh = 62;
+ }
+ else if (d1 > 1) {
+ sh = npyv__bitscan_revnz_u64(d1 - 1); // ceil(log2(abs(d))) - 1
+ m = npyv__divh128_u64(1ULL << sh, d1) + 1; // multiplier
+ }
+ else if (d1 == 1) {
+ sh = 0; m = 1;
+ }
+ else {
+ // raise arithmetic exception for d == 0
+ sh = m = 1 / ((npy_int64 volatile *)&d)[0]; // LCOV_EXCL_LINE
+ }
+ divisor.val[0] = npyv_setall_s64(m);
+ divisor.val[2] = npyv_setall_s64(d < 0 ? -1 : 0); // sign of divisor
+ #ifdef NPY_HAVE_SSE2 // SSE/AVX2/AVX512
+ divisor.val[1] = npyv_set_s64(sh);
+ #else
+ #error "please initialize the shifting operand for the new architecture"
+ #endif
+#endif
+ return divisor;
+}
+
+#endif // _NPY_SIMD_INTDIV_H
diff --git a/numpy/core/src/common/simd/neon/arithmetic.h b/numpy/core/src/common/simd/neon/arithmetic.h
index 87e00d5d1..00994806d 100644
--- a/numpy/core/src/common/simd/neon/arithmetic.h
+++ b/numpy/core/src/common/simd/neon/arithmetic.h
@@ -61,6 +61,154 @@
#define npyv_mul_f64 vmulq_f64
/***************************
+ * Integer Division
+ ***************************/
+// See simd/intdiv.h for more clarification
+// divide each unsigned 8-bit element by a precomputed divisor
+NPY_FINLINE npyv_u8 npyv_divc_u8(npyv_u8 a, const npyv_u8x3 divisor)
+{
+ const uint8x8_t mulc_lo = vget_low_u8(divisor.val[0]);
+ // high part of unsigned multiplication
+ uint16x8_t mull_lo = vmull_u8(vget_low_u8(a), mulc_lo);
+#if NPY_SIMD_F64
+ uint16x8_t mull_hi = vmull_high_u8(a, divisor.val[0]);
+ // get the high unsigned bytes
+ uint8x16_t mulhi = vuzp2q_u8(vreinterpretq_u8_u16(mull_lo), vreinterpretq_u8_u16(mull_hi));
+#else
+ const uint8x8_t mulc_hi = vget_high_u8(divisor.val[0]);
+ uint16x8_t mull_hi = vmull_u8(vget_high_u8(a), mulc_hi);
+ uint8x16_t mulhi = vuzpq_u8(vreinterpretq_u8_u16(mull_lo), vreinterpretq_u8_u16(mull_hi)).val[1];
+#endif
+ // floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
+ uint8x16_t q = vsubq_u8(a, mulhi);
+ q = vshlq_u8(q, vreinterpretq_s8_u8(divisor.val[1]));
+ q = vaddq_u8(mulhi, q);
+ q = vshlq_u8(q, vreinterpretq_s8_u8(divisor.val[2]));
+ return q;
+}
+// divide each signed 8-bit element by a precomputed divisor (round towards zero)
+NPY_FINLINE npyv_s8 npyv_divc_s8(npyv_s8 a, const npyv_s8x3 divisor)
+{
+ const int8x8_t mulc_lo = vget_low_s8(divisor.val[0]);
+ // high part of signed multiplication
+ int16x8_t mull_lo = vmull_s8(vget_low_s8(a), mulc_lo);
+#if NPY_SIMD_F64
+ int16x8_t mull_hi = vmull_high_s8(a, divisor.val[0]);
+ // get the high unsigned bytes
+ int8x16_t mulhi = vuzp2q_s8(vreinterpretq_s8_s16(mull_lo), vreinterpretq_s8_s16(mull_hi));
+#else
+ const int8x8_t mulc_hi = vget_high_s8(divisor.val[0]);
+ int16x8_t mull_hi = vmull_s8(vget_high_s8(a), mulc_hi);
+ int8x16_t mulhi = vuzpq_s8(vreinterpretq_s8_s16(mull_lo), vreinterpretq_s8_s16(mull_hi)).val[1];
+#endif
+ // q = ((a + mulhi) >> sh1) - XSIGN(a)
+ // trunc(a/d) = (q ^ dsign) - dsign
+ int8x16_t q = vshlq_s8(vaddq_s8(a, mulhi), divisor.val[1]);
+ q = vsubq_s8(q, vshrq_n_s8(a, 7));
+ q = vsubq_s8(veorq_s8(q, divisor.val[2]), divisor.val[2]);
+ return q;
+}
+// divide each unsigned 16-bit element by a precomputed divisor
+NPY_FINLINE npyv_u16 npyv_divc_u16(npyv_u16 a, const npyv_u16x3 divisor)
+{
+ const uint16x4_t mulc_lo = vget_low_u16(divisor.val[0]);
+ // high part of unsigned multiplication
+ uint32x4_t mull_lo = vmull_u16(vget_low_u16(a), mulc_lo);
+#if NPY_SIMD_F64
+ uint32x4_t mull_hi = vmull_high_u16(a, divisor.val[0]);
+ // get the high unsigned bytes
+ uint16x8_t mulhi = vuzp2q_u16(vreinterpretq_u16_u32(mull_lo), vreinterpretq_u16_u32(mull_hi));
+#else
+ const uint16x4_t mulc_hi = vget_high_u16(divisor.val[0]);
+ uint32x4_t mull_hi = vmull_u16(vget_high_u16(a), mulc_hi);
+ uint16x8_t mulhi = vuzpq_u16(vreinterpretq_u16_u32(mull_lo), vreinterpretq_u16_u32(mull_hi)).val[1];
+#endif
+ // floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
+ uint16x8_t q = vsubq_u16(a, mulhi);
+ q = vshlq_u16(q, vreinterpretq_s16_u16(divisor.val[1]));
+ q = vaddq_u16(mulhi, q);
+ q = vshlq_u16(q, vreinterpretq_s16_u16(divisor.val[2]));
+ return q;
+}
+// divide each signed 16-bit element by a precomputed divisor (round towards zero)
+NPY_FINLINE npyv_s16 npyv_divc_s16(npyv_s16 a, const npyv_s16x3 divisor)
+{
+ const int16x4_t mulc_lo = vget_low_s16(divisor.val[0]);
+ // high part of signed multiplication
+ int32x4_t mull_lo = vmull_s16(vget_low_s16(a), mulc_lo);
+#if NPY_SIMD_F64
+ int32x4_t mull_hi = vmull_high_s16(a, divisor.val[0]);
+ // get the high unsigned bytes
+ int16x8_t mulhi = vuzp2q_s16(vreinterpretq_s16_s32(mull_lo), vreinterpretq_s16_s32(mull_hi));
+#else
+ const int16x4_t mulc_hi = vget_high_s16(divisor.val[0]);
+ int32x4_t mull_hi = vmull_s16(vget_high_s16(a), mulc_hi);
+ int16x8_t mulhi = vuzpq_s16(vreinterpretq_s16_s32(mull_lo), vreinterpretq_s16_s32(mull_hi)).val[1];
+#endif
+ // q = ((a + mulhi) >> sh1) - XSIGN(a)
+ // trunc(a/d) = (q ^ dsign) - dsign
+ int16x8_t q = vshlq_s16(vaddq_s16(a, mulhi), divisor.val[1]);
+ q = vsubq_s16(q, vshrq_n_s16(a, 15));
+ q = vsubq_s16(veorq_s16(q, divisor.val[2]), divisor.val[2]);
+ return q;
+}
+// divide each unsigned 32-bit element by a precomputed divisor
+NPY_FINLINE npyv_u32 npyv_divc_u32(npyv_u32 a, const npyv_u32x3 divisor)
+{
+ const uint32x2_t mulc_lo = vget_low_u32(divisor.val[0]);
+ // high part of unsigned multiplication
+ uint64x2_t mull_lo = vmull_u32(vget_low_u32(a), mulc_lo);
+#if NPY_SIMD_F64
+ uint64x2_t mull_hi = vmull_high_u32(a, divisor.val[0]);
+ // get the high unsigned bytes
+ uint32x4_t mulhi = vuzp2q_u32(vreinterpretq_u32_u64(mull_lo), vreinterpretq_u32_u64(mull_hi));
+#else
+ const uint32x2_t mulc_hi = vget_high_u32(divisor.val[0]);
+ uint64x2_t mull_hi = vmull_u32(vget_high_u32(a), mulc_hi);
+ uint32x4_t mulhi = vuzpq_u32(vreinterpretq_u32_u64(mull_lo), vreinterpretq_u32_u64(mull_hi)).val[1];
+#endif
+ // floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
+ uint32x4_t q = vsubq_u32(a, mulhi);
+ q = vshlq_u32(q, vreinterpretq_s32_u32(divisor.val[1]));
+ q = vaddq_u32(mulhi, q);
+ q = vshlq_u32(q, vreinterpretq_s32_u32(divisor.val[2]));
+ return q;
+}
+// divide each signed 32-bit element by a precomputed divisor (round towards zero)
+NPY_FINLINE npyv_s32 npyv_divc_s32(npyv_s32 a, const npyv_s32x3 divisor)
+{
+ const int32x2_t mulc_lo = vget_low_s32(divisor.val[0]);
+ // high part of signed multiplication
+ int64x2_t mull_lo = vmull_s32(vget_low_s32(a), mulc_lo);
+#if NPY_SIMD_F64
+ int64x2_t mull_hi = vmull_high_s32(a, divisor.val[0]);
+ // get the high unsigned bytes
+ int32x4_t mulhi = vuzp2q_s32(vreinterpretq_s32_s64(mull_lo), vreinterpretq_s32_s64(mull_hi));
+#else
+ const int32x2_t mulc_hi = vget_high_s32(divisor.val[0]);
+ int64x2_t mull_hi = vmull_s32(vget_high_s32(a), mulc_hi);
+ int32x4_t mulhi = vuzpq_s32(vreinterpretq_s32_s64(mull_lo), vreinterpretq_s32_s64(mull_hi)).val[1];
+#endif
+ // q = ((a + mulhi) >> sh1) - XSIGN(a)
+ // trunc(a/d) = (q ^ dsign) - dsign
+ int32x4_t q = vshlq_s32(vaddq_s32(a, mulhi), divisor.val[1]);
+ q = vsubq_s32(q, vshrq_n_s32(a, 31));
+ q = vsubq_s32(veorq_s32(q, divisor.val[2]), divisor.val[2]);
+ return q;
+}
+// divide each unsigned 64-bit element by a divisor
+NPY_FINLINE npyv_u64 npyv_divc_u64(npyv_u64 a, const npyv_u64x3 divisor)
+{
+ const uint64_t d = vgetq_lane_u64(divisor.val[0], 0);
+ return npyv_set_u64(vgetq_lane_u64(a, 0) / d, vgetq_lane_u64(a, 1) / d);
+}
+// returns the high 64 bits of signed 64-bit multiplication
+NPY_FINLINE npyv_s64 npyv_divc_s64(npyv_s64 a, const npyv_s64x3 divisor)
+{
+ const int64_t d = vgetq_lane_s64(divisor.val[0], 0);
+ return npyv_set_s64(vgetq_lane_s64(a, 0) / d, vgetq_lane_s64(a, 1) / d);
+}
+/***************************
* Division
***************************/
#if NPY_SIMD_F64
@@ -131,11 +279,27 @@
{ return vfmsq_f64(vnegq_f64(c), a, b); }
#endif // NPY_SIMD_F64
-// Horizontal add: Calculates the sum of all vector elements.
+/***************************
+ * Summation
+ ***************************/
+// reduce sum across vector
#if NPY_SIMD_F64
+ #define npyv_sum_u32 vaddvq_u32
+ #define npyv_sum_u64 vaddvq_u64
#define npyv_sum_f32 vaddvq_f32
#define npyv_sum_f64 vaddvq_f64
#else
+ NPY_FINLINE npy_uint64 npyv_sum_u64(npyv_u64 a)
+ {
+ return vget_lane_u64(vadd_u64(vget_low_u64(a), vget_high_u64(a)),0);
+ }
+
+ NPY_FINLINE npy_uint32 npyv_sum_u32(npyv_u32 a)
+ {
+ uint32x2_t a0 = vpadd_u32(vget_low_u32(a), vget_high_u32(a));
+ return (unsigned)vget_lane_u32(vpadd_u32(a0, vget_high_u32(a)),0);
+ }
+
NPY_FINLINE float npyv_sum_f32(npyv_f32 a)
{
float32x2_t r = vadd_f32(vget_high_f32(a), vget_low_f32(a));
@@ -143,4 +307,24 @@
}
#endif
+// expand the source vector and performs sum reduce
+#if NPY_SIMD_F64
+ #define npyv_sumup_u8 vaddlvq_u8
+ #define npyv_sumup_u16 vaddlvq_u16
+#else
+ NPY_FINLINE npy_uint16 npyv_sumup_u8(npyv_u8 a)
+ {
+ uint32x4_t t0 = vpaddlq_u16(vpaddlq_u8(a));
+ uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0));
+ return vget_lane_u32(vpadd_u32(t1, t1), 0);
+ }
+
+ NPY_FINLINE npy_uint32 npyv_sumup_u16(npyv_u16 a)
+ {
+ uint32x4_t t0 = vpaddlq_u16(a);
+ uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0));
+ return vget_lane_u32(vpadd_u32(t1, t1), 0);
+ }
+#endif
+
#endif // _NPY_SIMD_NEON_ARITHMETIC_H
diff --git a/numpy/core/src/common/simd/neon/conversion.h b/numpy/core/src/common/simd/neon/conversion.h
index b286931d1..7487559d1 100644
--- a/numpy/core/src/common/simd/neon/conversion.h
+++ b/numpy/core/src/common/simd/neon/conversion.h
@@ -7,26 +7,103 @@
// convert boolean vectors to integer vectors
#define npyv_cvt_u8_b8(A) A
-#define npyv_cvt_s8_b8(A) vreinterpretq_s8_u8(A)
+#define npyv_cvt_s8_b8 vreinterpretq_s8_u8
#define npyv_cvt_u16_b16(A) A
-#define npyv_cvt_s16_b16(A) vreinterpretq_s16_u16(A)
+#define npyv_cvt_s16_b16 vreinterpretq_s16_u16
#define npyv_cvt_u32_b32(A) A
-#define npyv_cvt_s32_b32(A) vreinterpretq_s32_u32(A)
+#define npyv_cvt_s32_b32 vreinterpretq_s32_u32
#define npyv_cvt_u64_b64(A) A
-#define npyv_cvt_s64_b64(A) vreinterpretq_s64_u64(A)
-#define npyv_cvt_f32_b32(A) vreinterpretq_f32_u32(A)
-#define npyv_cvt_f64_b64(A) vreinterpretq_f64_u64(A)
+#define npyv_cvt_s64_b64 vreinterpretq_s64_u64
+#define npyv_cvt_f32_b32 vreinterpretq_f32_u32
+#define npyv_cvt_f64_b64 vreinterpretq_f64_u64
// convert integer vectors to boolean vectors
#define npyv_cvt_b8_u8(BL) BL
-#define npyv_cvt_b8_s8(BL) vreinterpretq_u8_s8(BL)
+#define npyv_cvt_b8_s8 vreinterpretq_u8_s8
#define npyv_cvt_b16_u16(BL) BL
-#define npyv_cvt_b16_s16(BL) vreinterpretq_u16_s16(BL)
+#define npyv_cvt_b16_s16 vreinterpretq_u16_s16
#define npyv_cvt_b32_u32(BL) BL
-#define npyv_cvt_b32_s32(BL) vreinterpretq_u32_s32(BL)
+#define npyv_cvt_b32_s32 vreinterpretq_u32_s32
#define npyv_cvt_b64_u64(BL) BL
-#define npyv_cvt_b64_s64(BL) vreinterpretq_u64_s64(BL)
-#define npyv_cvt_b32_f32(BL) vreinterpretq_u32_f32(BL)
-#define npyv_cvt_b64_f64(BL) vreinterpretq_u64_f64(BL)
+#define npyv_cvt_b64_s64 vreinterpretq_u64_s64
+#define npyv_cvt_b32_f32 vreinterpretq_u32_f32
+#define npyv_cvt_b64_f64 vreinterpretq_u64_f64
+
+// convert boolean vector to integer bitfield
+NPY_FINLINE npy_uint64 npyv_tobits_b8(npyv_b8 a)
+{
+ const npyv_u8 scale = npyv_set_u8(1, 2, 4, 8, 16, 32, 64, 128, 1, 2, 4, 8, 16, 32, 64, 128);
+ npyv_u8 seq_scale = vandq_u8(a, scale);
+#if NPY_SIMD_F64
+ npy_uint8 sumlo = vaddv_u8(vget_low_u8(seq_scale));
+ npy_uint8 sumhi = vaddv_u8(vget_high_u8(seq_scale));
+ return sumlo + ((int)sumhi << 8);
+#else
+ npyv_u64 sumh = vpaddlq_u32(vpaddlq_u16(vpaddlq_u8(seq_scale)));
+ return vgetq_lane_u64(sumh, 0) + ((int)vgetq_lane_u64(sumh, 1) << 8);
+#endif
+}
+NPY_FINLINE npy_uint64 npyv_tobits_b16(npyv_b16 a)
+{
+ const npyv_u16 scale = npyv_set_u16(1, 2, 4, 8, 16, 32, 64, 128);
+ npyv_u16 seq_scale = vandq_u16(a, scale);
+#if NPY_SIMD_F64
+ return vaddvq_u16(seq_scale);
+#else
+ npyv_u64 sumh = vpaddlq_u32(vpaddlq_u16(seq_scale));
+ return vgetq_lane_u64(sumh, 0) + vgetq_lane_u64(sumh, 1);
+#endif
+}
+NPY_FINLINE npy_uint64 npyv_tobits_b32(npyv_b32 a)
+{
+ const npyv_u32 scale = npyv_set_u32(1, 2, 4, 8);
+ npyv_u32 seq_scale = vandq_u32(a, scale);
+#if NPY_SIMD_F64
+ return vaddvq_u32(seq_scale);
+#else
+ npyv_u64 sumh = vpaddlq_u32(seq_scale);
+ return vgetq_lane_u64(sumh, 0) + vgetq_lane_u64(sumh, 1);
+#endif
+}
+NPY_FINLINE npy_uint64 npyv_tobits_b64(npyv_b64 a)
+{
+ npyv_u64 bit = vshrq_n_u64(a, 63);
+ return vgetq_lane_u64(bit, 0) | ((int)vgetq_lane_u64(bit, 1) << 1);
+}
+
+//expand
+NPY_FINLINE npyv_u16x2 npyv_expand_u16_u8(npyv_u8 data) {
+ npyv_u16x2 r;
+ r.val[0] = vmovl_u8(vget_low_u8(data));
+ r.val[1] = vmovl_u8(vget_high_u8(data));
+ return r;
+}
+
+NPY_FINLINE npyv_u32x2 npyv_expand_u32_u16(npyv_u16 data) {
+ npyv_u32x2 r;
+ r.val[0] = vmovl_u16(vget_low_u16(data));
+ r.val[1] = vmovl_u16(vget_high_u16(data));
+ return r;
+}
+
+// round to nearest integer
+#if NPY_SIMD_F64
+ #define npyv_round_s32_f32 vcvtnq_s32_f32
+ NPY_FINLINE npyv_s32 npyv_round_s32_f64(npyv_f64 a, npyv_f64 b)
+ {
+ npyv_s64 lo = vcvtnq_s64_f64(a), hi = vcvtnq_s64_f64(b);
+ return vcombine_s32(vmovn_s64(lo), vmovn_s64(hi));
+ }
+#else
+ NPY_FINLINE npyv_s32 npyv_round_s32_f32(npyv_f32 a)
+ {
+ // halves will be rounded up. it's very costly
+ // to obey IEEE standard on arm7. tests should pass +-1 difference
+ const npyv_u32 sign = vdupq_n_u32(0x80000000);
+ const npyv_f32 half = vdupq_n_f32(0.5f);
+ npyv_f32 sign_half = vbslq_f32(sign, a, half);
+ return vcvtq_s32_f32(vaddq_f32(a, sign_half));
+ }
+#endif
#endif // _NPY_SIMD_NEON_CVT_H
diff --git a/numpy/core/src/common/simd/neon/math.h b/numpy/core/src/common/simd/neon/math.h
index a2bbdf2a5..ced82d1de 100644
--- a/numpy/core/src/common/simd/neon/math.h
+++ b/numpy/core/src/common/simd/neon/math.h
@@ -83,4 +83,74 @@ NPY_FINLINE npyv_f32 npyv_recip_f32(npyv_f32 a)
}
#endif // NPY_SIMD_F64
-#endif // _NPY_SIMD_SSE_MATH_H
+// Maximum, natively mapping with no guarantees to handle NaN.
+#define npyv_max_f32 vmaxq_f32
+#define npyv_max_f64 vmaxq_f64
+// Maximum, supports IEEE floating-point arithmetic (IEC 60559),
+// - If one of the two vectors contains NaN, the equivalent element of the other vector is set
+// - Only if both corresponded elements are NaN, NaN is set.
+#ifdef NPY_HAVE_ASIMD
+ #define npyv_maxp_f32 vmaxnmq_f32
+#else
+ NPY_FINLINE npyv_f32 npyv_maxp_f32(npyv_f32 a, npyv_f32 b)
+ {
+ npyv_u32 nn_a = vceqq_f32(a, a);
+ npyv_u32 nn_b = vceqq_f32(b, b);
+ return vmaxq_f32(vbslq_f32(nn_a, a, b), vbslq_f32(nn_b, b, a));
+ }
+#endif
+#if NPY_SIMD_F64
+ #define npyv_maxp_f64 vmaxnmq_f64
+#endif // NPY_SIMD_F64
+// Maximum, integer operations
+#define npyv_max_u8 vmaxq_u8
+#define npyv_max_s8 vmaxq_s8
+#define npyv_max_u16 vmaxq_u16
+#define npyv_max_s16 vmaxq_s16
+#define npyv_max_u32 vmaxq_u32
+#define npyv_max_s32 vmaxq_s32
+NPY_FINLINE npyv_u64 npyv_max_u64(npyv_u64 a, npyv_u64 b)
+{
+ return vbslq_u64(npyv_cmpgt_u64(a, b), a, b);
+}
+NPY_FINLINE npyv_s64 npyv_max_s64(npyv_s64 a, npyv_s64 b)
+{
+ return vbslq_s64(npyv_cmpgt_s64(a, b), a, b);
+}
+
+// Minimum, natively mapping with no guarantees to handle NaN.
+#define npyv_min_f32 vminq_f32
+#define npyv_min_f64 vminq_f64
+// Minimum, supports IEEE floating-point arithmetic (IEC 60559),
+// - If one of the two vectors contains NaN, the equivalent element of the other vector is set
+// - Only if both corresponded elements are NaN, NaN is set.
+#ifdef NPY_HAVE_ASIMD
+ #define npyv_minp_f32 vminnmq_f32
+#else
+ NPY_FINLINE npyv_f32 npyv_minp_f32(npyv_f32 a, npyv_f32 b)
+ {
+ npyv_u32 nn_a = vceqq_f32(a, a);
+ npyv_u32 nn_b = vceqq_f32(b, b);
+ return vminq_f32(vbslq_f32(nn_a, a, b), vbslq_f32(nn_b, b, a));
+ }
+#endif
+#if NPY_SIMD_F64
+ #define npyv_minp_f64 vminnmq_f64
+#endif // NPY_SIMD_F64
+// Minimum, integer operations
+#define npyv_min_u8 vminq_u8
+#define npyv_min_s8 vminq_s8
+#define npyv_min_u16 vminq_u16
+#define npyv_min_s16 vminq_s16
+#define npyv_min_u32 vminq_u32
+#define npyv_min_s32 vminq_s32
+NPY_FINLINE npyv_u64 npyv_min_u64(npyv_u64 a, npyv_u64 b)
+{
+ return vbslq_u64(npyv_cmplt_u64(a, b), a, b);
+}
+NPY_FINLINE npyv_s64 npyv_min_s64(npyv_s64 a, npyv_s64 b)
+{
+ return vbslq_s64(npyv_cmplt_s64(a, b), a, b);
+}
+
+#endif // _NPY_SIMD_NEON_MATH_H
diff --git a/numpy/core/src/common/simd/neon/neon.h b/numpy/core/src/common/simd/neon/neon.h
index c8ddc92ad..e6f6a7324 100644
--- a/numpy/core/src/common/simd/neon/neon.h
+++ b/numpy/core/src/common/simd/neon/neon.h
@@ -10,6 +10,11 @@
#else
#define NPY_SIMD_F64 0
#endif
+#ifdef NPY_HAVE_NEON_VFPV4
+ #define NPY_SIMD_FMA3 1 // native support
+#else
+ #define NPY_SIMD_FMA3 0 // HW emulated
+#endif
typedef uint8x16_t npyv_u8;
typedef int8x16_t npyv_s8;
diff --git a/numpy/core/src/common/simd/neon/operators.h b/numpy/core/src/common/simd/neon/operators.h
index c1ad4ba12..b43ba3653 100644
--- a/numpy/core/src/common/simd/neon/operators.h
+++ b/numpy/core/src/common/simd/neon/operators.h
@@ -34,12 +34,12 @@
#define npyv_shr_s64(A, C) vshlq_s64(A, npyv_setall_s64(-(C)))
// right by an immediate constant
-#define npyv_shri_u16(VEC, C) ((C) == 0 ? VEC : vshrq_n_u16(VEC, C))
-#define npyv_shri_s16(VEC, C) ((C) == 0 ? VEC : vshrq_n_s16(VEC, C))
-#define npyv_shri_u32(VEC, C) ((C) == 0 ? VEC : vshrq_n_u32(VEC, C))
-#define npyv_shri_s32(VEC, C) ((C) == 0 ? VEC : vshrq_n_s32(VEC, C))
-#define npyv_shri_u64(VEC, C) ((C) == 0 ? VEC : vshrq_n_u64(VEC, C))
-#define npyv_shri_s64(VEC, C) ((C) == 0 ? VEC : vshrq_n_s64(VEC, C))
+#define npyv_shri_u16 vshrq_n_u16
+#define npyv_shri_s16 vshrq_n_s16
+#define npyv_shri_u32 vshrq_n_u32
+#define npyv_shri_s32 vshrq_n_s32
+#define npyv_shri_u64 vshrq_n_u64
+#define npyv_shri_s64 vshrq_n_s64
/***************************
* Logical
@@ -58,6 +58,10 @@
vreinterpretq_f32_u8(vandq_u8(vreinterpretq_u8_f32(A), vreinterpretq_u8_f32(B)))
#define npyv_and_f64(A, B) \
vreinterpretq_f64_u8(vandq_u8(vreinterpretq_u8_f64(A), vreinterpretq_u8_f64(B)))
+#define npyv_and_b8 vandq_u8
+#define npyv_and_b16 vandq_u16
+#define npyv_and_b32 vandq_u32
+#define npyv_and_b64 vandq_u64
// OR
#define npyv_or_u8 vorrq_u8
@@ -72,6 +76,11 @@
vreinterpretq_f32_u8(vorrq_u8(vreinterpretq_u8_f32(A), vreinterpretq_u8_f32(B)))
#define npyv_or_f64(A, B) \
vreinterpretq_f64_u8(vorrq_u8(vreinterpretq_u8_f64(A), vreinterpretq_u8_f64(B)))
+#define npyv_or_b8 vorrq_u8
+#define npyv_or_b16 vorrq_u16
+#define npyv_or_b32 vorrq_u32
+#define npyv_or_b64 vorrq_u64
+
// XOR
#define npyv_xor_u8 veorq_u8
@@ -86,6 +95,10 @@
vreinterpretq_f32_u8(veorq_u8(vreinterpretq_u8_f32(A), vreinterpretq_u8_f32(B)))
#define npyv_xor_f64(A, B) \
vreinterpretq_f64_u8(veorq_u8(vreinterpretq_u8_f64(A), vreinterpretq_u8_f64(B)))
+#define npyv_xor_b8 veorq_u8
+#define npyv_xor_b16 veorq_u16
+#define npyv_xor_b32 veorq_u32
+#define npyv_xor_b64 veorq_u64
// NOT
#define npyv_not_u8 vmvnq_u8
@@ -98,6 +111,10 @@
#define npyv_not_s64(A) vreinterpretq_s64_u8(vmvnq_u8(vreinterpretq_u8_s64(A)))
#define npyv_not_f32(A) vreinterpretq_f32_u8(vmvnq_u8(vreinterpretq_u8_f32(A)))
#define npyv_not_f64(A) vreinterpretq_f64_u8(vmvnq_u8(vreinterpretq_u8_f64(A)))
+#define npyv_not_b8 vmvnq_u8
+#define npyv_not_b16 vmvnq_u16
+#define npyv_not_b32 vmvnq_u32
+#define npyv_not_b64 npyv_not_u64
/***************************
* Comparison
@@ -215,4 +232,12 @@
#define npyv_cmple_f32(A, B) npyv_cmpge_f32(B, A)
#define npyv_cmple_f64(A, B) npyv_cmpge_f64(B, A)
+// check special cases
+NPY_FINLINE npyv_b32 npyv_notnan_f32(npyv_f32 a)
+{ return vceqq_f32(a, a); }
+#if NPY_SIMD_F64
+ NPY_FINLINE npyv_b64 npyv_notnan_f64(npyv_f64 a)
+ { return vceqq_f64(a, a); }
+#endif
+
#endif // _NPY_SIMD_NEON_OPERATORS_H
diff --git a/numpy/core/src/common/simd/neon/reorder.h b/numpy/core/src/common/simd/neon/reorder.h
index 712a77982..50b06ed11 100644
--- a/numpy/core/src/common/simd/neon/reorder.h
+++ b/numpy/core/src/common/simd/neon/reorder.h
@@ -107,4 +107,13 @@ NPYV_IMPL_NEON_COMBINE(npyv_f64, f64)
#define npyv_zip_u64 npyv_combine_u64
#define npyv_zip_s64 npyv_combine_s64
+// Reverse elements of each 64-bit lane
+#define npyv_rev64_u8 vrev64q_u8
+#define npyv_rev64_s8 vrev64q_s8
+#define npyv_rev64_u16 vrev64q_u16
+#define npyv_rev64_s16 vrev64q_s16
+#define npyv_rev64_u32 vrev64q_u32
+#define npyv_rev64_s32 vrev64q_s32
+#define npyv_rev64_f32 vrev64q_f32
+
#endif // _NPY_SIMD_NEON_REORDER_H
diff --git a/numpy/core/src/common/simd/simd.h b/numpy/core/src/common/simd/simd.h
index 8804223c9..a3e2b95de 100644
--- a/numpy/core/src/common/simd/simd.h
+++ b/numpy/core/src/common/simd/simd.h
@@ -48,7 +48,19 @@ typedef double npyv_lanetype_f64;
#define NPY_SIMD 0
#define NPY_SIMD_WIDTH 0
#define NPY_SIMD_F64 0
+ #define NPY_SIMD_FMA3 0
#endif
+
+// enable emulated mask operations for all SIMD extension except for AVX512
+#if !defined(NPY_HAVE_AVX512F) && NPY_SIMD && NPY_SIMD < 512
+ #include "emulate_maskop.h"
+#endif
+
+// enable integer divisor generator for all SIMD extensions
+#if NPY_SIMD
+ #include "intdiv.h"
+#endif
+
/**
* Some SIMD extensions currently(AVX2, AVX512F) require (de facto)
* a maximum number of strides sizes when dealing with non-contiguous memory access.
diff --git a/numpy/core/src/common/simd/sse/arithmetic.h b/numpy/core/src/common/simd/sse/arithmetic.h
index 8440cc52e..bced35108 100644
--- a/numpy/core/src/common/simd/sse/arithmetic.h
+++ b/numpy/core/src/common/simd/sse/arithmetic.h
@@ -25,7 +25,7 @@
#define npyv_adds_s8 _mm_adds_epi8
#define npyv_adds_u16 _mm_adds_epu16
#define npyv_adds_s16 _mm_adds_epi16
-// TODO: rest, after implment Packs intrins
+// TODO: rest, after implement Packs intrins
/***************************
* Subtraction
@@ -47,7 +47,7 @@
#define npyv_subs_s8 _mm_subs_epi8
#define npyv_subs_u16 _mm_subs_epu16
#define npyv_subs_s16 _mm_subs_epi16
-// TODO: rest, after implment Packs intrins
+// TODO: rest, after implement Packs intrins
/***************************
* Multiplication
@@ -83,9 +83,184 @@ NPY_FINLINE __m128i npyv_mul_u8(__m128i a, __m128i b)
#define npyv_mul_f64 _mm_mul_pd
// saturated
-// TODO: after implment Packs intrins
+// TODO: after implement Packs intrins
/***************************
+ * Integer Division
+ ***************************/
+// See simd/intdiv.h for more clarification
+// divide each unsigned 8-bit element by a precomputed divisor
+NPY_FINLINE npyv_u8 npyv_divc_u8(npyv_u8 a, const npyv_u8x3 divisor)
+{
+ const __m128i bmask = _mm_set1_epi32(0x00FF00FF);
+ const __m128i shf1b = _mm_set1_epi8(0xFFU >> _mm_cvtsi128_si32(divisor.val[1]));
+ const __m128i shf2b = _mm_set1_epi8(0xFFU >> _mm_cvtsi128_si32(divisor.val[2]));
+ // high part of unsigned multiplication
+ __m128i mulhi_even = _mm_mullo_epi16(_mm_and_si128(a, bmask), divisor.val[0]);
+ __m128i mulhi_odd = _mm_mullo_epi16(_mm_srli_epi16(a, 8), divisor.val[0]);
+ mulhi_even = _mm_srli_epi16(mulhi_even, 8);
+ __m128i mulhi = npyv_select_u8(bmask, mulhi_even, mulhi_odd);
+ // floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
+ __m128i q = _mm_sub_epi8(a, mulhi);
+ q = _mm_and_si128(_mm_srl_epi16(q, divisor.val[1]), shf1b);
+ q = _mm_add_epi8(mulhi, q);
+ q = _mm_and_si128(_mm_srl_epi16(q, divisor.val[2]), shf2b);
+ return q;
+}
+// divide each signed 8-bit element by a precomputed divisor (round towards zero)
+NPY_FINLINE npyv_s16 npyv_divc_s16(npyv_s16 a, const npyv_s16x3 divisor);
+NPY_FINLINE npyv_s8 npyv_divc_s8(npyv_s8 a, const npyv_s8x3 divisor)
+{
+ const __m128i bmask = _mm_set1_epi32(0x00FF00FF);
+ // instead of _mm_cvtepi8_epi16/_mm_packs_epi16 to wrap around overflow
+ __m128i divc_even = npyv_divc_s16(_mm_srai_epi16(_mm_slli_epi16(a, 8), 8), divisor);
+ __m128i divc_odd = npyv_divc_s16(_mm_srai_epi16(a, 8), divisor);
+ divc_odd = _mm_slli_epi16(divc_odd, 8);
+ return npyv_select_u8(bmask, divc_even, divc_odd);
+}
+// divide each unsigned 16-bit element by a precomputed divisor
+NPY_FINLINE npyv_u16 npyv_divc_u16(npyv_u16 a, const npyv_u16x3 divisor)
+{
+ // high part of unsigned multiplication
+ __m128i mulhi = _mm_mulhi_epu16(a, divisor.val[0]);
+ // floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
+ __m128i q = _mm_sub_epi16(a, mulhi);
+ q = _mm_srl_epi16(q, divisor.val[1]);
+ q = _mm_add_epi16(mulhi, q);
+ q = _mm_srl_epi16(q, divisor.val[2]);
+ return q;
+}
+// divide each signed 16-bit element by a precomputed divisor (round towards zero)
+NPY_FINLINE npyv_s16 npyv_divc_s16(npyv_s16 a, const npyv_s16x3 divisor)
+{
+ // high part of signed multiplication
+ __m128i mulhi = _mm_mulhi_epi16(a, divisor.val[0]);
+ // q = ((a + mulhi) >> sh1) - XSIGN(a)
+ // trunc(a/d) = (q ^ dsign) - dsign
+ __m128i q = _mm_sra_epi16(_mm_add_epi16(a, mulhi), divisor.val[1]);
+ q = _mm_sub_epi16(q, _mm_srai_epi16(a, 15));
+ q = _mm_sub_epi16(_mm_xor_si128(q, divisor.val[2]), divisor.val[2]);
+ return q;
+}
+// divide each unsigned 32-bit element by a precomputed divisor
+NPY_FINLINE npyv_u32 npyv_divc_u32(npyv_u32 a, const npyv_u32x3 divisor)
+{
+ // high part of unsigned multiplication
+ __m128i mulhi_even = _mm_srli_epi64(_mm_mul_epu32(a, divisor.val[0]), 32);
+ __m128i mulhi_odd = _mm_mul_epu32(_mm_srli_epi64(a, 32), divisor.val[0]);
+#ifdef NPY_HAVE_SSE41
+ __m128i mulhi = _mm_blend_epi16(mulhi_even, mulhi_odd, 0xCC);
+#else
+ __m128i mask_13 = _mm_setr_epi32(0, -1, 0, -1);
+ mulhi_odd = _mm_and_si128(mulhi_odd, mask_13);
+ __m128i mulhi = _mm_or_si128(mulhi_even, mulhi_odd);
+#endif
+ // floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
+ __m128i q = _mm_sub_epi32(a, mulhi);
+ q = _mm_srl_epi32(q, divisor.val[1]);
+ q = _mm_add_epi32(mulhi, q);
+ q = _mm_srl_epi32(q, divisor.val[2]);
+ return q;
+}
+// divide each signed 32-bit element by a precomputed divisor (round towards zero)
+NPY_FINLINE npyv_s32 npyv_divc_s32(npyv_s32 a, const npyv_s32x3 divisor)
+{
+ __m128i asign = _mm_srai_epi32(a, 31);
+#ifdef NPY_HAVE_SSE41
+ // high part of signed multiplication
+ __m128i mulhi_even = _mm_srli_epi64(_mm_mul_epi32(a, divisor.val[0]), 32);
+ __m128i mulhi_odd = _mm_mul_epi32(_mm_srli_epi64(a, 32), divisor.val[0]);
+ __m128i mulhi = _mm_blend_epi16(mulhi_even, mulhi_odd, 0xCC);
+#else // not SSE4.1
+ // high part of "unsigned" multiplication
+ __m128i mulhi_even = _mm_srli_epi64(_mm_mul_epu32(a, divisor.val[0]), 32);
+ __m128i mulhi_odd = _mm_mul_epu32(_mm_srli_epi64(a, 32), divisor.val[0]);
+ __m128i mask_13 = _mm_setr_epi32(0, -1, 0, -1);
+ mulhi_odd = _mm_and_si128(mulhi_odd, mask_13);
+ __m128i mulhi = _mm_or_si128(mulhi_even, mulhi_odd);
+ // convert unsigned to signed high multiplication
+ // mulhi - ((a < 0) ? m : 0) - ((m < 0) ? a : 0);
+ const __m128i msign= _mm_srai_epi32(divisor.val[0], 31);
+ __m128i m_asign = _mm_and_si128(divisor.val[0], asign);
+ __m128i a_msign = _mm_and_si128(a, msign);
+ mulhi = _mm_sub_epi32(mulhi, m_asign);
+ mulhi = _mm_sub_epi32(mulhi, a_msign);
+#endif
+ // q = ((a + mulhi) >> sh1) - XSIGN(a)
+ // trunc(a/d) = (q ^ dsign) - dsign
+ __m128i q = _mm_sra_epi32(_mm_add_epi32(a, mulhi), divisor.val[1]);
+ q = _mm_sub_epi32(q, asign);
+ q = _mm_sub_epi32(_mm_xor_si128(q, divisor.val[2]), divisor.val[2]);
+ return q;
+}
+// returns the high 64 bits of unsigned 64-bit multiplication
+// xref https://stackoverflow.com/a/28827013
+NPY_FINLINE npyv_u64 npyv__mullhi_u64(npyv_u64 a, npyv_u64 b)
+{
+ __m128i lomask = npyv_setall_s64(0xffffffff);
+ __m128i a_hi = _mm_srli_epi64(a, 32); // a0l, a0h, a1l, a1h
+ __m128i b_hi = _mm_srli_epi64(b, 32); // b0l, b0h, b1l, b1h
+ // compute partial products
+ __m128i w0 = _mm_mul_epu32(a, b); // a0l*b0l, a1l*b1l
+ __m128i w1 = _mm_mul_epu32(a, b_hi); // a0l*b0h, a1l*b1h
+ __m128i w2 = _mm_mul_epu32(a_hi, b); // a0h*b0l, a1h*b0l
+ __m128i w3 = _mm_mul_epu32(a_hi, b_hi); // a0h*b0h, a1h*b1h
+ // sum partial products
+ __m128i w0h = _mm_srli_epi64(w0, 32);
+ __m128i s1 = _mm_add_epi64(w1, w0h);
+ __m128i s1l = _mm_and_si128(s1, lomask);
+ __m128i s1h = _mm_srli_epi64(s1, 32);
+
+ __m128i s2 = _mm_add_epi64(w2, s1l);
+ __m128i s2h = _mm_srli_epi64(s2, 32);
+
+ __m128i hi = _mm_add_epi64(w3, s1h);
+ hi = _mm_add_epi64(hi, s2h);
+ return hi;
+}
+// divide each unsigned 64-bit element by a precomputed divisor
+NPY_FINLINE npyv_u64 npyv_divc_u64(npyv_u64 a, const npyv_u64x3 divisor)
+{
+ // high part of unsigned multiplication
+ __m128i mulhi = npyv__mullhi_u64(a, divisor.val[0]);
+ // floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
+ __m128i q = _mm_sub_epi64(a, mulhi);
+ q = _mm_srl_epi64(q, divisor.val[1]);
+ q = _mm_add_epi64(mulhi, q);
+ q = _mm_srl_epi64(q, divisor.val[2]);
+ return q;
+}
+// divide each signed 64-bit element by a precomputed divisor (round towards zero)
+NPY_FINLINE npyv_s64 npyv_divc_s64(npyv_s64 a, const npyv_s64x3 divisor)
+{
+ // high part of unsigned multiplication
+ __m128i mulhi = npyv__mullhi_u64(a, divisor.val[0]);
+ // convert unsigned to signed high multiplication
+ // mulhi - ((a < 0) ? m : 0) - ((m < 0) ? a : 0);
+#ifdef NPY_HAVE_SSE42
+ const __m128i msign= _mm_cmpgt_epi64(_mm_setzero_si128(), divisor.val[0]);
+ __m128i asign = _mm_cmpgt_epi64(_mm_setzero_si128(), a);
+#else
+ const __m128i msign= _mm_srai_epi32(_mm_shuffle_epi32(divisor.val[0], _MM_SHUFFLE(3, 3, 1, 1)), 31);
+ __m128i asign = _mm_srai_epi32(_mm_shuffle_epi32(a, _MM_SHUFFLE(3, 3, 1, 1)), 31);
+#endif
+ __m128i m_asign = _mm_and_si128(divisor.val[0], asign);
+ __m128i a_msign = _mm_and_si128(a, msign);
+ mulhi = _mm_sub_epi64(mulhi, m_asign);
+ mulhi = _mm_sub_epi64(mulhi, a_msign);
+ // q = (a + mulhi) >> sh
+ __m128i q = _mm_add_epi64(a, mulhi);
+ // emulate arithmetic right shift
+ const __m128i sigb = npyv_setall_s64(1LL << 63);
+ q = _mm_srl_epi64(_mm_add_epi64(q, sigb), divisor.val[1]);
+ q = _mm_sub_epi64(q, _mm_srl_epi64(sigb, divisor.val[1]));
+ // q = q - XSIGN(a)
+ // trunc(a/d) = (q ^ dsign) - dsign
+ q = _mm_sub_epi64(q, asign);
+ q = _mm_sub_epi64(_mm_xor_si128(q, divisor.val[2]), divisor.val[2]);
+ return q;
+}
+/***************************
* Division
***************************/
// TODO: emulate integer division
@@ -148,8 +323,24 @@ NPY_FINLINE __m128i npyv_mul_u8(__m128i a, __m128i b)
}
#endif // !NPY_HAVE_FMA3
-// Horizontal add: Calculates the sum of all vector elements.
-NPY_FINLINE float npyv_sum_f32(__m128 a)
+/***************************
+ * Summation
+ ***************************/
+// reduce sum across vector
+NPY_FINLINE npy_uint32 npyv_sum_u32(npyv_u32 a)
+{
+ __m128i t = _mm_add_epi32(a, _mm_srli_si128(a, 8));
+ t = _mm_add_epi32(t, _mm_srli_si128(t, 4));
+ return (unsigned)_mm_cvtsi128_si32(t);
+}
+
+NPY_FINLINE npy_uint64 npyv_sum_u64(npyv_u64 a)
+{
+ __m128i one = _mm_add_epi64(a, _mm_unpackhi_epi64(a, a));
+ return (npy_uint64)npyv128_cvtsi128_si64(one);
+}
+
+NPY_FINLINE float npyv_sum_f32(npyv_f32 a)
{
#ifdef NPY_HAVE_SSE3
__m128 sum_halves = _mm_hadd_ps(a, a);
@@ -159,11 +350,11 @@ NPY_FINLINE float npyv_sum_f32(__m128 a)
__m128 t2 = _mm_add_ps(a, t1);
__m128 t3 = _mm_shuffle_ps(t2, t2, 1);
__m128 t4 = _mm_add_ss(t2, t3);
- return _mm_cvtss_f32(t4);
+ return _mm_cvtss_f32(t4);
#endif
}
-NPY_FINLINE double npyv_sum_f64(__m128d a)
+NPY_FINLINE double npyv_sum_f64(npyv_f64 a)
{
#ifdef NPY_HAVE_SSE3
return _mm_cvtsd_f64(_mm_hadd_pd(a, a));
@@ -172,6 +363,23 @@ NPY_FINLINE double npyv_sum_f64(__m128d a)
#endif
}
+// expand the source vector and performs sum reduce
+NPY_FINLINE npy_uint16 npyv_sumup_u8(npyv_u8 a)
+{
+ __m128i two = _mm_sad_epu8(a, _mm_setzero_si128());
+ __m128i one = _mm_add_epi16(two, _mm_unpackhi_epi64(two, two));
+ return (npy_uint16)_mm_cvtsi128_si32(one);
+}
+
+NPY_FINLINE npy_uint32 npyv_sumup_u16(npyv_u16 a)
+{
+ const __m128i even_mask = _mm_set1_epi32(0x0000FFFF);
+ __m128i even = _mm_and_si128(a, even_mask);
+ __m128i odd = _mm_srli_epi32(a, 16);
+ __m128i four = _mm_add_epi32(even, odd);
+ return npyv_sum_u32(four);
+}
+
#endif // _NPY_SIMD_SSE_ARITHMETIC_H
diff --git a/numpy/core/src/common/simd/sse/conversion.h b/numpy/core/src/common/simd/sse/conversion.h
index ea9660d13..ab7eb4907 100644
--- a/numpy/core/src/common/simd/sse/conversion.h
+++ b/numpy/core/src/common/simd/sse/conversion.h
@@ -14,8 +14,8 @@
#define npyv_cvt_s32_b32(BL) BL
#define npyv_cvt_u64_b64(BL) BL
#define npyv_cvt_s64_b64(BL) BL
-#define npyv_cvt_f32_b32(BL) _mm_castsi128_ps(BL)
-#define npyv_cvt_f64_b64(BL) _mm_castsi128_pd(BL)
+#define npyv_cvt_f32_b32 _mm_castsi128_ps
+#define npyv_cvt_f64_b64 _mm_castsi128_pd
// convert integer types to mask types
#define npyv_cvt_b8_u8(A) A
@@ -26,7 +26,45 @@
#define npyv_cvt_b32_s32(A) A
#define npyv_cvt_b64_u64(A) A
#define npyv_cvt_b64_s64(A) A
-#define npyv_cvt_b32_f32(A) _mm_castps_si128(A)
-#define npyv_cvt_b64_f64(A) _mm_castpd_si128(A)
+#define npyv_cvt_b32_f32 _mm_castps_si128
+#define npyv_cvt_b64_f64 _mm_castpd_si128
+
+// convert boolean vector to integer bitfield
+NPY_FINLINE npy_uint64 npyv_tobits_b8(npyv_b8 a)
+{ return (npy_uint16)_mm_movemask_epi8(a); }
+NPY_FINLINE npy_uint64 npyv_tobits_b16(npyv_b16 a)
+{
+ __m128i pack = _mm_packs_epi16(a, a);
+ return (npy_uint8)_mm_movemask_epi8(pack);
+}
+NPY_FINLINE npy_uint64 npyv_tobits_b32(npyv_b32 a)
+{ return (npy_uint8)_mm_movemask_ps(_mm_castsi128_ps(a)); }
+NPY_FINLINE npy_uint64 npyv_tobits_b64(npyv_b64 a)
+{ return (npy_uint8)_mm_movemask_pd(_mm_castsi128_pd(a)); }
+
+// expand
+NPY_FINLINE npyv_u16x2 npyv_expand_u16_u8(npyv_u8 data) {
+ npyv_u16x2 r;
+ const __m128i z = _mm_setzero_si128();
+ r.val[0] = _mm_unpacklo_epi8(data, z);
+ r.val[1] = _mm_unpackhi_epi8(data, z);
+ return r;
+}
+
+NPY_FINLINE npyv_u32x2 npyv_expand_u32_u16(npyv_u16 data) {
+ npyv_u32x2 r;
+ const __m128i z = _mm_setzero_si128();
+ r.val[0] = _mm_unpacklo_epi16(data, z);
+ r.val[1] = _mm_unpackhi_epi16(data, z);
+ return r;
+}
+
+// round to nearest integer (assuming even)
+#define npyv_round_s32_f32 _mm_cvtps_epi32
+NPY_FINLINE npyv_s32 npyv_round_s32_f64(npyv_f64 a, npyv_f64 b)
+{
+ __m128i lo = _mm_cvtpd_epi32(a), hi = _mm_cvtpd_epi32(b);
+ return _mm_unpacklo_epi64(lo, hi);
+}
#endif // _NPY_SIMD_SSE_CVT_H
diff --git a/numpy/core/src/common/simd/sse/math.h b/numpy/core/src/common/simd/sse/math.h
index b7203cd89..97d35afc5 100644
--- a/numpy/core/src/common/simd/sse/math.h
+++ b/numpy/core/src/common/simd/sse/math.h
@@ -37,4 +37,110 @@ NPY_FINLINE npyv_f32 npyv_square_f32(npyv_f32 a)
NPY_FINLINE npyv_f64 npyv_square_f64(npyv_f64 a)
{ return _mm_mul_pd(a, a); }
+// Maximum, natively mapping with no guarantees to handle NaN.
+#define npyv_max_f32 _mm_max_ps
+#define npyv_max_f64 _mm_max_pd
+// Maximum, supports IEEE floating-point arithmetic (IEC 60559),
+// - If one of the two vectors contains NaN, the equivalent element of the other vector is set
+// - Only if both corresponded elements are NaN, NaN is set.
+NPY_FINLINE npyv_f32 npyv_maxp_f32(npyv_f32 a, npyv_f32 b)
+{
+ __m128 nn = _mm_cmpord_ps(b, b);
+ __m128 max = _mm_max_ps(a, b);
+ return npyv_select_f32(_mm_castps_si128(nn), max, a);
+}
+NPY_FINLINE npyv_f64 npyv_maxp_f64(npyv_f64 a, npyv_f64 b)
+{
+ __m128d nn = _mm_cmpord_pd(b, b);
+ __m128d max = _mm_max_pd(a, b);
+ return npyv_select_f64(_mm_castpd_si128(nn), max, a);
+}
+// Maximum, integer operations
+#ifdef NPY_HAVE_SSE41
+ #define npyv_max_s8 _mm_max_epi8
+ #define npyv_max_u16 _mm_max_epu16
+ #define npyv_max_u32 _mm_max_epu32
+ #define npyv_max_s32 _mm_max_epi32
+#else
+ NPY_FINLINE npyv_s8 npyv_max_s8(npyv_s8 a, npyv_s8 b)
+ {
+ return npyv_select_s8(npyv_cmpgt_s8(a, b), a, b);
+ }
+ NPY_FINLINE npyv_u16 npyv_max_u16(npyv_u16 a, npyv_u16 b)
+ {
+ return npyv_select_u16(npyv_cmpgt_u16(a, b), a, b);
+ }
+ NPY_FINLINE npyv_u32 npyv_max_u32(npyv_u32 a, npyv_u32 b)
+ {
+ return npyv_select_u32(npyv_cmpgt_u32(a, b), a, b);
+ }
+ NPY_FINLINE npyv_s32 npyv_max_s32(npyv_s32 a, npyv_s32 b)
+ {
+ return npyv_select_s32(npyv_cmpgt_s32(a, b), a, b);
+ }
#endif
+#define npyv_max_u8 _mm_max_epu8
+#define npyv_max_s16 _mm_max_epi16
+NPY_FINLINE npyv_u64 npyv_max_u64(npyv_u64 a, npyv_u64 b)
+{
+ return npyv_select_u64(npyv_cmpgt_u64(a, b), a, b);
+}
+NPY_FINLINE npyv_s64 npyv_max_s64(npyv_s64 a, npyv_s64 b)
+{
+ return npyv_select_s64(npyv_cmpgt_s64(a, b), a, b);
+}
+
+// Minimum, natively mapping with no guarantees to handle NaN.
+#define npyv_min_f32 _mm_min_ps
+#define npyv_min_f64 _mm_min_pd
+// Minimum, supports IEEE floating-point arithmetic (IEC 60559),
+// - If one of the two vectors contains NaN, the equivalent element of the other vector is set
+// - Only if both corresponded elements are NaN, NaN is set.
+NPY_FINLINE npyv_f32 npyv_minp_f32(npyv_f32 a, npyv_f32 b)
+{
+ __m128 nn = _mm_cmpord_ps(b, b);
+ __m128 min = _mm_min_ps(a, b);
+ return npyv_select_f32(_mm_castps_si128(nn), min, a);
+}
+NPY_FINLINE npyv_f64 npyv_minp_f64(npyv_f64 a, npyv_f64 b)
+{
+ __m128d nn = _mm_cmpord_pd(b, b);
+ __m128d min = _mm_min_pd(a, b);
+ return npyv_select_f64(_mm_castpd_si128(nn), min, a);
+}
+// Minimum, integer operations
+#ifdef NPY_HAVE_SSE41
+ #define npyv_min_s8 _mm_min_epi8
+ #define npyv_min_u16 _mm_min_epu16
+ #define npyv_min_u32 _mm_min_epu32
+ #define npyv_min_s32 _mm_min_epi32
+#else
+ NPY_FINLINE npyv_s8 npyv_min_s8(npyv_s8 a, npyv_s8 b)
+ {
+ return npyv_select_s8(npyv_cmplt_s8(a, b), a, b);
+ }
+ NPY_FINLINE npyv_u16 npyv_min_u16(npyv_u16 a, npyv_u16 b)
+ {
+ return npyv_select_u16(npyv_cmplt_u16(a, b), a, b);
+ }
+ NPY_FINLINE npyv_u32 npyv_min_u32(npyv_u32 a, npyv_u32 b)
+ {
+ return npyv_select_u32(npyv_cmplt_u32(a, b), a, b);
+ }
+ NPY_FINLINE npyv_s32 npyv_min_s32(npyv_s32 a, npyv_s32 b)
+ {
+ return npyv_select_s32(npyv_cmplt_s32(a, b), a, b);
+ }
+#endif
+#define npyv_min_u8 _mm_min_epu8
+#define npyv_min_s16 _mm_min_epi16
+NPY_FINLINE npyv_u64 npyv_min_u64(npyv_u64 a, npyv_u64 b)
+{
+ return npyv_select_u64(npyv_cmplt_u64(a, b), a, b);
+}
+NPY_FINLINE npyv_s64 npyv_min_s64(npyv_s64 a, npyv_s64 b)
+{
+ return npyv_select_s64(npyv_cmplt_s64(a, b), a, b);
+}
+
+#endif // _NPY_SIMD_SSE_MATH_H
diff --git a/numpy/core/src/common/simd/sse/misc.h b/numpy/core/src/common/simd/sse/misc.h
index 7ba47bc68..1099c491d 100644
--- a/numpy/core/src/common/simd/sse/misc.h
+++ b/numpy/core/src/common/simd/sse/misc.h
@@ -18,21 +18,16 @@
#define npyv_zero_f64 _mm_setzero_pd
// vector with a specific value set to all lanes
-#define npyv_setall_u8(VAL) _mm_set1_epi8((char)VAL)
-#define npyv_setall_s8(VAL) _mm_set1_epi8((char)VAL)
-#define npyv_setall_u16(VAL) _mm_set1_epi16((short)VAL)
-#define npyv_setall_s16(VAL) _mm_set1_epi16((short)VAL)
-#define npyv_setall_u32(VAL) _mm_set1_epi32((int)VAL)
-#define npyv_setall_s32(VAL) _mm_set1_epi32(VAL)
-#if !defined(__x86_64__) && !defined(_M_X64)
- #define npyv_setall_u64(VAL) _mm_set_epi32((int)(VAL >> 32), (int)VAL, (int)(VAL >> 32), (int)VAL)
- #define npyv_setall_s64 npyv_setall_u64
-#else
- #define npyv_setall_u64(VAL) _mm_set1_epi64x(VAL)
- #define npyv_setall_s64(VAL) _mm_set1_epi64x(VAL)
-#endif
-#define npyv_setall_f32(VAL) _mm_set1_ps(VAL)
-#define npyv_setall_f64(VAL) _mm_set1_pd(VAL)
+#define npyv_setall_u8(VAL) _mm_set1_epi8((char)(VAL))
+#define npyv_setall_s8(VAL) _mm_set1_epi8((char)(VAL))
+#define npyv_setall_u16(VAL) _mm_set1_epi16((short)(VAL))
+#define npyv_setall_s16(VAL) _mm_set1_epi16((short)(VAL))
+#define npyv_setall_u32(VAL) _mm_set1_epi32((int)(VAL))
+#define npyv_setall_s32(VAL) _mm_set1_epi32((int)(VAL))
+#define npyv_setall_u64(VAL) _mm_set1_epi64x((npy_int64)(VAL))
+#define npyv_setall_s64(VAL) _mm_set1_epi64x((npy_int64)(VAL))
+#define npyv_setall_f32 _mm_set1_ps
+#define npyv_setall_f64 _mm_set1_pd
/**
* vector with specific values set to each lane and
diff --git a/numpy/core/src/common/simd/sse/operators.h b/numpy/core/src/common/simd/sse/operators.h
index 6e32ca4fd..51c84fb4e 100644
--- a/numpy/core/src/common/simd/sse/operators.h
+++ b/numpy/core/src/common/simd/sse/operators.h
@@ -62,6 +62,10 @@ NPY_FINLINE __m128i npyv_shr_s64(__m128i a, int c)
#define npyv_and_s64 _mm_and_si128
#define npyv_and_f32 _mm_and_ps
#define npyv_and_f64 _mm_and_pd
+#define npyv_and_b8 _mm_and_si128
+#define npyv_and_b16 _mm_and_si128
+#define npyv_and_b32 _mm_and_si128
+#define npyv_and_b64 _mm_and_si128
// OR
#define npyv_or_u8 _mm_or_si128
@@ -74,6 +78,10 @@ NPY_FINLINE __m128i npyv_shr_s64(__m128i a, int c)
#define npyv_or_s64 _mm_or_si128
#define npyv_or_f32 _mm_or_ps
#define npyv_or_f64 _mm_or_pd
+#define npyv_or_b8 _mm_or_si128
+#define npyv_or_b16 _mm_or_si128
+#define npyv_or_b32 _mm_or_si128
+#define npyv_or_b64 _mm_or_si128
// XOR
#define npyv_xor_u8 _mm_xor_si128
@@ -86,6 +94,10 @@ NPY_FINLINE __m128i npyv_shr_s64(__m128i a, int c)
#define npyv_xor_s64 _mm_xor_si128
#define npyv_xor_f32 _mm_xor_ps
#define npyv_xor_f64 _mm_xor_pd
+#define npyv_xor_b8 _mm_xor_si128
+#define npyv_xor_b16 _mm_xor_si128
+#define npyv_xor_b32 _mm_xor_si128
+#define npyv_xor_b64 _mm_xor_si128
// NOT
#define npyv_not_u8(A) _mm_xor_si128(A, _mm_set1_epi32(-1))
@@ -98,6 +110,10 @@ NPY_FINLINE __m128i npyv_shr_s64(__m128i a, int c)
#define npyv_not_s64 npyv_not_u8
#define npyv_not_f32(A) _mm_xor_ps(A, _mm_castsi128_ps(_mm_set1_epi32(-1)))
#define npyv_not_f64(A) _mm_xor_pd(A, _mm_castsi128_pd(_mm_set1_epi32(-1)))
+#define npyv_not_b8 npyv_not_u8
+#define npyv_not_b16 npyv_not_u8
+#define npyv_not_b32 npyv_not_u8
+#define npyv_not_b64 npyv_not_u8
/***************************
* Comparison
@@ -255,4 +271,10 @@ NPY_FINLINE __m128i npyv_shr_s64(__m128i a, int c)
#define npyv_cmpge_f32(a, b) _mm_castps_si128(_mm_cmpge_ps(a, b))
#define npyv_cmpge_f64(a, b) _mm_castpd_si128(_mm_cmpge_pd(a, b))
+// check special cases
+NPY_FINLINE npyv_b32 npyv_notnan_f32(npyv_f32 a)
+{ return _mm_castps_si128(_mm_cmpord_ps(a, a)); }
+NPY_FINLINE npyv_b64 npyv_notnan_f64(npyv_f64 a)
+{ return _mm_castpd_si128(_mm_cmpord_pd(a, a)); }
+
#endif // _NPY_SIMD_SSE_OPERATORS_H
diff --git a/numpy/core/src/common/simd/sse/reorder.h b/numpy/core/src/common/simd/sse/reorder.h
index 3f68b4ad7..d96ab9c56 100644
--- a/numpy/core/src/common/simd/sse/reorder.h
+++ b/numpy/core/src/common/simd/sse/reorder.h
@@ -81,4 +81,45 @@ NPYV_IMPL_SSE_ZIP(npyv_s64, s64, epi64)
NPYV_IMPL_SSE_ZIP(npyv_f32, f32, ps)
NPYV_IMPL_SSE_ZIP(npyv_f64, f64, pd)
+// Reverse elements of each 64-bit lane
+NPY_FINLINE npyv_u16 npyv_rev64_u16(npyv_u16 a)
+{
+#ifdef NPY_HAVE_SSSE3
+ const __m128i idx = _mm_setr_epi8(
+ 6, 7, 4, 5, 2, 3, 0, 1,/*64*/14, 15, 12, 13, 10, 11, 8, 9
+ );
+ return _mm_shuffle_epi8(a, idx);
+#else
+ __m128i lo = _mm_shufflelo_epi16(a, _MM_SHUFFLE(0, 1, 2, 3));
+ return _mm_shufflehi_epi16(lo, _MM_SHUFFLE(0, 1, 2, 3));
+#endif
+}
+#define npyv_rev64_s16 npyv_rev64_u16
+
+NPY_FINLINE npyv_u8 npyv_rev64_u8(npyv_u8 a)
+{
+#ifdef NPY_HAVE_SSSE3
+ const __m128i idx = _mm_setr_epi8(
+ 7, 6, 5, 4, 3, 2, 1, 0,/*64*/15, 14, 13, 12, 11, 10, 9, 8
+ );
+ return _mm_shuffle_epi8(a, idx);
+#else
+ __m128i rev16 = npyv_rev64_u16(a);
+ // swap 8bit pairs
+ return _mm_or_si128(_mm_slli_epi16(rev16, 8), _mm_srli_epi16(rev16, 8));
+#endif
+}
+#define npyv_rev64_s8 npyv_rev64_u8
+
+NPY_FINLINE npyv_u32 npyv_rev64_u32(npyv_u32 a)
+{
+ return _mm_shuffle_epi32(a, _MM_SHUFFLE(2, 3, 0, 1));
+}
+#define npyv_rev64_s32 npyv_rev64_u32
+
+NPY_FINLINE npyv_f32 npyv_rev64_f32(npyv_f32 a)
+{
+ return _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 3, 0, 1));
+}
+
#endif // _NPY_SIMD_SSE_REORDER_H
diff --git a/numpy/core/src/common/simd/sse/sse.h b/numpy/core/src/common/simd/sse/sse.h
index 132d3d347..0bb404312 100644
--- a/numpy/core/src/common/simd/sse/sse.h
+++ b/numpy/core/src/common/simd/sse/sse.h
@@ -5,7 +5,11 @@
#define NPY_SIMD 128
#define NPY_SIMD_WIDTH 16
#define NPY_SIMD_F64 1
-
+#if defined(NPY_HAVE_FMA3) || defined(NPY_HAVE_FMA4)
+ #define NPY_SIMD_FMA3 1 // native support
+#else
+ #define NPY_SIMD_FMA3 0 // fast emulated
+#endif
typedef __m128i npyv_u8;
typedef __m128i npyv_s8;
typedef __m128i npyv_u16;
@@ -58,6 +62,7 @@ typedef struct { __m128d val[3]; } npyv_f64x3;
#define npyv_nlanes_f32 4
#define npyv_nlanes_f64 2
+#include "utils.h"
#include "memory.h"
#include "misc.h"
#include "reorder.h"
diff --git a/numpy/core/src/common/simd/sse/utils.h b/numpy/core/src/common/simd/sse/utils.h
new file mode 100644
index 000000000..c23def11d
--- /dev/null
+++ b/numpy/core/src/common/simd/sse/utils.h
@@ -0,0 +1,19 @@
+#ifndef NPY_SIMD
+ #error "Not a standalone header"
+#endif
+
+#ifndef _NPY_SIMD_SSE_UTILS_H
+#define _NPY_SIMD_SSE_UTILS_H
+
+#if !defined(__x86_64__) && !defined(_M_X64)
+NPY_FINLINE npy_int64 npyv128_cvtsi128_si64(__m128i a)
+{
+ npy_int64 NPY_DECL_ALIGNED(16) idx[2];
+ _mm_store_si128((__m128i *)idx, a);
+ return idx[0];
+}
+#else
+ #define npyv128_cvtsi128_si64 _mm_cvtsi128_si64
+#endif
+
+#endif // _NPY_SIMD_SSE_UTILS_H
diff --git a/numpy/core/src/common/simd/vsx/arithmetic.h b/numpy/core/src/common/simd/vsx/arithmetic.h
index 2f6762e63..eaca53620 100644
--- a/numpy/core/src/common/simd/vsx/arithmetic.h
+++ b/numpy/core/src/common/simd/vsx/arithmetic.h
@@ -95,6 +95,138 @@
#define npyv_mul_f64 vec_mul
/***************************
+ * Integer Division
+ ***************************/
+/***
+ * TODO: Add support for VSX4(Power10)
+ */
+// See simd/intdiv.h for more clarification
+// divide each unsigned 8-bit element by a precomputed divisor
+NPY_FINLINE npyv_u8 npyv_divc_u8(npyv_u8 a, const npyv_u8x3 divisor)
+{
+ const npyv_u8 mergeo_perm = {
+ 1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31
+ };
+ // high part of unsigned multiplication
+ npyv_u16 mul_even = vec_mule(a, divisor.val[0]);
+ npyv_u16 mul_odd = vec_mulo(a, divisor.val[0]);
+ npyv_u8 mulhi = (npyv_u8)vec_perm(mul_even, mul_odd, mergeo_perm);
+ // floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
+ npyv_u8 q = vec_sub(a, mulhi);
+ q = vec_sr(q, divisor.val[1]);
+ q = vec_add(mulhi, q);
+ q = vec_sr(q, divisor.val[2]);
+ return q;
+}
+// divide each signed 8-bit element by a precomputed divisor
+NPY_FINLINE npyv_s8 npyv_divc_s8(npyv_s8 a, const npyv_s8x3 divisor)
+{
+ const npyv_u8 mergeo_perm = {
+ 1, 17, 3, 19, 5, 21, 7, 23, 9, 25, 11, 27, 13, 29, 15, 31
+ };
+ // high part of signed multiplication
+ npyv_s16 mul_even = vec_mule(a, divisor.val[0]);
+ npyv_s16 mul_odd = vec_mulo(a, divisor.val[0]);
+ npyv_s8 mulhi = (npyv_s8)vec_perm(mul_even, mul_odd, mergeo_perm);
+ // q = ((a + mulhi) >> sh1) - XSIGN(a)
+ // trunc(a/d) = (q ^ dsign) - dsign
+ npyv_s8 q = vec_sra(vec_add(a, mulhi), (npyv_u8)divisor.val[1]);
+ q = vec_sub(q, vec_sra(a, npyv_setall_u8(7)));
+ q = vec_sub(vec_xor(q, divisor.val[2]), divisor.val[2]);
+ return q;
+}
+// divide each unsigned 16-bit element by a precomputed divisor
+NPY_FINLINE npyv_u16 npyv_divc_u16(npyv_u16 a, const npyv_u16x3 divisor)
+{
+ const npyv_u8 mergeo_perm = {
+ 2, 3, 18, 19, 6, 7, 22, 23, 10, 11, 26, 27, 14, 15, 30, 31
+ };
+ // high part of unsigned multiplication
+ npyv_u32 mul_even = vec_mule(a, divisor.val[0]);
+ npyv_u32 mul_odd = vec_mulo(a, divisor.val[0]);
+ npyv_u16 mulhi = (npyv_u16)vec_perm(mul_even, mul_odd, mergeo_perm);
+ // floor(a/d) = (mulhi + ((a-mulhi) >> sh1)) >> sh2
+ npyv_u16 q = vec_sub(a, mulhi);
+ q = vec_sr(q, divisor.val[1]);
+ q = vec_add(mulhi, q);
+ q = vec_sr(q, divisor.val[2]);
+ return q;
+}
+// divide each signed 16-bit element by a precomputed divisor (round towards zero)
+NPY_FINLINE npyv_s16 npyv_divc_s16(npyv_s16 a, const npyv_s16x3 divisor)
+{
+ const npyv_u8 mergeo_perm = {
+ 2, 3, 18, 19, 6, 7, 22, 23, 10, 11, 26, 27, 14, 15, 30, 31
+ };
+ // high part of signed multiplication
+ npyv_s32 mul_even = vec_mule(a, divisor.val[0]);
+ npyv_s32 mul_odd = vec_mulo(a, divisor.val[0]);
+ npyv_s16 mulhi = (npyv_s16)vec_perm(mul_even, mul_odd, mergeo_perm);
+ // q = ((a + mulhi) >> sh1) - XSIGN(a)
+ // trunc(a/d) = (q ^ dsign) - dsign
+ npyv_s16 q = vec_sra(vec_add(a, mulhi), (npyv_u16)divisor.val[1]);
+ q = vec_sub(q, vec_sra(a, npyv_setall_u16(15)));
+ q = vec_sub(vec_xor(q, divisor.val[2]), divisor.val[2]);
+ return q;
+}
+// divide each unsigned 32-bit element by a precomputed divisor
+NPY_FINLINE npyv_u32 npyv_divc_u32(npyv_u32 a, const npyv_u32x3 divisor)
+{
+#if defined(__GNUC__) && __GNUC__ < 8
+ // Doubleword integer wide multiplication supported by GCC 8+
+ npyv_u64 mul_even, mul_odd;
+ __asm__ ("vmulouw %0,%1,%2" : "=v" (mul_even) : "v" (a), "v" (divisor.val[0]));
+ __asm__ ("vmuleuw %0,%1,%2" : "=v" (mul_odd) : "v" (a), "v" (divisor.val[0]));
+#else
+ // Doubleword integer wide multiplication supported by GCC 8+
+ npyv_u64 mul_even = vec_mule(a, divisor.val[0]);
+ npyv_u64 mul_odd = vec_mulo(a, divisor.val[0]);
+#endif
+ // high part of unsigned multiplication
+ npyv_u32 mulhi = vec_mergeo((npyv_u32)mul_even, (npyv_u32)mul_odd);
+ // floor(x/d) = (((a-mulhi) >> sh1) + mulhi) >> sh2
+ npyv_u32 q = vec_sub(a, mulhi);
+ q = vec_sr(q, divisor.val[1]);
+ q = vec_add(mulhi, q);
+ q = vec_sr(q, divisor.val[2]);
+ return q;
+}
+// divide each signed 32-bit element by a precomputed divisor (round towards zero)
+NPY_FINLINE npyv_s32 npyv_divc_s32(npyv_s32 a, const npyv_s32x3 divisor)
+{
+#if defined(__GNUC__) && __GNUC__ < 8
+ // Doubleword integer wide multiplication supported by GCC8+
+ npyv_s64 mul_even, mul_odd;
+ __asm__ ("vmulosw %0,%1,%2" : "=v" (mul_even) : "v" (a), "v" (divisor.val[0]));
+ __asm__ ("vmulesw %0,%1,%2" : "=v" (mul_odd) : "v" (a), "v" (divisor.val[0]));
+#else
+ // Doubleword integer wide multiplication supported by GCC8+
+ npyv_s64 mul_even = vec_mule(a, divisor.val[0]);
+ npyv_s64 mul_odd = vec_mulo(a, divisor.val[0]);
+#endif
+ // high part of signed multiplication
+ npyv_s32 mulhi = vec_mergeo((npyv_s32)mul_even, (npyv_s32)mul_odd);
+ // q = ((a + mulhi) >> sh1) - XSIGN(a)
+ // trunc(a/d) = (q ^ dsign) - dsign
+ npyv_s32 q = vec_sra(vec_add(a, mulhi), (npyv_u32)divisor.val[1]);
+ q = vec_sub(q, vec_sra(a, npyv_setall_u32(31)));
+ q = vec_sub(vec_xor(q, divisor.val[2]), divisor.val[2]);
+ return q;
+}
+// divide each unsigned 64-bit element by a precomputed divisor
+NPY_FINLINE npyv_u64 npyv_divc_u64(npyv_u64 a, const npyv_u64x3 divisor)
+{
+ const npy_uint64 d = vec_extract(divisor.val[0], 0);
+ return npyv_set_u64(vec_extract(a, 0) / d, vec_extract(a, 1) / d);
+}
+// divide each signed 64-bit element by a precomputed divisor (round towards zero)
+NPY_FINLINE npyv_s64 npyv_divc_s64(npyv_s64 a, const npyv_s64x3 divisor)
+{
+ npyv_b64 overflow = npyv_and_b64(vec_cmpeq(a, npyv_setall_s64(-1LL << 63)), (npyv_b64)divisor.val[1]);
+ npyv_s64 d = vec_sel(divisor.val[0], npyv_setall_s64(1), overflow);
+ return vec_div(a, d);
+}
+/***************************
* Division
***************************/
#define npyv_div_f32 vec_div
@@ -116,7 +248,21 @@
#define npyv_nmulsub_f32 vec_nmadd // equivalent to -(a*b + c)
#define npyv_nmulsub_f64 vec_nmadd
-// Horizontal add: Calculates the sum of all vector elements.
+/***************************
+ * Summation
+ ***************************/
+// reduce sum across vector
+NPY_FINLINE npy_uint64 npyv_sum_u64(npyv_u64 a)
+{
+ return vec_extract(vec_add(a, vec_mergel(a, a)), 0);
+}
+
+NPY_FINLINE npy_uint32 npyv_sum_u32(npyv_u32 a)
+{
+ const npyv_u32 rs = vec_add(a, vec_sld(a, a, 8));
+ return vec_extract(vec_add(rs, vec_sld(rs, rs, 4)), 0);
+}
+
NPY_FINLINE float npyv_sum_f32(npyv_f32 a)
{
npyv_f32 sum = vec_add(a, npyv_combineh_f32(a, a));
@@ -128,4 +274,22 @@ NPY_FINLINE double npyv_sum_f64(npyv_f64 a)
return vec_extract(a, 0) + vec_extract(a, 1);
}
+// expand the source vector and performs sum reduce
+NPY_FINLINE npy_uint16 npyv_sumup_u8(npyv_u8 a)
+{
+ const npyv_u32 zero = npyv_zero_u32();
+ npyv_u32 four = vec_sum4s(a, zero);
+ npyv_s32 one = vec_sums((npyv_s32)four, (npyv_s32)zero);
+ return (npy_uint16)vec_extract(one, 3);
+}
+
+NPY_FINLINE npy_uint32 npyv_sumup_u16(npyv_u16 a)
+{
+ const npyv_s32 zero = npyv_zero_s32();
+ npyv_u32x2 eight = npyv_expand_u32_u16(a);
+ npyv_u32 four = vec_add(eight.val[0], eight.val[1]);
+ npyv_s32 one = vec_sums((npyv_s32)four, zero);
+ return (npy_uint32)vec_extract(one, 3);
+}
+
#endif // _NPY_SIMD_VSX_ARITHMETIC_H
diff --git a/numpy/core/src/common/simd/vsx/conversion.h b/numpy/core/src/common/simd/vsx/conversion.h
index 6ed135990..36bea7bba 100644
--- a/numpy/core/src/common/simd/vsx/conversion.h
+++ b/numpy/core/src/common/simd/vsx/conversion.h
@@ -29,4 +29,95 @@
#define npyv_cvt_b32_f32(A) ((npyv_b32) A)
#define npyv_cvt_b64_f64(A) ((npyv_b64) A)
+//expand
+NPY_FINLINE npyv_u16x2 npyv_expand_u16_u8(npyv_u8 data)
+{
+ npyv_u16x2 r;
+ npyv_u8 zero = npyv_zero_u8();
+ r.val[0] = (npyv_u16)vec_mergeh(data, zero);
+ r.val[1] = (npyv_u16)vec_mergel(data, zero);
+ return r;
+}
+
+NPY_FINLINE npyv_u32x2 npyv_expand_u32_u16(npyv_u16 data)
+{
+ npyv_u32x2 r;
+ npyv_u16 zero = npyv_zero_u16();
+ r.val[0] = (npyv_u32)vec_mergeh(data, zero);
+ r.val[1] = (npyv_u32)vec_mergel(data, zero);
+ return r;
+}
+
+// convert boolean vector to integer bitfield
+NPY_FINLINE npy_uint64 npyv_tobits_b8(npyv_b8 a)
+{
+ const npyv_u8 qperm = npyv_set_u8(120, 112, 104, 96, 88, 80, 72, 64, 56, 48, 40, 32, 24, 16, 8, 0);
+ return vec_extract((npyv_u32)vec_vbpermq((npyv_u8)a, qperm), 2);
+}
+NPY_FINLINE npy_uint64 npyv_tobits_b16(npyv_b16 a)
+{
+ const npyv_u8 qperm = npyv_setf_u8(128, 112, 96, 80, 64, 48, 32, 16, 0);
+ return vec_extract((npyv_u32)vec_vbpermq((npyv_u8)a, qperm), 2);
+}
+NPY_FINLINE npy_uint64 npyv_tobits_b32(npyv_b32 a)
+{
+ const npyv_u8 qperm = npyv_setf_u8(128, 96, 64, 32, 0);
+ return vec_extract((npyv_u32)vec_vbpermq((npyv_u8)a, qperm), 2);
+}
+NPY_FINLINE npy_uint64 npyv_tobits_b64(npyv_b64 a)
+{
+ npyv_u64 bit = npyv_shri_u64((npyv_u64)a, 63);
+ return vec_extract(bit, 0) | (int)vec_extract(bit, 1) << 1;
+}
+
+// truncate compatible with all compilers(internal use for now)
+NPY_FINLINE npyv_s32 npyv__trunc_s32_f32(npyv_f32 a)
+{
+#ifdef __IBMC__
+ return vec_cts(a, 0);
+#elif defined(__clang__)
+ /**
+ * old versions of CLANG doesn't support %x<n> in the inline asm template
+ * which fixes register number when using any of the register constraints wa, wd, wf.
+ * therefore, we count on built-in functions.
+ */
+ return __builtin_convertvector(a, npyv_s32);
+#else // gcc
+ npyv_s32 ret;
+ __asm__ ("xvcvspsxws %x0,%x1" : "=wa" (ret) : "wa" (a));
+ return ret;
+#endif
+}
+NPY_FINLINE npyv_s32 npyv__trunc_s32_f64(npyv_f64 a, npyv_f64 b)
+{
+#ifdef __IBMC__
+ const npyv_u8 seq_even = npyv_set_u8(0, 1, 2, 3, 8, 9, 10, 11, 16, 17, 18, 19, 24, 25, 26, 27);
+ // unfortunately, XLC missing asm register vsx fixer
+ // hopefully, xlc can optimize around big-endian compatibility
+ npyv_s32 lo_even = vec_cts(a, 0);
+ npyv_s32 hi_even = vec_cts(b, 0);
+ return vec_perm(lo_even, hi_even, seq_even);
+#else
+ const npyv_u8 seq_odd = npyv_set_u8(4, 5, 6, 7, 12, 13, 14, 15, 20, 21, 22, 23, 28, 29, 30, 31);
+ #ifdef __clang__
+ // __builtin_convertvector doesn't support this conversion on wide range of versions
+ // fortunately, almost all versions have direct builtin of 'xvcvdpsxws'
+ npyv_s32 lo_odd = __builtin_vsx_xvcvdpsxws(a);
+ npyv_s32 hi_odd = __builtin_vsx_xvcvdpsxws(b);
+ #else // gcc
+ npyv_s32 lo_odd, hi_odd;
+ __asm__ ("xvcvdpsxws %x0,%x1" : "=wa" (lo_odd) : "wa" (a));
+ __asm__ ("xvcvdpsxws %x0,%x1" : "=wa" (hi_odd) : "wa" (b));
+ #endif
+ return vec_perm(lo_odd, hi_odd, seq_odd);
+#endif
+}
+
+// round to nearest integer (assuming even)
+NPY_FINLINE npyv_s32 npyv_round_s32_f32(npyv_f32 a)
+{ return npyv__trunc_s32_f32(vec_rint(a)); }
+
+NPY_FINLINE npyv_s32 npyv_round_s32_f64(npyv_f64 a, npyv_f64 b)
+{ return npyv__trunc_s32_f64(vec_rint(a), vec_rint(b)); }
+
#endif // _NPY_SIMD_VSX_CVT_H
diff --git a/numpy/core/src/common/simd/vsx/math.h b/numpy/core/src/common/simd/vsx/math.h
index 7c8610b19..b2e393c7c 100644
--- a/numpy/core/src/common/simd/vsx/math.h
+++ b/numpy/core/src/common/simd/vsx/math.h
@@ -33,4 +33,40 @@ NPY_FINLINE npyv_f32 npyv_square_f32(npyv_f32 a)
NPY_FINLINE npyv_f64 npyv_square_f64(npyv_f64 a)
{ return vec_mul(a, a); }
+// Maximum, natively mapping with no guarantees to handle NaN.
+#define npyv_max_f32 vec_max
+#define npyv_max_f64 vec_max
+// Maximum, supports IEEE floating-point arithmetic (IEC 60559),
+// - If one of the two vectors contains NaN, the equivalent element of the other vector is set
+// - Only if both corresponded elements are NaN, NaN is set.
+#define npyv_maxp_f32 vec_max
+#define npyv_maxp_f64 vec_max
+// Maximum, integer operations
+#define npyv_max_u8 vec_max
+#define npyv_max_s8 vec_max
+#define npyv_max_u16 vec_max
+#define npyv_max_s16 vec_max
+#define npyv_max_u32 vec_max
+#define npyv_max_s32 vec_max
+#define npyv_max_u64 vec_max
+#define npyv_max_s64 vec_max
+
+// Minimum, natively mapping with no guarantees to handle NaN.
+#define npyv_min_f32 vec_min
+#define npyv_min_f64 vec_min
+// Minimum, supports IEEE floating-point arithmetic (IEC 60559),
+// - If one of the two vectors contains NaN, the equivalent element of the other vector is set
+// - Only if both corresponded elements are NaN, NaN is set.
+#define npyv_minp_f32 vec_min
+#define npyv_minp_f64 vec_min
+// Minimum, integer operations
+#define npyv_min_u8 vec_min
+#define npyv_min_s8 vec_min
+#define npyv_min_u16 vec_min
+#define npyv_min_s16 vec_min
+#define npyv_min_u32 vec_min
+#define npyv_min_s32 vec_min
+#define npyv_min_u64 vec_min
+#define npyv_min_s64 vec_min
+
#endif // _NPY_SIMD_VSX_MATH_H
diff --git a/numpy/core/src/common/simd/vsx/operators.h b/numpy/core/src/common/simd/vsx/operators.h
index ca020d9e0..23c5d0dbe 100644
--- a/numpy/core/src/common/simd/vsx/operators.h
+++ b/numpy/core/src/common/simd/vsx/operators.h
@@ -44,7 +44,16 @@
/***************************
* Logical
***************************/
+#define NPYV_IMPL_VSX_BIN_CAST(INTRIN, SFX, CAST) \
+ NPY_FINLINE npyv_##SFX npyv_##INTRIN##_##SFX(npyv_##SFX a, npyv_##SFX b) \
+ { return (npyv_##SFX)vec_##INTRIN((CAST)a, (CAST)b); }
+// Up to GCC 6 logical intrinsics don't support bool long long
+#if defined(__GNUC__) && __GNUC__ <= 6
+ #define NPYV_IMPL_VSX_BIN_B64(INTRIN) NPYV_IMPL_VSX_BIN_CAST(INTRIN, b64, npyv_u64)
+#else
+ #define NPYV_IMPL_VSX_BIN_B64(INTRIN) NPYV_IMPL_VSX_BIN_CAST(INTRIN, b64, npyv_b64)
+#endif
// AND
#define npyv_and_u8 vec_and
#define npyv_and_s8 vec_and
@@ -56,6 +65,10 @@
#define npyv_and_s64 vec_and
#define npyv_and_f32 vec_and
#define npyv_and_f64 vec_and
+#define npyv_and_b8 vec_and
+#define npyv_and_b16 vec_and
+#define npyv_and_b32 vec_and
+NPYV_IMPL_VSX_BIN_B64(and)
// OR
#define npyv_or_u8 vec_or
@@ -68,6 +81,10 @@
#define npyv_or_s64 vec_or
#define npyv_or_f32 vec_or
#define npyv_or_f64 vec_or
+#define npyv_or_b8 vec_or
+#define npyv_or_b16 vec_or
+#define npyv_or_b32 vec_or
+NPYV_IMPL_VSX_BIN_B64(or)
// XOR
#define npyv_xor_u8 vec_xor
@@ -80,6 +97,10 @@
#define npyv_xor_s64 vec_xor
#define npyv_xor_f32 vec_xor
#define npyv_xor_f64 vec_xor
+#define npyv_xor_b8 vec_xor
+#define npyv_xor_b16 vec_xor
+#define npyv_xor_b32 vec_xor
+NPYV_IMPL_VSX_BIN_B64(xor)
// NOT
// note: we implement npyv_not_b*(boolen types) for internal use*/
@@ -129,7 +150,8 @@ NPY_FINLINE npyv_f64 npyv_not_f64(npyv_f64 a)
#define npyv_cmpeq_f64 vec_cmpeq
// Int Not Equal
-#ifdef NPY_HAVE_VSX3
+#if defined(NPY_HAVE_VSX3) && (!defined(__GNUC__) || defined(vec_cmpne))
+ // vec_cmpne supported by gcc since version 7
#define npyv_cmpneq_u8 vec_cmpne
#define npyv_cmpneq_s8 vec_cmpne
#define npyv_cmpneq_u16 vec_cmpne
@@ -213,4 +235,10 @@ NPY_FINLINE npyv_f64 npyv_not_f64(npyv_f64 a)
#define npyv_cmple_f32(A, B) npyv_cmpge_f32(B, A)
#define npyv_cmple_f64(A, B) npyv_cmpge_f64(B, A)
+// check special cases
+NPY_FINLINE npyv_b32 npyv_notnan_f32(npyv_f32 a)
+{ return vec_cmpeq(a, a); }
+NPY_FINLINE npyv_b64 npyv_notnan_f64(npyv_f64 a)
+{ return vec_cmpeq(a, a); }
+
#endif // _NPY_SIMD_VSX_OPERATORS_H
diff --git a/numpy/core/src/common/simd/vsx/reorder.h b/numpy/core/src/common/simd/vsx/reorder.h
index bfb9115fa..6533e5093 100644
--- a/numpy/core/src/common/simd/vsx/reorder.h
+++ b/numpy/core/src/common/simd/vsx/reorder.h
@@ -62,4 +62,45 @@ NPYV_IMPL_VSX_COMBINE_ZIP(npyv_s64, s64)
NPYV_IMPL_VSX_COMBINE_ZIP(npyv_f32, f32)
NPYV_IMPL_VSX_COMBINE_ZIP(npyv_f64, f64)
+// Reverse elements of each 64-bit lane
+NPY_FINLINE npyv_u8 npyv_rev64_u8(npyv_u8 a)
+{
+#if defined(NPY_HAVE_VSX3) && ((defined(__GNUC__) && __GNUC__ > 7) || defined(__IBMC__))
+ return (npyv_u8)vec_revb((npyv_u64)a);
+#elif defined(NPY_HAVE_VSX3) && defined(NPY_HAVE_VSX_ASM)
+ npyv_u8 ret;
+ __asm__ ("xxbrd %x0,%x1" : "=wa" (ret) : "wa" (a));
+ return ret;
+#else
+ const npyv_u8 idx = npyv_set_u8(
+ 7, 6, 5, 4, 3, 2, 1, 0,/*64*/15, 14, 13, 12, 11, 10, 9, 8
+ );
+ return vec_perm(a, a, idx);
+#endif
+}
+NPY_FINLINE npyv_s8 npyv_rev64_s8(npyv_s8 a)
+{ return (npyv_s8)npyv_rev64_u8((npyv_u8)a); }
+
+NPY_FINLINE npyv_u16 npyv_rev64_u16(npyv_u16 a)
+{
+ const npyv_u8 idx = npyv_set_u8(
+ 6, 7, 4, 5, 2, 3, 0, 1,/*64*/14, 15, 12, 13, 10, 11, 8, 9
+ );
+ return vec_perm(a, a, idx);
+}
+NPY_FINLINE npyv_s16 npyv_rev64_s16(npyv_s16 a)
+{ return (npyv_s16)npyv_rev64_u16((npyv_u16)a); }
+
+NPY_FINLINE npyv_u32 npyv_rev64_u32(npyv_u32 a)
+{
+ const npyv_u8 idx = npyv_set_u8(
+ 4, 5, 6, 7, 0, 1, 2, 3,/*64*/12, 13, 14, 15, 8, 9, 10, 11
+ );
+ return vec_perm(a, a, idx);
+}
+NPY_FINLINE npyv_s32 npyv_rev64_s32(npyv_s32 a)
+{ return (npyv_s32)npyv_rev64_u32((npyv_u32)a); }
+NPY_FINLINE npyv_f32 npyv_rev64_f32(npyv_f32 a)
+{ return (npyv_f32)npyv_rev64_u32((npyv_u32)a); }
+
#endif // _NPY_SIMD_VSX_REORDER_H
diff --git a/numpy/core/src/common/simd/vsx/vsx.h b/numpy/core/src/common/simd/vsx/vsx.h
index 27dde98e7..66b76208f 100644
--- a/numpy/core/src/common/simd/vsx/vsx.h
+++ b/numpy/core/src/common/simd/vsx/vsx.h
@@ -2,9 +2,20 @@
#error "Not a standalone header"
#endif
+#if defined(__GNUC__) && __GNUC__ <= 7
+ /**
+ * GCC <= 7 produces ambiguous warning caused by -Werror=maybe-uninitialized,
+ * when certain intrinsics involved. `vec_ld` is one of them but it seemed to work fine,
+ * and suppressing the warning wouldn't affect its functionality.
+ */
+ #pragma GCC diagnostic ignored "-Wuninitialized"
+ #pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+
#define NPY_SIMD 128
#define NPY_SIMD_WIDTH 16
#define NPY_SIMD_F64 1
+#define NPY_SIMD_FMA3 1 // native support
typedef __vector unsigned char npyv_u8;
typedef __vector signed char npyv_s8;
diff --git a/numpy/core/src/common/umathmodule.h b/numpy/core/src/common/umathmodule.h
index 6998596ee..5c718a841 100644
--- a/numpy/core/src/common/umathmodule.h
+++ b/numpy/core/src/common/umathmodule.h
@@ -1,6 +1,9 @@
#include "__umath_generated.c"
#include "__ufunc_api.c"
+NPY_NO_EXPORT PyObject *
+get_sfloat_dtype(PyObject *NPY_UNUSED(mod), PyObject *NPY_UNUSED(args));
+
PyObject * add_newdoc_ufunc(PyObject *NPY_UNUSED(dummy), PyObject *args);
PyObject * ufunc_frompyfunc(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *NPY_UNUSED(kwds));
int initumath(PyObject *m);
diff --git a/numpy/core/src/multiarray/_multiarray_tests.c.src b/numpy/core/src/multiarray/_multiarray_tests.c.src
index 3c8caefce..f4764b371 100644
--- a/numpy/core/src/multiarray/_multiarray_tests.c.src
+++ b/numpy/core/src/multiarray/_multiarray_tests.c.src
@@ -1,4 +1,6 @@
/* -*-c-*- */
+#define PY_SSIZE_T_CLEAN
+
#define NPY_NO_DEPRECATED_API NPY_API_VERSION
#include <Python.h>
#define _NPY_NO_DEPRECATIONS /* for NPY_CHAR */
@@ -7,9 +9,12 @@
#include "numpy/npy_math.h"
#include "numpy/halffloat.h"
#include "common.h"
+#include "npy_argparse.h"
#include "mem_overlap.h"
#include "npy_extint128.h"
#include "array_method.h"
+#include "npy_hashtable.h"
+#include "dtypemeta.h"
#if defined(MS_WIN32) || defined(__CYGWIN__)
#define EXPORT(x) __declspec(dllexport) x
@@ -19,6 +24,25 @@
#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
+
+static PyObject *
+argparse_example_function(PyObject *NPY_UNUSED(mod),
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
+{
+ NPY_PREPARE_ARGPARSER;
+ int arg1;
+ PyObject *arg2, *arg3, *arg4;
+ if (npy_parse_arguments("func", args, len_args, kwnames,
+ "", &PyArray_PythonPyIntFromInt, &arg1,
+ "arg2", NULL, &arg2,
+ "|arg3", NULL, &arg3,
+ "$arg3", NULL, &arg4,
+ NULL, NULL, NULL) < 0) {
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
/* test PyArray_IsPythonScalar, before including private py3 compat header */
static PyObject *
IsPythonScalar(PyObject * dummy, PyObject *args)
@@ -67,7 +91,7 @@ static int copy_@name@(PyArrayIterObject *itx, PyArrayNeighborhoodIterObject *ni
* For each point in itx, copy the current neighborhood into an array which
* is appended at the output list
*/
- for (i = 0; i < itx->size; ++i) {
+ for (i = itx->index; i < itx->size; ++i) {
PyArrayNeighborhoodIter_Reset(niterx);
for (j = 0; j < PyArray_NDIM(itx->ao); ++j) {
@@ -110,7 +134,7 @@ static int copy_object(PyArrayIterObject *itx, PyArrayNeighborhoodIterObject *ni
* For each point in itx, copy the current neighborhood into an array which
* is appended at the output list
*/
- for (i = 0; i < itx->size; ++i) {
+ for (i = itx->index; i < itx->size; ++i) {
PyArrayNeighborhoodIter_Reset(niterx);
for (j = 0; j < PyArray_NDIM(itx->ao); ++j) {
@@ -141,10 +165,11 @@ test_neighborhood_iterator(PyObject* NPY_UNUSED(self), PyObject* args)
PyArrayObject *ax, *afill;
PyArrayIterObject *itx;
int i, typenum, mode, st;
+ Py_ssize_t idxstart = 0;
npy_intp bounds[NPY_MAXDIMS*2];
PyArrayNeighborhoodIterObject *niterx;
- if (!PyArg_ParseTuple(args, "OOOi", &x, &b, &fill, &mode)) {
+ if (!PyArg_ParseTuple(args, "OOOi|n", &x, &b, &fill, &mode, &idxstart)) {
return NULL;
}
@@ -204,12 +229,20 @@ test_neighborhood_iterator(PyObject* NPY_UNUSED(self), PyObject* args)
}
}
+ if (idxstart >= itx->size) {
+ PyErr_SetString(PyExc_ValueError,
+ "start index not compatible with x input");
+ goto clean_itx;
+ }
+
niterx = (PyArrayNeighborhoodIterObject*)PyArray_NeighborhoodIterNew(
(PyArrayIterObject*)itx, bounds, mode, afill);
if (niterx == NULL) {
goto clean_afill;
}
+ PyArray_ITER_GOTO1D((PyArrayIterObject*)itx, idxstart);
+
switch (typenum) {
case NPY_OBJECT:
st = copy_object(itx, niterx, bounds, &out);
@@ -387,7 +420,7 @@ test_neighborhood_iterator_oob(PyObject* NPY_UNUSED(self), PyObject* args)
niterx2 = (PyArrayNeighborhoodIterObject*)PyArray_NeighborhoodIterNew(
(PyArrayIterObject*)niterx1, bounds,
mode2, NULL);
- if (niterx1 == NULL) {
+ if (niterx2 == NULL) {
goto clean_niterx1;
}
@@ -1034,7 +1067,7 @@ get_all_cast_information(PyObject *NPY_UNUSED(mod), PyObject *NPY_UNUSED(args))
for (Py_ssize_t i = 0; i < nclass; i++) {
PyArray_DTypeMeta *from_dtype = (
(PyArray_DTypeMeta *)PySequence_Fast_GET_ITEM(classes, i));
- if (from_dtype->abstract) {
+ if (NPY_DT_is_abstract(from_dtype)) {
/*
* TODO: In principle probably needs to recursively check this,
* also we may allow casts to abstract dtypes at some point.
@@ -1045,7 +1078,8 @@ get_all_cast_information(PyObject *NPY_UNUSED(mod), PyObject *NPY_UNUSED(args))
PyObject *to_dtype, *cast_obj;
Py_ssize_t pos = 0;
- while (PyDict_Next(from_dtype->castingimpls, &pos, &to_dtype, &cast_obj)) {
+ while (PyDict_Next(NPY_DT_SLOTS(from_dtype)->castingimpls,
+ &pos, &to_dtype, &cast_obj)) {
if (cast_obj == Py_None) {
continue;
}
@@ -1087,6 +1121,92 @@ get_all_cast_information(PyObject *NPY_UNUSED(mod), PyObject *NPY_UNUSED(args))
/*
+ * Helper to test the identity cache, takes a list of values and adds
+ * all to the cache except the last key/value pair. The last value is
+ * ignored, instead the last key is looked up.
+ * None is returned, if the key is not found.
+ * If `replace` is True, duplicate entries are ignored when adding to the
+ * hashtable.
+ */
+static PyObject *
+identityhash_tester(PyObject *NPY_UNUSED(mod),
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
+{
+ NPY_PREPARE_ARGPARSER;
+
+ int key_len;
+ int replace;
+ PyObject *replace_obj = Py_False;
+ PyObject *sequence;
+ PyObject *result = NULL;
+
+ if (npy_parse_arguments("identityhash_tester", args, len_args, kwnames,
+ "key_len", &PyArray_PythonPyIntFromInt, &key_len,
+ "sequence", NULL, &sequence,
+ "|replace", NULL, &replace_obj,
+ NULL, NULL, NULL) < 0) {
+ return NULL;
+ }
+ replace = PyObject_IsTrue(replace_obj);
+ if (error_converting(replace)) {
+ return NULL;
+ }
+
+ if (key_len < 1 || key_len >= NPY_MAXARGS) {
+ PyErr_SetString(PyExc_ValueError, "must have 1 to max-args keys.");
+ return NULL;
+ }
+ PyArrayIdentityHash *tb = PyArrayIdentityHash_New(key_len);
+ if (tb == NULL) {
+ return NULL;
+ }
+
+ /* Replace the sequence with a guaranteed fast-sequence */
+ sequence = PySequence_Fast(sequence, "converting sequence.");
+ if (sequence == NULL) {
+ goto finish;
+ }
+
+ Py_ssize_t length = PySequence_Fast_GET_SIZE(sequence);
+ for (Py_ssize_t i = 0; i < length; i++) {
+ PyObject *key_val = PySequence_Fast_GET_ITEM(sequence, i);
+ if (!PyTuple_CheckExact(key_val) || PyTuple_GET_SIZE(key_val) != 2) {
+ PyErr_SetString(PyExc_TypeError, "bad key-value pair.");
+ goto finish;
+ }
+ PyObject *key = PyTuple_GET_ITEM(key_val, 0);
+ PyObject *value = PyTuple_GET_ITEM(key_val, 1);
+ if (!PyTuple_CheckExact(key) || PyTuple_GET_SIZE(key) != key_len) {
+ PyErr_SetString(PyExc_TypeError, "bad key tuple.");
+ goto finish;
+ }
+
+ PyObject *keys[NPY_MAXARGS];
+ for (int j = 0; j < key_len; j++) {
+ keys[j] = PyTuple_GET_ITEM(key, j);
+ }
+ if (i != length - 1) {
+ if (PyArrayIdentityHash_SetItem(tb, keys, value, replace) < 0) {
+ goto finish;
+ }
+ }
+ else {
+ result = PyArrayIdentityHash_GetItem(tb, keys);
+ if (result == NULL) {
+ result = Py_None;
+ }
+ Py_INCREF(result);
+ }
+ }
+
+ finish:
+ Py_DECREF(sequence);
+ PyArrayIdentityHash_Dealloc(tb);
+ return result;
+}
+
+
+/*
* Test C-api level item getting.
*/
static PyObject *
@@ -2121,17 +2241,6 @@ getset_numericops(PyObject* NPY_UNUSED(self), PyObject* NPY_UNUSED(args))
static PyObject *
-uses_new_casts(PyObject* NPY_UNUSED(self), PyObject* NPY_UNUSED(args))
-{
-#if NPY_USE_NEW_CASTINGIMPL
- Py_RETURN_TRUE;
-#else
- Py_RETURN_FALSE;
-#endif
-}
-
-
-static PyObject *
run_byteorder_converter(PyObject* NPY_UNUSED(self), PyObject *args)
{
char byteorder;
@@ -2255,6 +2364,9 @@ run_intp_converter(PyObject* NPY_UNUSED(self), PyObject *args)
}
static PyMethodDef Multiarray_TestsMethods[] = {
+ {"argparse_example_function",
+ (PyCFunction)argparse_example_function,
+ METH_KEYWORDS | METH_FASTCALL, NULL},
{"IsPythonScalar",
IsPythonScalar,
METH_VARARGS, NULL},
@@ -2324,6 +2436,9 @@ static PyMethodDef Multiarray_TestsMethods[] = {
"Return a list with info on all available casts. Some of the info"
"may differ for an actual cast if it uses value-based casting "
"(flexible types)."},
+ {"identityhash_tester",
+ (PyCFunction)identityhash_tester,
+ METH_KEYWORDS | METH_FASTCALL, NULL},
{"array_indexing",
array_indexing,
METH_VARARGS, NULL},
@@ -2384,9 +2499,6 @@ static PyMethodDef Multiarray_TestsMethods[] = {
{"getset_numericops",
getset_numericops,
METH_NOARGS, NULL},
- {"uses_new_casts",
- uses_new_casts,
- METH_NOARGS, NULL},
/**begin repeat
* #name = cabs, carg#
*/
diff --git a/numpy/core/src/multiarray/abstractdtypes.c b/numpy/core/src/multiarray/abstractdtypes.c
index 02c0eac53..3fa354ddc 100644
--- a/numpy/core/src/multiarray/abstractdtypes.c
+++ b/numpy/core/src/multiarray/abstractdtypes.c
@@ -13,6 +13,12 @@
#include "common.h"
+static NPY_INLINE PyArray_Descr *
+int_default_descriptor(PyArray_DTypeMeta* NPY_UNUSED(cls))
+{
+ return PyArray_DescrFromType(NPY_LONG);
+}
+
static PyArray_Descr *
discover_descriptor_from_pyint(
PyArray_DTypeMeta *NPY_UNUSED(cls), PyObject *obj)
@@ -45,6 +51,13 @@ discover_descriptor_from_pyint(
}
+static NPY_INLINE PyArray_Descr *
+float_default_descriptor(PyArray_DTypeMeta* NPY_UNUSED(cls))
+{
+ return PyArray_DescrFromType(NPY_DOUBLE);
+}
+
+
static PyArray_Descr*
discover_descriptor_from_pyfloat(
PyArray_DTypeMeta* NPY_UNUSED(cls), PyObject *obj)
@@ -53,6 +66,11 @@ discover_descriptor_from_pyfloat(
return PyArray_DescrFromType(NPY_DOUBLE);
}
+static NPY_INLINE PyArray_Descr *
+complex_default_descriptor(PyArray_DTypeMeta* NPY_UNUSED(cls))
+{
+ return PyArray_DescrFromType(NPY_CDOUBLE);
+}
static PyArray_Descr*
discover_descriptor_from_pycomplex(
@@ -66,21 +84,17 @@ discover_descriptor_from_pycomplex(
NPY_NO_EXPORT int
initialize_and_map_pytypes_to_dtypes()
{
- PyArrayAbstractObjDTypeMeta_Type.tp_base = &PyArrayDTypeMeta_Type;
- if (PyType_Ready(&PyArrayAbstractObjDTypeMeta_Type) < 0) {
- return -1;
- }
- ((PyTypeObject *)&PyArray_PyIntAbstractDType)->tp_base = &PyArrayDTypeMeta_Type;
+ ((PyTypeObject *)&PyArray_PyIntAbstractDType)->tp_base = &PyArrayDescr_Type;
PyArray_PyIntAbstractDType.scalar_type = &PyLong_Type;
if (PyType_Ready((PyTypeObject *)&PyArray_PyIntAbstractDType) < 0) {
return -1;
}
- ((PyTypeObject *)&PyArray_PyFloatAbstractDType)->tp_base = &PyArrayDTypeMeta_Type;
+ ((PyTypeObject *)&PyArray_PyFloatAbstractDType)->tp_base = &PyArrayDescr_Type;
PyArray_PyFloatAbstractDType.scalar_type = &PyFloat_Type;
if (PyType_Ready((PyTypeObject *)&PyArray_PyFloatAbstractDType) < 0) {
return -1;
}
- ((PyTypeObject *)&PyArray_PyComplexAbstractDType)->tp_base = &PyArrayDTypeMeta_Type;
+ ((PyTypeObject *)&PyArray_PyComplexAbstractDType)->tp_base = &PyArrayDescr_Type;
PyArray_PyComplexAbstractDType.scalar_type = &PyComplex_Type;
if (PyType_Ready((PyTypeObject *)&PyArray_PyComplexAbstractDType) < 0) {
return -1;
@@ -126,43 +140,158 @@ initialize_and_map_pytypes_to_dtypes()
}
+/*
+ * The following functions define the "common DType" for the abstract dtypes.
+ *
+ * Note that the logic with respect to the "higher" dtypes such as floats
+ * could likely be more logically defined for them, but since NumPy dtypes
+ * largely "know" each other, that is not necessary.
+ */
+static PyArray_DTypeMeta *
+int_common_dtype(PyArray_DTypeMeta *NPY_UNUSED(cls), PyArray_DTypeMeta *other)
+{
+ if (NPY_DT_is_legacy(other) && other->type_num < NPY_NTYPES) {
+ if (other->type_num == NPY_BOOL) {
+ /* Use the default integer for bools: */
+ return PyArray_DTypeFromTypeNum(NPY_LONG);
+ }
+ else if (PyTypeNum_ISNUMBER(other->type_num) ||
+ other->type_num == NPY_TIMEDELTA) {
+ /* All other numeric types (ant timdelta) are preserved: */
+ Py_INCREF(other);
+ return other;
+ }
+ }
+ else if (NPY_DT_is_legacy(other)) {
+ /* This is a back-compat fallback to usually do the right thing... */
+ return PyArray_DTypeFromTypeNum(NPY_UINT8);
+ }
+ Py_INCREF(Py_NotImplemented);
+ return (PyArray_DTypeMeta *)Py_NotImplemented;
+}
-/* Note: This is currently largely not used, but will be required eventually. */
-NPY_NO_EXPORT PyTypeObject PyArrayAbstractObjDTypeMeta_Type = {
- PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "numpy._AbstractObjDTypeMeta",
- .tp_basicsize = sizeof(PyArray_DTypeMeta),
- .tp_flags = Py_TPFLAGS_DEFAULT,
- .tp_doc = "Helper MetaClass for value based casting AbstractDTypes.",
+
+static PyArray_DTypeMeta *
+float_common_dtype(PyArray_DTypeMeta *cls, PyArray_DTypeMeta *other)
+{
+ if (NPY_DT_is_legacy(other) && other->type_num < NPY_NTYPES) {
+ if (other->type_num == NPY_BOOL || PyTypeNum_ISINTEGER(other->type_num)) {
+ /* Use the default integer for bools and ints: */
+ return PyArray_DTypeFromTypeNum(NPY_DOUBLE);
+ }
+ else if (PyTypeNum_ISNUMBER(other->type_num)) {
+ /* All other numeric types (float+complex) are preserved: */
+ Py_INCREF(other);
+ return other;
+ }
+ }
+ else if (other == &PyArray_PyIntAbstractDType) {
+ Py_INCREF(cls);
+ return cls;
+ }
+ else if (NPY_DT_is_legacy(other)) {
+ /* This is a back-compat fallback to usually do the right thing... */
+ return PyArray_DTypeFromTypeNum(NPY_HALF);
+ }
+ Py_INCREF(Py_NotImplemented);
+ return (PyArray_DTypeMeta *)Py_NotImplemented;
+}
+
+
+static PyArray_DTypeMeta *
+complex_common_dtype(PyArray_DTypeMeta *cls, PyArray_DTypeMeta *other)
+{
+ if (NPY_DT_is_legacy(other) && other->type_num < NPY_NTYPES) {
+ if (other->type_num == NPY_BOOL ||
+ PyTypeNum_ISINTEGER(other->type_num)) {
+ /* Use the default integer for bools and ints: */
+ return PyArray_DTypeFromTypeNum(NPY_CDOUBLE);
+ }
+ else if (PyTypeNum_ISFLOAT(other->type_num)) {
+ /*
+ * For floats we choose the equivalent precision complex, although
+ * there is no CHALF, so half also goes to CFLOAT.
+ */
+ if (other->type_num == NPY_HALF || other->type_num == NPY_FLOAT) {
+ return PyArray_DTypeFromTypeNum(NPY_CFLOAT);
+ }
+ if (other->type_num == NPY_DOUBLE) {
+ return PyArray_DTypeFromTypeNum(NPY_CDOUBLE);
+ }
+ assert(other->type_num == NPY_LONGDOUBLE);
+ return PyArray_DTypeFromTypeNum(NPY_CLONGDOUBLE);
+ }
+ else if (PyTypeNum_ISCOMPLEX(other->type_num)) {
+ /* All other numeric types are preserved: */
+ Py_INCREF(other);
+ return other;
+ }
+ }
+ else if (NPY_DT_is_legacy(other)) {
+ /* This is a back-compat fallback to usually do the right thing... */
+ return PyArray_DTypeFromTypeNum(NPY_CFLOAT);
+ }
+ else if (other == &PyArray_PyIntAbstractDType ||
+ other == &PyArray_PyFloatAbstractDType) {
+ Py_INCREF(cls);
+ return cls;
+ }
+ Py_INCREF(Py_NotImplemented);
+ return (PyArray_DTypeMeta *)Py_NotImplemented;
+}
+
+
+/*
+ * TODO: These abstract DTypes also carry the dual role of representing
+ * `Floating`, `Complex`, and `Integer` (both signed and unsigned).
+ * They will have to be renamed and exposed in that capacity.
+ */
+NPY_DType_Slots pyintabstractdtype_slots = {
+ .default_descr = int_default_descriptor,
+ .discover_descr_from_pyobject = discover_descriptor_from_pyint,
+ .common_dtype = int_common_dtype,
};
NPY_NO_EXPORT PyArray_DTypeMeta PyArray_PyIntAbstractDType = {{{
- PyVarObject_HEAD_INIT(&PyArrayAbstractObjDTypeMeta_Type, 0)
- .tp_basicsize = sizeof(PyArray_DTypeMeta),
- .tp_name = "numpy._PyIntBaseAbstractDType",
+ PyVarObject_HEAD_INIT(&PyArrayDTypeMeta_Type, 0)
+ .tp_basicsize = sizeof(PyArray_Descr),
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_name = "numpy._IntegerAbstractDType",
},},
- .abstract = 1,
- .discover_descr_from_pyobject = discover_descriptor_from_pyint,
- .kind = 'i',
+ .flags = NPY_DT_ABSTRACT,
+ .dt_slots = &pyintabstractdtype_slots,
};
-NPY_NO_EXPORT PyArray_DTypeMeta PyArray_PyFloatAbstractDType = {{{
- PyVarObject_HEAD_INIT(&PyArrayAbstractObjDTypeMeta_Type, 0)
- .tp_basicsize = sizeof(PyArray_DTypeMeta),
- .tp_name = "numpy._PyFloatBaseAbstractDType",
- },},
- .abstract = 1,
+
+NPY_DType_Slots pyfloatabstractdtype_slots = {
+ .default_descr = float_default_descriptor,
.discover_descr_from_pyobject = discover_descriptor_from_pyfloat,
- .kind = 'f',
+ .common_dtype = float_common_dtype,
};
-NPY_NO_EXPORT PyArray_DTypeMeta PyArray_PyComplexAbstractDType = {{{
- PyVarObject_HEAD_INIT(&PyArrayAbstractObjDTypeMeta_Type, 0)
- .tp_basicsize = sizeof(PyArray_DTypeMeta),
- .tp_name = "numpy._PyComplexBaseAbstractDType",
+NPY_NO_EXPORT PyArray_DTypeMeta PyArray_PyFloatAbstractDType = {{{
+ PyVarObject_HEAD_INIT(&PyArrayDTypeMeta_Type, 0)
+ .tp_basicsize = sizeof(PyArray_Descr),
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_name = "numpy._FloatAbstractDType",
},},
- .abstract = 1,
+ .flags = NPY_DT_ABSTRACT,
+ .dt_slots = &pyfloatabstractdtype_slots,
+};
+
+
+NPY_DType_Slots pycomplexabstractdtype_slots = {
+ .default_descr = complex_default_descriptor,
.discover_descr_from_pyobject = discover_descriptor_from_pycomplex,
- .kind = 'c',
+ .common_dtype = complex_common_dtype,
};
+NPY_NO_EXPORT PyArray_DTypeMeta PyArray_PyComplexAbstractDType = {{{
+ PyVarObject_HEAD_INIT(&PyArrayDTypeMeta_Type, 0)
+ .tp_basicsize = sizeof(PyArray_Descr),
+ .tp_flags = Py_TPFLAGS_DEFAULT,
+ .tp_name = "numpy._ComplexAbstractDType",
+ },},
+ .flags = NPY_DT_ABSTRACT,
+ .dt_slots = &pycomplexabstractdtype_slots,
+};
diff --git a/numpy/core/src/multiarray/abstractdtypes.h b/numpy/core/src/multiarray/abstractdtypes.h
index 3a982cd38..a6c526717 100644
--- a/numpy/core/src/multiarray/abstractdtypes.h
+++ b/numpy/core/src/multiarray/abstractdtypes.h
@@ -3,12 +3,12 @@
#include "dtypemeta.h"
+
/*
* These are mainly needed for value based promotion in ufuncs. It
* may be necessary to make them (partially) public, to allow user-defined
* dtypes to perform value based casting.
*/
-NPY_NO_EXPORT extern PyTypeObject PyArrayAbstractObjDTypeMeta_Type;
NPY_NO_EXPORT extern PyArray_DTypeMeta PyArray_PyIntAbstractDType;
NPY_NO_EXPORT extern PyArray_DTypeMeta PyArray_PyFloatAbstractDType;
NPY_NO_EXPORT extern PyArray_DTypeMeta PyArray_PyComplexAbstractDType;
diff --git a/numpy/core/src/multiarray/array_assign_array.c b/numpy/core/src/multiarray/array_assign_array.c
index 361964a5c..665dadfbf 100644
--- a/numpy/core/src/multiarray/array_assign_array.c
+++ b/numpy/core/src/multiarray/array_assign_array.c
@@ -23,6 +23,7 @@
#include "lowlevel_strided_loops.h"
#include "array_assign.h"
+#include "dtype_transfer.h"
/*
* Check that array data is both uint-aligned and true-aligned for all array
@@ -82,10 +83,7 @@ raw_array_assign_array(int ndim, npy_intp const *shape,
npy_intp src_strides_it[NPY_MAXDIMS];
npy_intp coord[NPY_MAXDIMS];
- PyArray_StridedUnaryOp *stransfer = NULL;
- NpyAuxData *transferdata = NULL;
int aligned, needs_api = 0;
- npy_intp src_itemsize = src_dtype->elsize;
NPY_BEGIN_THREADS_DEF;
@@ -117,12 +115,12 @@ raw_array_assign_array(int ndim, npy_intp const *shape,
}
/* Get the function to do the casting */
+ NPY_cast_info cast_info;
if (PyArray_GetDTypeTransferFunction(aligned,
src_strides_it[0], dst_strides_it[0],
src_dtype, dst_dtype,
0,
- &stransfer, &transferdata,
- &needs_api) != NPY_SUCCEED) {
+ &cast_info, &needs_api) != NPY_SUCCEED) {
return -1;
}
@@ -130,11 +128,13 @@ raw_array_assign_array(int ndim, npy_intp const *shape,
NPY_BEGIN_THREADS;
}
+ npy_intp strides[2] = {src_strides_it[0], dst_strides_it[0]};
+
NPY_RAW_ITER_START(idim, ndim, coord, shape_it) {
/* Process the innermost dimension */
- if (stransfer(
- dst_data, dst_strides_it[0], src_data, src_strides_it[0],
- shape_it[0], src_itemsize, transferdata) < 0) {
+ char *args[2] = {src_data, dst_data};
+ if (cast_info.func(&cast_info.context,
+ args, &shape_it[0], strides, cast_info.auxdata) < 0) {
goto fail;
}
} NPY_RAW_ITER_TWO_NEXT(idim, ndim, coord, shape_it,
@@ -142,11 +142,11 @@ raw_array_assign_array(int ndim, npy_intp const *shape,
src_data, src_strides_it);
NPY_END_THREADS;
- NPY_AUXDATA_FREE(transferdata);
+ NPY_cast_info_xfree(&cast_info);
return 0;
fail:
NPY_END_THREADS;
- NPY_AUXDATA_FREE(transferdata);
+ NPY_cast_info_xfree(&cast_info);
return -1;
}
@@ -170,10 +170,7 @@ raw_array_wheremasked_assign_array(int ndim, npy_intp const *shape,
npy_intp wheremask_strides_it[NPY_MAXDIMS];
npy_intp coord[NPY_MAXDIMS];
- PyArray_MaskedStridedUnaryOp *stransfer = NULL;
- NpyAuxData *transferdata = NULL;
int aligned, needs_api = 0;
- npy_intp src_itemsize = src_dtype->elsize;
NPY_BEGIN_THREADS_DEF;
@@ -209,35 +206,41 @@ raw_array_wheremasked_assign_array(int ndim, npy_intp const *shape,
}
/* Get the function to do the casting */
+ NPY_cast_info cast_info;
if (PyArray_GetMaskedDTypeTransferFunction(aligned,
src_strides_it[0],
dst_strides_it[0],
wheremask_strides_it[0],
src_dtype, dst_dtype, wheremask_dtype,
0,
- &stransfer, &transferdata,
- &needs_api) != NPY_SUCCEED) {
+ &cast_info, &needs_api) != NPY_SUCCEED) {
return -1;
}
if (!needs_api) {
NPY_BEGIN_THREADS;
}
+ npy_intp strides[2] = {src_strides_it[0], dst_strides_it[0]};
NPY_RAW_ITER_START(idim, ndim, coord, shape_it) {
+ PyArray_MaskedStridedUnaryOp *stransfer;
+ stransfer = (PyArray_MaskedStridedUnaryOp *)cast_info.func;
+
/* Process the innermost dimension */
- stransfer(dst_data, dst_strides_it[0], src_data, src_strides_it[0],
- (npy_bool *)wheremask_data, wheremask_strides_it[0],
- shape_it[0], src_itemsize, transferdata);
+ char *args[2] = {src_data, dst_data};
+ if (stransfer(&cast_info.context,
+ args, &shape_it[0], strides,
+ (npy_bool *)wheremask_data, wheremask_strides_it[0],
+ cast_info.auxdata) < 0) {
+ break;
+ }
} NPY_RAW_ITER_THREE_NEXT(idim, ndim, coord, shape_it,
dst_data, dst_strides_it,
src_data, src_strides_it,
wheremask_data, wheremask_strides_it);
NPY_END_THREADS;
-
- NPY_AUXDATA_FREE(transferdata);
-
+ NPY_cast_info_xfree(&cast_info);
return (needs_api && PyErr_Occurred()) ? -1 : 0;
}
diff --git a/numpy/core/src/multiarray/array_assign_scalar.c b/numpy/core/src/multiarray/array_assign_scalar.c
index 023772776..6cd5f4ad9 100644
--- a/numpy/core/src/multiarray/array_assign_scalar.c
+++ b/numpy/core/src/multiarray/array_assign_scalar.c
@@ -23,6 +23,7 @@
#include "lowlevel_strided_loops.h"
#include "array_assign.h"
+#include "dtype_transfer.h"
/*
* Assigns the scalar value to every element of the destination raw array.
@@ -38,10 +39,7 @@ raw_array_assign_scalar(int ndim, npy_intp const *shape,
npy_intp shape_it[NPY_MAXDIMS], dst_strides_it[NPY_MAXDIMS];
npy_intp coord[NPY_MAXDIMS];
- PyArray_StridedUnaryOp *stransfer = NULL;
- NpyAuxData *transferdata = NULL;
int aligned, needs_api = 0;
- npy_intp src_itemsize = src_dtype->elsize;
NPY_BEGIN_THREADS_DEF;
@@ -63,12 +61,12 @@ raw_array_assign_scalar(int ndim, npy_intp const *shape,
}
/* Get the function to do the casting */
+ NPY_cast_info cast_info;
if (PyArray_GetDTypeTransferFunction(aligned,
0, dst_strides_it[0],
src_dtype, dst_dtype,
0,
- &stransfer, &transferdata,
- &needs_api) != NPY_SUCCEED) {
+ &cast_info, &needs_api) != NPY_SUCCEED) {
return -1;
}
@@ -80,22 +78,24 @@ raw_array_assign_scalar(int ndim, npy_intp const *shape,
NPY_BEGIN_THREADS_THRESHOLDED(nitems);
}
+ npy_intp strides[2] = {0, dst_strides_it[0]};
+
NPY_RAW_ITER_START(idim, ndim, coord, shape_it) {
/* Process the innermost dimension */
- if (stransfer(
- dst_data, dst_strides_it[0], src_data, 0,
- shape_it[0], src_itemsize, transferdata) < 0) {
+ char *args[2] = {src_data, dst_data};
+ if (cast_info.func(&cast_info.context,
+ args, &shape_it[0], strides, cast_info.auxdata) < 0) {
goto fail;
}
} NPY_RAW_ITER_ONE_NEXT(idim, ndim, coord,
shape_it, dst_data, dst_strides_it);
NPY_END_THREADS;
- NPY_AUXDATA_FREE(transferdata);
+ NPY_cast_info_xfree(&cast_info);
return 0;
fail:
NPY_END_THREADS;
- NPY_AUXDATA_FREE(transferdata);
+ NPY_cast_info_xfree(&cast_info);
return -1;
}
@@ -117,10 +117,7 @@ raw_array_wheremasked_assign_scalar(int ndim, npy_intp const *shape,
npy_intp wheremask_strides_it[NPY_MAXDIMS];
npy_intp coord[NPY_MAXDIMS];
- PyArray_MaskedStridedUnaryOp *stransfer = NULL;
- NpyAuxData *transferdata = NULL;
int aligned, needs_api = 0;
- npy_intp src_itemsize = src_dtype->elsize;
NPY_BEGIN_THREADS_DEF;
@@ -144,12 +141,12 @@ raw_array_wheremasked_assign_scalar(int ndim, npy_intp const *shape,
}
/* Get the function to do the casting */
+ NPY_cast_info cast_info;
if (PyArray_GetMaskedDTypeTransferFunction(aligned,
0, dst_strides_it[0], wheremask_strides_it[0],
src_dtype, dst_dtype, wheremask_dtype,
0,
- &stransfer, &transferdata,
- &needs_api) != NPY_SUCCEED) {
+ &cast_info, &needs_api) != NPY_SUCCEED) {
return -1;
}
@@ -161,19 +158,26 @@ raw_array_wheremasked_assign_scalar(int ndim, npy_intp const *shape,
NPY_BEGIN_THREADS_THRESHOLDED(nitems);
}
+ npy_intp strides[2] = {0, dst_strides_it[0]};
+
NPY_RAW_ITER_START(idim, ndim, coord, shape_it) {
/* Process the innermost dimension */
- stransfer(dst_data, dst_strides_it[0], src_data, 0,
- (npy_bool *)wheremask_data, wheremask_strides_it[0],
- shape_it[0], src_itemsize, transferdata);
+ PyArray_MaskedStridedUnaryOp *stransfer;
+ stransfer = (PyArray_MaskedStridedUnaryOp *)cast_info.func;
+
+ char *args[2] = {src_data, dst_data};
+ if (stransfer(&cast_info.context,
+ args, &shape_it[0], strides,
+ (npy_bool *)wheremask_data, wheremask_strides_it[0],
+ cast_info.auxdata) < 0) {
+ break;
+ }
} NPY_RAW_ITER_TWO_NEXT(idim, ndim, coord, shape_it,
dst_data, dst_strides_it,
wheremask_data, wheremask_strides_it);
NPY_END_THREADS;
-
- NPY_AUXDATA_FREE(transferdata);
-
+ NPY_cast_info_xfree(&cast_info);
return (needs_api && PyErr_Occurred()) ? -1 : 0;
}
diff --git a/numpy/core/src/multiarray/array_coercion.c b/numpy/core/src/multiarray/array_coercion.c
index 53d891049..89719f129 100644
--- a/numpy/core/src/multiarray/array_coercion.c
+++ b/numpy/core/src/multiarray/array_coercion.c
@@ -11,6 +11,7 @@
#include "descriptor.h"
#include "convert_datatype.h"
+#include "common_dtype.h"
#include "dtypemeta.h"
#include "array_coercion.h"
@@ -153,7 +154,7 @@ _PyArray_MapPyTypeToDType(
* We expect that user dtypes (for now) will subclass some numpy
* scalar class to allow automatic discovery.
*/
- if (DType->legacy) {
+ if (NPY_DT_is_legacy(DType)) {
/*
* For legacy user dtypes, discovery relied on subclassing, but
* arbitrary type objects are supported, so do nothing.
@@ -205,7 +206,7 @@ _PyArray_MapPyTypeToDType(
* @return DType, None if it a known non-scalar, or NULL if an unknown object.
*/
static NPY_INLINE PyArray_DTypeMeta *
-discover_dtype_from_pytype(PyTypeObject *pytype)
+npy_discover_dtype_from_pytype(PyTypeObject *pytype)
{
PyObject *DType;
@@ -256,14 +257,13 @@ discover_dtype_from_pyobject(
* asked to attempt to do so later, if no other matching DType exists.)
*/
if ((Py_TYPE(obj) == fixed_DType->scalar_type) ||
- (fixed_DType->is_known_scalar_type != NULL &&
- fixed_DType->is_known_scalar_type(fixed_DType, Py_TYPE(obj)))) {
+ NPY_DT_CALL_is_known_scalar_type(fixed_DType, Py_TYPE(obj))) {
Py_INCREF(fixed_DType);
return fixed_DType;
}
}
- PyArray_DTypeMeta *DType = discover_dtype_from_pytype(Py_TYPE(obj));
+ PyArray_DTypeMeta *DType = npy_discover_dtype_from_pytype(Py_TYPE(obj));
if (DType != NULL) {
return DType;
}
@@ -345,10 +345,10 @@ find_scalar_descriptor(
* chance. This allows for example string, to call `str(obj)` to
* figure out the length for arbitrary objects.
*/
- descr = fixed_DType->discover_descr_from_pyobject(fixed_DType, obj);
+ descr = NPY_DT_CALL_discover_descr_from_pyobject(fixed_DType, obj);
}
else {
- descr = DType->discover_descr_from_pyobject(DType, obj);
+ descr = NPY_DT_CALL_discover_descr_from_pyobject(DType, obj);
}
if (descr == NULL) {
return NULL;
@@ -424,7 +424,7 @@ PyArray_Pack(PyArray_Descr *descr, char *item, PyObject *value)
return descr->f->setitem(value, item, &arr_fields);
}
PyArray_Descr *tmp_descr;
- tmp_descr = DType->discover_descr_from_pyobject(DType, value);
+ tmp_descr = NPY_DT_CALL_discover_descr_from_pyobject(DType, value);
Py_DECREF(DType);
if (tmp_descr == NULL) {
return -1;
@@ -452,18 +452,21 @@ PyArray_Pack(PyArray_Descr *descr, char *item, PyObject *value)
int res = 0;
int needs_api = 0;
- PyArray_StridedUnaryOp *stransfer;
- NpyAuxData *transferdata;
+ NPY_cast_info cast_info;
if (PyArray_GetDTypeTransferFunction(
- 0, 0, 0, tmp_descr, descr, 0, &stransfer, &transferdata,
+ 0, 0, 0, tmp_descr, descr, 0, &cast_info,
&needs_api) == NPY_FAIL) {
res = -1;
goto finish;
}
- if (stransfer(item, 0, data, 0, 1, tmp_descr->elsize, transferdata) < 0) {
+ char *args[2] = {data, item};
+ const npy_intp strides[2] = {0, 0};
+ const npy_intp length = 1;
+ if (cast_info.func(&cast_info.context,
+ args, &length, strides, cast_info.auxdata) < 0) {
res = -1;
}
- NPY_AUXDATA_FREE(transferdata);
+ NPY_cast_info_xfree(&cast_info);
finish:
if (PyDataType_REFCHK(tmp_descr)) {
@@ -570,7 +573,7 @@ npy_new_coercion_cache(
* @param current
* @return next coercion cache object (or NULL)
*/
-NPY_NO_EXPORT NPY_INLINE coercion_cache_obj *
+NPY_NO_EXPORT coercion_cache_obj *
npy_unlink_coercion_cache(coercion_cache_obj *current)
{
coercion_cache_obj *next = current->next;
@@ -585,7 +588,7 @@ npy_unlink_coercion_cache(coercion_cache_obj *current)
return next;
}
-NPY_NO_EXPORT NPY_INLINE void
+NPY_NO_EXPORT void
npy_free_coercion_cache(coercion_cache_obj *next) {
/* We only need to check from the last used cache pos */
while (next != NULL) {
@@ -619,8 +622,12 @@ handle_promotion(PyArray_Descr **out_descr, PyArray_Descr *descr,
}
PyArray_Descr *new_descr = PyArray_PromoteTypes(descr, *out_descr);
if (NPY_UNLIKELY(new_descr == NULL)) {
- if (fixed_DType != NULL) {
- /* If a DType is fixed, promotion must not fail. */
+ if (fixed_DType != NULL || PyErr_ExceptionMatches(PyExc_FutureWarning)) {
+ /*
+ * If a DType is fixed, promotion must not fail. Do not catch
+ * FutureWarning (raised for string+numeric promotions). We could
+ * only catch TypeError here or even always raise the error.
+ */
return -1;
}
PyErr_Clear();
@@ -705,7 +712,7 @@ find_descriptor_from_array(
return 0;
}
- if (NPY_UNLIKELY(DType->parametric && PyArray_ISOBJECT(arr))) {
+ if (NPY_UNLIKELY(NPY_DT_is_parametric(DType) && PyArray_ISOBJECT(arr))) {
/*
* We have one special case, if (and only if) the input array is of
* object DType and the dtype is not fixed already but parametric.
@@ -745,6 +752,7 @@ find_descriptor_from_array(
NULL, DType, &flags, item_DType) < 0) {
Py_DECREF(iter);
Py_DECREF(elem);
+ Py_XDECREF(*out_descr);
Py_XDECREF(item_DType);
return -1;
}
@@ -824,7 +832,7 @@ PyArray_AdaptDescriptorToArray(PyArrayObject *arr, PyObject *dtype)
}
if (new_dtype == NULL) {
/* This is an object array but contained no elements, use default */
- new_dtype = new_DType->default_descr(new_DType);
+ new_dtype = NPY_DT_CALL_default_descr(new_DType);
}
}
Py_DECREF(new_DType);
@@ -922,6 +930,53 @@ PyArray_DiscoverDTypeAndShape_Recursive(
Py_DECREF(arr);
arr = NULL;
}
+ else if (curr_dims > 0 && curr_dims != max_dims) {
+ /*
+ * Deprecated 2020-12-09, NumPy 1.20
+ *
+ * See https://github.com/numpy/numpy/issues/17965
+ * Shapely had objects which are not sequences but did export
+ * the array-interface (and so are arguably array-like).
+ * Previously numpy would not use array-like information during
+ * shape discovery, so that it ended up acting as if this was
+ * an (unknown) scalar but with the specified dtype.
+ * Thus we ignore "scalars" here, as the value stored in the
+ * array should be acceptable.
+ */
+ if (PyArray_NDIM(arr) > 0 && NPY_UNLIKELY(!PySequence_Check(obj))) {
+ if (PyErr_WarnFormat(PyExc_FutureWarning, 1,
+ "The input object of type '%s' is an array-like "
+ "implementing one of the corresponding protocols "
+ "(`__array__`, `__array_interface__` or "
+ "`__array_struct__`); but not a sequence (or 0-D). "
+ "In the future, this object will be coerced as if it "
+ "was first converted using `np.array(obj)`. "
+ "To retain the old behaviour, you have to either "
+ "modify the type '%s', or assign to an empty array "
+ "created with `np.empty(correct_shape, dtype=object)`.",
+ Py_TYPE(obj)->tp_name, Py_TYPE(obj)->tp_name) < 0) {
+ Py_DECREF(arr);
+ return -1;
+ }
+ /*
+ * Strangely enough, even though we threw away the result here,
+ * we did use it during descriptor discovery, so promote it:
+ */
+ if (update_shape(curr_dims, &max_dims, out_shape,
+ 0, NULL, NPY_FALSE, flags) < 0) {
+ *flags |= FOUND_RAGGED_ARRAY;
+ Py_DECREF(arr);
+ return max_dims;
+ }
+ if (!(*flags & DESCRIPTOR_WAS_SET) && handle_promotion(
+ out_descr, PyArray_DESCR(arr), fixed_DType, flags) < 0) {
+ Py_DECREF(arr);
+ return -1;
+ }
+ Py_DECREF(arr);
+ return max_dims;
+ }
+ }
}
if (arr != NULL) {
/*
@@ -979,14 +1034,28 @@ PyArray_DiscoverDTypeAndShape_Recursive(
* and to handle it recursively. That is, unless we have hit the
* dimension limit.
*/
- npy_bool is_sequence = (PySequence_Check(obj) && PySequence_Size(obj) >= 0);
+ npy_bool is_sequence = PySequence_Check(obj);
+ if (is_sequence) {
+ is_sequence = PySequence_Size(obj) >= 0;
+ if (NPY_UNLIKELY(!is_sequence)) {
+ /* NOTE: This should likely just raise all errors */
+ if (PyErr_ExceptionMatches(PyExc_RecursionError) ||
+ PyErr_ExceptionMatches(PyExc_MemoryError)) {
+ /*
+ * Consider these unrecoverable errors, continuing execution
+ * might crash the interpreter.
+ */
+ return -1;
+ }
+ PyErr_Clear();
+ }
+ }
if (NPY_UNLIKELY(*flags & DISCOVER_TUPLES_AS_ELEMENTS) &&
PyTuple_Check(obj)) {
is_sequence = NPY_FALSE;
}
if (curr_dims == max_dims || !is_sequence) {
/* Clear any PySequence_Size error which would corrupts further calls */
- PyErr_Clear();
max_dims = handle_scalar(
obj, curr_dims, &max_dims, out_descr, out_shape, fixed_DType,
flags, NULL);
@@ -1037,6 +1106,11 @@ PyArray_DiscoverDTypeAndShape_Recursive(
return curr_dims + 1;
}
+ /* Allow keyboard interrupts. See gh issue 18117. */
+ if (PyErr_CheckSignals() < 0) {
+ return -1;
+ }
+
/* Recursive call for each sequence item */
for (Py_ssize_t i = 0; i < size; i++) {
max_dims = PyArray_DiscoverDTypeAndShape_Recursive(
@@ -1301,7 +1375,7 @@ PyArray_DiscoverDTypeAndShape(
* the correct default.
*/
if (fixed_DType != NULL) {
- *out_descr = fixed_DType->default_descr(fixed_DType);
+ *out_descr = NPY_DT_CALL_default_descr(fixed_DType);
if (*out_descr == NULL) {
goto fail;
}
diff --git a/numpy/core/src/multiarray/array_coercion.h b/numpy/core/src/multiarray/array_coercion.h
index 90ce0355a..c5ccad225 100644
--- a/numpy/core/src/multiarray/array_coercion.h
+++ b/numpy/core/src/multiarray/array_coercion.h
@@ -15,7 +15,6 @@ typedef struct coercion_cache_obj {
int depth; /* the dimension at which this object was found. */
} coercion_cache_obj;
-
NPY_NO_EXPORT int
_PyArray_MapPyTypeToDType(
PyArray_DTypeMeta *DType, PyTypeObject *pytype, npy_bool userdef);
diff --git a/numpy/core/src/multiarray/array_method.c b/numpy/core/src/multiarray/array_method.c
index cae452454..44ba8c733 100644
--- a/numpy/core/src/multiarray/array_method.c
+++ b/numpy/core/src/multiarray/array_method.c
@@ -34,7 +34,9 @@
#include "arrayobject.h"
#include "array_method.h"
#include "dtypemeta.h"
+#include "common_dtype.h"
#include "convert_datatype.h"
+#include "common.h"
/*
@@ -70,7 +72,7 @@ default_resolve_descriptors(
output_descrs[i] = ensure_dtype_nbo(input_descrs[i]);
}
else {
- output_descrs[i] = dtype->default_descr(dtype);
+ output_descrs[i] = NPY_DT_CALL_default_descr(dtype);
}
if (NPY_UNLIKELY(output_descrs[i] == NULL)) {
goto fail;
@@ -104,7 +106,7 @@ default_resolve_descriptors(
output_descrs[i] = ensure_dtype_nbo(input_descrs[i]);
}
else {
- output_descrs[i] = common_dtype->default_descr(common_dtype);
+ output_descrs[i] = NPY_DT_CALL_default_descr(common_dtype);
}
if (NPY_UNLIKELY(output_descrs[i] == NULL)) {
goto fail;
@@ -121,6 +123,19 @@ default_resolve_descriptors(
}
+NPY_INLINE static int
+is_contiguous(
+ npy_intp const *strides, PyArray_Descr *const *descriptors, int nargs)
+{
+ for (int i = 0; i < nargs; i++) {
+ if (strides[i] != descriptors[i]->elsize) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+
/**
* The default method to fetch the correct loop for a cast or ufunc
* (at the time of writing only casts).
@@ -138,18 +153,36 @@ default_resolve_descriptors(
* @param flags
* @return 0 on success -1 on failure.
*/
-static int
-default_get_strided_loop(
- PyArrayMethod_Context *NPY_UNUSED(context),
- int NPY_UNUSED(aligned), int NPY_UNUSED(move_references),
- npy_intp *NPY_UNUSED(strides),
- PyArray_StridedUnaryOp **NPY_UNUSED(out_loop),
- NpyAuxData **NPY_UNUSED(out_transferdata),
- NPY_ARRAYMETHOD_FLAGS *NPY_UNUSED(flags))
+NPY_NO_EXPORT int
+npy_default_get_strided_loop(
+ PyArrayMethod_Context *context,
+ int aligned, int NPY_UNUSED(move_references), npy_intp *strides,
+ PyArrayMethod_StridedLoop **out_loop, NpyAuxData **out_transferdata,
+ NPY_ARRAYMETHOD_FLAGS *flags)
{
- PyErr_SetString(PyExc_NotImplementedError,
- "default loop getter is not implemented");
- return -1;
+ PyArray_Descr **descrs = context->descriptors;
+ PyArrayMethodObject *meth = context->method;
+ *flags = meth->flags & NPY_METH_RUNTIME_FLAGS;
+ *out_transferdata = NULL;
+
+ int nargs = meth->nin + meth->nout;
+ if (aligned) {
+ if (meth->contiguous_loop == NULL ||
+ !is_contiguous(strides, descrs, nargs)) {
+ *out_loop = meth->strided_loop;
+ return 0;
+ }
+ *out_loop = meth->contiguous_loop;
+ }
+ else {
+ if (meth->unaligned_contiguous_loop == NULL ||
+ !is_contiguous(strides, descrs, nargs)) {
+ *out_loop = meth->unaligned_strided_loop;
+ return 0;
+ }
+ *out_loop = meth->unaligned_contiguous_loop;
+ }
+ return 0;
}
@@ -178,10 +211,12 @@ validate_spec(PyArrayMethod_Spec *spec)
case NPY_UNSAFE_CASTING:
break;
default:
- PyErr_Format(PyExc_TypeError,
- "ArrayMethod has invalid casting `%d`. (method: %s)",
- spec->casting, spec->name);
- return -1;
+ if (spec->casting != -1) {
+ PyErr_Format(PyExc_TypeError,
+ "ArrayMethod has invalid casting `%d`. (method: %s)",
+ spec->casting, spec->name);
+ return -1;
+ }
}
for (int i = 0; i < nargs; i++) {
@@ -197,7 +232,7 @@ validate_spec(PyArrayMethod_Spec *spec)
"(method: %s)", spec->dtypes[i], spec->name);
return -1;
}
- if (spec->dtypes[i]->abstract && i < spec->nin) {
+ if (NPY_DT_is_abstract(spec->dtypes[i]) && i < spec->nin) {
PyErr_Format(PyExc_TypeError,
"abstract DType %S are currently not allowed for inputs."
"(method: %s defined at %s)", spec->dtypes[i], spec->name);
@@ -225,7 +260,7 @@ fill_arraymethod_from_slots(
PyArrayMethodObject *meth = res->method;
/* Set the defaults */
- meth->get_strided_loop = &default_get_strided_loop;
+ meth->get_strided_loop = &npy_default_get_strided_loop;
meth->resolve_descriptors = &default_resolve_descriptors;
/* Fill in the slots passed by the user */
@@ -269,6 +304,13 @@ fill_arraymethod_from_slots(
/* Check whether the slots are valid: */
if (meth->resolve_descriptors == &default_resolve_descriptors) {
+ if (spec->casting == -1) {
+ PyErr_Format(PyExc_TypeError,
+ "Cannot set casting to -1 (invalid) when not providing "
+ "the default `resolve_descriptors` function. "
+ "(method: %s)", spec->name);
+ return -1;
+ }
for (int i = 0; i < meth->nin + meth->nout; i++) {
if (res->dtypes[i] == NULL) {
if (i < meth->nin) {
@@ -286,7 +328,7 @@ fill_arraymethod_from_slots(
return -1;
}
}
- if (i >= meth->nin && res->dtypes[i]->parametric) {
+ if (i >= meth->nin && NPY_DT_is_parametric(res->dtypes[i])) {
PyErr_Format(PyExc_TypeError,
"must provide a `resolve_descriptors` function if any "
"output DType is parametric. (method: %s)",
@@ -295,7 +337,7 @@ fill_arraymethod_from_slots(
}
}
}
- if (meth->get_strided_loop != &default_get_strided_loop) {
+ if (meth->get_strided_loop != &npy_default_get_strided_loop) {
/* Do not check the actual loop fields. */
return 0;
}
@@ -391,7 +433,7 @@ PyArrayMethod_FromSpec_int(PyArrayMethod_Spec *spec, int private)
return NULL;
}
- ssize_t length = strlen(spec->name);
+ Py_ssize_t length = strlen(spec->name);
res->method->name = PyMem_Malloc(length + 1);
if (res->method->name == NULL) {
Py_DECREF(res);
@@ -430,14 +472,11 @@ static PyObject *
boundarraymethod_repr(PyBoundArrayMethodObject *self)
{
int nargs = self->method->nin + self->method->nout;
- PyObject *dtypes = PyTuple_New(nargs);
+ PyObject *dtypes = PyArray_TupleFromItems(
+ nargs, (PyObject **)self->dtypes, 0);
if (dtypes == NULL) {
return NULL;
}
- for (int i = 0; i < nargs; i++) {
- Py_INCREF(self->dtypes[i]);
- PyTuple_SET_ITEM(dtypes, i, (PyObject *)self->dtypes[i]);
- }
return PyUnicode_FromFormat(
"<np._BoundArrayMethod `%s` for dtypes %S>",
self->method->name, dtypes);
@@ -468,6 +507,9 @@ boundarraymethod_dealloc(PyObject *self)
* May raise an error, but usually should not.
* The function validates the casting attribute compared to the returned
* casting level.
+ *
+ * TODO: This function is not public API, and certain code paths will need
+ * changes and especially testing if they were to be made public.
*/
static PyObject *
boundarraymethod__resolve_descripors(
@@ -481,7 +523,7 @@ boundarraymethod__resolve_descripors(
if (!PyTuple_CheckExact(descr_tuple) ||
PyTuple_Size(descr_tuple) != nin + nout) {
- PyErr_Format(PyExc_ValueError,
+ PyErr_Format(PyExc_TypeError,
"_resolve_descriptors() takes exactly one tuple with as many "
"elements as the method takes arguments (%d+%d).", nin, nout);
return NULL;
@@ -494,7 +536,7 @@ boundarraymethod__resolve_descripors(
}
else if (tmp == Py_None) {
if (i < nin) {
- PyErr_SetString(PyExc_ValueError,
+ PyErr_SetString(PyExc_TypeError,
"only output dtypes may be omitted (set to None).");
return NULL;
}
@@ -502,7 +544,7 @@ boundarraymethod__resolve_descripors(
}
else if (PyArray_DescrCheck(tmp)) {
if (Py_TYPE(tmp) != (PyTypeObject *)self->dtypes[i]) {
- PyErr_Format(PyExc_ValueError,
+ PyErr_Format(PyExc_TypeError,
"input dtype %S was not an exact instance of the bound "
"DType class %S.", tmp, self->dtypes[i]);
return NULL;
@@ -538,51 +580,306 @@ boundarraymethod__resolve_descripors(
/*
* The casting flags should be the most generic casting level (except the
* cast-is-view flag. If no input is parametric, it must match exactly.
+ *
+ * (Note that these checks are only debugging checks.)
*/
int parametric = 0;
for (int i = 0; i < nin + nout; i++) {
- if (self->dtypes[i]->parametric) {
+ if (NPY_DT_is_parametric(self->dtypes[i])) {
parametric = 1;
break;
}
}
- if (!parametric) {
- /*
- * Non-parametric can only mismatch if it switches from no to equiv
- * (e.g. due to byteorder changes).
- */
- if (self->method->casting != (casting & ~_NPY_CAST_IS_VIEW) &&
- !(self->method->casting == NPY_NO_CASTING &&
- casting == NPY_EQUIV_CASTING)) {
+ if (self->method->casting != -1) {
+ NPY_CASTING cast = casting & ~_NPY_CAST_IS_VIEW;
+ if (self->method->casting !=
+ PyArray_MinCastSafety(cast, self->method->casting)) {
PyErr_Format(PyExc_RuntimeError,
- "resolve_descriptors cast level did not match stored one "
- "(expected %d, got %d) for method %s",
- self->method->casting, (casting & ~_NPY_CAST_IS_VIEW),
- self->method->name);
+ "resolve_descriptors cast level did not match stored one. "
+ "(set level is %d, got %d for method %s)",
+ self->method->casting, cast, self->method->name);
Py_DECREF(result_tuple);
return NULL;
}
+ if (!parametric) {
+ /*
+ * Non-parametric can only mismatch if it switches from equiv to no
+ * (e.g. due to byteorder changes).
+ */
+ if (cast != self->method->casting &&
+ self->method->casting != NPY_EQUIV_CASTING) {
+ PyErr_Format(PyExc_RuntimeError,
+ "resolve_descriptors cast level changed even though "
+ "the cast is non-parametric where the only possible "
+ "change should be from equivalent to no casting. "
+ "(set level is %d, got %d for method %s)",
+ self->method->casting, cast, self->method->name);
+ Py_DECREF(result_tuple);
+ return NULL;
+ }
+ }
}
- else {
- NPY_CASTING cast = casting & ~_NPY_CAST_IS_VIEW;
- if (cast != PyArray_MinCastSafety(cast, self->method->casting)) {
- PyErr_Format(PyExc_RuntimeError,
- "resolve_descriptors cast level did not match stored one "
- "(expected %d, got %d) for method %s",
- self->method->casting, (casting & ~_NPY_CAST_IS_VIEW),
- self->method->name);
- Py_DECREF(result_tuple);
+
+ return Py_BuildValue("iN", casting, result_tuple);
+}
+
+
+/*
+ * TODO: This function is not public API, and certain code paths will need
+ * changes and especially testing if they were to be made public.
+ */
+static PyObject *
+boundarraymethod__simple_strided_call(
+ PyBoundArrayMethodObject *self, PyObject *arr_tuple)
+{
+ PyArrayObject *arrays[NPY_MAXARGS];
+ PyArray_Descr *descrs[NPY_MAXARGS];
+ PyArray_Descr *out_descrs[NPY_MAXARGS];
+ Py_ssize_t length = -1;
+ int aligned = 1;
+ char *args[NPY_MAXARGS];
+ npy_intp strides[NPY_MAXARGS];
+ int nin = self->method->nin;
+ int nout = self->method->nout;
+
+ if (!PyTuple_CheckExact(arr_tuple) ||
+ PyTuple_Size(arr_tuple) != nin + nout) {
+ PyErr_Format(PyExc_TypeError,
+ "_simple_strided_call() takes exactly one tuple with as many "
+ "arrays as the method takes arguments (%d+%d).", nin, nout);
+ return NULL;
+ }
+
+ for (int i = 0; i < nin + nout; i++) {
+ PyObject *tmp = PyTuple_GetItem(arr_tuple, i);
+ if (tmp == NULL) {
+ return NULL;
+ }
+ else if (!PyArray_CheckExact(tmp)) {
+ PyErr_SetString(PyExc_TypeError,
+ "All inputs must be NumPy arrays.");
+ return NULL;
+ }
+ arrays[i] = (PyArrayObject *)tmp;
+ descrs[i] = PyArray_DESCR(arrays[i]);
+
+ /* Check that the input is compatible with a simple method call. */
+ if (Py_TYPE(descrs[i]) != (PyTypeObject *)self->dtypes[i]) {
+ PyErr_Format(PyExc_TypeError,
+ "input dtype %S was not an exact instance of the bound "
+ "DType class %S.", descrs[i], self->dtypes[i]);
+ return NULL;
+ }
+ if (PyArray_NDIM(arrays[i]) != 1) {
+ PyErr_SetString(PyExc_ValueError,
+ "All arrays must be one dimensional.");
return NULL;
}
+ if (i == 0) {
+ length = PyArray_SIZE(arrays[i]);
+ }
+ else if (PyArray_SIZE(arrays[i]) != length) {
+ PyErr_SetString(PyExc_ValueError,
+ "All arrays must have the same length.");
+ return NULL;
+ }
+ if (i >= nout) {
+ if (PyArray_FailUnlessWriteable(
+ arrays[i], "_simple_strided_call() output") < 0) {
+ return NULL;
+ }
+ }
+
+ args[i] = PyArray_BYTES(arrays[i]);
+ strides[i] = PyArray_STRIDES(arrays[i])[0];
+ /* TODO: We may need to distinguish aligned and itemsize-aligned */
+ aligned &= PyArray_ISALIGNED(arrays[i]);
+ }
+ if (!aligned && !(self->method->flags & NPY_METH_SUPPORTS_UNALIGNED)) {
+ PyErr_SetString(PyExc_ValueError,
+ "method does not support unaligned input.");
+ return NULL;
}
- return Py_BuildValue("iN", casting, result_tuple);
+ NPY_CASTING casting = self->method->resolve_descriptors(
+ self->method, self->dtypes, descrs, out_descrs);
+
+ if (casting < 0) {
+ PyObject *err_type = NULL, *err_value = NULL, *err_traceback = NULL;
+ PyErr_Fetch(&err_type, &err_value, &err_traceback);
+ PyErr_SetString(PyExc_TypeError,
+ "cannot perform method call with the given dtypes.");
+ npy_PyErr_ChainExceptions(err_type, err_value, err_traceback);
+ return NULL;
+ }
+
+ int dtypes_were_adapted = 0;
+ for (int i = 0; i < nin + nout; i++) {
+ /* NOTE: This check is probably much stricter than necessary... */
+ dtypes_were_adapted |= descrs[i] != out_descrs[i];
+ Py_DECREF(out_descrs[i]);
+ }
+ if (dtypes_were_adapted) {
+ PyErr_SetString(PyExc_TypeError,
+ "_simple_strided_call(): requires dtypes to not require a cast "
+ "(must match exactly with `_resolve_descriptors()`).");
+ return NULL;
+ }
+
+ PyArrayMethod_Context context = {
+ .caller = NULL,
+ .method = self->method,
+ .descriptors = descrs,
+ };
+ PyArrayMethod_StridedLoop *strided_loop = NULL;
+ NpyAuxData *loop_data = NULL;
+ NPY_ARRAYMETHOD_FLAGS flags = 0;
+
+ if (self->method->get_strided_loop(
+ &context, aligned, 0, strides,
+ &strided_loop, &loop_data, &flags) < 0) {
+ return NULL;
+ }
+
+ /*
+ * TODO: Add floating point error checks if requested and
+ * possibly release GIL if allowed by the flags.
+ */
+ int res = strided_loop(&context, args, &length, strides, loop_data);
+ if (loop_data != NULL) {
+ loop_data->free(loop_data);
+ }
+ if (res < 0) {
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+
+/*
+ * Support for masked inner-strided loops. Masked inner-strided loops are
+ * only used in the ufunc machinery. So this special cases them.
+ * In the future it probably makes sense to create an::
+ *
+ * Arraymethod->get_masked_strided_loop()
+ *
+ * Function which this can wrap instead.
+ */
+typedef struct {
+ NpyAuxData base;
+ PyArrayMethod_StridedLoop *unmasked_stridedloop;
+ NpyAuxData *unmasked_auxdata;
+ int nargs;
+ char *dataptrs[];
+} _masked_stridedloop_data;
+
+
+static void
+_masked_stridedloop_data_free(NpyAuxData *auxdata)
+{
+ _masked_stridedloop_data *data = (_masked_stridedloop_data *)auxdata;
+ NPY_AUXDATA_FREE(data->unmasked_auxdata);
+ PyMem_Free(data);
+}
+
+
+/*
+ * This function wraps a regular unmasked strided-loop as a
+ * masked strided-loop, only calling the function for elements
+ * where the mask is True.
+ */
+static int
+generic_masked_strided_loop(PyArrayMethod_Context *context,
+ char *const *data, const npy_intp *dimensions,
+ const npy_intp *strides, NpyAuxData *_auxdata)
+{
+ _masked_stridedloop_data *auxdata = (_masked_stridedloop_data *)_auxdata;
+ int nargs = auxdata->nargs;
+ PyArrayMethod_StridedLoop *strided_loop = auxdata->unmasked_stridedloop;
+ NpyAuxData *strided_loop_auxdata = auxdata->unmasked_auxdata;
+
+ char **dataptrs = auxdata->dataptrs;
+ memcpy(dataptrs, data, nargs * sizeof(char *));
+ char *mask = data[nargs];
+ npy_intp mask_stride = strides[nargs];
+
+ npy_intp N = dimensions[0];
+ /* Process the data as runs of unmasked values */
+ do {
+ ssize_t subloopsize;
+
+ /* Skip masked values */
+ mask = npy_memchr(mask, 0, mask_stride, N, &subloopsize, 1);
+ for (int i = 0; i < nargs; i++) {
+ dataptrs[i] += subloopsize * strides[i];
+ }
+ N -= subloopsize;
+
+ /* Process unmasked values */
+ mask = npy_memchr(mask, 0, mask_stride, N, &subloopsize, 0);
+ int res = strided_loop(context,
+ dataptrs, &subloopsize, strides, strided_loop_auxdata);
+ if (res != 0) {
+ return res;
+ }
+ for (int i = 0; i < nargs; i++) {
+ dataptrs[i] += subloopsize * strides[i];
+ }
+ N -= subloopsize;
+ } while (N > 0);
+
+ return 0;
+}
+
+
+/*
+ * Fetches a strided-loop function that supports a boolean mask as additional
+ * (last) operand to the strided-loop. It is otherwise largely identical to
+ * the `get_loop` method which it wraps.
+ * This is the core implementation for the ufunc `where=...` keyword argument.
+ *
+ * NOTE: This function does not support `move_references` or inner dimensions.
+ */
+NPY_NO_EXPORT int
+PyArrayMethod_GetMaskedStridedLoop(
+ PyArrayMethod_Context *context,
+ int aligned, npy_intp *fixed_strides,
+ PyArrayMethod_StridedLoop **out_loop,
+ NpyAuxData **out_transferdata,
+ NPY_ARRAYMETHOD_FLAGS *flags)
+{
+ _masked_stridedloop_data *data;
+ int nargs = context->method->nin + context->method->nout;
+
+ /* Add working memory for the data pointers, to modify them in-place */
+ data = PyMem_Malloc(sizeof(_masked_stridedloop_data) +
+ sizeof(char *) * nargs);
+ if (data == NULL) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ data->base.free = _masked_stridedloop_data_free;
+ data->base.clone = NULL; /* not currently used */
+ data->unmasked_stridedloop = NULL;
+ data->nargs = nargs;
+
+ if (context->method->get_strided_loop(context,
+ aligned, 0, fixed_strides,
+ &data->unmasked_stridedloop, &data->unmasked_auxdata, flags) < 0) {
+ PyMem_Free(data);
+ return -1;
+ }
+ *out_transferdata = (NpyAuxData *)data;
+ *out_loop = generic_masked_strided_loop;
+ return 0;
}
PyMethodDef boundarraymethod_methods[] = {
{"_resolve_descriptors", (PyCFunction)boundarraymethod__resolve_descripors,
METH_O, "Resolve the given dtypes."},
+ {"_simple_strided_call", (PyCFunction)boundarraymethod__simple_strided_call,
+ METH_O, "call on 1-d inputs and pre-allocated outputs (single call)."},
{NULL, 0, 0, NULL},
};
diff --git a/numpy/core/src/multiarray/array_method.h b/numpy/core/src/multiarray/array_method.h
index 15ea948ce..fc2304889 100644
--- a/numpy/core/src/multiarray/array_method.h
+++ b/numpy/core/src/multiarray/array_method.h
@@ -6,7 +6,6 @@
#include <Python.h>
#include <numpy/ndarraytypes.h>
-#include <lowlevel_strided_loops.h>
typedef enum {
@@ -18,6 +17,7 @@ typedef enum {
* setup/check. No function should set error flags and ignore them
* since it would interfere with chaining operations (e.g. casting).
*/
+ /* TODO: Change this into a positive flag */
NPY_METH_NO_FLOATINGPOINT_ERRORS = 1 << 2,
/* Whether the method supports unaligned access (not runtime) */
NPY_METH_SUPPORTS_UNALIGNED = 1 << 3,
@@ -50,6 +50,11 @@ typedef struct {
} PyArrayMethod_Context;
+typedef int (PyArrayMethod_StridedLoop)(PyArrayMethod_Context *context,
+ char *const *data, const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *transferdata);
+
+
typedef NPY_CASTING (resolve_descriptors_function)(
struct PyArrayMethodObject_tag *method,
PyArray_DTypeMeta **dtypes,
@@ -61,7 +66,7 @@ typedef int (get_loop_function)(
PyArrayMethod_Context *context,
int aligned, int move_references,
npy_intp *strides,
- PyArray_StridedUnaryOp **out_loop,
+ PyArrayMethod_StridedLoop **out_loop,
NpyAuxData **out_transferdata,
NPY_ARRAYMETHOD_FLAGS *flags);
@@ -104,10 +109,10 @@ typedef struct PyArrayMethodObject_tag {
resolve_descriptors_function *resolve_descriptors;
get_loop_function *get_strided_loop;
/* Typical loop functions (contiguous ones are used in current casts) */
- PyArray_StridedUnaryOp *strided_loop;
- PyArray_StridedUnaryOp *contiguous_loop;
- PyArray_StridedUnaryOp *unaligned_strided_loop;
- PyArray_StridedUnaryOp *unaligned_contiguous_loop;
+ PyArrayMethod_StridedLoop *strided_loop;
+ PyArrayMethod_StridedLoop *contiguous_loop;
+ PyArrayMethod_StridedLoop *unaligned_strided_loop;
+ PyArrayMethod_StridedLoop *unaligned_contiguous_loop;
} PyArrayMethodObject;
@@ -144,6 +149,31 @@ extern NPY_NO_EXPORT PyTypeObject PyBoundArrayMethod_Type;
#define NPY_METH_unaligned_contiguous_loop 6
+/*
+ * Used internally (initially) for real to complex loops only
+ */
+NPY_NO_EXPORT int
+npy_default_get_strided_loop(
+ PyArrayMethod_Context *context,
+ int aligned, int NPY_UNUSED(move_references), npy_intp *strides,
+ PyArrayMethod_StridedLoop **out_loop, NpyAuxData **out_transferdata,
+ NPY_ARRAYMETHOD_FLAGS *flags);
+
+
+NPY_NO_EXPORT int
+PyArrayMethod_GetMaskedStridedLoop(
+ PyArrayMethod_Context *context,
+ int aligned,
+ npy_intp *fixed_strides,
+ PyArrayMethod_StridedLoop **out_loop,
+ NpyAuxData **out_transferdata,
+ NPY_ARRAYMETHOD_FLAGS *flags);
+
+
+/*
+ * TODO: This function is the internal version, and its error paths may
+ * need better tests when a public version is exposed.
+ */
NPY_NO_EXPORT PyBoundArrayMethodObject *
PyArrayMethod_FromSpec_int(PyArrayMethod_Spec *spec, int private);
diff --git a/numpy/core/src/multiarray/arrayfunction_override.c b/numpy/core/src/multiarray/arrayfunction_override.c
index 2c07cdebc..463a2d4d8 100644
--- a/numpy/core/src/multiarray/arrayfunction_override.c
+++ b/numpy/core/src/multiarray/arrayfunction_override.c
@@ -213,7 +213,7 @@ call_array_function(PyObject* argument, PyObject* method,
* to NotImplemented to indicate the default implementation should
* be used.
*/
-NPY_NO_EXPORT PyObject *
+static PyObject *
array_implement_array_function_internal(
PyObject *public_api, PyObject *relevant_args,
PyObject *args, PyObject *kwargs)
@@ -341,18 +341,23 @@ array_implement_array_function(
return NULL;
}
- /* Remove `like=` kwarg, which is NumPy-exclusive and thus not present
+ /*
+ * Remove `like=` kwarg, which is NumPy-exclusive and thus not present
* in downstream libraries. If `like=` is specified but doesn't
* implement `__array_function__`, raise a `TypeError`.
*/
if (kwargs != NULL && PyDict_Contains(kwargs, npy_ma_str_like)) {
PyObject *like_arg = PyDict_GetItem(kwargs, npy_ma_str_like);
- if (like_arg && !get_array_function(like_arg)) {
- return PyErr_Format(PyExc_TypeError,
- "The `like` argument must be an array-like that implements "
- "the `__array_function__` protocol.");
+ if (like_arg != NULL) {
+ PyObject *tmp_has_override = get_array_function(like_arg);
+ if (tmp_has_override == NULL) {
+ return PyErr_Format(PyExc_TypeError,
+ "The `like` argument must be an array-like that "
+ "implements the `__array_function__` protocol.");
+ }
+ Py_DECREF(tmp_has_override);
+ PyDict_DelItem(kwargs, npy_ma_str_like);
}
- PyDict_DelItem(kwargs, npy_ma_str_like);
}
PyObject *res = array_implement_array_function_internal(
@@ -364,66 +369,104 @@ array_implement_array_function(
return res;
}
-
/*
* Implements the __array_function__ protocol for C array creation functions
* only. Added as an extension to NEP-18 in an effort to bring NEP-35 to
* life with minimal dispatch overhead.
+ *
+ * The caller must ensure that `like != NULL`.
*/
NPY_NO_EXPORT PyObject *
array_implement_c_array_function_creation(
- const char *function_name, PyObject *args, PyObject *kwargs)
+ const char *function_name, PyObject *like,
+ PyObject *args, PyObject *kwargs,
+ PyObject *const *fast_args, Py_ssize_t len_args, PyObject *kwnames)
{
- if (kwargs == NULL) {
- return Py_NotImplemented;
+ PyObject *relevant_args = NULL;
+ PyObject *numpy_module = NULL;
+ PyObject *public_api = NULL;
+ PyObject *result = NULL;
+
+ /* If `like` doesn't implement `__array_function__`, raise a `TypeError` */
+ PyObject *tmp_has_override = get_array_function(like);
+ if (tmp_has_override == NULL) {
+ return PyErr_Format(PyExc_TypeError,
+ "The `like` argument must be an array-like that "
+ "implements the `__array_function__` protocol.");
}
+ Py_DECREF(tmp_has_override);
- /* Remove `like=` kwarg, which is NumPy-exclusive and thus not present
- * in downstream libraries. If that key isn't present, return NULL and
- * let originating call to continue. If the key is present but doesn't
- * implement `__array_function__`, raise a `TypeError`.
- */
- if (!PyDict_Contains(kwargs, npy_ma_str_like)) {
- return Py_NotImplemented;
+ if (fast_args != NULL) {
+ /*
+ * Convert from vectorcall convention, since the protocol requires
+ * the normal convention. We have to do this late to ensure the
+ * normal path where NotImplemented is returned is fast.
+ */
+ assert(args == NULL);
+ assert(kwargs == NULL);
+ args = PyTuple_New(len_args);
+ if (args == NULL) {
+ return NULL;
+ }
+ for (Py_ssize_t i = 0; i < len_args; i++) {
+ Py_INCREF(fast_args[i]);
+ PyTuple_SET_ITEM(args, i, fast_args[i]);
+ }
+ if (kwnames != NULL) {
+ kwargs = PyDict_New();
+ if (kwargs == NULL) {
+ Py_DECREF(args);
+ return NULL;
+ }
+ Py_ssize_t nkwargs = PyTuple_GET_SIZE(kwnames);
+ for (Py_ssize_t i = 0; i < nkwargs; i++) {
+ PyObject *key = PyTuple_GET_ITEM(kwnames, i);
+ PyObject *value = fast_args[i+len_args];
+ if (PyDict_SetItem(kwargs, key, value) < 0) {
+ Py_DECREF(args);
+ Py_DECREF(kwargs);
+ return NULL;
+ }
+ }
+ }
}
- PyObject *like_arg = PyDict_GetItem(kwargs, npy_ma_str_like);
- if (like_arg == NULL) {
- return NULL;
+ relevant_args = PyTuple_Pack(1, like);
+ if (relevant_args == NULL) {
+ goto finish;
}
- else if (!get_array_function(like_arg)) {
- return PyErr_Format(PyExc_TypeError,
- "The `like` argument must be an array-like that implements "
- "the `__array_function__` protocol.");
+ /* The like argument must be present in the keyword arguments, remove it */
+ if (PyDict_DelItem(kwargs, npy_ma_str_like) < 0) {
+ goto finish;
}
- PyObject *relevant_args = PyTuple_Pack(1, like_arg);
- PyDict_DelItem(kwargs, npy_ma_str_like);
- PyObject *numpy_module = PyImport_Import(npy_ma_str_numpy);
+ numpy_module = PyImport_Import(npy_ma_str_numpy);
if (numpy_module == NULL) {
- Py_DECREF(relevant_args);
- return NULL;
+ goto finish;
}
- PyObject *public_api = PyObject_GetAttrString(numpy_module, function_name);
+ public_api = PyObject_GetAttrString(numpy_module, function_name);
Py_DECREF(numpy_module);
if (public_api == NULL) {
- Py_DECREF(relevant_args);
- return NULL;
+ goto finish;
}
if (!PyCallable_Check(public_api)) {
- Py_DECREF(relevant_args);
- Py_DECREF(public_api);
- return PyErr_Format(PyExc_RuntimeError,
- "numpy.%s is not callable.",
- function_name);
+ PyErr_Format(PyExc_RuntimeError,
+ "numpy.%s is not callable.", function_name);
+ goto finish;
}
- PyObject* result = array_implement_array_function_internal(
+ result = array_implement_array_function_internal(
public_api, relevant_args, args, kwargs);
- Py_DECREF(relevant_args);
- Py_DECREF(public_api);
+ finish:
+ if (kwnames != NULL) {
+ /* args and kwargs were converted from vectorcall convention */
+ Py_XDECREF(args);
+ Py_XDECREF(kwargs);
+ }
+ Py_XDECREF(relevant_args);
+ Py_XDECREF(public_api);
return result;
}
diff --git a/numpy/core/src/multiarray/arrayfunction_override.h b/numpy/core/src/multiarray/arrayfunction_override.h
index fdcf1746d..fdf0dfcaf 100644
--- a/numpy/core/src/multiarray/arrayfunction_override.h
+++ b/numpy/core/src/multiarray/arrayfunction_override.h
@@ -11,7 +11,9 @@ array__get_implementing_args(
NPY_NO_EXPORT PyObject *
array_implement_c_array_function_creation(
- const char *function_name, PyObject *args, PyObject *kwargs);
+ const char *function_name, PyObject *like,
+ PyObject *args, PyObject *kwargs,
+ PyObject *const *fast_args, Py_ssize_t len_args, PyObject *kwnames);
NPY_NO_EXPORT PyObject *
array_function_method_impl(PyObject *func, PyObject *types, PyObject *args,
diff --git a/numpy/core/src/multiarray/arrayobject.c b/numpy/core/src/multiarray/arrayobject.c
index a2474d79f..55ba5601b 100644
--- a/numpy/core/src/multiarray/arrayobject.c
+++ b/numpy/core/src/multiarray/arrayobject.c
@@ -41,6 +41,7 @@ maintainer email: oliphant.travis@ieee.org
#include "arraytypes.h"
#include "scalartypes.h"
#include "arrayobject.h"
+#include "convert_datatype.h"
#include "conversion_utils.h"
#include "ctors.h"
#include "dtypemeta.h"
@@ -971,8 +972,7 @@ _strings_richcompare(PyArrayObject *self, PyArrayObject *other, int cmp_op,
PyArrayMultiIterObject *mit;
int val;
- /* Cast arrays to a common type */
- if (PyArray_TYPE(self) != PyArray_DESCR(other)->type_num) {
+ if (PyArray_TYPE(self) != PyArray_TYPE(other)) {
/*
* Comparison between Bytes and Unicode is not defined in Py3K;
* we follow.
@@ -981,53 +981,22 @@ _strings_richcompare(PyArrayObject *self, PyArrayObject *other, int cmp_op,
return Py_NotImplemented;
}
if (PyArray_ISNOTSWAPPED(self) != PyArray_ISNOTSWAPPED(other)) {
- PyObject *new;
- if (PyArray_TYPE(self) == NPY_STRING &&
- PyArray_DESCR(other)->type_num == NPY_UNICODE) {
- PyArray_Descr* unicode = PyArray_DescrNew(PyArray_DESCR(other));
- unicode->elsize = PyArray_DESCR(self)->elsize << 2;
- new = PyArray_FromAny((PyObject *)self, unicode,
- 0, 0, 0, NULL);
- if (new == NULL) {
- return NULL;
- }
- Py_INCREF(other);
- self = (PyArrayObject *)new;
- }
- else if ((PyArray_TYPE(self) == NPY_UNICODE) &&
- ((PyArray_DESCR(other)->type_num == NPY_STRING) ||
- (PyArray_ISNOTSWAPPED(self) != PyArray_ISNOTSWAPPED(other)))) {
- PyArray_Descr* unicode = PyArray_DescrNew(PyArray_DESCR(self));
-
- if (PyArray_DESCR(other)->type_num == NPY_STRING) {
- unicode->elsize = PyArray_DESCR(other)->elsize << 2;
- }
- else {
- unicode->elsize = PyArray_DESCR(other)->elsize;
- }
- new = PyArray_FromAny((PyObject *)other, unicode,
- 0, 0, 0, NULL);
- if (new == NULL) {
- return NULL;
- }
- Py_INCREF(self);
- other = (PyArrayObject *)new;
- }
- else {
- PyErr_SetString(PyExc_TypeError,
- "invalid string data-types "
- "in comparison");
+ /* Cast `other` to the same byte order as `self` (both unicode here) */
+ PyArray_Descr* unicode = PyArray_DescrNew(PyArray_DESCR(self));
+ unicode->elsize = PyArray_DESCR(other)->elsize;
+ PyObject *new = PyArray_FromAny((PyObject *)other,
+ unicode, 0, 0, 0, NULL);
+ if (new == NULL) {
return NULL;
}
+ other = (PyArrayObject *)new;
}
else {
- Py_INCREF(self);
Py_INCREF(other);
}
/* Broad-cast the arrays to a common shape */
mit = (PyArrayMultiIterObject *)PyArray_MultiIterNew(2, self, other);
- Py_DECREF(self);
Py_DECREF(other);
if (mit == NULL) {
return NULL;
@@ -1356,11 +1325,13 @@ array_richcompare(PyArrayObject *self, PyObject *other, int cmp_op)
switch (cmp_op) {
case Py_LT:
RICHCMP_GIVE_UP_IF_NEEDED(obj_self, other);
- result = PyArray_GenericBinaryFunction(self, other, n_ops.less);
+ result = PyArray_GenericBinaryFunction(
+ (PyObject *)self, other, n_ops.less);
break;
case Py_LE:
RICHCMP_GIVE_UP_IF_NEEDED(obj_self, other);
- result = PyArray_GenericBinaryFunction(self, other, n_ops.less_equal);
+ result = PyArray_GenericBinaryFunction(
+ (PyObject *)self, other, n_ops.less_equal);
break;
case Py_EQ:
RICHCMP_GIVE_UP_IF_NEEDED(obj_self, other);
@@ -1388,9 +1359,13 @@ array_richcompare(PyArrayObject *self, PyObject *other, int cmp_op)
return Py_NotImplemented;
}
- _res = PyArray_CanCastTypeTo(PyArray_DESCR(self),
- PyArray_DESCR(array_other),
- NPY_EQUIV_CASTING);
+ _res = PyArray_CheckCastSafety(
+ NPY_EQUIV_CASTING,
+ PyArray_DESCR(self), PyArray_DESCR(array_other), NULL);
+ if (_res < 0) {
+ PyErr_Clear();
+ _res = 0;
+ }
if (_res == 0) {
/* 2015-05-07, 1.10 */
Py_DECREF(array_other);
@@ -1410,9 +1385,8 @@ array_richcompare(PyArrayObject *self, PyObject *other, int cmp_op)
return result;
}
- result = PyArray_GenericBinaryFunction(self,
- (PyObject *)other,
- n_ops.equal);
+ result = PyArray_GenericBinaryFunction(
+ (PyObject *)self, (PyObject *)other, n_ops.equal);
break;
case Py_NE:
RICHCMP_GIVE_UP_IF_NEEDED(obj_self, other);
@@ -1440,9 +1414,13 @@ array_richcompare(PyArrayObject *self, PyObject *other, int cmp_op)
return Py_NotImplemented;
}
- _res = PyArray_CanCastTypeTo(PyArray_DESCR(self),
- PyArray_DESCR(array_other),
- NPY_EQUIV_CASTING);
+ _res = PyArray_CheckCastSafety(
+ NPY_EQUIV_CASTING,
+ PyArray_DESCR(self), PyArray_DESCR(array_other), NULL);
+ if (_res < 0) {
+ PyErr_Clear();
+ _res = 0;
+ }
if (_res == 0) {
/* 2015-05-07, 1.10 */
Py_DECREF(array_other);
@@ -1462,18 +1440,18 @@ array_richcompare(PyArrayObject *self, PyObject *other, int cmp_op)
return result;
}
- result = PyArray_GenericBinaryFunction(self, (PyObject *)other,
- n_ops.not_equal);
+ result = PyArray_GenericBinaryFunction(
+ (PyObject *)self, (PyObject *)other, n_ops.not_equal);
break;
case Py_GT:
RICHCMP_GIVE_UP_IF_NEEDED(obj_self, other);
- result = PyArray_GenericBinaryFunction(self, other,
- n_ops.greater);
+ result = PyArray_GenericBinaryFunction(
+ (PyObject *)self, other, n_ops.greater);
break;
case Py_GE:
RICHCMP_GIVE_UP_IF_NEEDED(obj_self, other);
- result = PyArray_GenericBinaryFunction(self, other,
- n_ops.greater_equal);
+ result = PyArray_GenericBinaryFunction(
+ (PyObject *)self, other, n_ops.greater_equal);
break;
default:
Py_INCREF(Py_NotImplemented);
@@ -1754,10 +1732,6 @@ NPY_NO_EXPORT PyTypeObject PyArray_Type = {
.tp_as_number = &array_as_number,
.tp_as_sequence = &array_as_sequence,
.tp_as_mapping = &array_as_mapping,
- /*
- * The tp_hash slot will be set PyObject_HashNotImplemented when the
- * module is loaded.
- */
.tp_str = (reprfunc)array_str,
.tp_as_buffer = &array_as_buffer,
.tp_flags =(Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE),
diff --git a/numpy/core/src/multiarray/arraytypes.c.src b/numpy/core/src/multiarray/arraytypes.c.src
index ecaca72a1..b3ea7544d 100644
--- a/numpy/core/src/multiarray/arraytypes.c.src
+++ b/numpy/core/src/multiarray/arraytypes.c.src
@@ -42,6 +42,32 @@
#include "npy_cblas.h"
#include "npy_buffer.h"
+
+/*
+ * Define a stack allocated dummy array with only the minimum information set:
+ * 1. The descr, the main field interesting here.
+ * 2. The flags, which are needed for alignment;.
+ * 3. The type is set to NULL and the base is the original array, if this
+ * is used within a subarray getitem to create a new view, the base
+ * must be walked until the type is not NULL.
+ *
+ * The following should create errors in debug mode (if deallocated
+ * incorrectly), since base would be incorrectly decref'd as well.
+ * This is especially important for nonzero and copyswap, which may run with
+ * the GIL released.
+ */
+static NPY_INLINE PyArrayObject_fields
+get_dummy_stack_array(PyArrayObject *orig)
+{
+ PyArrayObject_fields new_fields;
+ new_fields.flags = PyArray_FLAGS(orig);
+ /* Set to NULL so the dummy object can be distinguished from the real one */
+ Py_TYPE(&new_fields) = NULL;
+ new_fields.base = (PyObject *)orig;
+ return new_fields;
+}
+
+
/* check for sequences, but ignore the types numpy considers scalars */
static NPY_INLINE npy_bool
PySequence_NoString_Check(PyObject *op) {
@@ -674,6 +700,7 @@ OBJECT_setitem(PyObject *op, void *ov, void *NPY_UNUSED(ap))
return PyErr_Occurred() ? -1 : 0;
}
+
/* VOID */
static PyObject *
@@ -681,22 +708,21 @@ VOID_getitem(void *input, void *vap)
{
PyArrayObject *ap = vap;
char *ip = input;
- PyArray_Descr* descr;
+ PyArray_Descr* descr = PyArray_DESCR(vap);
- descr = PyArray_DESCR(ap);
if (PyDataType_HASFIELDS(descr)) {
PyObject *key;
PyObject *names;
int i, n;
PyObject *ret;
PyObject *tup;
- int savedflags;
+ PyArrayObject_fields dummy_fields = get_dummy_stack_array(ap);
+ PyArrayObject *dummy_arr = (PyArrayObject *)&dummy_fields;
/* get the names from the fields dictionary*/
names = descr->names;
n = PyTuple_GET_SIZE(names);
ret = PyTuple_New(n);
- savedflags = PyArray_FLAGS(ap);
for (i = 0; i < n; i++) {
npy_intp offset;
PyArray_Descr *new;
@@ -704,26 +730,19 @@ VOID_getitem(void *input, void *vap)
tup = PyDict_GetItem(descr->fields, key);
if (_unpack_field(tup, &new, &offset) < 0) {
Py_DECREF(ret);
- ((PyArrayObject_fields *)ap)->descr = descr;
return NULL;
}
- /*
- * TODO: temporarily modifying the array like this
- * is bad coding style, should be changed.
- */
- ((PyArrayObject_fields *)ap)->descr = new;
+ dummy_fields.descr = new;
/* update alignment based on offset */
if ((new->alignment > 1)
&& ((((npy_intp)(ip+offset)) % new->alignment) != 0)) {
- PyArray_CLEARFLAGS(ap, NPY_ARRAY_ALIGNED);
+ PyArray_CLEARFLAGS(dummy_arr, NPY_ARRAY_ALIGNED);
}
else {
- PyArray_ENABLEFLAGS(ap, NPY_ARRAY_ALIGNED);
+ PyArray_ENABLEFLAGS(dummy_arr, NPY_ARRAY_ALIGNED);
}
- PyTuple_SET_ITEM(ret, i, PyArray_GETITEM(ap, ip+offset));
- ((PyArrayObject_fields *)ap)->flags = savedflags;
+ PyTuple_SET_ITEM(ret, i, PyArray_GETITEM(dummy_arr, ip+offset));
}
- ((PyArrayObject_fields *)ap)->descr = descr;
return ret;
}
@@ -739,11 +758,28 @@ VOID_getitem(void *input, void *vap)
return NULL;
}
Py_INCREF(descr->subarray->base);
+
+ /*
+ * NOTE: There is the possibility of recursive calls from the above
+ * field branch. These calls use a dummy arr for thread
+ * (and general) safety. However, we must set the base array,
+ * so if such a dummy array was passed (its type is NULL),
+ * we have walk its base until the initial array is found.
+ *
+ * TODO: This should be fixed, the next "generation" of GETITEM will
+ * probably need to pass in the original array (in addition
+ * to the dtype as a method). Alternatively, VOID dtypes
+ * could have special handling.
+ */
+ PyObject *base = (PyObject *)ap;
+ while (Py_TYPE(base) == NULL) {
+ base = PyArray_BASE((PyArrayObject *)base);
+ }
ret = (PyArrayObject *)PyArray_NewFromDescrAndBase(
&PyArray_Type, descr->subarray->base,
shape.len, shape.ptr, NULL, ip,
PyArray_FLAGS(ap) & ~NPY_ARRAY_F_CONTIGUOUS,
- NULL, (PyObject *)ap);
+ NULL, base);
npy_free_cache_dim_obj(shape);
return (PyObject *)ret;
}
@@ -761,7 +797,8 @@ NPY_NO_EXPORT int PyArray_CopyObject(PyArrayObject *, PyObject *);
* individual fields of a numpy structure, in VOID_setitem. Compare to inner
* loops in VOID_getitem and VOID_nonzero.
*
- * WARNING: Clobbers arr's dtype and alignment flag.
+ * WARNING: Clobbers arr's dtype and alignment flag, should not be used
+ * on the original array!
*/
NPY_NO_EXPORT int
_setup_field(int i, PyArray_Descr *descr, PyArrayObject *arr,
@@ -798,7 +835,7 @@ static int
_copy_and_return_void_setitem(PyArray_Descr *dstdescr, char *dstdata,
PyArray_Descr *srcdescr, char *srcdata){
PyArrayObject_fields dummy_struct;
- PyArrayObject *dummy = (PyArrayObject *)&dummy_struct;
+ PyArrayObject *dummy_arr = (PyArrayObject *)&dummy_struct;
npy_int names_size = PyTuple_GET_SIZE(dstdescr->names);
npy_intp offset;
npy_int i;
@@ -808,11 +845,11 @@ _copy_and_return_void_setitem(PyArray_Descr *dstdescr, char *dstdata,
if (PyArray_EquivTypes(srcdescr, dstdescr)) {
for (i = 0; i < names_size; i++) {
/* neither line can ever fail, in principle */
- if (_setup_field(i, dstdescr, dummy, &offset, dstdata)) {
+ if (_setup_field(i, dstdescr, dummy_arr, &offset, dstdata)) {
return -1;
}
- PyArray_DESCR(dummy)->f->copyswap(dstdata + offset,
- srcdata + offset, 0, dummy);
+ PyArray_DESCR(dummy_arr)->f->copyswap(dstdata + offset,
+ srcdata + offset, 0, dummy_arr);
}
return 0;
}
@@ -831,13 +868,10 @@ VOID_setitem(PyObject *op, void *input, void *vap)
{
char *ip = input;
PyArrayObject *ap = vap;
- PyArray_Descr *descr;
- int flags;
- int itemsize=PyArray_DESCR(ap)->elsize;
+ int itemsize = PyArray_DESCR(ap)->elsize;
int res;
+ PyArray_Descr *descr = PyArray_DESCR(ap);
- descr = PyArray_DESCR(ap);
- flags = PyArray_FLAGS(ap);
if (PyDataType_HASFIELDS(descr)) {
PyObject *errmsg;
npy_int i;
@@ -874,11 +908,13 @@ VOID_setitem(PyObject *op, void *input, void *vap)
return -1;
}
+ PyArrayObject_fields dummy_fields = get_dummy_stack_array(ap);
+ PyArrayObject *dummy_arr = (PyArrayObject *)&dummy_fields;
+
for (i = 0; i < names_size; i++) {
PyObject *item;
- /* temporarily make ap have only this field */
- if (_setup_field(i, descr, ap, &offset, ip) == -1) {
+ if (_setup_field(i, descr, dummy_arr, &offset, ip) == -1) {
failed = 1;
break;
}
@@ -888,7 +924,7 @@ VOID_setitem(PyObject *op, void *input, void *vap)
break;
}
/* use setitem to set this field */
- if (PyArray_SETITEM(ap, ip + offset, item) < 0) {
+ if (PyArray_SETITEM(dummy_arr, ip + offset, item) < 0) {
failed = 1;
break;
}
@@ -898,24 +934,23 @@ VOID_setitem(PyObject *op, void *input, void *vap)
/* Otherwise must be non-void scalar. Try to assign to each field */
npy_intp names_size = PyTuple_GET_SIZE(descr->names);
+ PyArrayObject_fields dummy_fields = get_dummy_stack_array(ap);
+ PyArrayObject *dummy_arr = (PyArrayObject *)&dummy_fields;
+
for (i = 0; i < names_size; i++) {
/* temporarily make ap have only this field */
- if (_setup_field(i, descr, ap, &offset, ip) == -1) {
+ if (_setup_field(i, descr, dummy_arr, &offset, ip) == -1) {
failed = 1;
break;
}
/* use setitem to set this field */
- if (PyArray_SETITEM(ap, ip + offset, op) < 0) {
+ if (PyArray_SETITEM(dummy_arr, ip + offset, op) < 0) {
failed = 1;
break;
}
}
}
- /* reset clobbered attributes */
- ((PyArrayObject_fields *)(ap))->descr = descr;
- ((PyArrayObject_fields *)(ap))->flags = flags;
-
if (failed) {
return -1;
}
@@ -924,7 +959,6 @@ VOID_setitem(PyObject *op, void *input, void *vap)
else if (PyDataType_HASSUBARRAY(descr)) {
/* copy into an array of the same basic type */
PyArray_Dims shape = {NULL, -1};
- PyArrayObject *ret;
if (!(PyArray_IntpConverter(descr->subarray->shape, &shape))) {
npy_free_cache_dim_obj(shape);
PyErr_SetString(PyExc_ValueError,
@@ -932,10 +966,15 @@ VOID_setitem(PyObject *op, void *input, void *vap)
return -1;
}
Py_INCREF(descr->subarray->base);
- ret = (PyArrayObject *)PyArray_NewFromDescrAndBase(
+ /*
+ * Note we set no base object here, as to not rely on the input
+ * being a valid object for base setting. `ret` nevertheless does
+ * does not own its data, this is generally not good, but localized.
+ */
+ PyArrayObject *ret = (PyArrayObject *)PyArray_NewFromDescrAndBase(
&PyArray_Type, descr->subarray->base,
shape.len, shape.ptr, NULL, ip,
- PyArray_FLAGS(ap), NULL, (PyObject *)ap);
+ PyArray_FLAGS(ap), NULL, NULL);
npy_free_cache_dim_obj(shape);
if (!ret) {
return -1;
@@ -2287,6 +2326,7 @@ STRING_copyswapn (char *dst, npy_intp dstride, char *src, npy_intp sstride,
return;
}
+
/* */
static void
VOID_copyswapn (char *dst, npy_intp dstride, char *src, npy_intp sstride,
@@ -2303,29 +2343,26 @@ VOID_copyswapn (char *dst, npy_intp dstride, char *src, npy_intp sstride,
if (PyArray_HASFIELDS(arr)) {
PyObject *key, *value;
-
Py_ssize_t pos = 0;
+ PyArrayObject_fields dummy_fields = get_dummy_stack_array(arr);
+ PyArrayObject *dummy_arr = (PyArrayObject *)&dummy_fields;
+
while (PyDict_Next(descr->fields, &pos, &key, &value)) {
npy_intp offset;
- PyArray_Descr * new;
+ PyArray_Descr *new;
if (NPY_TITLE_KEY(key, value)) {
continue;
}
if (_unpack_field(value, &new, &offset) < 0) {
- ((PyArrayObject_fields *)arr)->descr = descr;
return;
}
- /*
- * TODO: temporarily modifying the array like this
- * is bad coding style, should be changed.
- */
- ((PyArrayObject_fields *)arr)->descr = new;
+
+ dummy_fields.descr = new;
new->f->copyswapn(dst+offset, dstride,
(src != NULL ? src+offset : NULL),
- sstride, n, swap, arr);
+ sstride, n, swap, dummy_arr);
}
- ((PyArrayObject_fields *)arr)->descr = descr;
return;
}
if (PyDataType_HASSUBARRAY(descr)) {
@@ -2351,11 +2388,6 @@ VOID_copyswapn (char *dst, npy_intp dstride, char *src, npy_intp sstride,
}
new = descr->subarray->base;
- /*
- * TODO: temporarily modifying the array like this
- * is bad coding style, should be changed.
- */
- ((PyArrayObject_fields *)arr)->descr = new;
dstptr = dst;
srcptr = src;
subitemsize = new->elsize;
@@ -2363,16 +2395,20 @@ VOID_copyswapn (char *dst, npy_intp dstride, char *src, npy_intp sstride,
/* There cannot be any elements, so return */
return;
}
+
+ PyArrayObject_fields dummy_fields = get_dummy_stack_array(arr);
+ PyArrayObject *dummy_arr = (PyArrayObject *)&dummy_fields;
+ ((PyArrayObject_fields *)dummy_arr)->descr = new;
+
num = descr->elsize / subitemsize;
for (i = 0; i < n; i++) {
new->f->copyswapn(dstptr, subitemsize, srcptr,
- subitemsize, num, swap, arr);
+ subitemsize, num, swap, dummy_arr);
dstptr += dstride;
if (srcptr) {
srcptr += sstride;
}
}
- ((PyArrayObject_fields *)arr)->descr = descr;
return;
}
/* Must be a naive Void type (e.g. a "V8") so simple copy is sufficient. */
@@ -2396,26 +2432,24 @@ VOID_copyswap (char *dst, char *src, int swap, PyArrayObject *arr)
PyObject *key, *value;
Py_ssize_t pos = 0;
+ PyArrayObject_fields dummy_fields = get_dummy_stack_array(arr);
+ PyArrayObject *dummy_arr = (PyArrayObject *)&dummy_fields;
+
while (PyDict_Next(descr->fields, &pos, &key, &value)) {
npy_intp offset;
+
PyArray_Descr * new;
if (NPY_TITLE_KEY(key, value)) {
continue;
}
if (_unpack_field(value, &new, &offset) < 0) {
- ((PyArrayObject_fields *)arr)->descr = descr;
return;
}
- /*
- * TODO: temporarily modifying the array like this
- * is bad coding style, should be changed.
- */
- ((PyArrayObject_fields *)arr)->descr = new;
+ dummy_fields.descr = new;
new->f->copyswap(dst+offset,
(src != NULL ? src+offset : NULL),
- swap, arr);
+ swap, dummy_arr);
}
- ((PyArrayObject_fields *)arr)->descr = descr;
return;
}
if (PyDataType_HASSUBARRAY(descr)) {
@@ -2439,20 +2473,19 @@ VOID_copyswap (char *dst, char *src, int swap, PyArrayObject *arr)
}
new = descr->subarray->base;
- /*
- * TODO: temporarily modifying the array like this
- * is bad coding style, should be changed.
- */
- ((PyArrayObject_fields *)arr)->descr = new;
subitemsize = new->elsize;
if (subitemsize == 0) {
/* There cannot be any elements, so return */
return;
}
+
+ PyArrayObject_fields dummy_fields = get_dummy_stack_array(arr);
+ PyArrayObject *dummy_arr = (PyArrayObject *)&dummy_fields;
+ dummy_fields.descr = new;
+
num = descr->elsize / subitemsize;
new->f->copyswapn(dst, subitemsize, src,
- subitemsize, num, swap, arr);
- ((PyArrayObject_fields *)arr)->descr = descr;
+ subitemsize, num, swap, dummy_arr);
return;
}
/* Must be a naive Void type (e.g. a "V8") so simple copy is sufficient. */
@@ -2707,11 +2740,11 @@ VOID_nonzero (char *ip, PyArrayObject *ap)
if (PyArray_HASFIELDS(ap)) {
PyArray_Descr *descr;
PyObject *key, *value;
- int savedflags;
Py_ssize_t pos = 0;
+ PyArrayObject_fields dummy_fields = get_dummy_stack_array(ap);
+ PyArrayObject *dummy_arr = (PyArrayObject *)&dummy_fields;
descr = PyArray_DESCR(ap);
- savedflags = PyArray_FLAGS(ap);
while (PyDict_Next(descr->fields, &pos, &key, &value)) {
PyArray_Descr * new;
npy_intp offset;
@@ -2722,12 +2755,8 @@ VOID_nonzero (char *ip, PyArrayObject *ap)
PyErr_Clear();
continue;
}
- /*
- * TODO: temporarily modifying the array like this
- * is bad coding style, should be changed.
- */
- ((PyArrayObject_fields *)ap)->descr = new;
- ((PyArrayObject_fields *)ap)->flags = savedflags;
+
+ dummy_fields.descr = new;
if ((new->alignment > 1) && !__ALIGNED(ip + offset,
new->alignment)) {
PyArray_CLEARFLAGS(ap, NPY_ARRAY_ALIGNED);
@@ -2735,13 +2764,11 @@ VOID_nonzero (char *ip, PyArrayObject *ap)
else {
PyArray_ENABLEFLAGS(ap, NPY_ARRAY_ALIGNED);
}
- if (new->f->nonzero(ip+offset, ap)) {
+ if (new->f->nonzero(ip+offset, dummy_arr)) {
nonz = NPY_TRUE;
break;
}
}
- ((PyArrayObject_fields *)ap)->descr = descr;
- ((PyArrayObject_fields *)ap)->flags = savedflags;
return nonz;
}
len = PyArray_DESCR(ap)->elsize;
@@ -2778,11 +2805,9 @@ BOOL_compare(npy_bool *ip1, npy_bool *ip2, PyArrayObject *NPY_UNUSED(ap))
/**begin repeat
* #TYPE = BYTE, UBYTE, SHORT, USHORT, INT, UINT,
- * LONG, ULONG, LONGLONG, ULONGLONG,
- * DATETIME, TIMEDELTA#
+ * LONG, ULONG, LONGLONG, ULONGLONG#
* #type = npy_byte, npy_ubyte, npy_short, npy_ushort, npy_int, npy_uint,
- * npy_long, npy_ulong, npy_longlong, npy_ulonglong,
- * npy_datetime, npy_timedelta#
+ * npy_long, npy_ulong, npy_longlong, npy_ulonglong#
*/
static int
@@ -2893,6 +2918,37 @@ C@TYPE@_compare(@type@ *pa, @type@ *pb)
/**end repeat**/
+/**begin repeat
+ * #TYPE = DATETIME, TIMEDELTA#
+ * #type = npy_datetime, npy_timedelta#
+ */
+
+static int
+@TYPE@_compare(@type@ *pa, @type@ *pb)
+{
+ const @type@ a = *pa;
+ const @type@ b = *pb;
+ int ret;
+
+ if (a == NPY_DATETIME_NAT) {
+ if (b == NPY_DATETIME_NAT) {
+ ret = 0;
+ }
+ else {
+ ret = 1;
+ }
+ }
+ else if (b == NPY_DATETIME_NAT) {
+ ret = -1;
+ }
+ else {
+ ret = a < b ? -1 : a == b ? 0 : 1;
+ }
+ return ret;
+}
+
+/**end repeat**/
+
static int
HALF_compare (npy_half *pa, npy_half *pb, PyArrayObject *NPY_UNUSED(ap))
{
diff --git a/numpy/core/src/multiarray/buffer.c b/numpy/core/src/multiarray/buffer.c
index 813850224..5458c81cc 100644
--- a/numpy/core/src/multiarray/buffer.c
+++ b/numpy/core/src/multiarray/buffer.c
@@ -878,6 +878,7 @@ void_getbuffer(PyObject *self, Py_buffer *view, int flags)
*/
_buffer_info_t *info = _buffer_get_info(&scalar->_buffer_info, self, flags);
if (info == NULL) {
+ Py_DECREF(self);
return -1;
}
view->format = info->format;
diff --git a/numpy/core/src/multiarray/calculation.c b/numpy/core/src/multiarray/calculation.c
index 43d88271b..21e52c32b 100644
--- a/numpy/core/src/multiarray/calculation.c
+++ b/numpy/core/src/multiarray/calculation.c
@@ -34,18 +34,25 @@ power_of_ten(int n)
return ret;
}
-/*NUMPY_API
- * ArgMax
- */
NPY_NO_EXPORT PyObject *
-PyArray_ArgMax(PyArrayObject *op, int axis, PyArrayObject *out)
+_PyArray_ArgMinMaxCommon(PyArrayObject *op,
+ int axis, PyArrayObject *out, int keepdims,
+ npy_bool is_argmax)
{
PyArrayObject *ap = NULL, *rp = NULL;
- PyArray_ArgFunc* arg_func;
- char *ip;
+ PyArray_ArgFunc* arg_func = NULL;
+ char *ip, *func_name;
npy_intp *rptr;
npy_intp i, n, m;
int elsize;
+ // Keep a copy because axis changes via call to PyArray_CheckAxis
+ int axis_copy = axis;
+ npy_intp _shape_buf[NPY_MAXDIMS];
+ npy_intp *out_shape;
+ // Keep the number of dimensions and shape of
+ // original array. Helps when `keepdims` is True.
+ npy_intp* original_op_shape = PyArray_DIMS(op);
+ int out_ndim = PyArray_NDIM(op);
NPY_BEGIN_THREADS_DEF;
if ((ap = (PyArrayObject *)PyArray_CheckAxis(op, &axis, 0)) == NULL) {
@@ -86,123 +93,37 @@ PyArray_ArgMax(PyArrayObject *op, int axis, PyArrayObject *out)
if (ap == NULL) {
return NULL;
}
- arg_func = PyArray_DESCR(ap)->f->argmax;
- if (arg_func == NULL) {
- PyErr_SetString(PyExc_TypeError,
- "data type not ordered");
- goto fail;
- }
- elsize = PyArray_DESCR(ap)->elsize;
- m = PyArray_DIMS(ap)[PyArray_NDIM(ap)-1];
- if (m == 0) {
- PyErr_SetString(PyExc_ValueError,
- "attempt to get argmax of an empty sequence");
- goto fail;
- }
- if (!out) {
- rp = (PyArrayObject *)PyArray_NewFromDescr(
- Py_TYPE(ap), PyArray_DescrFromType(NPY_INTP),
- PyArray_NDIM(ap) - 1, PyArray_DIMS(ap), NULL, NULL,
- 0, (PyObject *)ap);
- if (rp == NULL) {
- goto fail;
- }
+ // Decides the shape of the output array.
+ if (!keepdims) {
+ out_ndim = PyArray_NDIM(ap) - 1;
+ out_shape = PyArray_DIMS(ap);
}
else {
- if ((PyArray_NDIM(out) != PyArray_NDIM(ap) - 1) ||
- !PyArray_CompareLists(PyArray_DIMS(out), PyArray_DIMS(ap),
- PyArray_NDIM(out))) {
- PyErr_SetString(PyExc_ValueError,
- "output array does not match result of np.argmax.");
- goto fail;
- }
- rp = (PyArrayObject *)PyArray_FromArray(out,
- PyArray_DescrFromType(NPY_INTP),
- NPY_ARRAY_CARRAY | NPY_ARRAY_WRITEBACKIFCOPY);
- if (rp == NULL) {
- goto fail;
+ out_shape = _shape_buf;
+ if (axis_copy == NPY_MAXDIMS) {
+ for (int i = 0; i < out_ndim; i++) {
+ out_shape[i] = 1;
+ }
+ }
+ else {
+ /*
+ * While `ap` may be transposed, we can ignore this for `out` because the
+ * transpose only reorders the size 1 `axis` (not changing memory layout).
+ */
+ memcpy(out_shape, original_op_shape, out_ndim * sizeof(npy_intp));
+ out_shape[axis] = 1;
}
}
- NPY_BEGIN_THREADS_DESCR(PyArray_DESCR(ap));
- n = PyArray_SIZE(ap)/m;
- rptr = (npy_intp *)PyArray_DATA(rp);
- for (ip = PyArray_DATA(ap), i = 0; i < n; i++, ip += elsize*m) {
- arg_func(ip, m, rptr, ap);
- rptr += 1;
- }
- NPY_END_THREADS_DESCR(PyArray_DESCR(ap));
-
- Py_DECREF(ap);
- /* Trigger the UPDATEIFCOPY/WRTIEBACKIFCOPY if necessary */
- if (out != NULL && out != rp) {
- PyArray_ResolveWritebackIfCopy(rp);
- Py_DECREF(rp);
- rp = out;
- Py_INCREF(rp);
- }
- return (PyObject *)rp;
-
- fail:
- Py_DECREF(ap);
- Py_XDECREF(rp);
- return NULL;
-}
-
-/*NUMPY_API
- * ArgMin
- */
-NPY_NO_EXPORT PyObject *
-PyArray_ArgMin(PyArrayObject *op, int axis, PyArrayObject *out)
-{
- PyArrayObject *ap = NULL, *rp = NULL;
- PyArray_ArgFunc* arg_func;
- char *ip;
- npy_intp *rptr;
- npy_intp i, n, m;
- int elsize;
- NPY_BEGIN_THREADS_DEF;
-
- if ((ap = (PyArrayObject *)PyArray_CheckAxis(op, &axis, 0)) == NULL) {
- return NULL;
- }
- /*
- * We need to permute the array so that axis is placed at the end.
- * And all other dimensions are shifted left.
- */
- if (axis != PyArray_NDIM(ap)-1) {
- PyArray_Dims newaxes;
- npy_intp dims[NPY_MAXDIMS];
- int i;
-
- newaxes.ptr = dims;
- newaxes.len = PyArray_NDIM(ap);
- for (i = 0; i < axis; i++) {
- dims[i] = i;
- }
- for (i = axis; i < PyArray_NDIM(ap) - 1; i++) {
- dims[i] = i + 1;
- }
- dims[PyArray_NDIM(ap) - 1] = axis;
- op = (PyArrayObject *)PyArray_Transpose(ap, &newaxes);
- Py_DECREF(ap);
- if (op == NULL) {
- return NULL;
- }
+ if (is_argmax) {
+ func_name = "argmax";
+ arg_func = PyArray_DESCR(ap)->f->argmax;
}
else {
- op = ap;
- }
-
- /* Will get native-byte order contiguous copy. */
- ap = (PyArrayObject *)PyArray_ContiguousFromAny((PyObject *)op,
- PyArray_DESCR(op)->type_num, 1, 0);
- Py_DECREF(op);
- if (ap == NULL) {
- return NULL;
+ func_name = "argmin";
+ arg_func = PyArray_DESCR(ap)->f->argmin;
}
- arg_func = PyArray_DESCR(ap)->f->argmin;
if (arg_func == NULL) {
PyErr_SetString(PyExc_TypeError,
"data type not ordered");
@@ -211,26 +132,28 @@ PyArray_ArgMin(PyArrayObject *op, int axis, PyArrayObject *out)
elsize = PyArray_DESCR(ap)->elsize;
m = PyArray_DIMS(ap)[PyArray_NDIM(ap)-1];
if (m == 0) {
- PyErr_SetString(PyExc_ValueError,
- "attempt to get argmin of an empty sequence");
+ PyErr_Format(PyExc_ValueError,
+ "attempt to get %s of an empty sequence",
+ func_name);
goto fail;
}
if (!out) {
rp = (PyArrayObject *)PyArray_NewFromDescr(
Py_TYPE(ap), PyArray_DescrFromType(NPY_INTP),
- PyArray_NDIM(ap) - 1, PyArray_DIMS(ap), NULL, NULL,
+ out_ndim, out_shape, NULL, NULL,
0, (PyObject *)ap);
if (rp == NULL) {
goto fail;
}
}
else {
- if ((PyArray_NDIM(out) != PyArray_NDIM(ap) - 1) ||
- !PyArray_CompareLists(PyArray_DIMS(out), PyArray_DIMS(ap),
- PyArray_NDIM(out))) {
- PyErr_SetString(PyExc_ValueError,
- "output array does not match result of np.argmin.");
+ if ((PyArray_NDIM(out) != out_ndim) ||
+ !PyArray_CompareLists(PyArray_DIMS(out), out_shape,
+ out_ndim)) {
+ PyErr_Format(PyExc_ValueError,
+ "output array does not match result of np.%s.",
+ func_name);
goto fail;
}
rp = (PyArrayObject *)PyArray_FromArray(out,
@@ -266,6 +189,38 @@ PyArray_ArgMin(PyArrayObject *op, int axis, PyArrayObject *out)
return NULL;
}
+NPY_NO_EXPORT PyObject*
+_PyArray_ArgMaxWithKeepdims(PyArrayObject *op,
+ int axis, PyArrayObject *out, int keepdims)
+{
+ return _PyArray_ArgMinMaxCommon(op, axis, out, keepdims, 1);
+}
+
+/*NUMPY_API
+ * ArgMax
+ */
+NPY_NO_EXPORT PyObject *
+PyArray_ArgMax(PyArrayObject *op, int axis, PyArrayObject *out)
+{
+ return _PyArray_ArgMinMaxCommon(op, axis, out, 0, 1);
+}
+
+NPY_NO_EXPORT PyObject *
+_PyArray_ArgMinWithKeepdims(PyArrayObject *op,
+ int axis, PyArrayObject *out, int keepdims)
+{
+ return _PyArray_ArgMinMaxCommon(op, axis, out, keepdims, 0);
+}
+
+/*NUMPY_API
+ * ArgMin
+ */
+NPY_NO_EXPORT PyObject *
+PyArray_ArgMin(PyArrayObject *op, int axis, PyArrayObject *out)
+{
+ return _PyArray_ArgMinMaxCommon(op, axis, out, 0, 0);
+}
+
/*NUMPY_API
* Max
*/
@@ -392,7 +347,7 @@ __New_PyArray_Std(PyArrayObject *self, int axis, int rtype, PyArrayObject *out,
else {
val = PyArray_DIM(arrnew,i);
}
- PyTuple_SET_ITEM(newshape, i, PyLong_FromLong((long)val));
+ PyTuple_SET_ITEM(newshape, i, PyLong_FromSsize_t(val));
}
arr2 = (PyArrayObject *)PyArray_Reshape(arr1, newshape);
Py_DECREF(arr1);
@@ -423,7 +378,8 @@ __New_PyArray_Std(PyArrayObject *self, int axis, int rtype, PyArrayObject *out,
return NULL;
}
arr2 = (PyArrayObject *)PyArray_EnsureAnyArray(
- PyArray_GenericBinaryFunction(arr1, obj3, n_ops.multiply));
+ PyArray_GenericBinaryFunction((PyObject *)arr1, obj3,
+ n_ops.multiply));
Py_DECREF(arr1);
Py_DECREF(obj3);
if (arr2 == NULL) {
@@ -1211,7 +1167,7 @@ PyArray_Conjugate(PyArrayObject *self, PyArrayObject *out)
n_ops.conjugate);
}
else {
- return PyArray_GenericBinaryFunction(self,
+ return PyArray_GenericBinaryFunction((PyObject *)self,
(PyObject *)out,
n_ops.conjugate);
}
diff --git a/numpy/core/src/multiarray/calculation.h b/numpy/core/src/multiarray/calculation.h
index 34bc31f69..49105a138 100644
--- a/numpy/core/src/multiarray/calculation.h
+++ b/numpy/core/src/multiarray/calculation.h
@@ -5,9 +5,15 @@ NPY_NO_EXPORT PyObject*
PyArray_ArgMax(PyArrayObject* self, int axis, PyArrayObject *out);
NPY_NO_EXPORT PyObject*
+_PyArray_ArgMaxWithKeepdims(PyArrayObject* self, int axis, PyArrayObject *out, int keepdims);
+
+NPY_NO_EXPORT PyObject*
PyArray_ArgMin(PyArrayObject* self, int axis, PyArrayObject *out);
NPY_NO_EXPORT PyObject*
+_PyArray_ArgMinWithKeepdims(PyArrayObject* self, int axis, PyArrayObject *out, int keepdims);
+
+NPY_NO_EXPORT PyObject*
PyArray_Max(PyArrayObject* self, int axis, PyArrayObject* out);
NPY_NO_EXPORT PyObject*
diff --git a/numpy/core/src/multiarray/common.c b/numpy/core/src/multiarray/common.c
index 841ed799d..1fd9ab1a3 100644
--- a/numpy/core/src/multiarray/common.c
+++ b/numpy/core/src/multiarray/common.c
@@ -46,8 +46,8 @@ _array_find_python_scalar_type(PyObject *op)
return PyArray_DescrFromType(NPY_CDOUBLE);
}
else if (PyLong_Check(op)) {
- return PyArray_PyIntAbstractDType.discover_descr_from_pyobject(
- &PyArray_PyIntAbstractDType, op);
+ return NPY_DT_CALL_discover_descr_from_pyobject(
+ &PyArray_PyIntAbstractDType, op);
}
return NULL;
}
diff --git a/numpy/core/src/multiarray/common.h b/numpy/core/src/multiarray/common.h
index ef9bc79da..203decaa0 100644
--- a/numpy/core/src/multiarray/common.h
+++ b/numpy/core/src/multiarray/common.h
@@ -209,7 +209,7 @@ npy_is_aligned(const void * p, const npy_uintp alignment)
}
/* Get equivalent "uint" alignment given an itemsize, for use in copy code */
-static NPY_INLINE int
+static NPY_INLINE npy_uintp
npy_uint_alignment(int itemsize)
{
npy_uintp alignment = 0; /* return value of 0 means unaligned */
@@ -267,7 +267,7 @@ npy_memchr(char * haystack, char needle,
}
else {
/* usually find elements to skip path */
- if (NPY_CPU_HAVE_UNALIGNED_ACCESS && needle == 0 && stride == 1) {
+ if (!NPY_ALIGNMENT_REQUIRED && needle == 0 && stride == 1) {
/* iterate until last multiple of 4 */
char * block_end = haystack + size - (size % sizeof(unsigned int));
while (p < block_end) {
@@ -291,6 +291,34 @@ npy_memchr(char * haystack, char needle,
return p;
}
+
+/*
+ * Simple helper to create a tuple from an array of items. The `make_null_none`
+ * flag means that NULL entries are replaced with None, which is occasionally
+ * useful.
+ */
+static NPY_INLINE PyObject *
+PyArray_TupleFromItems(int n, PyObject *const *items, int make_null_none)
+{
+ PyObject *tuple = PyTuple_New(n);
+ if (tuple == NULL) {
+ return NULL;
+ }
+ for (int i = 0; i < n; i ++) {
+ PyObject *tmp;
+ if (!make_null_none || items[i] != NULL) {
+ tmp = items[i];
+ }
+ else {
+ tmp = Py_None;
+ }
+ Py_INCREF(tmp);
+ PyTuple_SET_ITEM(tuple, i, tmp);
+ }
+ return tuple;
+}
+
+
#include "ucsnarrow.h"
/*
diff --git a/numpy/core/src/multiarray/common_dtype.c b/numpy/core/src/multiarray/common_dtype.c
new file mode 100644
index 000000000..659580c98
--- /dev/null
+++ b/numpy/core/src/multiarray/common_dtype.c
@@ -0,0 +1,318 @@
+#define PY_SSIZE_T_CLEAN
+#include <Python.h>
+
+#define NPY_NO_DEPRECATED_API NPY_API_VERSION
+#define _MULTIARRAYMODULE
+#include <numpy/npy_common.h>
+#include "numpy/arrayobject.h"
+
+#include "common_dtype.h"
+#include "dtypemeta.h"
+#include "abstractdtypes.h"
+
+
+/*
+ * This file defines all logic necessary for generic "common dtype"
+ * operations. This is unfortunately surprisingly complicated to get right
+ * due to the value based logic NumPy uses and the fact that NumPy has
+ * no clear (non-transitive) type promotion hierarchy.
+ * Unlike most languages `int32 + float32 -> float64` instead of `float32`.
+ * The other complicated thing is value-based-promotion, which means that
+ * in many cases a Python 1, may end up as an `int8` or `uint8`.
+ *
+ * This file implements the necessary logic so that `np.result_type(...)`
+ * can give the correct result for any order of inputs and can further
+ * generalize to user DTypes.
+ */
+
+
+/**
+ * This function defines the common DType operator.
+ *
+ * Note that the common DType will not be "object" (unless one of the dtypes
+ * is object), even though object can technically represent all values
+ * correctly.
+ *
+ * TODO: Before exposure, we should review the return value (e.g. no error
+ * when no common DType is found).
+ *
+ * @param dtype1 DType class to find the common type for.
+ * @param dtype2 Second DType class.
+ * @return The common DType or NULL with an error set
+ */
+NPY_NO_EXPORT NPY_INLINE PyArray_DTypeMeta *
+PyArray_CommonDType(PyArray_DTypeMeta *dtype1, PyArray_DTypeMeta *dtype2)
+{
+ if (dtype1 == dtype2) {
+ Py_INCREF(dtype1);
+ return dtype1;
+ }
+
+ PyArray_DTypeMeta *common_dtype;
+
+ common_dtype = NPY_DT_CALL_common_dtype(dtype1, dtype2);
+ if (common_dtype == (PyArray_DTypeMeta *)Py_NotImplemented) {
+ Py_DECREF(common_dtype);
+ common_dtype = NPY_DT_CALL_common_dtype(dtype2, dtype1);
+ }
+ if (common_dtype == NULL) {
+ return NULL;
+ }
+ if (common_dtype == (PyArray_DTypeMeta *)Py_NotImplemented) {
+ Py_DECREF(Py_NotImplemented);
+ PyErr_Format(PyExc_TypeError,
+ "The DTypes %S and %S do not have a common DType. "
+ "For example they cannot be stored in a single array unless "
+ "the dtype is `object`.", dtype1, dtype2);
+ return NULL;
+ }
+ return common_dtype;
+}
+
+
+/**
+ * This function takes a list of dtypes and "reduces" them (in a sense,
+ * it finds the maximal dtype). Note that "maximum" here is defined by
+ * knowledge (or category or domain). A user DType must always "know"
+ * about all NumPy dtypes, floats "know" about integers, integers "know"
+ * about unsigned integers.
+ *
+ * c
+ * / \
+ * a \ <-- The actual promote(a, b) may be c or unknown.
+ * / \ \
+ * a b c
+ *
+ * The reduction is done "pairwise". In the above `a.__common_dtype__(b)`
+ * has a result (so `a` knows more) and `a.__common_dtype__(c)` returns
+ * NotImplemented (so `c` knows more). You may notice that the result
+ * `res = a.__common_dtype__(b)` is not important. We could try to use it
+ * to remove the whole branch if `res is c` or by checking if
+ * `c.__common_dtype(res) is c`.
+ * Right now, we only clear initial elements in the most simple case where
+ * `a.__common_dtype(b) is a` (and thus `b` cannot alter the end-result).
+ * Clearing means, we do not have to worry about them later.
+ *
+ * There is one further subtlety. If we have an abstract DType and a
+ * non-abstract one, we "prioritize" the non-abstract DType here.
+ * In this sense "prioritizing" means that we use:
+ * abstract.__common_dtype__(other)
+ * If both return NotImplemented (which is acceptable and even expected in
+ * this case, see later) then `other` will be considered to know more.
+ *
+ * The reason why this may be acceptable for abstract DTypes, is that
+ * the value-dependent abstract DTypes may provide default fall-backs.
+ * The priority inversion effectively means that abstract DTypes are ordered
+ * just below their concrete counterparts.
+ * (This fall-back is convenient but not perfect, it can lead to
+ * non-minimal promotions: e.g. `np.uint24 + 2**20 -> int32`. And such
+ * cases may also be possible in some mixed type scenarios; they can be
+ * avoided by defining the promotion explicitly in the user DType.)
+ *
+ * @param length Number of DTypes
+ * @param dtypes
+ */
+static PyArray_DTypeMeta *
+reduce_dtypes_to_most_knowledgeable(
+ npy_intp length, PyArray_DTypeMeta **dtypes)
+{
+ assert(length >= 2);
+ npy_intp half = length / 2;
+
+ PyArray_DTypeMeta *res = NULL;
+
+ for (npy_intp low = 0; low < half; low++) {
+ npy_intp high = length - 1 - low;
+ if (dtypes[high] == dtypes[low]) {
+ Py_INCREF(dtypes[low]);
+ Py_XSETREF(res, dtypes[low]);
+ }
+ else {
+ if (NPY_DT_is_abstract(dtypes[high])) {
+ /*
+ * Priority inversion, start with abstract, because if it
+ * returns `other`, we can let other pass instead.
+ */
+ PyArray_DTypeMeta *tmp = dtypes[low];
+ dtypes[low] = dtypes[high];
+ dtypes[high] = tmp;
+ }
+
+ Py_XSETREF(res, NPY_DT_CALL_common_dtype(dtypes[low], dtypes[high]));
+ if (res == NULL) {
+ return NULL;
+ }
+ }
+
+ if (res == (PyArray_DTypeMeta *)Py_NotImplemented) {
+ PyArray_DTypeMeta *tmp = dtypes[low];
+ dtypes[low] = dtypes[high];
+ dtypes[high] = tmp;
+ }
+ if (res == dtypes[low]) {
+ /* `dtypes[high]` cannot influence the final result, so clear: */
+ dtypes[high] = NULL;
+ }
+ }
+
+ if (length == 2) {
+ return res;
+ }
+ Py_DECREF(res);
+ return reduce_dtypes_to_most_knowledgeable(length - half, dtypes);
+}
+
+
+/**
+ * Promotes a list of DTypes with each other in a way that should guarantee
+ * stable results even when changing the order.
+ *
+ * In general this approach always works as long as the most generic dtype
+ * is either strictly larger, or compatible with all other dtypes.
+ * For example promoting float16 with any other float, integer, or unsigned
+ * integer again gives a floating point number. And any floating point number
+ * promotes in the "same way" as `float16`.
+ * If a user inserts more than one type into the NumPy type hierarchy, this
+ * can break. Given:
+ * uint24 + int32 -> int48 # Promotes to a *new* dtype!
+ *
+ * The following becomes problematic (order does not matter):
+ * uint24 + int16 + uint32 -> int64
+ * <== (uint24 + int16) + (uint24 + uint32) -> int64
+ * <== int32 + uint32 -> int64
+ *
+ * It is impossible to achieve an `int48` result in the above.
+ *
+ * This is probably only resolvable by asking `uint24` to take over the
+ * whole reduction step; which we currently do not do.
+ * (It may be possible to notice the last up-cast and implement use something
+ * like: `uint24.nextafter(int32).__common_dtype__(uint32)`, but that seems
+ * even harder to grasp.)
+ *
+ * Note that a case where two dtypes are mixed (and know nothing about each
+ * other) will always generate an error:
+ * uint24 + int48 + int64 -> Error
+ *
+ * Even though `int64` is a safe solution, since `uint24 + int64 -> int64` and
+ * `int48 + int64 -> int64` and `int64` and there cannot be a smaller solution.
+ *
+ * //TODO: Maybe this function should allow not setting an error?
+ *
+ * @param length Number of dtypes (and values) must be at least 1
+ * @param dtypes The concrete or abstract DTypes to promote
+ * @return NULL or the promoted DType.
+ */
+NPY_NO_EXPORT PyArray_DTypeMeta *
+PyArray_PromoteDTypeSequence(
+ npy_intp length, PyArray_DTypeMeta **dtypes_in)
+{
+ if (length == 1) {
+ Py_INCREF(dtypes_in[0]);
+ return dtypes_in[0];
+ }
+ PyArray_DTypeMeta *result = NULL;
+
+ /* Copy dtypes so that we can reorder them (only allocate when many) */
+ PyObject *_scratch_stack[NPY_MAXARGS];
+ PyObject **_scratch_heap = NULL;
+ PyArray_DTypeMeta **dtypes = (PyArray_DTypeMeta **)_scratch_stack;
+
+ if (length > NPY_MAXARGS) {
+ _scratch_heap = PyMem_Malloc(length * sizeof(PyObject *));
+ if (_scratch_heap == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ dtypes = (PyArray_DTypeMeta **)_scratch_heap;
+ }
+
+ memcpy(dtypes, dtypes_in, length * sizeof(PyObject *));
+
+ /*
+ * `result` is the last promotion result, which can usually be reused if
+ * it is not NotImplemneted.
+ * The passed in dtypes are partially sorted (and cleared, when clearly
+ * not relevant anymore).
+ * `dtypes[0]` will be the most knowledgeable (highest category) which
+ * we consider the "main_dtype" here.
+ */
+ result = reduce_dtypes_to_most_knowledgeable(length, dtypes);
+ if (result == NULL) {
+ goto finish;
+ }
+ PyArray_DTypeMeta *main_dtype = dtypes[0];
+
+ npy_intp reduce_start = 1;
+ if (result == (PyArray_DTypeMeta *)Py_NotImplemented) {
+ Py_SETREF(result, NULL);
+ }
+ else {
+ /* (new) first value is already taken care of in `result` */
+ reduce_start = 2;
+ }
+ /*
+ * At this point, we have only looked at every DType at most once.
+ * The `main_dtype` must know all others (or it will be a failure) and
+ * all dtypes returned by its `common_dtype` must be guaranteed to succeed
+ * promotion with one another.
+ * It is the job of the "main DType" to ensure that at this point order
+ * is irrelevant.
+ * If this turns out to be a limitation, this "reduction" will have to
+ * become a default version and we have to allow DTypes to override it.
+ */
+ PyArray_DTypeMeta *prev = NULL;
+ for (npy_intp i = reduce_start; i < length; i++) {
+ if (dtypes[i] == NULL || dtypes[i] == prev) {
+ continue;
+ }
+ /*
+ * "Promote" the current dtype with the main one (which should be
+ * a higher category). We assume that the result is not in a lower
+ * category.
+ */
+ PyArray_DTypeMeta *promotion = NPY_DT_CALL_common_dtype(
+ main_dtype, dtypes[i]);
+ if (promotion == NULL) {
+ Py_XSETREF(result, NULL);
+ goto finish;
+ }
+ else if ((PyObject *)promotion == Py_NotImplemented) {
+ Py_DECREF(Py_NotImplemented);
+ Py_XSETREF(result, NULL);
+ PyObject *dtypes_in_tuple = PyTuple_New(length);
+ if (dtypes_in_tuple == NULL) {
+ goto finish;
+ }
+ for (npy_intp l=0; l < length; l++) {
+ Py_INCREF(dtypes_in[l]);
+ PyTuple_SET_ITEM(dtypes_in_tuple, l, (PyObject *)dtypes_in[l]);
+ }
+ PyErr_Format(PyExc_TypeError,
+ "The DType %S could not be promoted by %S. This means that "
+ "no common DType exists for the given inputs. "
+ "For example they cannot be stored in a single array unless "
+ "the dtype is `object`. The full list of DTypes is: %S",
+ dtypes[i], main_dtype, dtypes_in_tuple);
+ Py_DECREF(dtypes_in_tuple);
+ goto finish;
+ }
+ if (result == NULL) {
+ result = promotion;
+ continue;
+ }
+
+ /*
+ * The above promoted, now "reduce" with the current result; note that
+ * in the typical cases we expect this step to be a no-op.
+ */
+ Py_SETREF(result, PyArray_CommonDType(result, promotion));
+ Py_DECREF(promotion);
+ if (result == NULL) {
+ goto finish;
+ }
+ }
+
+ finish:
+ PyMem_Free(_scratch_heap);
+ return result;
+}
diff --git a/numpy/core/src/multiarray/common_dtype.h b/numpy/core/src/multiarray/common_dtype.h
new file mode 100644
index 000000000..b3666531a
--- /dev/null
+++ b/numpy/core/src/multiarray/common_dtype.h
@@ -0,0 +1,17 @@
+#ifndef _NPY_COMMON_DTYPE_H_
+#define _NPY_COMMON_DTYPE_H_
+
+#define NPY_NO_DEPRECATED_API NPY_API_VERSION
+#define _MULTIARRAYMODULE
+
+#include <numpy/ndarraytypes.h>
+#include "dtypemeta.h"
+
+NPY_NO_EXPORT PyArray_DTypeMeta *
+PyArray_CommonDType(PyArray_DTypeMeta *dtype1, PyArray_DTypeMeta *dtype2);
+
+NPY_NO_EXPORT PyArray_DTypeMeta *
+PyArray_PromoteDTypeSequence(
+ npy_intp length, PyArray_DTypeMeta **dtypes_in);
+
+#endif /* _NPY_COMMON_DTYPE_H_ */
diff --git a/numpy/core/src/multiarray/compiled_base.c b/numpy/core/src/multiarray/compiled_base.c
index 8ab592015..de793f87c 100644
--- a/numpy/core/src/multiarray/compiled_base.c
+++ b/numpy/core/src/multiarray/compiled_base.c
@@ -13,7 +13,12 @@
#include "alloc.h"
#include "ctors.h"
#include "common.h"
+#include "simd/simd.h"
+typedef enum {
+ PACK_ORDER_LITTLE = 0,
+ PACK_ORDER_BIG
+} PACK_ORDER;
/*
* Returns -1 if the array is monotonic decreasing,
@@ -1032,7 +1037,7 @@ arr_ravel_multi_index(PyObject *self, PyObject *args, PyObject *kwds)
NpyIter *iter = NULL;
- char *kwlist[] = {"multi_index", "dims", "mode", "order", NULL};
+ static char *kwlist[] = {"multi_index", "dims", "mode", "order", NULL};
memset(op, 0, sizeof(op));
dtype[0] = NULL;
@@ -1227,42 +1232,7 @@ arr_unravel_index(PyObject *self, PyObject *args, PyObject *kwds)
int i, ret_ndim;
npy_intp ret_dims[NPY_MAXDIMS], ret_strides[NPY_MAXDIMS];
- char *kwlist[] = {"indices", "shape", "order", NULL};
-
- /*
- * TODO: remove this in favor of warning raised in the dispatcher when
- * __array_function__ is enabled by default.
- */
-
- /*
- * Continue to support the older "dims" argument in place
- * of the "shape" argument. Issue an appropriate warning
- * if "dims" is detected in keywords, then replace it with
- * the new "shape" argument and continue processing as usual.
- */
- if (kwds) {
- PyObject *dims_item, *shape_item;
- dims_item = _PyDict_GetItemStringWithError(kwds, "dims");
- if (dims_item == NULL && PyErr_Occurred()){
- return NULL;
- }
- shape_item = _PyDict_GetItemStringWithError(kwds, "shape");
- if (shape_item == NULL && PyErr_Occurred()){
- return NULL;
- }
- if (dims_item != NULL && shape_item == NULL) {
- if (DEPRECATE("'shape' argument should be"
- " used instead of 'dims'") < 0) {
- return NULL;
- }
- if (PyDict_SetItemString(kwds, "shape", dims_item) < 0) {
- return NULL;
- }
- if (PyDict_DelItemString(kwds, "dims") < 0) {
- return NULL;
- }
- }
- }
+ static char *kwlist[] = {"indices", "shape", "order", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO&|O&:unravel_index",
kwlist,
@@ -1500,27 +1470,12 @@ arr_add_docstring(PyObject *NPY_UNUSED(dummy), PyObject *args)
Py_RETURN_NONE;
}
-#if defined NPY_HAVE_SSE2_INTRINSICS
-#include <emmintrin.h>
-#endif
-
-#ifdef NPY_HAVE_NEON
- typedef npy_uint64 uint64_unaligned __attribute__((aligned(16)));
- static NPY_INLINE int32_t
- sign_mask(uint8x16_t input)
- {
- int8x8_t m0 = vcreate_s8(0x0706050403020100ULL);
- uint8x16_t v0 = vshlq_u8(vshrq_n_u8(input, 7), vcombine_s8(m0, m0));
- uint64x2_t v1 = vpaddlq_u32(vpaddlq_u16(vpaddlq_u8(v0)));
- return (int)vgetq_lane_u64(v1, 0) + ((int)vgetq_lane_u64(v1, 1) << 8);
- }
-#endif
/*
* This function packs boolean values in the input array into the bits of a
* byte array. Truth values are determined as usual: 0 is false, everything
* else is true.
*/
-static NPY_INLINE void
+static NPY_GCC_OPT_3 NPY_INLINE void
pack_inner(const char *inptr,
npy_intp element_size, /* in bytes */
npy_intp n_in,
@@ -1528,7 +1483,7 @@ pack_inner(const char *inptr,
char *outptr,
npy_intp n_out,
npy_intp out_stride,
- char order)
+ PACK_ORDER order)
{
/*
* Loop through the elements of inptr.
@@ -1540,62 +1495,64 @@ pack_inner(const char *inptr,
npy_intp index = 0;
int remain = n_in % 8; /* uneven bits */
-#if defined NPY_HAVE_SSE2_INTRINSICS && defined HAVE__M_FROM_INT64
+#if NPY_SIMD
if (in_stride == 1 && element_size == 1 && n_out > 2) {
- __m128i zero = _mm_setzero_si128();
+ npyv_u8 v_zero = npyv_zero_u8();
/* don't handle non-full 8-byte remainder */
npy_intp vn_out = n_out - (remain ? 1 : 0);
- vn_out -= (vn_out & 1);
- for (index = 0; index < vn_out; index += 2) {
- unsigned int r;
- npy_uint64 a = *(npy_uint64*)inptr;
- npy_uint64 b = *(npy_uint64*)(inptr + 8);
- if (order == 'b') {
- a = npy_bswap8(a);
- b = npy_bswap8(b);
+ const int vstep = npyv_nlanes_u64;
+ const int vstepx4 = vstep * 4;
+ const int isAligned = npy_is_aligned(outptr, sizeof(npy_uint64));
+ vn_out -= (vn_out & (vstep - 1));
+ for (; index <= vn_out - vstepx4; index += vstepx4, inptr += npyv_nlanes_u8 * 4) {
+ npyv_u8 v0 = npyv_load_u8((const npy_uint8*)inptr);
+ npyv_u8 v1 = npyv_load_u8((const npy_uint8*)inptr + npyv_nlanes_u8 * 1);
+ npyv_u8 v2 = npyv_load_u8((const npy_uint8*)inptr + npyv_nlanes_u8 * 2);
+ npyv_u8 v3 = npyv_load_u8((const npy_uint8*)inptr + npyv_nlanes_u8 * 3);
+ if (order == PACK_ORDER_BIG) {
+ v0 = npyv_rev64_u8(v0);
+ v1 = npyv_rev64_u8(v1);
+ v2 = npyv_rev64_u8(v2);
+ v3 = npyv_rev64_u8(v3);
}
-
- /* note x86 can load unaligned */
- __m128i v = _mm_set_epi64(_m_from_int64(b), _m_from_int64(a));
- /* false -> 0x00 and true -> 0xFF (there is no cmpneq) */
- v = _mm_cmpeq_epi8(v, zero);
- v = _mm_cmpeq_epi8(v, zero);
- /* extract msb of 16 bytes and pack it into 16 bit */
- r = _mm_movemask_epi8(v);
- /* store result */
- memcpy(outptr, &r, 1);
- outptr += out_stride;
- memcpy(outptr, (char*)&r + 1, 1);
- outptr += out_stride;
- inptr += 16;
- }
- }
-#elif defined NPY_HAVE_NEON
- if (in_stride == 1 && element_size == 1 && n_out > 2) {
- /* don't handle non-full 8-byte remainder */
- npy_intp vn_out = n_out - (remain ? 1 : 0);
- vn_out -= (vn_out & 1);
- for (index = 0; index < vn_out; index += 2) {
- unsigned int r;
- npy_uint64 a = *((uint64_unaligned*)inptr);
- npy_uint64 b = *((uint64_unaligned*)(inptr + 8));
- if (order == 'b') {
- a = npy_bswap8(a);
- b = npy_bswap8(b);
+ npy_uint64 bb[4];
+ bb[0] = npyv_tobits_b8(npyv_cmpneq_u8(v0, v_zero));
+ bb[1] = npyv_tobits_b8(npyv_cmpneq_u8(v1, v_zero));
+ bb[2] = npyv_tobits_b8(npyv_cmpneq_u8(v2, v_zero));
+ bb[3] = npyv_tobits_b8(npyv_cmpneq_u8(v3, v_zero));
+ if(out_stride == 1 &&
+ (!NPY_ALIGNMENT_REQUIRED || isAligned)) {
+ npy_uint64 *ptr64 = (npy_uint64*)outptr;
+ #if NPY_SIMD_WIDTH == 16
+ npy_uint64 bcomp = bb[0] | (bb[1] << 16) | (bb[2] << 32) | (bb[3] << 48);
+ ptr64[0] = bcomp;
+ #elif NPY_SIMD_WIDTH == 32
+ ptr64[0] = bb[0] | (bb[1] << 32);
+ ptr64[1] = bb[2] | (bb[3] << 32);
+ #else
+ ptr64[0] = bb[0]; ptr64[1] = bb[1];
+ ptr64[2] = bb[2]; ptr64[3] = bb[3];
+ #endif
+ outptr += vstepx4;
+ } else {
+ for(int i = 0; i < 4; i++) {
+ for (int j = 0; j < vstep; j++) {
+ memcpy(outptr, (char*)&bb[i] + j, 1);
+ outptr += out_stride;
+ }
+ }
+ }
+ }
+ for (; index < vn_out; index += vstep, inptr += npyv_nlanes_u8) {
+ npyv_u8 va = npyv_load_u8((const npy_uint8*)inptr);
+ if (order == PACK_ORDER_BIG) {
+ va = npyv_rev64_u8(va);
+ }
+ npy_uint64 bb = npyv_tobits_b8(npyv_cmpneq_u8(va, v_zero));
+ for (int i = 0; i < vstep; ++i) {
+ memcpy(outptr, (char*)&bb + i, 1);
+ outptr += out_stride;
}
- uint64x2_t v = vcombine_u64(vcreate_u64(a), vcreate_u64(b));
- uint64x2_t zero = vdupq_n_u64(0);
- /* false -> 0x00 and true -> 0xFF */
- v = vreinterpretq_u64_u8(vmvnq_u8(vceqq_u8(vreinterpretq_u8_u64(v), vreinterpretq_u8_u64(zero))));
- /* extract msb of 16 bytes and pack it into 16 bit */
- uint8x16_t input = vreinterpretq_u8_u64(v);
- r = sign_mask(input);
- /* store result */
- memcpy(outptr, &r, 1);
- outptr += out_stride;
- memcpy(outptr, (char*)&r + 1, 1);
- outptr += out_stride;
- inptr += 16;
}
}
#endif
@@ -1606,14 +1563,11 @@ pack_inner(const char *inptr,
/* Don't reset index. Just handle remainder of above block */
for (; index < n_out; index++) {
unsigned char build = 0;
- int i, maxi;
- npy_intp j;
-
- maxi = (index == n_out - 1) ? remain : 8;
- if (order == 'b') {
- for (i = 0; i < maxi; i++) {
+ int maxi = (index == n_out - 1) ? remain : 8;
+ if (order == PACK_ORDER_BIG) {
+ for (int i = 0; i < maxi; i++) {
build <<= 1;
- for (j = 0; j < element_size; j++) {
+ for (npy_intp j = 0; j < element_size; j++) {
build |= (inptr[j] != 0);
}
inptr += in_stride;
@@ -1624,9 +1578,9 @@ pack_inner(const char *inptr,
}
else
{
- for (i = 0; i < maxi; i++) {
+ for (int i = 0; i < maxi; i++) {
build >>= 1;
- for (j = 0; j < element_size; j++) {
+ for (npy_intp j = 0; j < element_size; j++) {
build |= (inptr[j] != 0) ? 128 : 0;
}
inptr += in_stride;
@@ -1720,13 +1674,13 @@ pack_bits(PyObject *input, int axis, char order)
Py_XDECREF(ot);
goto fail;
}
-
+ const PACK_ORDER ordere = order == 'b' ? PACK_ORDER_BIG : PACK_ORDER_LITTLE;
NPY_BEGIN_THREADS_THRESHOLDED(PyArray_DIM(out, axis));
while (PyArray_ITER_NOTDONE(it)) {
pack_inner(PyArray_ITER_DATA(it), PyArray_ITEMSIZE(new),
PyArray_DIM(new, axis), PyArray_STRIDE(new, axis),
PyArray_ITER_DATA(ot), PyArray_DIM(out, axis),
- PyArray_STRIDE(out, axis), order);
+ PyArray_STRIDE(out, axis), ordere);
PyArray_ITER_NEXT(it);
PyArray_ITER_NEXT(ot);
}
diff --git a/numpy/core/src/multiarray/conversion_utils.c b/numpy/core/src/multiarray/conversion_utils.c
index dd18f71fd..adfff1129 100644
--- a/numpy/core/src/multiarray/conversion_utils.c
+++ b/numpy/core/src/multiarray/conversion_utils.c
@@ -715,6 +715,78 @@ PyArray_ConvertClipmodeSequence(PyObject *object, NPY_CLIPMODE *modes, int n)
return NPY_SUCCEED;
}
+static int correlatemode_parser(char const *str, Py_ssize_t length, void *data)
+{
+ NPY_CORRELATEMODE *val = (NPY_CORRELATEMODE *)data;
+ int is_exact = 0;
+
+ if (length < 1) {
+ return -1;
+ }
+ if (str[0] == 'V' || str[0] == 'v') {
+ *val = NPY_VALID;
+ is_exact = (length == 5 && strcmp(str, "valid") == 0);
+ }
+ else if (str[0] == 'S' || str[0] == 's') {
+ *val = NPY_SAME;
+ is_exact = (length == 4 && strcmp(str, "same") == 0);
+ }
+ else if (str[0] == 'F' || str[0] == 'f') {
+ *val = NPY_FULL;
+ is_exact = (length == 4 && strcmp(str, "full") == 0);
+ }
+ else {
+ return -1;
+ }
+
+ /* Filters out the case sensitive/non-exact
+ * match inputs and other inputs and outputs DeprecationWarning
+ */
+ if (!is_exact) {
+ /* Numpy 1.21, 2021-01-19 */
+ if (DEPRECATE("inexact matches and case insensitive matches for "
+ "convolve/correlate mode are deprecated, please "
+ "use one of 'valid', 'same', or 'full' instead.") < 0) {
+ return -1;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * Convert an object to NPY_VALID / NPY_SAME / NPY_FULL
+ */
+NPY_NO_EXPORT int
+PyArray_CorrelatemodeConverter(PyObject *object, NPY_CORRELATEMODE *val)
+{
+ if (PyUnicode_Check(object)) {
+ return string_converter_helper(
+ object, (void *)val, correlatemode_parser, "mode",
+ "must be one of 'valid', 'same', or 'full'");
+ }
+
+ else {
+ /* For users passing integers */
+ int number = PyArray_PyIntAsInt(object);
+ if (error_converting(number)) {
+ PyErr_SetString(PyExc_TypeError,
+ "convolve/correlate mode not understood");
+ return NPY_FAIL;
+ }
+ if (number <= (int) NPY_FULL
+ && number >= (int) NPY_VALID) {
+ *val = (NPY_CORRELATEMODE) number;
+ return NPY_SUCCEED;
+ }
+ else {
+ PyErr_Format(PyExc_ValueError,
+ "integer convolve/correlate mode must be 0, 1, or 2");
+ return NPY_FAIL;
+ }
+ }
+}
+
static int casting_parser(char const *str, Py_ssize_t length, void *data)
{
NPY_CASTING *casting = (NPY_CASTING *)data;
@@ -1150,11 +1222,7 @@ PyArray_IntTupleFromIntp(int len, npy_intp const *vals)
goto fail;
}
for (i = 0; i < len; i++) {
-#if NPY_SIZEOF_INTP <= NPY_SIZEOF_LONG
- PyObject *o = PyLong_FromLong((long) vals[i]);
-#else
- PyObject *o = PyLong_FromLongLong((npy_longlong) vals[i]);
-#endif
+ PyObject *o = PyArray_PyIntFromIntp(vals[i]);
if (!o) {
Py_DECREF(intTuple);
intTuple = NULL;
diff --git a/numpy/core/src/multiarray/conversion_utils.h b/numpy/core/src/multiarray/conversion_utils.h
index bee0c6064..55c0cdd35 100644
--- a/numpy/core/src/multiarray/conversion_utils.h
+++ b/numpy/core/src/multiarray/conversion_utils.h
@@ -39,10 +39,24 @@ PyArray_IntpFromSequence(PyObject *seq, npy_intp *vals, int maxvals);
NPY_NO_EXPORT int
PyArray_TypestrConvert(int itemsize, int gentype);
+
+static NPY_INLINE PyObject *
+PyArray_PyIntFromIntp(npy_intp const value)
+{
+#if NPY_SIZEOF_INTP <= NPY_SIZEOF_LONG
+ return PyLong_FromLong((long)value);
+#else
+ return PyLong_FromLongLong((npy_longlong)value);
+#endif
+}
+
NPY_NO_EXPORT PyObject *
PyArray_IntTupleFromIntp(int len, npy_intp const *vals);
NPY_NO_EXPORT int
+PyArray_CorrelatemodeConverter(PyObject *object, NPY_CORRELATEMODE *val);
+
+NPY_NO_EXPORT int
PyArray_SelectkindConverter(PyObject *obj, NPY_SELECTKIND *selectkind);
/*
diff --git a/numpy/core/src/multiarray/convert_datatype.c b/numpy/core/src/multiarray/convert_datatype.c
index f9dd35a73..e3b25d076 100644
--- a/numpy/core/src/multiarray/convert_datatype.c
+++ b/numpy/core/src/multiarray/convert_datatype.c
@@ -8,6 +8,7 @@
#include "numpy/arrayscalars.h"
#include "npy_config.h"
+#include "lowlevel_strided_loops.h"
#include "npy_pycompat.h"
#include "numpy/npy_math.h"
@@ -16,15 +17,18 @@
#include "common.h"
#include "ctors.h"
#include "dtypemeta.h"
+#include "common_dtype.h"
#include "scalartypes.h"
#include "mapping.h"
#include "legacy_dtype_implementation.h"
+#include "abstractdtypes.h"
#include "convert_datatype.h"
#include "_datetime.h"
#include "datetime_strings.h"
#include "array_method.h"
#include "usertypes.h"
+#include "dtype_transfer.h"
/*
@@ -61,10 +65,16 @@ PyArray_GetObjectToGenericCastingImpl(void);
* @returns A castingimpl (PyArrayDTypeMethod *), None or NULL with an
* error set.
*/
-static PyObject *
+NPY_NO_EXPORT PyObject *
PyArray_GetCastingImpl(PyArray_DTypeMeta *from, PyArray_DTypeMeta *to)
{
- PyObject *res = PyDict_GetItem(from->castingimpls, (PyObject *)to);
+ PyObject *res;
+ if (from == to) {
+ res = NPY_DT_SLOTS(from)->within_dtype_castingimpl;
+ }
+ else {
+ res = PyDict_GetItemWithError(NPY_DT_SLOTS(from)->castingimpls, (PyObject *)to);
+ }
if (res != NULL || PyErr_Occurred()) {
Py_XINCREF(res);
return res;
@@ -90,16 +100,16 @@ PyArray_GetCastingImpl(PyArray_DTypeMeta *from, PyArray_DTypeMeta *to)
else if (from->type_num < NPY_NTYPES && to->type_num < NPY_NTYPES) {
/* All builtin dtypes have their casts explicitly defined. */
PyErr_Format(PyExc_RuntimeError,
- "builtin cast from %S to %s not found, this should not "
+ "builtin cast from %S to %S not found, this should not "
"be possible.", from, to);
return NULL;
}
else {
- if (from->parametric || to->parametric) {
+ if (NPY_DT_is_parametric(from) || NPY_DT_is_parametric(to)) {
Py_RETURN_NONE;
}
/* Reject non-legacy dtypes (they need to use the new API) */
- if (!from->legacy || !to->legacy) {
+ if (!NPY_DT_is_legacy(from) || !NPY_DT_is_legacy(to)) {
Py_RETURN_NONE;
}
if (from != to) {
@@ -109,7 +119,8 @@ PyArray_GetCastingImpl(PyArray_DTypeMeta *from, PyArray_DTypeMeta *to)
if (castfunc == NULL) {
PyErr_Clear();
/* Remember that this cast is not possible */
- if (PyDict_SetItem(from->castingimpls, (PyObject *) to, Py_None) < 0) {
+ if (PyDict_SetItem(NPY_DT_SLOTS(from)->castingimpls,
+ (PyObject *) to, Py_None) < 0) {
return NULL;
}
Py_RETURN_NONE;
@@ -131,7 +142,14 @@ PyArray_GetCastingImpl(PyArray_DTypeMeta *from, PyArray_DTypeMeta *to)
if (res == NULL) {
return NULL;
}
- if (PyDict_SetItem(from->castingimpls, (PyObject *)to, res) < 0) {
+ if (from == to) {
+ PyErr_Format(PyExc_RuntimeError,
+ "Internal NumPy error, within-DType cast missing for %S!", from);
+ Py_DECREF(res);
+ return NULL;
+ }
+ if (PyDict_SetItem(NPY_DT_SLOTS(from)->castingimpls,
+ (PyObject *)to, res) < 0) {
Py_DECREF(res);
return NULL;
}
@@ -342,6 +360,54 @@ PyArray_CastAnyTo(PyArrayObject *out, PyArrayObject *mp)
}
+static NPY_CASTING
+_get_cast_safety_from_castingimpl(PyArrayMethodObject *castingimpl,
+ PyArray_DTypeMeta *dtypes[2], PyArray_Descr *from, PyArray_Descr *to)
+{
+ PyArray_Descr *descrs[2] = {from, to};
+ PyArray_Descr *out_descrs[2];
+
+ NPY_CASTING casting = castingimpl->resolve_descriptors(
+ castingimpl, dtypes, descrs, out_descrs);
+ if (casting < 0) {
+ return -1;
+ }
+ /* The returned descriptors may not match, requiring a second check */
+ if (out_descrs[0] != descrs[0]) {
+ NPY_CASTING from_casting = PyArray_GetCastSafety(
+ descrs[0], out_descrs[0], NULL);
+ casting = PyArray_MinCastSafety(casting, from_casting);
+ if (casting < 0) {
+ goto finish;
+ }
+ }
+ if (descrs[1] != NULL && out_descrs[1] != descrs[1]) {
+ NPY_CASTING from_casting = PyArray_GetCastSafety(
+ descrs[1], out_descrs[1], NULL);
+ casting = PyArray_MinCastSafety(casting, from_casting);
+ if (casting < 0) {
+ goto finish;
+ }
+ }
+
+ finish:
+ Py_DECREF(out_descrs[0]);
+ Py_DECREF(out_descrs[1]);
+ /*
+ * Check for less harmful non-standard returns. The following two returns
+ * should never happen. They would be roughly equivalent, but less precise,
+ * versions of `(NPY_NO_CASTING|_NPY_CAST_IS_VIEW)`.
+ * 1. No-casting must imply cast-is-view.
+ * 2. Equivalent-casting + cast-is-view is (currently) the definition
+ * of a "no" cast (there may be reasons to relax this).
+ * Note that e.g. `(NPY_UNSAFE_CASTING|_NPY_CAST_IS_VIEW)` is valid.
+ */
+ assert(casting != NPY_NO_CASTING);
+ assert(casting != (NPY_EQUIV_CASTING|_NPY_CAST_IS_VIEW));
+ return casting;
+}
+
+
/**
* Given two dtype instances, find the correct casting safety.
*
@@ -359,7 +425,6 @@ NPY_NO_EXPORT NPY_CASTING
PyArray_GetCastSafety(
PyArray_Descr *from, PyArray_Descr *to, PyArray_DTypeMeta *to_dtype)
{
- NPY_CASTING casting;
if (to != NULL) {
to_dtype = NPY_DTYPE(to);
}
@@ -373,41 +438,68 @@ PyArray_GetCastSafety(
}
PyArrayMethodObject *castingimpl = (PyArrayMethodObject *)meth;
-
PyArray_DTypeMeta *dtypes[2] = {NPY_DTYPE(from), to_dtype};
- PyArray_Descr *descrs[2] = {from, to};
- PyArray_Descr *out_descrs[2];
-
- casting = castingimpl->resolve_descriptors(
- castingimpl, dtypes, descrs, out_descrs);
+ NPY_CASTING casting = _get_cast_safety_from_castingimpl(castingimpl,
+ dtypes, from, to);
Py_DECREF(meth);
- if (casting < 0) {
+
+ return casting;
+}
+
+
+/**
+ * Check whether a cast is safe, see also `PyArray_GetCastSafety` for
+ * a similiar function. Unlike GetCastSafety, this function checks the
+ * `castingimpl->casting` when available. This allows for two things:
+ *
+ * 1. It avoids calling `resolve_descriptors` in some cases.
+ * 2. Strings need to discover the length, but in some cases we know that the
+ * cast is valid (assuming the string length is discovered first).
+ *
+ * The latter means that a `can_cast` could return True, but the cast fail
+ * because the parametric type cannot guess the correct output descriptor.
+ * (I.e. if `object_arr.astype("S")` did _not_ inspect the objects, and the
+ * user would have to guess the string length.)
+ *
+ * @param casting the requested casting safety.
+ * @param from
+ * @param to The descriptor to cast to (may be NULL)
+ * @param to_dtype If `to` is NULL, must pass the to_dtype (otherwise this
+ * is ignored).
+ * @return 0 for an invalid cast, 1 for a valid and -1 for an error.
+ */
+NPY_NO_EXPORT int
+PyArray_CheckCastSafety(NPY_CASTING casting,
+ PyArray_Descr *from, PyArray_Descr *to, PyArray_DTypeMeta *to_dtype)
+{
+ if (to != NULL) {
+ to_dtype = NPY_DTYPE(to);
+ }
+ PyObject *meth = PyArray_GetCastingImpl(NPY_DTYPE(from), to_dtype);
+ if (meth == NULL) {
return -1;
}
- /* The returned descriptors may not match, requiring a second check */
- if (out_descrs[0] != descrs[0]) {
- NPY_CASTING from_casting = PyArray_GetCastSafety(
- descrs[0], out_descrs[0], NULL);
- casting = PyArray_MinCastSafety(casting, from_casting);
- if (casting < 0) {
- goto finish;
- }
+ if (meth == Py_None) {
+ Py_DECREF(Py_None);
+ return -1;
}
- if (descrs[1] != NULL && out_descrs[1] != descrs[1]) {
- NPY_CASTING from_casting = PyArray_GetCastSafety(
- descrs[1], out_descrs[1], NULL);
- casting = PyArray_MinCastSafety(casting, from_casting);
- if (casting < 0) {
- goto finish;
- }
+ PyArrayMethodObject *castingimpl = (PyArrayMethodObject *)meth;
+
+ if (PyArray_MinCastSafety(castingimpl->casting, casting) == casting) {
+ /* No need to check using `castingimpl.resolve_descriptors()` */
+ Py_DECREF(meth);
+ return 1;
}
- finish:
- Py_DECREF(out_descrs[0]);
- Py_DECREF(out_descrs[1]);
- /* NPY_NO_CASTING has to be used for (NPY_EQUIV_CASTING|_NPY_CAST_IS_VIEW) */
- assert(casting != (NPY_EQUIV_CASTING|_NPY_CAST_IS_VIEW));
- return casting;
+ PyArray_DTypeMeta *dtypes[2] = {NPY_DTYPE(from), to_dtype};
+ NPY_CASTING safety = _get_cast_safety_from_castingimpl(castingimpl,
+ dtypes, from, to);
+ Py_DECREF(meth);
+ /* If casting is the smaller (or equal) safety we match */
+ if (safety < 0) {
+ return -1;
+ }
+ return PyArray_MinCastSafety(safety, casting) == casting;
}
@@ -417,7 +509,24 @@ PyArray_GetCastSafety(
NPY_NO_EXPORT int
PyArray_CanCastSafely(int fromtype, int totype)
{
-#if NPY_USE_NEW_CASTINGIMPL
+ /* Identity */
+ if (fromtype == totype) {
+ return 1;
+ }
+ /*
+ * As a micro-optimization, keep the cast table around. This can probably
+ * be removed as soon as the ufunc loop lookup is modified (presumably
+ * before the 1.21 release). It does no harm, but the main user of this
+ * function is the ufunc-loop lookup calling it until a loop matches!
+ *
+ * (The table extends further, but is not strictly correct for void).
+ * TODO: Check this!
+ */
+ if ((unsigned int)fromtype <= NPY_CLONGDOUBLE &&
+ (unsigned int)totype <= NPY_CLONGDOUBLE) {
+ return _npy_can_cast_safely_table[fromtype][totype];
+ }
+
PyArray_DTypeMeta *from = PyArray_DTypeFromTypeNum(fromtype);
if (from == NULL) {
PyErr_WriteUnraisable(NULL);
@@ -444,9 +553,6 @@ PyArray_CanCastSafely(int fromtype, int totype)
int res = PyArray_MinCastSafety(safety, NPY_SAFE_CASTING) == NPY_SAFE_CASTING;
Py_DECREF(castingimpl);
return res;
-#else
- return PyArray_LegacyCanCastSafely(fromtype, totype);
-#endif
}
@@ -460,11 +566,7 @@ PyArray_CanCastSafely(int fromtype, int totype)
NPY_NO_EXPORT npy_bool
PyArray_CanCastTo(PyArray_Descr *from, PyArray_Descr *to)
{
-#if NPY_USE_NEW_CASTINGIMPL
return PyArray_CanCastTypeTo(from, to, NPY_SAFE_CASTING);
-#else
- return PyArray_LegacyCanCastTo(from, to);
-#endif
}
@@ -539,7 +641,8 @@ NPY_NO_EXPORT npy_bool
PyArray_CanCastTypeTo(PyArray_Descr *from, PyArray_Descr *to,
NPY_CASTING casting)
{
-#if NPY_USE_NEW_CASTINGIMPL
+ PyArray_DTypeMeta *to_dtype = NPY_DTYPE(to);
+
/*
* NOTE: This code supports U and S, this is identical to the code
* in `ctors.c` which does not allow these dtypes to be attached
@@ -551,24 +654,21 @@ PyArray_CanCastTypeTo(PyArray_Descr *from, PyArray_Descr *to,
* TODO: We should grow support for `np.can_cast("d", "S")` being
* different from `np.can_cast("d", "S0")` here, at least for
* the python side API.
+ * The `to = NULL` branch, which considers "S0" to be "flexible"
+ * should probably be deprecated.
+ * (This logic is duplicated in `PyArray_CanCastArrayTo`)
*/
- NPY_CASTING safety;
if (PyDataType_ISUNSIZED(to) && to->subarray == NULL) {
- safety = PyArray_GetCastSafety(from, NULL, NPY_DTYPE(to));
- }
- else {
- safety = PyArray_GetCastSafety(from, to, NPY_DTYPE(to));
+ to = NULL; /* consider mainly S0 and U0 as S and U */
}
- if (safety < 0) {
+ int is_valid = PyArray_CheckCastSafety(casting, from, to, to_dtype);
+ /* Clear any errors and consider this unsafe (should likely be changed) */
+ if (is_valid < 0) {
PyErr_Clear();
return 0;
}
- /* If casting is the smaller (or equal) safety we match */
- return PyArray_MinCastSafety(safety, casting) == casting;
-#else
- return PyArray_LegacyCanCastTypeTo(from, to, casting);
-#endif
+ return is_valid;
}
@@ -576,36 +676,53 @@ PyArray_CanCastTypeTo(PyArray_Descr *from, PyArray_Descr *to,
static int min_scalar_type_num(char *valueptr, int type_num,
int *is_small_unsigned);
+
+/*
+ * NOTE: This function uses value based casting logic for scalars. It will
+ * require updates when we phase out value-based-casting.
+ */
NPY_NO_EXPORT npy_bool
can_cast_scalar_to(PyArray_Descr *scal_type, char *scal_data,
PyArray_Descr *to, NPY_CASTING casting)
{
- int swap;
- int is_small_unsigned = 0, type_num;
- npy_bool ret;
- PyArray_Descr *dtype;
-
- /* An aligned memory buffer large enough to hold any type */
- npy_longlong value[4];
-
/*
* If the two dtypes are actually references to the same object
* or if casting type is forced unsafe then always OK.
+ *
+ * TODO: Assuming that unsafe casting always works is not actually correct
*/
if (scal_type == to || casting == NPY_UNSAFE_CASTING ) {
return 1;
}
+ int valid = PyArray_CheckCastSafety(casting, scal_type, to, NPY_DTYPE(to));
+ if (valid == 1) {
+ /* This is definitely a valid cast. */
+ return 1;
+ }
+ if (valid < 0) {
+ /* Probably must return 0, but just keep trying for now. */
+ PyErr_Clear();
+ }
+
/*
- * If the scalar isn't a number, or the rule is stricter than
- * NPY_SAFE_CASTING, use the straight type-based rules
+ * If the scalar isn't a number, value-based casting cannot kick in and
+ * we must not attempt it.
+ * (Additional fast-checks would be possible, but probably unnecessary.)
*/
- if (!PyTypeNum_ISNUMBER(scal_type->type_num) ||
- casting < NPY_SAFE_CASTING) {
- return PyArray_CanCastTypeTo(scal_type, to, casting);
+ if (!PyTypeNum_ISNUMBER(scal_type->type_num)) {
+ return 0;
}
- swap = !PyArray_ISNBO(scal_type->byteorder);
+ /*
+ * At this point we have to check value-based casting.
+ */
+ PyArray_Descr *dtype;
+ int is_small_unsigned = 0, type_num;
+ /* An aligned memory buffer large enough to hold any builtin numeric type */
+ npy_longlong value[4];
+
+ int swap = !PyArray_ISNBO(scal_type->byteorder);
scal_type->f->copyswap(&value, scal_data, swap, NULL);
type_num = min_scalar_type_num((char *)&value, scal_type->type_num,
@@ -631,7 +748,7 @@ can_cast_scalar_to(PyArray_Descr *scal_type, char *scal_data,
PyObject_Print(to, stdout, 0);
printf("\n");
#endif
- ret = PyArray_CanCastTypeTo(dtype, to, casting);
+ npy_bool ret = PyArray_CanCastTypeTo(dtype, to, casting);
Py_DECREF(dtype);
return ret;
}
@@ -647,14 +764,29 @@ PyArray_CanCastArrayTo(PyArrayObject *arr, PyArray_Descr *to,
NPY_CASTING casting)
{
PyArray_Descr *from = PyArray_DESCR(arr);
+ PyArray_DTypeMeta *to_dtype = NPY_DTYPE(to);
+
+ /* NOTE, TODO: The same logic as `PyArray_CanCastTypeTo`: */
+ if (PyDataType_ISUNSIZED(to) && to->subarray == NULL) {
+ to = NULL;
+ }
- /* If it's a scalar, check the value */
- if (PyArray_NDIM(arr) == 0 && !PyArray_HASFIELDS(arr)) {
+ /*
+ * If it's a scalar, check the value. (This only currently matters for
+ * numeric types and for `to == NULL` it can't be numeric.)
+ */
+ if (PyArray_NDIM(arr) == 0 && !PyArray_HASFIELDS(arr) && to != NULL) {
return can_cast_scalar_to(from, PyArray_DATA(arr), to, casting);
}
- /* Otherwise, use the standard rules */
- return PyArray_CanCastTypeTo(from, to, casting);
+ /* Otherwise, use the standard rules (same as `PyArray_CanCastTypeTo`) */
+ int is_valid = PyArray_CheckCastSafety(casting, from, to, to_dtype);
+ /* Clear any errors and consider this unsafe (should likely be changed) */
+ if (is_valid < 0) {
+ PyErr_Clear();
+ return 0;
+ }
+ return is_valid;
}
@@ -816,19 +948,18 @@ PyArray_CastDescrToDType(PyArray_Descr *descr, PyArray_DTypeMeta *given_DType)
Py_INCREF(descr);
return descr;
}
- if (!given_DType->parametric) {
+ if (!NPY_DT_is_parametric(given_DType)) {
/*
* Don't actually do anything, the default is always the result
* of any cast.
*/
- return given_DType->default_descr(given_DType);
+ return NPY_DT_CALL_default_descr(given_DType);
}
if (PyObject_TypeCheck((PyObject *)descr, (PyTypeObject *)given_DType)) {
Py_INCREF(descr);
return descr;
}
-#if NPY_USE_NEW_CASTINGIMPL
PyObject *tmp = PyArray_GetCastingImpl(NPY_DTYPE(descr), given_DType);
if (tmp == NULL || tmp == Py_None) {
Py_XDECREF(tmp);
@@ -851,67 +982,76 @@ PyArray_CastDescrToDType(PyArray_Descr *descr, PyArray_DTypeMeta *given_DType)
error:; /* (; due to compiler limitations) */
PyObject *err_type = NULL, *err_value = NULL, *err_traceback = NULL;
PyErr_Fetch(&err_type, &err_value, &err_traceback);
- PyErr_Format(PyExc_ValueError,
+ PyErr_Format(PyExc_TypeError,
"cannot cast dtype %S to %S.", descr, given_DType);
- npy_PyErr_ChainExceptions(err_type, err_value, err_traceback);
+ npy_PyErr_ChainExceptionsCause(err_type, err_value, err_traceback);
return NULL;
-
-#else /* NPY_USE_NEW_CASTS */
- if (!given_DType->legacy) {
- PyErr_SetString(PyExc_NotImplementedError,
- "Must use casting to find the correct DType for a parametric "
- "user DType. This is not yet implemented (this error should be "
- "unreachable).");
- return NULL;
- }
-
- PyArray_Descr *flex_dtype = PyArray_DescrNew(given_DType->singleton);
- return PyArray_AdaptFlexibleDType(descr, flex_dtype);
-#endif /* NPY_USE_NEW_CASTS */
}
-/**
- * This function defines the common DType operator.
- *
- * Note that the common DType will not be "object" (unless one of the dtypes
- * is object), even though object can technically represent all values
- * correctly.
- *
- * TODO: Before exposure, we should review the return value (e.g. no error
- * when no common DType is found).
+/*
+ * Helper to find the target descriptor for multiple arrays given an input
+ * one that may be a DType class (e.g. "U" or "S").
+ * Works with arrays, since that is what `concatenate` works with. However,
+ * unlike `np.array(...)` or `arr.astype()` we will never inspect the array's
+ * content, which means that object arrays can only be cast to strings if a
+ * fixed width is provided (same for string -> generic datetime).
*
- * @param dtype1 DType class to find the common type for.
- * @param dtype2 Second DType class.
- * @return The common DType or NULL with an error set
+ * As this function uses `PyArray_ExtractDTypeAndDescriptor`, it should
+ * eventually be refactored to move the step to an earlier point.
*/
-NPY_NO_EXPORT PyArray_DTypeMeta *
-PyArray_CommonDType(PyArray_DTypeMeta *dtype1, PyArray_DTypeMeta *dtype2)
+NPY_NO_EXPORT PyArray_Descr *
+PyArray_FindConcatenationDescriptor(
+ npy_intp n, PyArrayObject **arrays, PyObject *requested_dtype)
{
- if (dtype1 == dtype2) {
- Py_INCREF(dtype1);
- return dtype1;
+ if (requested_dtype == NULL) {
+ return PyArray_LegacyResultType(n, arrays, 0, NULL);
}
PyArray_DTypeMeta *common_dtype;
-
- common_dtype = dtype1->common_dtype(dtype1, dtype2);
- if (common_dtype == (PyArray_DTypeMeta *)Py_NotImplemented) {
- Py_DECREF(common_dtype);
- common_dtype = dtype2->common_dtype(dtype2, dtype1);
- }
- if (common_dtype == NULL) {
+ PyArray_Descr *result = NULL;
+ if (PyArray_ExtractDTypeAndDescriptor(
+ requested_dtype, &result, &common_dtype) < 0) {
return NULL;
}
- if (common_dtype == (PyArray_DTypeMeta *)Py_NotImplemented) {
- Py_DECREF(Py_NotImplemented);
- PyErr_Format(PyExc_TypeError,
- "The DTypes %S and %S do not have a common DType. "
- "For example they cannot be stored in a single array unless "
- "the dtype is `object`.", dtype1, dtype2);
- return NULL;
+ if (result != NULL) {
+ if (result->subarray != NULL) {
+ PyErr_Format(PyExc_TypeError,
+ "The dtype `%R` is not a valid dtype for concatenation "
+ "since it is a subarray dtype (the subarray dimensions "
+ "would be added as array dimensions).", result);
+ Py_SETREF(result, NULL);
+ }
+ goto finish;
}
- return common_dtype;
+ assert(n > 0); /* concatenate requires at least one array input. */
+
+ /*
+ * NOTE: This code duplicates `PyArray_CastToDTypeAndPromoteDescriptors`
+ * to use arrays, copying the descriptors seems not better.
+ */
+ PyArray_Descr *descr = PyArray_DESCR(arrays[0]);
+ result = PyArray_CastDescrToDType(descr, common_dtype);
+ if (result == NULL || n == 1) {
+ goto finish;
+ }
+ for (npy_intp i = 1; i < n; i++) {
+ descr = PyArray_DESCR(arrays[i]);
+ PyArray_Descr *curr = PyArray_CastDescrToDType(descr, common_dtype);
+ if (curr == NULL) {
+ Py_SETREF(result, NULL);
+ goto finish;
+ }
+ Py_SETREF(result, NPY_DT_SLOTS(common_dtype)->common_instance(result, curr));
+ Py_DECREF(curr);
+ if (result == NULL) {
+ goto finish;
+ }
+ }
+
+ finish:
+ Py_DECREF(common_dtype);
+ return result;
}
@@ -936,8 +1076,9 @@ PyArray_PromoteTypes(PyArray_Descr *type1, PyArray_Descr *type2)
return NULL;
}
- if (!common_dtype->parametric) {
- res = common_dtype->default_descr(common_dtype);
+ if (!NPY_DT_is_parametric(common_dtype)) {
+ /* Note that this path loses all metadata */
+ res = NPY_DT_CALL_default_descr(common_dtype);
Py_DECREF(common_dtype);
return res;
}
@@ -959,7 +1100,7 @@ PyArray_PromoteTypes(PyArray_Descr *type1, PyArray_Descr *type2)
* And find the common instance of the two inputs
* NOTE: Common instance preserves metadata (normally and of one input)
*/
- res = common_dtype->common_instance(type1, type2);
+ res = NPY_DT_SLOTS(common_dtype)->common_instance(type1, type2);
Py_DECREF(type1);
Py_DECREF(type2);
Py_DECREF(common_dtype);
@@ -970,28 +1111,17 @@ PyArray_PromoteTypes(PyArray_Descr *type1, PyArray_Descr *type2)
* Produces the smallest size and lowest kind type to which all
* input types can be cast.
*
- * Equivalent to functools.reduce(PyArray_PromoteTypes, types)
+ * Roughly equivalent to functools.reduce(PyArray_PromoteTypes, types)
+ * but uses a more complex pairwise approach.
*/
NPY_NO_EXPORT PyArray_Descr *
PyArray_PromoteTypeSequence(PyArray_Descr **types, npy_intp ntypes)
{
- npy_intp i;
- PyArray_Descr *ret = NULL;
if (ntypes == 0) {
PyErr_SetString(PyExc_TypeError, "at least one type needed to promote");
return NULL;
}
- ret = types[0];
- Py_INCREF(ret);
- for (i = 1; i < ntypes; ++i) {
- PyArray_Descr *tmp = PyArray_PromoteTypes(types[i], ret);
- Py_DECREF(ret);
- ret = tmp;
- if (ret == NULL) {
- return NULL;
- }
- }
- return ret;
+ return PyArray_ResultType(0, NULL, ntypes, types);
}
/*
@@ -1357,6 +1487,8 @@ dtype_kind_to_simplified_ordering(char kind)
* If the scalars are of a lower or same category as the arrays, they may be
* demoted to a lower type within their category (the lowest type they can
* be cast to safely according to scalar casting rules).
+ *
+ * If any new style dtype is involved (non-legacy), always returns 0.
*/
NPY_NO_EXPORT int
should_use_min_scalar(npy_intp narrs, PyArrayObject **arr,
@@ -1373,6 +1505,9 @@ should_use_min_scalar(npy_intp narrs, PyArrayObject **arr,
/* Compute the maximum "kinds" and whether everything is scalar */
for (npy_intp i = 0; i < narrs; ++i) {
+ if (!NPY_DT_is_legacy(NPY_DTYPE(PyArray_DESCR(arr[i])))) {
+ return 0;
+ }
if (PyArray_NDIM(arr[i]) == 0) {
int kind = dtype_kind_to_simplified_ordering(
PyArray_DESCR(arr[i])->kind);
@@ -1394,6 +1529,9 @@ should_use_min_scalar(npy_intp narrs, PyArrayObject **arr,
* finish computing the max array kind
*/
for (npy_intp i = 0; i < ndtypes; ++i) {
+ if (!NPY_DT_is_legacy(NPY_DTYPE(dtypes[i]))) {
+ return 0;
+ }
int kind = dtype_kind_to_simplified_ordering(dtypes[i]->kind);
if (kind > max_array_kind) {
max_array_kind = kind;
@@ -1410,6 +1548,209 @@ should_use_min_scalar(npy_intp narrs, PyArrayObject **arr,
/*NUMPY_API
+ *
+ * Produces the result type of a bunch of inputs, using the same rules
+ * as `np.result_type`.
+ *
+ * NOTE: This function is expected to through a transitional period or
+ * change behaviour. DTypes should always be strictly enforced for
+ * 0-D arrays, while "weak DTypes" will be used to represent Python
+ * integers, floats, and complex in all cases.
+ * (Within this function, these are currently flagged on the array
+ * object to work through `np.result_type`, this may change.)
+ *
+ * Until a time where this transition is complete, we probably cannot
+ * add new "weak DTypes" or allow users to create their own.
+ */
+NPY_NO_EXPORT PyArray_Descr *
+PyArray_ResultType(
+ npy_intp narrs, PyArrayObject *arrs[],
+ npy_intp ndtypes, PyArray_Descr *descrs[])
+{
+ PyArray_Descr *result = NULL;
+
+ if (narrs + ndtypes <= 1) {
+ /* If the input is a single value, skip promotion. */
+ if (narrs == 1) {
+ result = PyArray_DTYPE(arrs[0]);
+ }
+ else if (ndtypes == 1) {
+ result = descrs[0];
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "no arrays or types available to calculate result type");
+ return NULL;
+ }
+ return ensure_dtype_nbo(result);
+ }
+
+ void **info_on_heap = NULL;
+ void *_info_on_stack[NPY_MAXARGS * 2];
+ PyArray_DTypeMeta **all_DTypes;
+ PyArray_Descr **all_descriptors;
+
+ if (narrs + ndtypes > NPY_MAXARGS) {
+ info_on_heap = PyMem_Malloc(2 * (narrs+ndtypes) * sizeof(PyObject *));
+ if (info_on_heap == NULL) {
+ PyErr_NoMemory();
+ return NULL;
+ }
+ all_DTypes = (PyArray_DTypeMeta **)info_on_heap;
+ all_descriptors = (PyArray_Descr **)(info_on_heap + narrs + ndtypes);
+ }
+ else {
+ all_DTypes = (PyArray_DTypeMeta **)_info_on_stack;
+ all_descriptors = (PyArray_Descr **)(_info_on_stack + narrs + ndtypes);
+ }
+
+ /* Copy all dtypes into a single array defining non-value-based behaviour */
+ for (npy_intp i=0; i < ndtypes; i++) {
+ all_DTypes[i] = NPY_DTYPE(descrs[i]);
+ Py_INCREF(all_DTypes[i]);
+ all_descriptors[i] = descrs[i];
+ }
+
+ int at_least_one_scalar = 0;
+ int all_pyscalar = ndtypes == 0;
+ for (npy_intp i=0, i_all=ndtypes; i < narrs; i++, i_all++) {
+ /* Array descr is also the correct "default" for scalars: */
+ if (PyArray_NDIM(arrs[i]) == 0) {
+ at_least_one_scalar = 1;
+ }
+
+ if (!(PyArray_FLAGS(arrs[i]) & _NPY_ARRAY_WAS_PYSCALAR)) {
+ /* This was not a scalar with an abstract DType */
+ all_descriptors[i_all] = PyArray_DTYPE(arrs[i]);
+ all_DTypes[i_all] = NPY_DTYPE(all_descriptors[i_all]);
+ Py_INCREF(all_DTypes[i_all]);
+ all_pyscalar = 0;
+ continue;
+ }
+
+ /*
+ * The original was a Python scalar with an abstract DType.
+ * In a future world, this type of code may need to work on the
+ * DType level first and discover those from the original value.
+ * But, right now we limit the logic to int, float, and complex
+ * and do it here to allow for a transition without losing all of
+ * our remaining sanity.
+ */
+ if (PyArray_ISFLOAT(arrs[i])) {
+ all_DTypes[i_all] = &PyArray_PyFloatAbstractDType;
+ }
+ else if (PyArray_ISCOMPLEX(arrs[i])) {
+ all_DTypes[i_all] = &PyArray_PyComplexAbstractDType;
+ }
+ else {
+ /* N.B.: Could even be an object dtype here for large ints */
+ all_DTypes[i_all] = &PyArray_PyIntAbstractDType;
+ }
+ Py_INCREF(all_DTypes[i_all]);
+ /*
+ * Leave the decriptor empty, if we need it, we will have to go
+ * to more extreme lengths unfortunately.
+ */
+ all_descriptors[i_all] = NULL;
+ }
+
+ PyArray_DTypeMeta *common_dtype = PyArray_PromoteDTypeSequence(
+ narrs+ndtypes, all_DTypes);
+ for (npy_intp i=0; i < narrs+ndtypes; i++) {
+ Py_DECREF(all_DTypes[i]);
+ }
+ if (common_dtype == NULL) {
+ goto error;
+ }
+
+ if (NPY_DT_is_abstract(common_dtype)) {
+ /* (ab)use default descriptor to define a default */
+ PyArray_Descr *tmp_descr = NPY_DT_CALL_default_descr(common_dtype);
+ if (tmp_descr == NULL) {
+ goto error;
+ }
+ Py_INCREF(NPY_DTYPE(tmp_descr));
+ Py_SETREF(common_dtype, NPY_DTYPE(tmp_descr));
+ Py_DECREF(tmp_descr);
+ }
+
+ /*
+ * NOTE: Code duplicates `PyArray_CastToDTypeAndPromoteDescriptors`, but
+ * supports special handling of the abstract values.
+ */
+ if (!NPY_DT_is_parametric(common_dtype)) {
+ /* Note that this "fast" path loses all metadata */
+ result = NPY_DT_CALL_default_descr(common_dtype);
+ }
+ else {
+ result = PyArray_CastDescrToDType(all_descriptors[0], common_dtype);
+
+ for (npy_intp i = 1; i < ndtypes+narrs; i++) {
+ PyArray_Descr *curr;
+ if (NPY_LIKELY(i < ndtypes ||
+ !(PyArray_FLAGS(arrs[i-ndtypes]) & _NPY_ARRAY_WAS_PYSCALAR))) {
+ curr = PyArray_CastDescrToDType(all_descriptors[i], common_dtype);
+ }
+ else {
+ /*
+ * Unlike `PyArray_CastToDTypeAndPromoteDescriptors` deal with
+ * plain Python values "graciously". This recovers the original
+ * value the long route, but it should almost never happen...
+ */
+ PyObject *tmp = PyArray_GETITEM(
+ arrs[i-ndtypes], PyArray_BYTES(arrs[i-ndtypes]));
+ if (tmp == NULL) {
+ goto error;
+ }
+ curr = NPY_DT_CALL_discover_descr_from_pyobject(common_dtype, tmp);
+ Py_DECREF(tmp);
+ }
+ if (curr == NULL) {
+ goto error;
+ }
+ Py_SETREF(result, NPY_DT_SLOTS(common_dtype)->common_instance(result, curr));
+ Py_DECREF(curr);
+ if (result == NULL) {
+ goto error;
+ }
+ }
+ }
+
+ /*
+ * Unfortunately, when 0-D "scalar" arrays are involved and mixed, we
+ * have to use the value-based logic. The intention is to move away from
+ * the complex logic arising from it. We thus fall back to the legacy
+ * version here.
+ * It may be possible to micro-optimize this to skip some of the above
+ * logic when this path is necessary.
+ */
+ if (at_least_one_scalar && !all_pyscalar && result->type_num < NPY_NTYPES) {
+ PyArray_Descr *legacy_result = PyArray_LegacyResultType(
+ narrs, arrs, ndtypes, descrs);
+ if (legacy_result == NULL) {
+ /*
+ * Going from error to success should not really happen, but is
+ * probably OK if it does.
+ */
+ goto error;
+ }
+ /* Return the old "legacy" result (could warn here if different) */
+ Py_SETREF(result, legacy_result);
+ }
+
+ Py_DECREF(common_dtype);
+ PyMem_Free(info_on_heap);
+ return result;
+
+ error:
+ Py_XDECREF(result);
+ Py_XDECREF(common_dtype);
+ PyMem_Free(info_on_heap);
+ return NULL;
+}
+
+
+/*
* Produces the result type of a bunch of inputs, using the UFunc
* type promotion rules. Use this function when you have a set of
* input arrays, and need to determine an output array dtype.
@@ -1421,11 +1762,11 @@ should_use_min_scalar(npy_intp narrs, PyArrayObject **arr,
* Otherwise, does a type promotion on the MinScalarType
* of all the inputs. Data types passed directly are treated as array
* types.
- *
*/
NPY_NO_EXPORT PyArray_Descr *
-PyArray_ResultType(npy_intp narrs, PyArrayObject **arr,
- npy_intp ndtypes, PyArray_Descr **dtypes)
+PyArray_LegacyResultType(
+ npy_intp narrs, PyArrayObject **arr,
+ npy_intp ndtypes, PyArray_Descr **dtypes)
{
npy_intp i;
@@ -1524,6 +1865,49 @@ PyArray_ResultType(npy_intp narrs, PyArrayObject **arr,
}
}
+/**
+ * Promotion of descriptors (of arbitrary DType) to their correctly
+ * promoted instances of the given DType.
+ * I.e. the given DType could be a string, which then finds the correct
+ * string length, given all `descrs`.
+ *
+ * @param ndescrs number of descriptors to cast and find the common instance.
+ * At least one must be passed in.
+ * @param descrs The descriptors to work with.
+ * @param DType The DType of the desired output descriptor.
+ */
+NPY_NO_EXPORT PyArray_Descr *
+PyArray_CastToDTypeAndPromoteDescriptors(
+ npy_intp ndescr, PyArray_Descr *descrs[], PyArray_DTypeMeta *DType)
+{
+ assert(ndescr > 0);
+
+ PyArray_Descr *result = PyArray_CastDescrToDType(descrs[0], DType);
+ if (result == NULL || ndescr == 1) {
+ return result;
+ }
+ if (!NPY_DT_is_parametric(DType)) {
+ /* Note that this "fast" path loses all metadata */
+ Py_DECREF(result);
+ return NPY_DT_CALL_default_descr(DType);
+ }
+
+ for (npy_intp i = 1; i < ndescr; i++) {
+ PyArray_Descr *curr = PyArray_CastDescrToDType(descrs[i], DType);
+ if (curr == NULL) {
+ Py_DECREF(result);
+ return NULL;
+ }
+ Py_SETREF(result, NPY_DT_SLOTS(DType)->common_instance(result, curr));
+ Py_DECREF(curr);
+ if (result == NULL) {
+ return NULL;
+ }
+ }
+ return result;
+}
+
+
/*NUMPY_API
* Is the typenum valid?
*/
@@ -1684,7 +2068,7 @@ PyArray_ObjectType(PyObject *op, int minimum_type)
if (dtype == NULL) {
ret = NPY_DEFAULT_TYPE;
}
- else if (!NPY_DTYPE(dtype)->legacy) {
+ else if (!NPY_DT_is_legacy(NPY_DTYPE(dtype))) {
/*
* TODO: If we keep all type number style API working, by defining
* type numbers always. We may be able to allow this again.
@@ -1808,7 +2192,7 @@ PyArray_ConvertToCommonType(PyObject *op, int *retn)
* @return 0 on success -1 on failure.
*/
NPY_NO_EXPORT int
-PyArray_AddCastingImplmentation(PyBoundArrayMethodObject *meth)
+PyArray_AddCastingImplementation(PyBoundArrayMethodObject *meth)
{
if (meth->method->nin != 1 || meth->method->nout != 1) {
PyErr_SetString(PyExc_TypeError,
@@ -1816,6 +2200,11 @@ PyArray_AddCastingImplmentation(PyBoundArrayMethodObject *meth)
return -1;
}
if (meth->dtypes[0] == meth->dtypes[1]) {
+ /*
+ * The method casting between instances of the same dtype is special,
+ * since it is common, it is stored explicitly (currently) and must
+ * obey additional constraints to ensure convenient casting.
+ */
if (!(meth->method->flags & NPY_METH_SUPPORTS_UNALIGNED)) {
PyErr_Format(PyExc_TypeError,
"A cast where input and output DType (class) are identical "
@@ -1823,22 +2212,26 @@ PyArray_AddCastingImplmentation(PyBoundArrayMethodObject *meth)
meth->method->name);
return -1;
}
- if ((meth->method->casting & ~_NPY_CAST_IS_VIEW) != NPY_NO_CASTING) {
- PyErr_Format(PyExc_TypeError,
- "A cast where input and output DType (class) are identical "
- "must signal `no-casting`. (method: %s)",
- meth->method->name);
+ if (NPY_DT_SLOTS(meth->dtypes[0])->within_dtype_castingimpl != NULL) {
+ PyErr_Format(PyExc_RuntimeError,
+ "A cast was already added for %S -> %S. (method: %s)",
+ meth->dtypes[0], meth->dtypes[1], meth->method->name);
return -1;
}
+ Py_INCREF(meth->method);
+ NPY_DT_SLOTS(meth->dtypes[0])->within_dtype_castingimpl = (
+ (PyObject *)meth->method);
+
+ return 0;
}
- if (PyDict_Contains(meth->dtypes[0]->castingimpls,
+ if (PyDict_Contains(NPY_DT_SLOTS(meth->dtypes[0])->castingimpls,
(PyObject *)meth->dtypes[1])) {
PyErr_Format(PyExc_RuntimeError,
"A cast was already added for %S -> %S. (method: %s)",
meth->dtypes[0], meth->dtypes[1], meth->method->name);
return -1;
}
- if (PyDict_SetItem(meth->dtypes[0]->castingimpls,
+ if (PyDict_SetItem(NPY_DT_SLOTS(meth->dtypes[0])->castingimpls,
(PyObject *)meth->dtypes[1], (PyObject *)meth->method) < 0) {
return -1;
}
@@ -1860,7 +2253,7 @@ PyArray_AddCastingImplementation_FromSpec(PyArrayMethod_Spec *spec, int private)
if (meth == NULL) {
return -1;
}
- int res = PyArray_AddCastingImplmentation(meth);
+ int res = PyArray_AddCastingImplementation(meth);
Py_DECREF(meth);
if (res < 0) {
return -1;
@@ -1906,6 +2299,30 @@ legacy_same_dtype_resolve_descriptors(
}
+NPY_NO_EXPORT int
+legacy_cast_get_strided_loop(
+ PyArrayMethod_Context *context,
+ int aligned, int move_references, npy_intp *strides,
+ PyArrayMethod_StridedLoop **out_loop, NpyAuxData **out_transferdata,
+ NPY_ARRAYMETHOD_FLAGS *flags)
+{
+ PyArray_Descr **descrs = context->descriptors;
+ int out_needs_api = 0;
+
+ *flags = context->method->flags & NPY_METH_RUNTIME_FLAGS;
+
+ if (get_wrapped_legacy_cast_function(
+ aligned, strides[0], strides[1], descrs[0], descrs[1],
+ move_references, out_loop, out_transferdata, &out_needs_api, 0) < 0) {
+ return -1;
+ }
+ if (!out_needs_api) {
+ *flags &= ~NPY_METH_REQUIRES_PYAPI;
+ }
+ return 0;
+}
+
+
/*
* Simple dtype resolver for casting between two different (non-parametric)
* (legacy) dtypes.
@@ -1917,7 +2334,7 @@ simple_cast_resolve_descriptors(
PyArray_Descr *given_descrs[2],
PyArray_Descr *loop_descrs[2])
{
- assert(dtypes[0]->legacy && dtypes[1]->legacy);
+ assert(NPY_DT_is_legacy(dtypes[0]) && NPY_DT_is_legacy(dtypes[1]));
loop_descrs[0] = ensure_dtype_nbo(given_descrs[0]);
if (loop_descrs[0] == NULL) {
@@ -1931,7 +2348,7 @@ simple_cast_resolve_descriptors(
}
}
else {
- loop_descrs[1] = dtypes[1]->default_descr(dtypes[1]);
+ loop_descrs[1] = NPY_DT_CALL_default_descr(dtypes[1]);
}
if (self->casting != NPY_NO_CASTING) {
@@ -1945,10 +2362,77 @@ simple_cast_resolve_descriptors(
}
+NPY_NO_EXPORT int
+get_byteswap_loop(
+ PyArrayMethod_Context *context,
+ int aligned, int NPY_UNUSED(move_references), npy_intp *strides,
+ PyArrayMethod_StridedLoop **out_loop, NpyAuxData **out_transferdata,
+ NPY_ARRAYMETHOD_FLAGS *flags)
+{
+ PyArray_Descr **descrs = context->descriptors;
+ assert(descrs[0]->kind == descrs[1]->kind);
+ assert(descrs[0]->elsize == descrs[1]->elsize);
+ int itemsize = descrs[0]->elsize;
+ *flags = NPY_METH_NO_FLOATINGPOINT_ERRORS;
+ *out_transferdata = NULL;
+ if (descrs[0]->kind == 'c') {
+ /*
+ * TODO: we have an issue with complex, since the below loops
+ * use the itemsize, the complex alignment would be too small.
+ * Using aligned = 0, might cause slow downs in some cases.
+ */
+ aligned = 0;
+ }
+
+ if (PyDataType_ISNOTSWAPPED(descrs[0]) ==
+ PyDataType_ISNOTSWAPPED(descrs[1])) {
+ *out_loop = PyArray_GetStridedCopyFn(
+ aligned, strides[0], strides[1], itemsize);
+ }
+ else if (!PyTypeNum_ISCOMPLEX(descrs[0]->type_num)) {
+ *out_loop = PyArray_GetStridedCopySwapFn(
+ aligned, strides[0], strides[1], itemsize);
+ }
+ else {
+ *out_loop = PyArray_GetStridedCopySwapPairFn(
+ aligned, strides[0], strides[1], itemsize);
+ }
+ if (*out_loop == NULL) {
+ return -1;
+ }
+ return 0;
+}
+
+
+NPY_NO_EXPORT int
+complex_to_noncomplex_get_loop(
+ PyArrayMethod_Context *context,
+ int aligned, int move_references, npy_intp *strides,
+ PyArrayMethod_StridedLoop **out_loop, NpyAuxData **out_transferdata,
+ NPY_ARRAYMETHOD_FLAGS *flags)
+{
+ static PyObject *cls = NULL;
+ int ret;
+ npy_cache_import("numpy.core", "ComplexWarning", &cls);
+ if (cls == NULL) {
+ return -1;
+ }
+ ret = PyErr_WarnEx(cls,
+ "Casting complex values to real discards "
+ "the imaginary part", 1);
+ if (ret < 0) {
+ return -1;
+ }
+ return npy_default_get_strided_loop(
+ context, aligned, move_references, strides,
+ out_loop, out_transferdata, flags);
+}
+
+
static int
add_numeric_cast(PyArray_DTypeMeta *from, PyArray_DTypeMeta *to)
{
- PyType_Slot slots[6];
+ PyType_Slot slots[7];
PyArray_DTypeMeta *dtypes[2] = {from, to};
PyArrayMethod_Spec spec = {
.name = "numeric_cast",
@@ -1959,8 +2443,8 @@ add_numeric_cast(PyArray_DTypeMeta *from, PyArray_DTypeMeta *to)
.dtypes = dtypes,
};
- npy_intp from_itemsize = dtypes[0]->singleton->elsize;
- npy_intp to_itemsize = dtypes[1]->singleton->elsize;
+ npy_intp from_itemsize = from->singleton->elsize;
+ npy_intp to_itemsize = to->singleton->elsize;
slots[0].slot = NPY_METH_resolve_descriptors;
slots[0].pfunc = &simple_cast_resolve_descriptors;
@@ -1977,20 +2461,37 @@ add_numeric_cast(PyArray_DTypeMeta *from, PyArray_DTypeMeta *to)
slots[4].slot = NPY_METH_unaligned_contiguous_loop;
slots[4].pfunc = PyArray_GetStridedNumericCastFn(
0, from_itemsize, to_itemsize, from->type_num, to->type_num);
- slots[5].slot = 0;
- slots[5].pfunc = NULL;
+ if (PyTypeNum_ISCOMPLEX(from->type_num) &&
+ !PyTypeNum_ISCOMPLEX(to->type_num) &&
+ !PyTypeNum_ISBOOL(to->type_num)) {
+ /*
+ * The get_loop function must also give a ComplexWarning. We could
+ * consider moving this warning into the inner-loop at some point
+ * for simplicity (this requires ensuring it is only emitted once).
+ */
+ slots[5].slot = NPY_METH_get_loop;
+ slots[5].pfunc = &complex_to_noncomplex_get_loop;
+ slots[6].slot = 0;
+ slots[6].pfunc = NULL;
+ }
+ else {
+ /* Use the default get loop function. */
+ slots[5].slot = 0;
+ slots[5].pfunc = NULL;
+ }
assert(slots[1].pfunc && slots[2].pfunc && slots[3].pfunc && slots[4].pfunc);
/* Find the correct casting level, and special case no-cast */
- if (dtypes[0]->kind == dtypes[1]->kind && from_itemsize == to_itemsize) {
- spec.casting = NPY_NO_CASTING;
+ if (dtypes[0]->singleton->kind == dtypes[1]->singleton->kind
+ && from_itemsize == to_itemsize) {
+ spec.casting = NPY_EQUIV_CASTING;
/* When there is no casting (equivalent C-types) use byteswap loops */
slots[0].slot = NPY_METH_resolve_descriptors;
slots[0].pfunc = &legacy_same_dtype_resolve_descriptors;
slots[1].slot = NPY_METH_get_loop;
- slots[1].pfunc = NULL;
+ slots[1].pfunc = &get_byteswap_loop;
slots[2].slot = 0;
slots[2].pfunc = NULL;
@@ -2000,8 +2501,8 @@ add_numeric_cast(PyArray_DTypeMeta *from, PyArray_DTypeMeta *to)
else if (_npy_can_cast_safely_table[from->type_num][to->type_num]) {
spec.casting = NPY_SAFE_CASTING;
}
- else if (dtype_kind_to_ordering(dtypes[0]->kind) <=
- dtype_kind_to_ordering(dtypes[1]->kind)) {
+ else if (dtype_kind_to_ordering(dtypes[0]->singleton->kind) <=
+ dtype_kind_to_ordering(dtypes[1]->singleton->kind)) {
spec.casting = NPY_SAME_KIND_CASTING;
}
else {
@@ -2059,7 +2560,7 @@ cast_to_string_resolve_descriptors(
* a multiple of eight.
*/
npy_intp size = -1;
- switch (dtypes[0]->type_num) {
+ switch (given_descrs[0]->type_num) {
case NPY_BOOL:
case NPY_UBYTE:
case NPY_BYTE:
@@ -2071,18 +2572,18 @@ cast_to_string_resolve_descriptors(
case NPY_LONG:
case NPY_ULONGLONG:
case NPY_LONGLONG:
- assert(dtypes[0]->singleton->elsize <= 8);
- assert(dtypes[0]->singleton->elsize > 0);
- if (dtypes[0]->kind == 'b') {
+ assert(given_descrs[0]->elsize <= 8);
+ assert(given_descrs[0]->elsize > 0);
+ if (given_descrs[0]->kind == 'b') {
/* 5 chars needed for cast to 'True' or 'False' */
size = 5;
}
- else if (dtypes[0]->kind == 'u') {
- size = REQUIRED_STR_LEN[dtypes[0]->singleton->elsize];
+ else if (given_descrs[0]->kind == 'u') {
+ size = REQUIRED_STR_LEN[given_descrs[0]->elsize];
}
- else if (dtypes[0]->kind == 'i') {
+ else if (given_descrs[0]->kind == 'i') {
/* Add character for sign symbol */
- size = REQUIRED_STR_LEN[dtypes[0]->singleton->elsize] + 1;
+ size = REQUIRED_STR_LEN[given_descrs[0]->elsize] + 1;
}
break;
case NPY_HALF:
@@ -2142,7 +2643,6 @@ cast_to_string_resolve_descriptors(
dtypes[1]->type_num == NPY_STRING);
return NPY_UNSAFE_CASTING;
}
- assert(self->casting == NPY_SAFE_CASTING);
if (loop_descrs[1]->elsize >= size) {
return NPY_SAFE_CASTING;
@@ -2173,9 +2673,9 @@ add_other_to_and_from_string_cast(
*/
PyArray_DTypeMeta *dtypes[2] = {other, string};
PyType_Slot slots[] = {
- {NPY_METH_get_loop, NULL},
+ {NPY_METH_get_loop, &legacy_cast_get_strided_loop},
{NPY_METH_resolve_descriptors, &cast_to_string_resolve_descriptors},
- {0, NULL}};
+ {0, NULL}};
PyArrayMethod_Spec spec = {
.name = "legacy_cast_to_string",
.nin = 1,
@@ -2184,9 +2684,9 @@ add_other_to_and_from_string_cast(
.dtypes = dtypes,
.slots = slots,
};
- /* Almost everything can be safely cast to string (except unicode) */
+ /* Almost everything can be same-kind cast to string (except unicode) */
if (other->type_num != NPY_UNICODE) {
- spec.casting = NPY_SAFE_CASTING;
+ spec.casting = NPY_SAME_KIND_CASTING; /* same-kind if too short */
}
else {
spec.casting = NPY_UNSAFE_CASTING;
@@ -2233,6 +2733,35 @@ string_to_string_resolve_descriptors(
}
+NPY_NO_EXPORT int
+string_to_string_get_loop(
+ PyArrayMethod_Context *context,
+ int aligned, int NPY_UNUSED(move_references), npy_intp *strides,
+ PyArrayMethod_StridedLoop **out_loop, NpyAuxData **out_transferdata,
+ NPY_ARRAYMETHOD_FLAGS *flags)
+{
+ int unicode_swap = 0;
+ PyArray_Descr **descrs = context->descriptors;
+
+ assert(NPY_DTYPE(descrs[0]) == NPY_DTYPE(descrs[1]));
+ *flags = context->method->flags & NPY_METH_RUNTIME_FLAGS;
+ if (descrs[0]->type_num == NPY_UNICODE) {
+ if (PyDataType_ISNOTSWAPPED(descrs[0]) !=
+ PyDataType_ISNOTSWAPPED(descrs[1])) {
+ unicode_swap = 1;
+ }
+ }
+
+ if (PyArray_GetStridedZeroPadCopyFn(
+ aligned, unicode_swap, strides[0], strides[1],
+ descrs[0]->elsize, descrs[1]->elsize,
+ out_loop, out_transferdata) == NPY_FAIL) {
+ return -1;
+ }
+ return 0;
+}
+
+
/*
* Add string casts. Right now all string casts are just legacy-wrapped ones
* (except string<->string and unicode<->unicode), but they do require
@@ -2272,12 +2801,12 @@ PyArray_InitializeStringCasts(void)
/* string<->string and unicode<->unicode have their own specialized casts */
PyArray_DTypeMeta *dtypes[2];
PyType_Slot slots[] = {
- {NPY_METH_get_loop, NULL},
+ {NPY_METH_get_loop, &string_to_string_get_loop},
{NPY_METH_resolve_descriptors, &string_to_string_resolve_descriptors},
- {0, NULL}};
+ {0, NULL}};
PyArrayMethod_Spec spec = {
.name = "string_to_string_cast",
- .casting = NPY_NO_CASTING,
+ .casting = NPY_UNSAFE_CASTING,
.nin = 1,
.nout = 1,
.flags = (NPY_METH_REQUIRES_PYAPI |
@@ -2325,6 +2854,10 @@ cast_to_void_dtype_class(
loop_descrs[1]->elsize = given_descrs[0]->elsize;
Py_INCREF(given_descrs[0]);
loop_descrs[0] = given_descrs[0];
+ if (loop_descrs[0]->type_num == NPY_VOID &&
+ loop_descrs[0]->subarray == NULL && loop_descrs[1]->names == NULL) {
+ return NPY_NO_CASTING | _NPY_CAST_IS_VIEW;
+ }
return NPY_SAFE_CASTING | _NPY_CAST_IS_VIEW;
}
@@ -2422,6 +2955,57 @@ int give_bad_field_error(PyObject *key)
}
+static int
+nonstructured_to_structured_get_loop(
+ PyArrayMethod_Context *context,
+ int aligned, int move_references,
+ npy_intp *strides,
+ PyArrayMethod_StridedLoop **out_loop,
+ NpyAuxData **out_transferdata,
+ NPY_ARRAYMETHOD_FLAGS *flags)
+{
+ if (context->descriptors[1]->names != NULL) {
+ int needs_api = 0;
+ if (get_fields_transfer_function(
+ aligned, strides[0], strides[1],
+ context->descriptors[0], context->descriptors[1],
+ move_references, out_loop, out_transferdata,
+ &needs_api) == NPY_FAIL) {
+ return -1;
+ }
+ *flags = needs_api ? NPY_METH_REQUIRES_PYAPI : 0;
+ }
+ else if (context->descriptors[1]->subarray != NULL) {
+ int needs_api = 0;
+ if (get_subarray_transfer_function(
+ aligned, strides[0], strides[1],
+ context->descriptors[0], context->descriptors[1],
+ move_references, out_loop, out_transferdata,
+ &needs_api) == NPY_FAIL) {
+ return -1;
+ }
+ *flags = needs_api ? NPY_METH_REQUIRES_PYAPI : 0;
+ }
+ else {
+ /*
+ * TODO: This could be a simple zero padded cast, adding a decref
+ * in case of `move_references`. But for now use legacy casts
+ * (which is the behaviour at least up to 1.20).
+ */
+ int needs_api = 0;
+ if (get_wrapped_legacy_cast_function(
+ 1, strides[0], strides[1],
+ context->descriptors[0], context->descriptors[1],
+ move_references, out_loop, out_transferdata,
+ &needs_api, 1) < 0) {
+ return -1;
+ }
+ *flags = needs_api ? NPY_METH_REQUIRES_PYAPI : 0;
+ }
+ return 0;
+}
+
+
static PyObject *
PyArray_GetGenericToVoidCastingImpl(void)
{
@@ -2439,9 +3023,9 @@ PyArray_GetGenericToVoidCastingImpl(void)
method->name = "any_to_void_cast";
method->flags = NPY_METH_SUPPORTS_UNALIGNED | NPY_METH_REQUIRES_PYAPI;
- method->casting = NPY_SAFE_CASTING;
+ method->casting = -1;
method->resolve_descriptors = &nonstructured_to_structured_resolve_descriptors;
- method->get_strided_loop = NULL;
+ method->get_strided_loop = &nonstructured_to_structured_get_loop;
return (PyObject *)method;
}
@@ -2487,7 +3071,7 @@ structured_to_nonstructured_resolve_descriptors(
/* Void dtypes always do the full cast. */
if (given_descrs[1] == NULL) {
- loop_descrs[1] = dtypes[1]->default_descr(dtypes[1]);
+ loop_descrs[1] = NPY_DT_CALL_default_descr(dtypes[1]);
/*
* Special case strings here, it should be useless (and only actually
* work for empty arrays). Possibly this should simply raise for
@@ -2511,6 +3095,56 @@ structured_to_nonstructured_resolve_descriptors(
}
+static int
+structured_to_nonstructured_get_loop(
+ PyArrayMethod_Context *context,
+ int aligned, int move_references,
+ npy_intp *strides,
+ PyArrayMethod_StridedLoop **out_loop,
+ NpyAuxData **out_transferdata,
+ NPY_ARRAYMETHOD_FLAGS *flags)
+{
+ if (context->descriptors[0]->names != NULL) {
+ int needs_api = 0;
+ if (get_fields_transfer_function(
+ aligned, strides[0], strides[1],
+ context->descriptors[0], context->descriptors[1],
+ move_references, out_loop, out_transferdata,
+ &needs_api) == NPY_FAIL) {
+ return -1;
+ }
+ *flags = needs_api ? NPY_METH_REQUIRES_PYAPI : 0;
+ }
+ else if (context->descriptors[0]->subarray != NULL) {
+ int needs_api = 0;
+ if (get_subarray_transfer_function(
+ aligned, strides[0], strides[1],
+ context->descriptors[0], context->descriptors[1],
+ move_references, out_loop, out_transferdata,
+ &needs_api) == NPY_FAIL) {
+ return -1;
+ }
+ *flags = needs_api ? NPY_METH_REQUIRES_PYAPI : 0;
+ }
+ else {
+ /*
+ * In general this is currently defined through legacy behaviour via
+ * scalars, and should likely just not be allowed.
+ */
+ int needs_api = 0;
+ if (get_wrapped_legacy_cast_function(
+ aligned, strides[0], strides[1],
+ context->descriptors[0], context->descriptors[1],
+ move_references, out_loop, out_transferdata,
+ &needs_api, 1) < 0) {
+ return -1;
+ }
+ *flags = needs_api ? NPY_METH_REQUIRES_PYAPI : 0;
+ }
+ return 0;
+}
+
+
static PyObject *
PyArray_GetVoidToGenericCastingImpl(void)
{
@@ -2528,9 +3162,9 @@ PyArray_GetVoidToGenericCastingImpl(void)
method->name = "void_to_any_cast";
method->flags = NPY_METH_SUPPORTS_UNALIGNED | NPY_METH_REQUIRES_PYAPI;
- method->casting = NPY_UNSAFE_CASTING;
+ method->casting = -1;
method->resolve_descriptors = &structured_to_nonstructured_resolve_descriptors;
- method->get_strided_loop = NULL;
+ method->get_strided_loop = &structured_to_nonstructured_get_loop;
return (PyObject *)method;
}
@@ -2676,8 +3310,10 @@ void_to_void_resolve_descriptors(
casting = NPY_NO_CASTING | _NPY_CAST_IS_VIEW;
}
}
- NPY_CASTING field_casting = PyArray_GetCastSafety(
- given_descrs[0]->subarray->base, given_descrs[1]->subarray->base, NULL);
+
+ PyArray_Descr *from_base = (from_sub == NULL) ? given_descrs[0] : from_sub->base;
+ PyArray_Descr *to_base = (to_sub == NULL) ? given_descrs[1] : to_sub->base;
+ NPY_CASTING field_casting = PyArray_GetCastSafety(from_base, to_base, NULL);
if (field_casting < 0) {
return -1;
}
@@ -2694,6 +3330,56 @@ void_to_void_resolve_descriptors(
}
+NPY_NO_EXPORT int
+void_to_void_get_loop(
+ PyArrayMethod_Context *context,
+ int aligned, int move_references,
+ npy_intp *strides,
+ PyArrayMethod_StridedLoop **out_loop,
+ NpyAuxData **out_transferdata,
+ NPY_ARRAYMETHOD_FLAGS *flags)
+{
+ if (context->descriptors[0]->names != NULL ||
+ context->descriptors[1]->names != NULL) {
+ int needs_api = 0;
+ if (get_fields_transfer_function(
+ aligned, strides[0], strides[1],
+ context->descriptors[0], context->descriptors[1],
+ move_references, out_loop, out_transferdata,
+ &needs_api) == NPY_FAIL) {
+ return -1;
+ }
+ *flags = needs_api ? NPY_METH_REQUIRES_PYAPI : 0;
+ }
+ else if (context->descriptors[0]->subarray != NULL ||
+ context->descriptors[1]->subarray != NULL) {
+ int needs_api = 0;
+ if (get_subarray_transfer_function(
+ aligned, strides[0], strides[1],
+ context->descriptors[0], context->descriptors[1],
+ move_references, out_loop, out_transferdata,
+ &needs_api) == NPY_FAIL) {
+ return -1;
+ }
+ *flags = needs_api ? NPY_METH_REQUIRES_PYAPI : 0;
+ }
+ else {
+ /*
+ * This is a string-like copy of the two bytes (zero padding if
+ * necessary)
+ */
+ if (PyArray_GetStridedZeroPadCopyFn(
+ 0, 0, strides[0], strides[1],
+ context->descriptors[0]->elsize, context->descriptors[1]->elsize,
+ out_loop, out_transferdata) == NPY_FAIL) {
+ return -1;
+ }
+ *flags = 0;
+ }
+ return 0;
+}
+
+
/*
* This initializes the void to void cast. Voids include structured dtypes,
* which means that they can cast from and to any other dtype and, in that
@@ -2705,12 +3391,12 @@ PyArray_InitializeVoidToVoidCast(void)
PyArray_DTypeMeta *Void = PyArray_DTypeFromTypeNum(NPY_VOID);
PyArray_DTypeMeta *dtypes[2] = {Void, Void};
PyType_Slot slots[] = {
- {NPY_METH_get_loop, NULL},
+ {NPY_METH_get_loop, &void_to_void_get_loop},
{NPY_METH_resolve_descriptors, &void_to_void_resolve_descriptors},
- {0, NULL}};
+ {0, NULL}};
PyArrayMethod_Spec spec = {
.name = "void_to_void_cast",
- .casting = NPY_NO_CASTING,
+ .casting = -1, /* may not cast at all */
.nin = 1,
.nout = 1,
.flags = NPY_METH_REQUIRES_PYAPI | NPY_METH_SUPPORTS_UNALIGNED,
@@ -2744,7 +3430,7 @@ object_to_any_resolve_descriptors(
* here is that e.g. "M8" input is considered to be the DType class,
* and by allowing it here, we go back to the "M8" instance.
*/
- if (dtypes[1]->parametric) {
+ if (NPY_DT_is_parametric(dtypes[1])) {
PyErr_Format(PyExc_TypeError,
"casting from object to the parametric DType %S requires "
"the specified output dtype instance. "
@@ -2752,7 +3438,7 @@ object_to_any_resolve_descriptors(
"should be discovered automatically, however.", dtypes[1]);
return -1;
}
- loop_descrs[1] = dtypes[1]->default_descr(dtypes[1]);
+ loop_descrs[1] = NPY_DT_CALL_default_descr(dtypes[1]);
if (loop_descrs[1] == NULL) {
return -1;
}
@@ -2792,7 +3478,7 @@ PyArray_GetObjectToGenericCastingImpl(void)
method->flags = NPY_METH_SUPPORTS_UNALIGNED | NPY_METH_REQUIRES_PYAPI;
method->casting = NPY_UNSAFE_CASTING;
method->resolve_descriptors = &object_to_any_resolve_descriptors;
- method->get_strided_loop = NULL;
+ method->get_strided_loop = &object_to_any_get_loop;
return (PyObject *)method;
}
@@ -2808,7 +3494,7 @@ any_to_object_resolve_descriptors(
PyArray_Descr *loop_descrs[2])
{
if (given_descrs[1] == NULL) {
- loop_descrs[1] = dtypes[1]->default_descr(dtypes[1]);
+ loop_descrs[1] = NPY_DT_CALL_default_descr(dtypes[1]);
if (loop_descrs[1] == NULL) {
return -1;
}
@@ -2848,12 +3534,38 @@ PyArray_GetGenericToObjectCastingImpl(void)
method->flags = NPY_METH_SUPPORTS_UNALIGNED | NPY_METH_REQUIRES_PYAPI;
method->casting = NPY_SAFE_CASTING;
method->resolve_descriptors = &any_to_object_resolve_descriptors;
- method->get_strided_loop = NULL;
+ method->get_strided_loop = &any_to_object_get_loop;
return (PyObject *)method;
}
+/*
+ * Casts within the object dtype is always just a plain copy/view.
+ * For that reason, this function might remain unimplemented.
+ */
+static int
+object_to_object_get_loop(
+ PyArrayMethod_Context *NPY_UNUSED(context),
+ int NPY_UNUSED(aligned), int move_references,
+ npy_intp *NPY_UNUSED(strides),
+ PyArrayMethod_StridedLoop **out_loop,
+ NpyAuxData **out_transferdata,
+ NPY_ARRAYMETHOD_FLAGS *flags)
+{
+ *flags = NPY_METH_REQUIRES_PYAPI | NPY_METH_NO_FLOATINGPOINT_ERRORS;
+ if (move_references) {
+ *out_loop = &_strided_to_strided_move_references;
+ *out_transferdata = NULL;
+ }
+ else {
+ *out_loop = &_strided_to_strided_copy_references;
+ *out_transferdata = NULL;
+ }
+ return 0;
+}
+
+
static int
PyArray_InitializeObjectToObjectCast(void)
{
@@ -2864,8 +3576,8 @@ PyArray_InitializeObjectToObjectCast(void)
PyArray_DTypeMeta *Object = PyArray_DTypeFromTypeNum(NPY_OBJECT);
PyArray_DTypeMeta *dtypes[2] = {Object, Object};
PyType_Slot slots[] = {
- {NPY_METH_get_loop, NULL},
- {0, NULL}};
+ {NPY_METH_get_loop, &object_to_object_get_loop},
+ {0, NULL}};
PyArrayMethod_Spec spec = {
.name = "object_to_object_cast",
.casting = NPY_NO_CASTING | _NPY_CAST_IS_VIEW,
diff --git a/numpy/core/src/multiarray/convert_datatype.h b/numpy/core/src/multiarray/convert_datatype.h
index cc1930f77..22b3859d2 100644
--- a/numpy/core/src/multiarray/convert_datatype.h
+++ b/numpy/core/src/multiarray/convert_datatype.h
@@ -6,6 +6,9 @@
extern NPY_NO_EXPORT npy_intp REQUIRED_STR_LEN[];
NPY_NO_EXPORT PyObject *
+PyArray_GetCastingImpl(PyArray_DTypeMeta *from, PyArray_DTypeMeta *to);
+
+NPY_NO_EXPORT PyObject *
_get_castingimpl(PyObject *NPY_UNUSED(module), PyObject *args);
NPY_NO_EXPORT PyArray_VectorUnaryFunc *
@@ -17,8 +20,10 @@ PyArray_ObjectType(PyObject *op, int minimum_type);
NPY_NO_EXPORT PyArrayObject **
PyArray_ConvertToCommonType(PyObject *op, int *retn);
-NPY_NO_EXPORT PyArray_DTypeMeta *
-PyArray_CommonDType(PyArray_DTypeMeta *dtype1, PyArray_DTypeMeta *dtype2);
+NPY_NO_EXPORT PyArray_Descr *
+PyArray_LegacyResultType(
+ npy_intp narrs, PyArrayObject **arr,
+ npy_intp ndtypes, PyArray_Descr **dtypes);
NPY_NO_EXPORT int
PyArray_ValidType(int type);
@@ -26,7 +31,7 @@ PyArray_ValidType(int type);
NPY_NO_EXPORT int
dtype_kind_to_ordering(char kind);
-/* Like PyArray_CanCastArrayTo */
+/* Used by PyArray_CanCastArrayTo and in the legacy ufunc type resolution */
NPY_NO_EXPORT npy_bool
can_cast_scalar_to(PyArray_Descr *scal_type, char *scal_data,
PyArray_Descr *to, NPY_CASTING casting);
@@ -49,8 +54,12 @@ npy_set_invalid_cast_error(
NPY_NO_EXPORT PyArray_Descr *
PyArray_CastDescrToDType(PyArray_Descr *descr, PyArray_DTypeMeta *given_DType);
+NPY_NO_EXPORT PyArray_Descr *
+PyArray_FindConcatenationDescriptor(
+ npy_intp n, PyArrayObject **arrays, PyObject *requested_dtype);
+
NPY_NO_EXPORT int
-PyArray_AddCastingImplmentation(PyBoundArrayMethodObject *meth);
+PyArray_AddCastingImplementation(PyBoundArrayMethodObject *meth);
NPY_NO_EXPORT int
PyArray_AddCastingImplementation_FromSpec(PyArrayMethod_Spec *spec, int private);
@@ -62,6 +71,10 @@ NPY_NO_EXPORT NPY_CASTING
PyArray_GetCastSafety(
PyArray_Descr *from, PyArray_Descr *to, PyArray_DTypeMeta *to_dtype);
+NPY_NO_EXPORT int
+PyArray_CheckCastSafety(NPY_CASTING casting,
+ PyArray_Descr *from, PyArray_Descr *to, PyArray_DTypeMeta *to_dtype);
+
NPY_NO_EXPORT NPY_CASTING
legacy_same_dtype_resolve_descriptors(
PyArrayMethodObject *self,
@@ -69,6 +82,13 @@ legacy_same_dtype_resolve_descriptors(
PyArray_Descr **given_descrs,
PyArray_Descr **loop_descrs);
+NPY_NO_EXPORT int
+legacy_cast_get_strided_loop(
+ PyArrayMethod_Context *context,
+ int aligned, int move_references, npy_intp *strides,
+ PyArrayMethod_StridedLoop **out_loop, NpyAuxData **out_transferdata,
+ NPY_ARRAYMETHOD_FLAGS *flags);
+
NPY_NO_EXPORT NPY_CASTING
simple_cast_resolve_descriptors(
PyArrayMethodObject *self,
diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c
index f6031e370..aaa645c16 100644
--- a/numpy/core/src/multiarray/ctors.c
+++ b/numpy/core/src/multiarray/ctors.c
@@ -552,7 +552,7 @@ PyArray_AssignFromCache_Recursive(
else {
PyArrayObject *view;
view = (PyArrayObject *)array_item_asarray(self, i);
- if (view < 0) {
+ if (view == NULL) {
goto fail;
}
if (PyArray_AssignFromCache_Recursive(view, ndim, cache) < 0) {
@@ -665,9 +665,15 @@ PyArray_NewFromDescr_int(
int allow_emptystring)
{
PyArrayObject_fields *fa;
- int i;
npy_intp nbytes;
+ if (nd > NPY_MAXDIMS || nd < 0) {
+ PyErr_Format(PyExc_ValueError,
+ "number of dimensions must be within [0, %d]", NPY_MAXDIMS);
+ Py_DECREF(descr);
+ return NULL;
+ }
+
if (descr->subarray) {
PyObject *ret;
npy_intp newdims[2*NPY_MAXDIMS];
@@ -687,14 +693,6 @@ PyArray_NewFromDescr_int(
return ret;
}
- if ((unsigned int)nd > (unsigned int)NPY_MAXDIMS) {
- PyErr_Format(PyExc_ValueError,
- "number of dimensions must be within [0, %d]",
- NPY_MAXDIMS);
- Py_DECREF(descr);
- return NULL;
- }
-
/* Check datatype element size */
nbytes = descr->elsize;
if (PyDataType_ISUNSIZED(descr)) {
@@ -718,39 +716,6 @@ PyArray_NewFromDescr_int(
}
}
- /* Check dimensions and multiply them to nbytes */
- for (i = 0; i < nd; i++) {
- npy_intp dim = dims[i];
-
- if (dim == 0) {
- /*
- * Compare to PyArray_OverflowMultiplyList that
- * returns 0 in this case.
- */
- continue;
- }
-
- if (dim < 0) {
- PyErr_SetString(PyExc_ValueError,
- "negative dimensions are not allowed");
- Py_DECREF(descr);
- return NULL;
- }
-
- /*
- * Care needs to be taken to avoid integer overflow when
- * multiplying the dimensions together to get the total size of the
- * array.
- */
- if (npy_mul_with_overflow_intp(&nbytes, nbytes, dim)) {
- PyErr_SetString(PyExc_ValueError,
- "array is too big; `arr.size * arr.dtype.itemsize` "
- "is larger than the maximum possible size.");
- Py_DECREF(descr);
- return NULL;
- }
- }
-
fa = (PyArrayObject_fields *) subtype->tp_alloc(subtype, 0);
if (fa == NULL) {
Py_DECREF(descr);
@@ -786,26 +751,57 @@ PyArray_NewFromDescr_int(
goto fail;
}
fa->strides = fa->dimensions + nd;
- if (nd) {
- memcpy(fa->dimensions, dims, sizeof(npy_intp)*nd);
+
+ /* Copy dimensions, check them, and find total array size `nbytes` */
+ for (int i = 0; i < nd; i++) {
+ fa->dimensions[i] = dims[i];
+
+ if (fa->dimensions[i] == 0) {
+ /*
+ * Compare to PyArray_OverflowMultiplyList that
+ * returns 0 in this case.
+ */
+ continue;
+ }
+
+ if (fa->dimensions[i] < 0) {
+ PyErr_SetString(PyExc_ValueError,
+ "negative dimensions are not allowed");
+ goto fail;
+ }
+
+ /*
+ * Care needs to be taken to avoid integer overflow when multiplying
+ * the dimensions together to get the total size of the array.
+ */
+ if (npy_mul_with_overflow_intp(&nbytes, nbytes, fa->dimensions[i])) {
+ PyErr_SetString(PyExc_ValueError,
+ "array is too big; `arr.size * arr.dtype.itemsize` "
+ "is larger than the maximum possible size.");
+ goto fail;
+ }
}
- if (strides == NULL) { /* fill it in */
+
+ /* Fill the strides (or copy them if they were passed in) */
+ if (strides == NULL) {
+ /* fill the strides and set the contiguity flags */
_array_fill_strides(fa->strides, dims, nd, descr->elsize,
flags, &(fa->flags));
}
else {
- /*
- * we allow strides even when we create
- * the memory, but be careful with this...
- */
- if (nd) {
- memcpy(fa->strides, strides, sizeof(npy_intp)*nd);
+ /* User to provided strides (user is responsible for correctness) */
+ for (int i = 0; i < nd; i++) {
+ fa->strides[i] = strides[i];
}
+ /* Since the strides were passed in must update contiguity */
+ PyArray_UpdateFlags((PyArrayObject *)fa,
+ NPY_ARRAY_C_CONTIGUOUS|NPY_ARRAY_F_CONTIGUOUS);
}
}
else {
- fa->dimensions = fa->strides = NULL;
- fa->flags |= NPY_ARRAY_F_CONTIGUOUS;
+ fa->dimensions = NULL;
+ fa->strides = NULL;
+ fa->flags |= NPY_ARRAY_C_CONTIGUOUS|NPY_ARRAY_F_CONTIGUOUS;
}
if (data == NULL) {
@@ -844,12 +840,11 @@ PyArray_NewFromDescr_int(
fa->data = data;
/*
- * always update the flags to get the right CONTIGUOUS, ALIGN properties
- * not owned data and input strides may not be aligned and on some
- * platforms (debian sparc) malloc does not provide enough alignment for
- * long double types
+ * Always update the aligned flag. Not owned data or input strides may
+ * not be aligned. Also on some platforms (debian sparc) malloc does not
+ * provide enough alignment for long double types.
*/
- PyArray_UpdateFlags((PyArrayObject *)fa, NPY_ARRAY_UPDATE_ALL);
+ PyArray_UpdateFlags((PyArrayObject *)fa, NPY_ARRAY_ALIGNED);
/* Set the base object. It's important to do it here so that
* __array_finalize__ below receives it
@@ -862,15 +857,20 @@ PyArray_NewFromDescr_int(
}
/*
- * call the __array_finalize__
- * method if a subtype.
- * If obj is NULL, then call method with Py_None
+ * call the __array_finalize__ method if a subtype was requested.
+ * If obj is NULL use Py_None for the Python callback.
*/
- if ((subtype != &PyArray_Type)) {
- PyObject *res, *func, *args;
+ if (subtype != &PyArray_Type) {
+ PyObject *res, *func;
func = PyObject_GetAttr((PyObject *)fa, npy_ma_str_array_finalize);
- if (func && func != Py_None) {
+ if (func == NULL) {
+ goto fail;
+ }
+ else if (func == Py_None) {
+ Py_DECREF(func);
+ }
+ else {
if (PyCapsule_CheckExact(func)) {
/* A C-function is stored here */
PyArray_FinalizeFunc *cfunc;
@@ -884,14 +884,10 @@ PyArray_NewFromDescr_int(
}
}
else {
- args = PyTuple_New(1);
if (obj == NULL) {
- obj=Py_None;
+ obj = Py_None;
}
- Py_INCREF(obj);
- PyTuple_SET_ITEM(args, 0, obj);
- res = PyObject_Call(func, args, NULL);
- Py_DECREF(args);
+ res = PyObject_CallFunctionObjArgs(func, obj, NULL);
Py_DECREF(func);
if (res == NULL) {
goto fail;
@@ -901,7 +897,6 @@ PyArray_NewFromDescr_int(
}
}
}
- else Py_XDECREF(func);
}
return (PyObject *)fa;
@@ -1150,7 +1145,7 @@ _array_from_buffer_3118(PyObject *memoryview)
* bpo-32780
* bpo-32782
*
- * Note that even if the above are fixed in master, we have to drop the
+ * Note that even if the above are fixed in main, we have to drop the
* early patch versions of python to actually make use of the fixes.
*/
if (!npy_ctypes_check(Py_TYPE(view->obj))) {
@@ -2105,6 +2100,39 @@ _is_default_descr(PyObject *descr, PyObject *typestr) {
return PyObject_RichCompareBool(typestr, typestr2, Py_EQ);
}
+
+/*
+ * A helper function to transition away from ignoring errors during
+ * special attribute lookups during array coercion.
+ */
+static NPY_INLINE int
+deprecated_lookup_error_clearing(PyTypeObject *type, char *attribute)
+{
+ PyObject *exc_type, *exc_value, *traceback;
+ PyErr_Fetch(&exc_type, &exc_value, &traceback);
+
+ /* DEPRECATED 2021-05-12, NumPy 1.21. */
+ int res = PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
+ "An exception was ignored while fetching the attribute `%s` from "
+ "an object of type '%s'. With the exception of `AttributeError` "
+ "NumPy will always raise this exception in the future. Raise this "
+ "deprecation warning to see the original exception. "
+ "(Warning added NumPy 1.21)", attribute, type->tp_name);
+
+ if (res < 0) {
+ npy_PyErr_ChainExceptionsCause(exc_type, exc_value, traceback);
+ return -1;
+ }
+ else {
+ /* `PyErr_Fetch` cleared the original error, delete the references */
+ Py_DECREF(exc_type);
+ Py_XDECREF(exc_value);
+ Py_XDECREF(traceback);
+ return 0;
+ }
+}
+
+
/*NUMPY_API*/
NPY_NO_EXPORT PyObject *
PyArray_FromInterface(PyObject *origin)
@@ -2124,7 +2152,15 @@ PyArray_FromInterface(PyObject *origin)
if (iface == NULL) {
if (PyErr_Occurred()) {
- PyErr_Clear(); /* TODO[gh-14801]: propagate crashes during attribute access? */
+ if (PyErr_ExceptionMatches(PyExc_RecursionError) ||
+ PyErr_ExceptionMatches(PyExc_MemoryError)) {
+ /* RecursionError and MemoryError are considered fatal */
+ return NULL;
+ }
+ if (deprecated_lookup_error_clearing(
+ Py_TYPE(origin), "__array_interface__") < 0) {
+ return NULL;
+ }
}
return Py_NotImplemented;
}
@@ -2392,7 +2428,15 @@ PyArray_FromArrayAttr(PyObject *op, PyArray_Descr *typecode, PyObject *context)
array_meth = PyArray_LookupSpecial_OnInstance(op, "__array__");
if (array_meth == NULL) {
if (PyErr_Occurred()) {
- PyErr_Clear(); /* TODO[gh-14801]: propagate crashes during attribute access? */
+ if (PyErr_ExceptionMatches(PyExc_RecursionError) ||
+ PyErr_ExceptionMatches(PyExc_MemoryError)) {
+ /* RecursionError and MemoryError are considered fatal */
+ return NULL;
+ }
+ if (deprecated_lookup_error_clearing(
+ Py_TYPE(op), "__array__") < 0) {
+ return NULL;
+ }
}
return Py_NotImplemented;
}
@@ -2530,8 +2574,6 @@ PyArray_EnsureAnyArray(PyObject *op)
NPY_NO_EXPORT int
PyArray_CopyAsFlat(PyArrayObject *dst, PyArrayObject *src, NPY_ORDER order)
{
- PyArray_StridedUnaryOp *stransfer = NULL;
- NpyAuxData *transferdata = NULL;
NpyIter *dst_iter, *src_iter;
NpyIter_IterNextFunc *dst_iternext, *src_iternext;
@@ -2540,9 +2582,7 @@ PyArray_CopyAsFlat(PyArrayObject *dst, PyArrayObject *src, NPY_ORDER order)
npy_intp *dst_countptr, *src_countptr;
npy_uint32 baseflags;
- char *dst_data, *src_data;
npy_intp dst_count, src_count, count;
- npy_intp src_itemsize;
npy_intp dst_size, src_size;
int needs_api;
@@ -2614,7 +2654,6 @@ PyArray_CopyAsFlat(PyArrayObject *dst, PyArrayObject *src, NPY_ORDER order)
/* Since buffering is disabled, we can cache the stride */
src_stride = NpyIter_GetInnerStrideArray(src_iter)[0];
src_countptr = NpyIter_GetInnerLoopSizePtr(src_iter);
- src_itemsize = PyArray_DESCR(src)->elsize;
if (dst_iternext == NULL || src_iternext == NULL) {
NpyIter_Deallocate(dst_iter);
@@ -2631,14 +2670,14 @@ PyArray_CopyAsFlat(PyArrayObject *dst, PyArrayObject *src, NPY_ORDER order)
* we can pass them to this function to take advantage of
* contiguous strides, etc.
*/
+ NPY_cast_info cast_info;
if (PyArray_GetDTypeTransferFunction(
IsUintAligned(src) && IsAligned(src) &&
IsUintAligned(dst) && IsAligned(dst),
src_stride, dst_stride,
PyArray_DESCR(src), PyArray_DESCR(dst),
0,
- &stransfer, &transferdata,
- &needs_api) != NPY_SUCCEED) {
+ &cast_info, &needs_api) != NPY_SUCCEED) {
NpyIter_Deallocate(dst_iter);
NpyIter_Deallocate(src_iter);
return -1;
@@ -2650,15 +2689,15 @@ PyArray_CopyAsFlat(PyArrayObject *dst, PyArrayObject *src, NPY_ORDER order)
dst_count = *dst_countptr;
src_count = *src_countptr;
- dst_data = dst_dataptr[0];
- src_data = src_dataptr[0];
+ char *args[2] = {src_dataptr[0], dst_dataptr[0]};
+ npy_intp strides[2] = {src_stride, dst_stride};
+
int res = 0;
for(;;) {
/* Transfer the biggest amount that fits both */
count = (src_count < dst_count) ? src_count : dst_count;
- if (stransfer(
- dst_data, dst_stride, src_data, src_stride,
- count, src_itemsize, transferdata) < 0) {
+ if (cast_info.func(&cast_info.context,
+ args, &count, strides, cast_info.auxdata) < 0) {
res = -1;
break;
}
@@ -2670,11 +2709,11 @@ PyArray_CopyAsFlat(PyArrayObject *dst, PyArrayObject *src, NPY_ORDER order)
break;
}
dst_count = *dst_countptr;
- dst_data = dst_dataptr[0];
+ args[1] = dst_dataptr[0];
}
else {
dst_count -= count;
- dst_data += count*dst_stride;
+ args[1] += count*dst_stride;
}
/* If we exhausted the src block, refresh it */
@@ -2684,17 +2723,17 @@ PyArray_CopyAsFlat(PyArrayObject *dst, PyArrayObject *src, NPY_ORDER order)
break;
}
src_count = *src_countptr;
- src_data = src_dataptr[0];
+ args[0] = src_dataptr[0];
}
else {
src_count -= count;
- src_data += count*src_stride;
+ args[0] += count*src_stride;
}
}
NPY_END_THREADS;
- NPY_AUXDATA_FREE(transferdata);
+ NPY_cast_info_xfree(&cast_info);
NpyIter_Deallocate(dst_iter);
NpyIter_Deallocate(src_iter);
if (res > 0) {
@@ -2892,7 +2931,7 @@ _arange_safe_ceil_to_intp(double value)
"arange: cannot compute length");
return -1;
}
- if (!(NPY_MIN_INTP <= ivalue && ivalue <= NPY_MAX_INTP)) {
+ if (!((double)NPY_MIN_INTP <= ivalue && ivalue <= (double)NPY_MAX_INTP)) {
PyErr_SetString(PyExc_OverflowError,
"arange: overflow while computing length");
return -1;
@@ -3944,8 +3983,8 @@ _array_fill_strides(npy_intp *strides, npy_intp const *dims, int nd, size_t item
NPY_NO_EXPORT PyArrayObject *
PyArray_SubclassWrap(PyArrayObject *arr_of_subclass, PyArrayObject *towrap)
{
- PyObject *wrapped = PyObject_CallMethod((PyObject *)arr_of_subclass,
- "__array_wrap__", "O", towrap);
+ PyObject *wrapped = PyObject_CallMethodObjArgs((PyObject *)arr_of_subclass,
+ npy_ma_str_array_wrap, (PyObject *)towrap, NULL);
if (wrapped == NULL) {
return NULL;
}
diff --git a/numpy/core/src/multiarray/datetime.c b/numpy/core/src/multiarray/datetime.c
index 9c1b606bb..182eb12f9 100644
--- a/numpy/core/src/multiarray/datetime.c
+++ b/numpy/core/src/multiarray/datetime.c
@@ -29,6 +29,9 @@
#include "dtypemeta.h"
#include "usertypes.h"
+#include "dtype_transfer.h"
+#include <lowlevel_strided_loops.h>
+
/*
* Computes the python `ret, d = divmod(d, unit)`.
*
@@ -947,10 +950,6 @@ convert_datetime_divisor_to_multiple(PyArray_DatetimeMetaData *meta,
return -1;
}
- ind = ((int)meta->base - (int)NPY_FR_Y)*2;
- totry = _multiples_table[ind];
- baseunit = _multiples_table[ind + 1];
-
num = 3;
if (meta->base == NPY_FR_W) {
num = 4;
@@ -959,6 +958,7 @@ convert_datetime_divisor_to_multiple(PyArray_DatetimeMetaData *meta,
num = 2;
}
if (meta->base >= NPY_FR_s) {
+ /* _multiplies_table only has entries up to NPY_FR_s */
ind = ((int)NPY_FR_s - (int)NPY_FR_Y)*2;
totry = _multiples_table[ind];
baseunit = _multiples_table[ind + 1];
@@ -971,6 +971,11 @@ convert_datetime_divisor_to_multiple(PyArray_DatetimeMetaData *meta,
num = 0;
}
}
+ else {
+ ind = ((int)meta->base - (int)NPY_FR_Y)*2;
+ totry = _multiples_table[ind];
+ baseunit = _multiples_table[ind + 1];
+ }
for (i = 0; i < num; i++) {
q = totry[i] / den;
@@ -3803,6 +3808,72 @@ time_to_time_resolve_descriptors(
}
+static int
+time_to_time_get_loop(
+ PyArrayMethod_Context *context,
+ int aligned, int NPY_UNUSED(move_references), npy_intp *strides,
+ PyArrayMethod_StridedLoop **out_loop, NpyAuxData **out_transferdata,
+ NPY_ARRAYMETHOD_FLAGS *flags)
+{
+ int requires_wrap = 0;
+ int inner_aligned = aligned;
+ PyArray_Descr **descrs = context->descriptors;
+ *flags = NPY_METH_NO_FLOATINGPOINT_ERRORS;
+
+ PyArray_DatetimeMetaData *meta1 = get_datetime_metadata_from_dtype(descrs[0]);
+ PyArray_DatetimeMetaData *meta2 = get_datetime_metadata_from_dtype(descrs[1]);
+
+ if (meta1->base == meta2->base && meta1->num == meta2->num) {
+ /*
+ * If the metadata matches, use the low-level copy or copy-swap
+ * functions. (If they do not match, but swapping is necessary this
+ * path is hit recursively.)
+ */
+ if (PyDataType_ISNOTSWAPPED(descrs[0]) ==
+ PyDataType_ISNOTSWAPPED(descrs[1])) {
+ *out_loop = PyArray_GetStridedCopyFn(
+ aligned, strides[0], strides[1], NPY_SIZEOF_DATETIME);
+ }
+ else {
+ *out_loop = PyArray_GetStridedCopySwapFn(
+ aligned, strides[0], strides[1], NPY_SIZEOF_DATETIME);
+ }
+ return 0;
+ }
+
+ if (!PyDataType_ISNOTSWAPPED(descrs[0]) ||
+ !PyDataType_ISNOTSWAPPED(descrs[1])) {
+ inner_aligned = 1;
+ requires_wrap = 1;
+ }
+ if (get_nbo_cast_datetime_transfer_function(
+ inner_aligned, descrs[0], descrs[1],
+ out_loop, out_transferdata) == NPY_FAIL) {
+ return -1;
+ }
+
+ if (!requires_wrap) {
+ return 0;
+ }
+
+ PyArray_Descr *src_wrapped_dtype = ensure_dtype_nbo(descrs[0]);
+ PyArray_Descr *dst_wrapped_dtype = ensure_dtype_nbo(descrs[1]);
+
+ int needs_api = 0;
+ int res = wrap_aligned_transferfunction(
+ aligned, 0,
+ strides[0], strides[1],
+ descrs[0], descrs[1],
+ src_wrapped_dtype, dst_wrapped_dtype,
+ out_loop, out_transferdata, &needs_api);
+ Py_DECREF(src_wrapped_dtype);
+ Py_DECREF(dst_wrapped_dtype);
+
+ assert(needs_api == 0);
+ return res;
+}
+
+
/* Handles datetime<->timedelta type resolution (both directions) */
static NPY_CASTING
datetime_to_timedelta_resolve_descriptors(
@@ -3844,9 +3915,7 @@ time_to_string_resolve_descriptors(
PyArray_Descr **given_descrs,
PyArray_Descr **loop_descrs)
{
- Py_INCREF(given_descrs[0]);
- loop_descrs[0] = given_descrs[0];
- if (given_descrs[1] != NULL) {
+ if (given_descrs[1] != NULL && dtypes[0]->type_num == NPY_DATETIME) {
/*
* At the time of writing, NumPy does not check the length here,
* but will error if filling fails.
@@ -3863,6 +3932,10 @@ time_to_string_resolve_descriptors(
size = get_datetime_iso_8601_strlen(0, meta->base);
}
else {
+ /*
+ * This is arguably missing space for the unit, e.g. for:
+ * `np.timedelta64(1231234342124, 'ms')`
+ */
size = 21;
}
if (dtypes[1]->type_num == NPY_UNICODE) {
@@ -3870,15 +3943,49 @@ time_to_string_resolve_descriptors(
}
loop_descrs[1] = PyArray_DescrNewFromType(dtypes[1]->type_num);
if (loop_descrs[1] == NULL) {
- Py_DECREF(loop_descrs[0]);
return -1;
}
loop_descrs[1]->elsize = size;
}
- assert(self->casting == NPY_UNSAFE_CASTING);
+
+ loop_descrs[0] = ensure_dtype_nbo(given_descrs[0]);
+ if (loop_descrs[0] == NULL) {
+ Py_DECREF(loop_descrs[1]);
+ return -1;
+ }
+
return NPY_UNSAFE_CASTING;
}
+static int
+datetime_to_string_get_loop(
+ PyArrayMethod_Context *context,
+ int aligned, int NPY_UNUSED(move_references), npy_intp *strides,
+ PyArrayMethod_StridedLoop **out_loop, NpyAuxData **out_transferdata,
+ NPY_ARRAYMETHOD_FLAGS *flags)
+{
+ PyArray_Descr **descrs = context->descriptors;
+ *flags = context->method->flags & NPY_METH_RUNTIME_FLAGS;
+
+ if (descrs[1]->type_num == NPY_STRING) {
+ if (get_nbo_datetime_to_string_transfer_function(
+ descrs[0], descrs[1],
+ out_loop, out_transferdata) == NPY_FAIL) {
+ return -1;
+ }
+ }
+ else {
+ assert(descrs[1]->type_num == NPY_UNICODE);
+ int out_needs_api;
+ if (get_datetime_to_unicode_transfer_function(
+ aligned, strides[0], strides[1], descrs[0], descrs[1],
+ out_loop, out_transferdata, &out_needs_api) == NPY_FAIL) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
static NPY_CASTING
string_to_datetime_cast_resolve_descriptors(
@@ -3887,27 +3994,58 @@ string_to_datetime_cast_resolve_descriptors(
PyArray_Descr *given_descrs[2],
PyArray_Descr *loop_descrs[2])
{
- /* We currently support byte-swapping, so any (unicode) string is OK */
- Py_INCREF(given_descrs[0]);
- loop_descrs[0] = given_descrs[0];
-
if (given_descrs[1] == NULL) {
/* NOTE: This doesn't actually work, and will error during the cast */
- loop_descrs[1] = dtypes[1]->default_descr(dtypes[1]);
+ loop_descrs[1] = NPY_DT_CALL_default_descr(dtypes[1]);
if (loop_descrs[1] == NULL) {
- Py_DECREF(loop_descrs[0]);
return -1;
}
}
else {
- Py_INCREF(given_descrs[1]);
- loop_descrs[1] = given_descrs[1];
+ loop_descrs[1] = ensure_dtype_nbo(given_descrs[1]);
+ if (loop_descrs[1] == NULL) {
+ return -1;
+ }
}
+ /* We currently support byte-swapping, so any (unicode) string is OK */
+ Py_INCREF(given_descrs[0]);
+ loop_descrs[0] = given_descrs[0];
+
return NPY_UNSAFE_CASTING;
}
+static int
+string_to_datetime_cast_get_loop(
+ PyArrayMethod_Context *context,
+ int aligned, int NPY_UNUSED(move_references), npy_intp *strides,
+ PyArrayMethod_StridedLoop **out_loop, NpyAuxData **out_transferdata,
+ NPY_ARRAYMETHOD_FLAGS *flags)
+{
+ PyArray_Descr **descrs = context->descriptors;
+ *flags = context->method->flags & NPY_METH_RUNTIME_FLAGS;
+
+ if (descrs[0]->type_num == NPY_STRING) {
+ if (get_nbo_string_to_datetime_transfer_function(
+ descrs[0], descrs[1], out_loop, out_transferdata) == NPY_FAIL) {
+ return -1;
+ }
+ }
+ else {
+ assert(descrs[0]->type_num == NPY_UNICODE);
+ int out_needs_api;
+ if (get_unicode_to_datetime_transfer_function(
+ aligned, strides[0], strides[1], descrs[0], descrs[1],
+ out_loop, out_transferdata, &out_needs_api) == NPY_FAIL) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+
+
/*
* This registers the castingimpl for all datetime related casts.
*/
@@ -3922,7 +4060,7 @@ PyArray_InitializeDatetimeCasts()
.name = "datetime_casts",
.nin = 1,
.nout = 1,
- .casting = NPY_NO_CASTING,
+ .casting = NPY_UNSAFE_CASTING,
.flags = NPY_METH_SUPPORTS_UNALIGNED,
.slots = slots,
.dtypes = dtypes,
@@ -3930,7 +4068,7 @@ PyArray_InitializeDatetimeCasts()
slots[0].slot = NPY_METH_resolve_descriptors;
slots[0].pfunc = &time_to_time_resolve_descriptors;
slots[1].slot = NPY_METH_get_loop;
- slots[1].pfunc = NULL;
+ slots[1].pfunc = &time_to_time_get_loop;
slots[2].slot = 0;
slots[2].pfunc = NULL;
@@ -3955,10 +4093,12 @@ PyArray_InitializeDatetimeCasts()
* Casting between timedelta and datetime uses legacy casting loops, but
* custom dtype resolution (to handle copying of the time unit).
*/
+ spec.flags = NPY_METH_REQUIRES_PYAPI;
+
slots[0].slot = NPY_METH_resolve_descriptors;
slots[0].pfunc = &datetime_to_timedelta_resolve_descriptors;
slots[1].slot = NPY_METH_get_loop;
- slots[1].pfunc = NULL;
+ slots[1].pfunc = &legacy_cast_get_strided_loop;
slots[2].slot = 0;
slots[2].pfunc = NULL;
@@ -4024,26 +4164,36 @@ PyArray_InitializeDatetimeCasts()
/*
* Casts can error and need API (unicodes needs it for string->unicode).
* Unicode handling is currently implemented via a legacy cast.
+ * Datetime->string has its own fast cast while timedelta->string uses
+ * the legacy fallback.
*/
- spec.flags = NPY_METH_SUPPORTS_UNALIGNED | NPY_METH_REQUIRES_PYAPI;
-
slots[0].slot = NPY_METH_resolve_descriptors;
slots[0].pfunc = &time_to_string_resolve_descriptors;
+ /* Strided loop differs for the two */
slots[1].slot = NPY_METH_get_loop;
- slots[1].pfunc = NULL;
slots[2].slot = 0;
slots[2].pfunc = NULL;
+ dtypes[0] = datetime;
for (int num = NPY_DATETIME; num <= NPY_TIMEDELTA; num++) {
+ if (num == NPY_DATETIME) {
+ dtypes[0] = datetime;
+ spec.flags = NPY_METH_SUPPORTS_UNALIGNED | NPY_METH_REQUIRES_PYAPI;
+ slots[1].pfunc = &datetime_to_string_get_loop;
+ }
+ else {
+ dtypes[0] = timedelta;
+ spec.flags = NPY_METH_REQUIRES_PYAPI;
+ slots[1].pfunc = &legacy_cast_get_strided_loop;
+ }
+
for (int str = NPY_STRING; str <= NPY_UNICODE; str++) {
- dtypes[0] = PyArray_DTypeFromTypeNum(num);
dtypes[1] = PyArray_DTypeFromTypeNum(str);
int res = PyArray_AddCastingImplementation_FromSpec(&spec, 1);
- Py_SETREF(dtypes[0], NULL);
Py_SETREF(dtypes[1], NULL);
if (res < 0) {
- return -1;
+ goto fail;
}
}
}
@@ -4070,7 +4220,7 @@ PyArray_InitializeDatetimeCasts()
slots[0].slot = NPY_METH_resolve_descriptors;
slots[0].pfunc = &string_to_datetime_cast_resolve_descriptors;
slots[1].slot = NPY_METH_get_loop;
- slots[1].pfunc = NULL;
+ slots[1].pfunc = &string_to_datetime_cast_get_loop;
slots[2].slot = 0;
slots[2].pfunc = NULL;
diff --git a/numpy/core/src/multiarray/datetime_busday.c b/numpy/core/src/multiarray/datetime_busday.c
index 2cf157551..f0564146d 100644
--- a/numpy/core/src/multiarray/datetime_busday.c
+++ b/numpy/core/src/multiarray/datetime_busday.c
@@ -934,8 +934,8 @@ NPY_NO_EXPORT PyObject *
array_busday_offset(PyObject *NPY_UNUSED(self),
PyObject *args, PyObject *kwds)
{
- char *kwlist[] = {"dates", "offsets", "roll",
- "weekmask", "holidays", "busdaycal", "out", NULL};
+ static char *kwlist[] = {"dates", "offsets", "roll",
+ "weekmask", "holidays", "busdaycal", "out", NULL};
PyObject *dates_in = NULL, *offsets_in = NULL, *out_in = NULL;
@@ -1065,8 +1065,8 @@ NPY_NO_EXPORT PyObject *
array_busday_count(PyObject *NPY_UNUSED(self),
PyObject *args, PyObject *kwds)
{
- char *kwlist[] = {"begindates", "enddates",
- "weekmask", "holidays", "busdaycal", "out", NULL};
+ static char *kwlist[] = {"begindates", "enddates",
+ "weekmask", "holidays", "busdaycal", "out", NULL};
PyObject *dates_begin_in = NULL, *dates_end_in = NULL, *out_in = NULL;
@@ -1210,8 +1210,8 @@ NPY_NO_EXPORT PyObject *
array_is_busday(PyObject *NPY_UNUSED(self),
PyObject *args, PyObject *kwds)
{
- char *kwlist[] = {"dates",
- "weekmask", "holidays", "busdaycal", "out", NULL};
+ static char *kwlist[] = {"dates",
+ "weekmask", "holidays", "busdaycal", "out", NULL};
PyObject *dates_in = NULL, *out_in = NULL;
diff --git a/numpy/core/src/multiarray/datetime_busdaycal.c b/numpy/core/src/multiarray/datetime_busdaycal.c
index d48141d4c..e3e729d3c 100644
--- a/numpy/core/src/multiarray/datetime_busdaycal.c
+++ b/numpy/core/src/multiarray/datetime_busdaycal.c
@@ -434,7 +434,7 @@ busdaycalendar_dealloc(NpyBusDayCalendar *self)
}
static PyObject *
-busdaycalendar_weekmask_get(NpyBusDayCalendar *self)
+busdaycalendar_weekmask_get(NpyBusDayCalendar *self, void *NPY_UNUSED(ignored))
{
PyArrayObject *ret;
npy_intp size = 7;
@@ -452,7 +452,7 @@ busdaycalendar_weekmask_get(NpyBusDayCalendar *self)
}
static PyObject *
-busdaycalendar_holidays_get(NpyBusDayCalendar *self)
+busdaycalendar_holidays_get(NpyBusDayCalendar *self, void *NPY_UNUSED(ignored))
{
PyArrayObject *ret;
PyArray_Descr *date_dtype;
diff --git a/numpy/core/src/multiarray/descriptor.c b/numpy/core/src/multiarray/descriptor.c
index a8d575248..50964dab8 100644
--- a/numpy/core/src/multiarray/descriptor.c
+++ b/numpy/core/src/multiarray/descriptor.c
@@ -20,6 +20,7 @@
#include "alloc.h"
#include "assert.h"
#include "npy_buffer.h"
+#include "dtypemeta.h"
/*
* offset: A starting offset.
@@ -108,6 +109,11 @@ _try_convert_from_dtype_attr(PyObject *obj)
goto fail;
}
+ if (PyArray_DescrCheck(dtypedescr)) {
+ /* The dtype attribute is already a valid descriptor */
+ return (PyArray_Descr *)dtypedescr;
+ }
+
if (Py_EnterRecursiveCall(
" while trying to convert the given data type from its "
"`.dtype` attribute.") != 0) {
@@ -122,6 +128,15 @@ _try_convert_from_dtype_attr(PyObject *obj)
goto fail;
}
+ /* Deprecated 2021-01-05, NumPy 1.21 */
+ if (DEPRECATE("in the future the `.dtype` attribute of a given data"
+ "type object must be a valid dtype instance. "
+ "`data_type.dtype` may need to be coerced using "
+ "`np.dtype(data_type.dtype)`. (Deprecated NumPy 1.20)") < 0) {
+ Py_DECREF(newdescr);
+ return NULL;
+ }
+
return newdescr;
fail:
@@ -1881,7 +1896,7 @@ static PyMemberDef arraydescr_members[] = {
};
static PyObject *
-arraydescr_subdescr_get(PyArray_Descr *self)
+arraydescr_subdescr_get(PyArray_Descr *self, void *NPY_UNUSED(ignored))
{
if (!PyDataType_HASSUBARRAY(self)) {
Py_RETURN_NONE;
@@ -1891,7 +1906,7 @@ arraydescr_subdescr_get(PyArray_Descr *self)
}
NPY_NO_EXPORT PyObject *
-arraydescr_protocol_typestr_get(PyArray_Descr *self)
+arraydescr_protocol_typestr_get(PyArray_Descr *self, void *NPY_UNUSED(ignored))
{
char basic_ = self->kind;
char endian = self->byteorder;
@@ -1937,7 +1952,7 @@ arraydescr_protocol_typestr_get(PyArray_Descr *self)
}
static PyObject *
-arraydescr_name_get(PyArray_Descr *self)
+arraydescr_name_get(PyArray_Descr *self, void *NPY_UNUSED(ignored))
{
/* let python handle this */
PyObject *_numpy_dtype;
@@ -1952,7 +1967,7 @@ arraydescr_name_get(PyArray_Descr *self)
}
static PyObject *
-arraydescr_base_get(PyArray_Descr *self)
+arraydescr_base_get(PyArray_Descr *self, void *NPY_UNUSED(ignored))
{
if (!PyDataType_HASSUBARRAY(self)) {
Py_INCREF(self);
@@ -1963,7 +1978,7 @@ arraydescr_base_get(PyArray_Descr *self)
}
static PyObject *
-arraydescr_shape_get(PyArray_Descr *self)
+arraydescr_shape_get(PyArray_Descr *self, void *NPY_UNUSED(ignored))
{
if (!PyDataType_HASSUBARRAY(self)) {
return PyTuple_New(0);
@@ -1974,7 +1989,7 @@ arraydescr_shape_get(PyArray_Descr *self)
}
static PyObject *
-arraydescr_ndim_get(PyArray_Descr *self)
+arraydescr_ndim_get(PyArray_Descr *self, void *NPY_UNUSED(ignored))
{
Py_ssize_t ndim;
@@ -1992,7 +2007,7 @@ arraydescr_ndim_get(PyArray_Descr *self)
NPY_NO_EXPORT PyObject *
-arraydescr_protocol_descr_get(PyArray_Descr *self)
+arraydescr_protocol_descr_get(PyArray_Descr *self, void *NPY_UNUSED(ignored))
{
PyObject *dobj, *res;
PyObject *_numpy_internal;
@@ -2004,7 +2019,7 @@ arraydescr_protocol_descr_get(PyArray_Descr *self)
return NULL;
}
PyTuple_SET_ITEM(dobj, 0, PyUnicode_FromString(""));
- PyTuple_SET_ITEM(dobj, 1, arraydescr_protocol_typestr_get(self));
+ PyTuple_SET_ITEM(dobj, 1, arraydescr_protocol_typestr_get(self, NULL));
res = PyList_New(1);
if (res == NULL) {
Py_DECREF(dobj);
@@ -2029,7 +2044,7 @@ arraydescr_protocol_descr_get(PyArray_Descr *self)
* return 0 if neither (i.e. it's a copy of one)
*/
static PyObject *
-arraydescr_isbuiltin_get(PyArray_Descr *self)
+arraydescr_isbuiltin_get(PyArray_Descr *self, void *NPY_UNUSED(ignored))
{
long val;
val = 0;
@@ -2076,7 +2091,7 @@ _arraydescr_isnative(PyArray_Descr *self)
* fields are defined
*/
static PyObject *
-arraydescr_isnative_get(PyArray_Descr *self)
+arraydescr_isnative_get(PyArray_Descr *self, void *NPY_UNUSED(ignored))
{
PyObject *ret;
int retval;
@@ -2090,7 +2105,7 @@ arraydescr_isnative_get(PyArray_Descr *self)
}
static PyObject *
-arraydescr_isalignedstruct_get(PyArray_Descr *self)
+arraydescr_isalignedstruct_get(PyArray_Descr *self, void *NPY_UNUSED(ignored))
{
PyObject *ret;
ret = (self->flags&NPY_ALIGNED_STRUCT) ? Py_True : Py_False;
@@ -2099,7 +2114,7 @@ arraydescr_isalignedstruct_get(PyArray_Descr *self)
}
static PyObject *
-arraydescr_fields_get(PyArray_Descr *self)
+arraydescr_fields_get(PyArray_Descr *self, void *NPY_UNUSED(ignored))
{
if (!PyDataType_HASFIELDS(self)) {
Py_RETURN_NONE;
@@ -2108,7 +2123,7 @@ arraydescr_fields_get(PyArray_Descr *self)
}
static PyObject *
-arraydescr_metadata_get(PyArray_Descr *self)
+arraydescr_metadata_get(PyArray_Descr *self, void *NPY_UNUSED(ignored))
{
if (self->metadata == NULL) {
Py_RETURN_NONE;
@@ -2117,7 +2132,7 @@ arraydescr_metadata_get(PyArray_Descr *self)
}
static PyObject *
-arraydescr_hasobject_get(PyArray_Descr *self)
+arraydescr_hasobject_get(PyArray_Descr *self, void *NPY_UNUSED(ignored))
{
if (PyDataType_FLAGCHK(self, NPY_ITEM_HASOBJECT)) {
Py_RETURN_TRUE;
@@ -2128,7 +2143,7 @@ arraydescr_hasobject_get(PyArray_Descr *self)
}
static PyObject *
-arraydescr_names_get(PyArray_Descr *self)
+arraydescr_names_get(PyArray_Descr *self, void *NPY_UNUSED(ignored))
{
if (!PyDataType_HASFIELDS(self)) {
Py_RETURN_NONE;
@@ -2138,7 +2153,8 @@ arraydescr_names_get(PyArray_Descr *self)
}
static int
-arraydescr_names_set(PyArray_Descr *self, PyObject *val)
+arraydescr_names_set(
+ PyArray_Descr *self, PyObject *val, void *NPY_UNUSED(ignored))
{
int N = 0;
int i;
@@ -2522,7 +2538,7 @@ arraydescr_reduce(PyArray_Descr *self, PyObject *NPY_UNUSED(args))
}
PyTuple_SET_ITEM(state, 1, PyUnicode_FromFormat("%c", endian));
- PyTuple_SET_ITEM(state, 2, arraydescr_subdescr_get(self));
+ PyTuple_SET_ITEM(state, 2, arraydescr_subdescr_get(self, NULL));
if (PyDataType_HASFIELDS(self)) {
Py_INCREF(self->names);
Py_INCREF(self->fields);
@@ -3214,7 +3230,9 @@ arraydescr_richcompare(PyArray_Descr *self, PyObject *other, int cmp_op)
{
PyArray_Descr *new = _convert_from_any(other, 0);
if (new == NULL) {
- return NULL;
+ /* Cannot convert `other` to dtype */
+ PyErr_Clear();
+ Py_RETURN_NOTIMPLEMENTED;
}
npy_bool ret;
@@ -3527,9 +3545,7 @@ NPY_NO_EXPORT PyArray_DTypeMeta PyArrayDescr_TypeFull = {
.tp_new = arraydescr_new,
},},
.type_num = -1,
- .kind = '\0',
- .abstract = 1,
- .parametric = 0,
- .singleton = 0,
+ .flags = NPY_DT_ABSTRACT,
+ .singleton = NULL,
.scalar_type = NULL,
};
diff --git a/numpy/core/src/multiarray/descriptor.h b/numpy/core/src/multiarray/descriptor.h
index fc9e0895b..e1316acbd 100644
--- a/numpy/core/src/multiarray/descriptor.h
+++ b/numpy/core/src/multiarray/descriptor.h
@@ -1,8 +1,10 @@
#ifndef _NPY_ARRAYDESCR_H_
#define _NPY_ARRAYDESCR_H_
-NPY_NO_EXPORT PyObject *arraydescr_protocol_typestr_get(PyArray_Descr *);
-NPY_NO_EXPORT PyObject *arraydescr_protocol_descr_get(PyArray_Descr *self);
+NPY_NO_EXPORT PyObject *arraydescr_protocol_typestr_get(
+ PyArray_Descr *, void *);
+NPY_NO_EXPORT PyObject *arraydescr_protocol_descr_get(
+ PyArray_Descr *self, void *);
NPY_NO_EXPORT PyObject *
array_set_typeDict(PyObject *NPY_UNUSED(ignored), PyObject *args);
diff --git a/numpy/core/src/multiarray/dragon4.c b/numpy/core/src/multiarray/dragon4.c
index a7b252a77..1d8c27570 100644
--- a/numpy/core/src/multiarray/dragon4.c
+++ b/numpy/core/src/multiarray/dragon4.c
@@ -1130,8 +1130,9 @@ BigInt_ShiftLeft(BigInt *result, npy_uint32 shift)
* * exponent - value exponent in base 2
* * mantissaBit - index of the highest set mantissa bit
* * hasUnequalMargins - is the high margin twice as large as the low margin
- * * cutoffMode - how to interpret cutoffNumber: fractional or total digits?
- * * cutoffNumber - cut off printing after this many digits. -1 for no cutoff
+ * * cutoffMode - how to interpret cutoff_*: fractional or total digits?
+ * * cutoff_max - cut off printing after this many digits. -1 for no cutoff
+ * * cutoff_min - print at least this many digits. -1 for no cutoff
* * pOutBuffer - buffer to output into
* * bufferSize - maximum characters that can be printed to pOutBuffer
* * pOutExponent - the base 10 exponent of the first digit
@@ -1142,7 +1143,7 @@ static npy_uint32
Dragon4(BigInt *bigints, const npy_int32 exponent,
const npy_uint32 mantissaBit, const npy_bool hasUnequalMargins,
const DigitMode digitMode, const CutoffMode cutoffMode,
- npy_int32 cutoffNumber, char *pOutBuffer,
+ npy_int32 cutoff_max, npy_int32 cutoff_min, char *pOutBuffer,
npy_uint32 bufferSize, npy_int32 *pOutExponent)
{
char *curDigit = pOutBuffer;
@@ -1169,7 +1170,8 @@ Dragon4(BigInt *bigints, const npy_int32 exponent,
BigInt *temp2 = &bigints[6];
const npy_float64 log10_2 = 0.30102999566398119521373889472449;
- npy_int32 digitExponent, cutoffExponent, hiBlock;
+ npy_int32 digitExponent, hiBlock;
+ npy_int32 cutoff_max_Exponent, cutoff_min_Exponent;
npy_uint32 outputDigit; /* current digit being output */
npy_uint32 outputLen;
npy_bool isEven = BigInt_IsEven(mantissa);
@@ -1294,9 +1296,9 @@ Dragon4(BigInt *bigints, const npy_int32 exponent,
* increases the number. This will either correct digitExponent to an
* accurate value or it will clamp it above the accurate value.
*/
- if (cutoffNumber >= 0 && cutoffMode == CutoffMode_FractionLength &&
- digitExponent <= -cutoffNumber) {
- digitExponent = -cutoffNumber + 1;
+ if (cutoff_max >= 0 && cutoffMode == CutoffMode_FractionLength &&
+ digitExponent <= -cutoff_max) {
+ digitExponent = -cutoff_max + 1;
}
@@ -1347,26 +1349,44 @@ Dragon4(BigInt *bigints, const npy_int32 exponent,
}
/*
- * Compute the cutoff exponent (the exponent of the final digit to print).
- * Default to the maximum size of the output buffer.
+ * Compute the cutoff_max exponent (the exponent of the final digit to
+ * print). Default to the maximum size of the output buffer.
*/
- cutoffExponent = digitExponent - bufferSize;
- if (cutoffNumber >= 0) {
+ cutoff_max_Exponent = digitExponent - bufferSize;
+ if (cutoff_max >= 0) {
npy_int32 desiredCutoffExponent;
if (cutoffMode == CutoffMode_TotalLength) {
- desiredCutoffExponent = digitExponent - cutoffNumber;
- if (desiredCutoffExponent > cutoffExponent) {
- cutoffExponent = desiredCutoffExponent;
+ desiredCutoffExponent = digitExponent - cutoff_max;
+ if (desiredCutoffExponent > cutoff_max_Exponent) {
+ cutoff_max_Exponent = desiredCutoffExponent;
}
}
- /* Otherwise it's CutoffMode_FractionLength. Print cutoffNumber digits
+ /* Otherwise it's CutoffMode_FractionLength. Print cutoff_max digits
* past the decimal point or until we reach the buffer size
*/
else {
- desiredCutoffExponent = -cutoffNumber;
- if (desiredCutoffExponent > cutoffExponent) {
- cutoffExponent = desiredCutoffExponent;
+ desiredCutoffExponent = -cutoff_max;
+ if (desiredCutoffExponent > cutoff_max_Exponent) {
+ cutoff_max_Exponent = desiredCutoffExponent;
+ }
+ }
+ }
+ /* Also compute the cutoff_min exponent. */
+ cutoff_min_Exponent = digitExponent;
+ if (cutoff_min >= 0) {
+ npy_int32 desiredCutoffExponent;
+
+ if (cutoffMode == CutoffMode_TotalLength) {
+ desiredCutoffExponent = digitExponent - cutoff_min;
+ if (desiredCutoffExponent < cutoff_min_Exponent) {
+ cutoff_min_Exponent = desiredCutoffExponent;
+ }
+ }
+ else {
+ desiredCutoffExponent = -cutoff_min;
+ if (desiredCutoffExponent < cutoff_min_Exponent) {
+ cutoff_min_Exponent = desiredCutoffExponent;
}
}
}
@@ -1432,14 +1452,17 @@ Dragon4(BigInt *bigints, const npy_int32 exponent,
/*
* stop looping if we are far enough away from our neighboring
- * values or if we have reached the cutoff digit
+ * values (and we have printed at least the requested minimum
+ * digits) or if we have reached the cutoff digit
*/
cmp = BigInt_Compare(scaledValue, scaledMarginLow);
low = isEven ? (cmp <= 0) : (cmp < 0);
cmp = BigInt_Compare(scaledValueHigh, scale);
high = isEven ? (cmp >= 0) : (cmp > 0);
- if (low | high | (digitExponent == cutoffExponent))
+ if (((low | high) & (digitExponent <= cutoff_min_Exponent)) |
+ (digitExponent == cutoff_max_Exponent)) {
break;
+ }
/* store the output digit */
*curDigit = (char)('0' + outputDigit);
@@ -1471,7 +1494,7 @@ Dragon4(BigInt *bigints, const npy_int32 exponent,
DEBUG_ASSERT(outputDigit < 10);
if ((scaledValue->length == 0) |
- (digitExponent == cutoffExponent)) {
+ (digitExponent == cutoff_max_Exponent)) {
break;
}
@@ -1589,6 +1612,7 @@ typedef struct Dragon4_Options {
DigitMode digit_mode;
CutoffMode cutoff_mode;
npy_int32 precision;
+ npy_int32 min_digits;
npy_bool sign;
TrimMode trim_mode;
npy_int32 digits_left;
@@ -1617,11 +1641,12 @@ FormatPositional(char *buffer, npy_uint32 bufferSize, BigInt *mantissa,
npy_int32 exponent, char signbit, npy_uint32 mantissaBit,
npy_bool hasUnequalMargins, DigitMode digit_mode,
CutoffMode cutoff_mode, npy_int32 precision,
- TrimMode trim_mode, npy_int32 digits_left,
- npy_int32 digits_right)
+ npy_int32 min_digits, TrimMode trim_mode,
+ npy_int32 digits_left, npy_int32 digits_right)
{
npy_int32 printExponent;
npy_int32 numDigits, numWholeDigits=0, has_sign=0;
+ npy_int32 add_digits;
npy_int32 maxPrintLen = (npy_int32)bufferSize - 1, pos = 0;
@@ -1644,8 +1669,9 @@ FormatPositional(char *buffer, npy_uint32 bufferSize, BigInt *mantissa,
}
numDigits = Dragon4(mantissa, exponent, mantissaBit, hasUnequalMargins,
- digit_mode, cutoff_mode, precision, buffer + has_sign,
- maxPrintLen - has_sign, &printExponent);
+ digit_mode, cutoff_mode, precision, min_digits,
+ buffer + has_sign, maxPrintLen - has_sign,
+ &printExponent);
DEBUG_ASSERT(numDigits > 0);
DEBUG_ASSERT(numDigits <= bufferSize);
@@ -1744,9 +1770,10 @@ FormatPositional(char *buffer, npy_uint32 bufferSize, BigInt *mantissa,
buffer[pos++] = '.';
}
- desiredFractionalDigits = precision;
- if (cutoff_mode == CutoffMode_TotalLength && precision >= 0) {
- desiredFractionalDigits = precision - numWholeDigits;
+ add_digits = digit_mode == DigitMode_Unique ? min_digits : precision;
+ desiredFractionalDigits = add_digits < 0 ? 0 : add_digits;
+ if (cutoff_mode == CutoffMode_TotalLength) {
+ desiredFractionalDigits = add_digits - numWholeDigits;
}
if (trim_mode == TrimMode_LeaveOneZero) {
@@ -1757,10 +1784,9 @@ FormatPositional(char *buffer, npy_uint32 bufferSize, BigInt *mantissa,
}
}
else if (trim_mode == TrimMode_None &&
- digit_mode != DigitMode_Unique &&
desiredFractionalDigits > numFractionDigits &&
pos < maxPrintLen) {
- /* add trailing zeros up to precision length */
+ /* add trailing zeros up to add_digits length */
/* compute the number of trailing zeros needed */
npy_int32 count = desiredFractionalDigits - numFractionDigits;
if (pos + count > maxPrintLen) {
@@ -1778,7 +1804,7 @@ FormatPositional(char *buffer, npy_uint32 bufferSize, BigInt *mantissa,
* when rounding, we may still end up with trailing zeros. Remove them
* depending on trim settings.
*/
- if (precision >= 0 && trim_mode != TrimMode_None && numFractionDigits > 0) {
+ if (trim_mode != TrimMode_None && numFractionDigits > 0) {
while (buffer[pos-1] == '0') {
pos--;
numFractionDigits--;
@@ -1852,7 +1878,7 @@ static npy_uint32
FormatScientific (char *buffer, npy_uint32 bufferSize, BigInt *mantissa,
npy_int32 exponent, char signbit, npy_uint32 mantissaBit,
npy_bool hasUnequalMargins, DigitMode digit_mode,
- npy_int32 precision, TrimMode trim_mode,
+ npy_int32 precision, npy_int32 min_digits, TrimMode trim_mode,
npy_int32 digits_left, npy_int32 exp_digits)
{
npy_int32 printExponent;
@@ -1860,12 +1886,12 @@ FormatScientific (char *buffer, npy_uint32 bufferSize, BigInt *mantissa,
char *pCurOut;
npy_int32 numFractionDigits;
npy_int32 leftchars;
+ npy_int32 add_digits;
if (digit_mode != DigitMode_Unique) {
DEBUG_ASSERT(precision >= 0);
}
-
DEBUG_ASSERT(bufferSize > 0);
pCurOut = buffer;
@@ -1893,7 +1919,9 @@ FormatScientific (char *buffer, npy_uint32 bufferSize, BigInt *mantissa,
}
numDigits = Dragon4(mantissa, exponent, mantissaBit, hasUnequalMargins,
- digit_mode, CutoffMode_TotalLength, precision + 1,
+ digit_mode, CutoffMode_TotalLength,
+ precision < 0 ? -1 : precision + 1,
+ min_digits < 0 ? -1 : min_digits + 1,
pCurOut, bufferSize, &printExponent);
DEBUG_ASSERT(numDigits > 0);
@@ -1928,6 +1956,8 @@ FormatScientific (char *buffer, npy_uint32 bufferSize, BigInt *mantissa,
--bufferSize;
}
+ add_digits = digit_mode == DigitMode_Unique ? min_digits : precision;
+ add_digits = add_digits < 0 ? 0 : add_digits;
if (trim_mode == TrimMode_LeaveOneZero) {
/* if we didn't print any fractional digits, add the 0 */
if (numFractionDigits == 0 && bufferSize > 1) {
@@ -1937,13 +1967,12 @@ FormatScientific (char *buffer, npy_uint32 bufferSize, BigInt *mantissa,
++numFractionDigits;
}
}
- else if (trim_mode == TrimMode_None &&
- digit_mode != DigitMode_Unique) {
- /* add trailing zeros up to precision length */
- if (precision > (npy_int32)numFractionDigits) {
+ else if (trim_mode == TrimMode_None) {
+ /* add trailing zeros up to add_digits length */
+ if (add_digits > (npy_int32)numFractionDigits) {
char *pEnd;
/* compute the number of trailing zeros needed */
- npy_int32 numZeros = (precision - numFractionDigits);
+ npy_int32 numZeros = (add_digits - numFractionDigits);
if (numZeros > (npy_int32)bufferSize - 1) {
numZeros = (npy_int32)bufferSize - 1;
@@ -1961,7 +1990,7 @@ FormatScientific (char *buffer, npy_uint32 bufferSize, BigInt *mantissa,
* when rounding, we may still end up with trailing zeros. Remove them
* depending on trim settings.
*/
- if (precision >= 0 && trim_mode != TrimMode_None && numFractionDigits > 0) {
+ if (trim_mode != TrimMode_None && numFractionDigits > 0) {
--pCurOut;
while (*pCurOut == '0') {
--pCurOut;
@@ -2153,14 +2182,14 @@ Format_floatbits(char *buffer, npy_uint32 bufferSize, BigInt *mantissa,
return FormatScientific(buffer, bufferSize, mantissa, exponent,
signbit, mantissaBit, hasUnequalMargins,
opt->digit_mode, opt->precision,
- opt->trim_mode, opt->digits_left,
- opt->exp_digits);
+ opt->min_digits, opt->trim_mode,
+ opt->digits_left, opt->exp_digits);
}
else {
return FormatPositional(buffer, bufferSize, mantissa, exponent,
signbit, mantissaBit, hasUnequalMargins,
opt->digit_mode, opt->cutoff_mode,
- opt->precision, opt->trim_mode,
+ opt->precision, opt->min_digits, opt->trim_mode,
opt->digits_left, opt->digits_right);
}
}
@@ -3100,7 +3129,7 @@ Dragon4_Positional_##Type##_opt(npy_type *val, Dragon4_Options *opt)\
\
PyObject *\
Dragon4_Positional_##Type(npy_type *val, DigitMode digit_mode,\
- CutoffMode cutoff_mode, int precision,\
+ CutoffMode cutoff_mode, int precision, int min_digits, \
int sign, TrimMode trim, int pad_left, int pad_right)\
{\
Dragon4_Options opt;\
@@ -3109,6 +3138,7 @@ Dragon4_Positional_##Type(npy_type *val, DigitMode digit_mode,\
opt.digit_mode = digit_mode;\
opt.cutoff_mode = cutoff_mode;\
opt.precision = precision;\
+ opt.min_digits = min_digits;\
opt.sign = sign;\
opt.trim_mode = trim;\
opt.digits_left = pad_left;\
@@ -3136,7 +3166,8 @@ Dragon4_Scientific_##Type##_opt(npy_type *val, Dragon4_Options *opt)\
}\
PyObject *\
Dragon4_Scientific_##Type(npy_type *val, DigitMode digit_mode, int precision,\
- int sign, TrimMode trim, int pad_left, int exp_digits)\
+ int min_digits, int sign, TrimMode trim, int pad_left, \
+ int exp_digits)\
{\
Dragon4_Options opt;\
\
@@ -3144,6 +3175,7 @@ Dragon4_Scientific_##Type(npy_type *val, DigitMode digit_mode, int precision,\
opt.digit_mode = digit_mode;\
opt.cutoff_mode = CutoffMode_TotalLength;\
opt.precision = precision;\
+ opt.min_digits = min_digits;\
opt.sign = sign;\
opt.trim_mode = trim;\
opt.digits_left = pad_left;\
@@ -3166,8 +3198,8 @@ make_dragon4_typefuncs(LongDouble, npy_longdouble, NPY_LONGDOUBLE_BINFMT_NAME)
PyObject *
Dragon4_Positional(PyObject *obj, DigitMode digit_mode, CutoffMode cutoff_mode,
- int precision, int sign, TrimMode trim, int pad_left,
- int pad_right)
+ int precision, int min_digits, int sign, TrimMode trim,
+ int pad_left, int pad_right)
{
npy_double val;
Dragon4_Options opt;
@@ -3176,6 +3208,7 @@ Dragon4_Positional(PyObject *obj, DigitMode digit_mode, CutoffMode cutoff_mode,
opt.digit_mode = digit_mode;
opt.cutoff_mode = cutoff_mode;
opt.precision = precision;
+ opt.min_digits = min_digits;
opt.sign = sign;
opt.trim_mode = trim;
opt.digits_left = pad_left;
@@ -3208,7 +3241,8 @@ Dragon4_Positional(PyObject *obj, DigitMode digit_mode, CutoffMode cutoff_mode,
PyObject *
Dragon4_Scientific(PyObject *obj, DigitMode digit_mode, int precision,
- int sign, TrimMode trim, int pad_left, int exp_digits)
+ int min_digits, int sign, TrimMode trim, int pad_left,
+ int exp_digits)
{
npy_double val;
Dragon4_Options opt;
@@ -3217,6 +3251,7 @@ Dragon4_Scientific(PyObject *obj, DigitMode digit_mode, int precision,
opt.digit_mode = digit_mode;
opt.cutoff_mode = CutoffMode_TotalLength;
opt.precision = precision;
+ opt.min_digits = min_digits;
opt.sign = sign;
opt.trim_mode = trim;
opt.digits_left = pad_left;
diff --git a/numpy/core/src/multiarray/dragon4.h b/numpy/core/src/multiarray/dragon4.h
index 3a99bde6c..4b76bf9e5 100644
--- a/numpy/core/src/multiarray/dragon4.h
+++ b/numpy/core/src/multiarray/dragon4.h
@@ -112,12 +112,12 @@ typedef enum TrimMode
PyObject *\
Dragon4_Positional_##Type(npy_type *val, DigitMode digit_mode,\
CutoffMode cutoff_mode, int precision,\
- int sign, TrimMode trim, int pad_left,\
- int pad_right);\
+ int min_digits, int sign, TrimMode trim, \
+ int pad_left, int pad_right);\
PyObject *\
Dragon4_Scientific_##Type(npy_type *val, DigitMode digit_mode,\
- int precision, int sign, TrimMode trim,\
- int pad_left, int exp_digits);
+ int precision, int min_digits, int sign, \
+ TrimMode trim, int pad_left, int exp_digits);
make_dragon4_typedecl(Half, npy_half)
make_dragon4_typedecl(Float, npy_float)
@@ -128,12 +128,13 @@ make_dragon4_typedecl(LongDouble, npy_longdouble)
PyObject *
Dragon4_Positional(PyObject *obj, DigitMode digit_mode, CutoffMode cutoff_mode,
- int precision, int sign, TrimMode trim, int pad_left,
- int pad_right);
+ int precision, int min_digits, int sign, TrimMode trim,
+ int pad_left, int pad_right);
PyObject *
Dragon4_Scientific(PyObject *obj, DigitMode digit_mode, int precision,
- int sign, TrimMode trim, int pad_left, int exp_digits);
+ int min_digits, int sign, TrimMode trim, int pad_left,
+ int exp_digits);
#endif
diff --git a/numpy/core/src/multiarray/dtype_transfer.c b/numpy/core/src/multiarray/dtype_transfer.c
index 630bd76f3..50db627ea 100644
--- a/numpy/core/src/multiarray/dtype_transfer.c
+++ b/numpy/core/src/multiarray/dtype_transfer.c
@@ -18,6 +18,7 @@
#define _MULTIARRAYMODULE
#include <numpy/arrayobject.h>
+#include "lowlevel_strided_loops.h"
#include "npy_pycompat.h"
#include "convert_datatype.h"
@@ -28,8 +29,11 @@
#include "array_assign.h"
#include "shape.h"
-#include "lowlevel_strided_loops.h"
+#include "dtype_transfer.h"
#include "alloc.h"
+#include "dtypemeta.h"
+#include "array_method.h"
+#include "array_coercion.h"
#define NPY_LOWLEVEL_BUFFER_BLOCKSIZE 128
@@ -71,46 +75,26 @@ _safe_print(PyObject *obj)
* Returns NPY_SUCCEED or NPY_FAIL.
*/
static int
-get_decsrcref_transfer_function(int aligned,
+get_decref_transfer_function(int aligned,
npy_intp src_stride,
PyArray_Descr *src_dtype,
- PyArray_StridedUnaryOp **out_stransfer,
- NpyAuxData **out_transferdata,
+ NPY_cast_info *cast_info,
int *out_needs_api);
-/*
- * Returns a transfer function which zeros out the dest values.
- *
- * Returns NPY_SUCCEED or NPY_FAIL.
- */
-static int
-get_setdstzero_transfer_function(int aligned,
- npy_intp dst_stride,
- PyArray_Descr *dst_dtype,
- PyArray_StridedUnaryOp **out_stransfer,
- NpyAuxData **out_transferdata,
- int *out_needs_api);
-
-/*
- * Returns a transfer function which sets a boolean type to ones.
- *
- * Returns NPY_SUCCEED or NPY_FAIL.
- */
-NPY_NO_EXPORT int
-get_bool_setdstone_transfer_function(npy_intp dst_stride,
- PyArray_StridedUnaryOp **out_stransfer,
- NpyAuxData **out_transferdata,
- int *NPY_UNUSED(out_needs_api));
/*************************** COPY REFERENCES *******************************/
/* Moves references from src to dst */
-static int
-_strided_to_strided_move_references(char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp src_itemsize,
- NpyAuxData *data)
+NPY_NO_EXPORT int
+_strided_to_strided_move_references(
+ PyArrayMethod_Context *NPY_UNUSED(context), char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *NPY_UNUSED(auxdata))
{
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+
PyObject *src_ref = NULL, *dst_ref = NULL;
while (N > 0) {
memcpy(&src_ref, src, sizeof(src_ref));
@@ -134,12 +118,16 @@ _strided_to_strided_move_references(char *dst, npy_intp dst_stride,
}
/* Copies references from src to dst */
-static int
-_strided_to_strided_copy_references(char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp src_itemsize,
- NpyAuxData *data)
+NPY_NO_EXPORT int
+_strided_to_strided_copy_references(
+ PyArrayMethod_Context *NPY_UNUSED(context), char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *NPY_UNUSED(auxdata))
{
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+
PyObject *src_ref = NULL, *dst_ref = NULL;
while (N > 0) {
memcpy(&src_ref, src, sizeof(src_ref));
@@ -161,42 +149,242 @@ _strided_to_strided_copy_references(char *dst, npy_intp dst_stride,
return 0;
}
+/************************** ANY TO OBJECT *********************************/
-/************************** ZERO-PADDED COPY ******************************/
+typedef struct {
+ NpyAuxData base;
+ PyArray_GetItemFunc *getitem;
+ PyArrayObject_fields arr_fields;
+ NPY_cast_info decref_src;
+} _any_to_object_auxdata;
+
+
+static void
+_any_to_object_auxdata_free(NpyAuxData *auxdata)
+{
+ _any_to_object_auxdata *data = (_any_to_object_auxdata *)auxdata;
+
+ Py_DECREF(data->arr_fields.descr);
+ NPY_cast_info_xfree(&data->decref_src);
+ PyMem_Free(data);
+}
+
+
+static NpyAuxData *
+_any_to_object_auxdata_clone(NpyAuxData *auxdata)
+{
+ _any_to_object_auxdata *data = (_any_to_object_auxdata *)auxdata;
+
+ _any_to_object_auxdata *res = PyMem_Malloc(sizeof(_any_to_object_auxdata));
+
+ res->base = data->base;
+ res->getitem = data->getitem;
+ res->arr_fields = data->arr_fields;
+ Py_INCREF(res->arr_fields.descr);
+
+ if (data->decref_src.func != NULL) {
+ if (NPY_cast_info_copy(&res->decref_src, &data->decref_src) < 0) {
+ NPY_AUXDATA_FREE((NpyAuxData *)res);
+ return NULL;
+ }
+ }
+ else {
+ res->decref_src.func = NULL;
+ }
+ return (NpyAuxData *)res;
+}
+
+
+static int
+_strided_to_strided_any_to_object(
+ PyArrayMethod_Context *NPY_UNUSED(context), char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *auxdata)
+{
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+
+ _any_to_object_auxdata *data = (_any_to_object_auxdata *)auxdata;
+
+ PyObject *dst_ref = NULL;
+ char *orig_src = src;
+ while (N > 0) {
+ memcpy(&dst_ref, dst, sizeof(dst_ref));
+ Py_XDECREF(dst_ref);
+ dst_ref = data->getitem(src, &data->arr_fields);
+ memcpy(dst, &dst_ref, sizeof(PyObject *));
+
+ if (dst_ref == NULL) {
+ return -1;
+ }
+ src += src_stride;
+ dst += dst_stride;
+ --N;
+ }
+ if (data->decref_src.func != NULL) {
+ /* If necessary, clear the input buffer (`move_references`) */
+ if (data->decref_src.func(&data->decref_src.context,
+ &orig_src, &N, &src_stride, data->decref_src.auxdata) < 0) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+
+NPY_NO_EXPORT int
+any_to_object_get_loop(
+ PyArrayMethod_Context *context,
+ int aligned, int move_references,
+ npy_intp *strides,
+ PyArrayMethod_StridedLoop **out_loop,
+ NpyAuxData **out_transferdata,
+ NPY_ARRAYMETHOD_FLAGS *flags)
+{
+
+ *flags = NPY_METH_REQUIRES_PYAPI; /* No need for floating point errors */
+
+ *out_loop = _strided_to_strided_any_to_object;
+ *out_transferdata = PyMem_Malloc(sizeof(_any_to_object_auxdata));
+ if (*out_transferdata == NULL) {
+ return -1;
+ }
+ _any_to_object_auxdata *data = (_any_to_object_auxdata *)*out_transferdata;
+ data->base.free = &_any_to_object_auxdata_free;
+ data->base.clone = &_any_to_object_auxdata_clone;
+ data->arr_fields.base = NULL;
+ data->arr_fields.descr = context->descriptors[0];
+ Py_INCREF(data->arr_fields.descr);
+ data->arr_fields.flags = aligned ? NPY_ARRAY_ALIGNED : 0;
+ data->arr_fields.nd = 0;
+
+ data->getitem = context->descriptors[0]->f->getitem;
+ NPY_cast_info_init(&data->decref_src);
+
+ if (move_references && PyDataType_REFCHK(context->descriptors[0])) {
+ int needs_api;
+ if (get_decref_transfer_function(
+ aligned, strides[0], context->descriptors[0],
+ &data->decref_src,
+ &needs_api) == NPY_FAIL) {
+ NPY_AUXDATA_FREE(*out_transferdata);
+ *out_transferdata = NULL;
+ return -1;
+ }
+ }
+ return 0;
+}
+
+
+/************************** OBJECT TO ANY *********************************/
-/* Does a zero-padded copy */
typedef struct {
NpyAuxData base;
- npy_intp dst_itemsize;
-} _strided_zero_pad_data;
+ PyArray_Descr *descr;
+ int move_references;
+} _object_to_any_auxdata;
-/* zero-padded data copy function */
-static NpyAuxData *_strided_zero_pad_data_clone(NpyAuxData *data)
+
+static void
+_object_to_any_auxdata_free(NpyAuxData *auxdata)
{
- _strided_zero_pad_data *newdata =
- (_strided_zero_pad_data *)PyArray_malloc(
- sizeof(_strided_zero_pad_data));
- if (newdata == NULL) {
+ _object_to_any_auxdata *data = (_object_to_any_auxdata *)auxdata;
+ Py_DECREF(data->descr);
+ PyMem_Free(data);
+}
+
+static NpyAuxData *
+_object_to_any_auxdata_clone(NpyAuxData *data)
+{
+ _object_to_any_auxdata *res = PyMem_Malloc(sizeof(*res));
+ if (res == NULL) {
return NULL;
}
+ memcpy(res, data, sizeof(*res));
+ Py_INCREF(res->descr);
+ return (NpyAuxData *)res;
+}
- memcpy(newdata, data, sizeof(_strided_zero_pad_data));
- return (NpyAuxData *)newdata;
+static int
+strided_to_strided_object_to_any(
+ PyArrayMethod_Context *NPY_UNUSED(context), char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *auxdata)
+{
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+ _object_to_any_auxdata *data = (_object_to_any_auxdata *)auxdata;
+
+ PyObject *src_ref;
+
+ while (N > 0) {
+ memcpy(&src_ref, src, sizeof(src_ref));
+ if (PyArray_Pack(data->descr, dst, src_ref ? src_ref : Py_None) < 0) {
+ return -1;
+ }
+
+ if (data->move_references && src_ref != NULL) {
+ Py_DECREF(src_ref);
+ memset(src, 0, sizeof(src_ref));
+ }
+
+ N--;
+ dst += dst_stride;
+ src += src_stride;
+ }
+ return 0;
+}
+
+
+NPY_NO_EXPORT int
+object_to_any_get_loop(
+ PyArrayMethod_Context *context,
+ int NPY_UNUSED(aligned), int move_references,
+ npy_intp *NPY_UNUSED(strides),
+ PyArrayMethod_StridedLoop **out_loop,
+ NpyAuxData **out_transferdata,
+ NPY_ARRAYMETHOD_FLAGS *flags)
+{
+ *flags = NPY_METH_REQUIRES_PYAPI;
+
+ /* NOTE: auxdata is only really necessary to flag `move_references` */
+ _object_to_any_auxdata *data = PyMem_Malloc(sizeof(*data));
+ if (data == NULL) {
+ return -1;
+ }
+ data->base.free = &_object_to_any_auxdata_free;
+ data->base.clone = &_object_to_any_auxdata_clone;
+
+ Py_INCREF(context->descriptors[1]);
+ data->descr = context->descriptors[1];
+ data->move_references = move_references;
+ *out_transferdata = (NpyAuxData *)data;
+ *out_loop = &strided_to_strided_object_to_any;
+ return 0;
}
+
+/************************** ZERO-PADDED COPY ******************************/
+
/*
* Does a strided to strided zero-padded copy for the case where
* dst_itemsize > src_itemsize
*/
static int
-_strided_to_strided_zero_pad_copy(char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp src_itemsize,
- NpyAuxData *data)
+_strided_to_strided_zero_pad_copy(
+ PyArrayMethod_Context *context, char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *NPY_UNUSED(auxdata))
{
- _strided_zero_pad_data *d = (_strided_zero_pad_data *)data;
- npy_intp dst_itemsize = d->dst_itemsize;
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+ npy_intp src_itemsize = context->descriptors[0]->elsize;
+ npy_intp dst_itemsize = context->descriptors[1]->elsize;
+
npy_intp zero_size = dst_itemsize-src_itemsize;
while (N > 0) {
@@ -214,13 +402,15 @@ _strided_to_strided_zero_pad_copy(char *dst, npy_intp dst_stride,
* dst_itemsize < src_itemsize
*/
static int
-_strided_to_strided_truncate_copy(char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp src_itemsize,
- NpyAuxData *data)
+_strided_to_strided_truncate_copy(
+ PyArrayMethod_Context *context, char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *NPY_UNUSED(auxdata))
{
- _strided_zero_pad_data *d = (_strided_zero_pad_data *)data;
- npy_intp dst_itemsize = d->dst_itemsize;
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+ npy_intp dst_itemsize = context->descriptors[1]->elsize;
while (N > 0) {
memcpy(dst, src, dst_itemsize);
@@ -236,13 +426,17 @@ _strided_to_strided_truncate_copy(char *dst, npy_intp dst_stride,
* unicode swapping is needed.
*/
static int
-_strided_to_strided_unicode_copyswap(char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp src_itemsize,
- NpyAuxData *data)
+_strided_to_strided_unicode_copyswap(
+ PyArrayMethod_Context *context, char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *NPY_UNUSED(auxdata))
{
- _strided_zero_pad_data *d = (_strided_zero_pad_data *)data;
- npy_intp dst_itemsize = d->dst_itemsize;
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+ npy_intp src_itemsize = context->descriptors[0]->elsize;
+ npy_intp dst_itemsize = context->descriptors[1]->elsize;
+
npy_intp zero_size = dst_itemsize - src_itemsize;
npy_intp copy_size = zero_size > 0 ? src_itemsize : dst_itemsize;
char *_dst;
@@ -271,26 +465,16 @@ NPY_NO_EXPORT int
PyArray_GetStridedZeroPadCopyFn(int aligned, int unicode_swap,
npy_intp src_stride, npy_intp dst_stride,
npy_intp src_itemsize, npy_intp dst_itemsize,
- PyArray_StridedUnaryOp **out_stransfer,
+ PyArrayMethod_StridedLoop **out_stransfer,
NpyAuxData **out_transferdata)
{
+ *out_transferdata = NULL;
if ((src_itemsize == dst_itemsize) && !unicode_swap) {
*out_stransfer = PyArray_GetStridedCopyFn(aligned, src_stride,
dst_stride, src_itemsize);
- *out_transferdata = NULL;
return (*out_stransfer == NULL) ? NPY_FAIL : NPY_SUCCEED;
}
else {
- _strided_zero_pad_data *d = PyArray_malloc(
- sizeof(_strided_zero_pad_data));
- if (d == NULL) {
- PyErr_NoMemory();
- return NPY_FAIL;
- }
- d->dst_itemsize = dst_itemsize;
- d->base.free = (NpyAuxData_FreeFunc *)&PyArray_free;
- d->base.clone = &_strided_zero_pad_data_clone;
-
if (unicode_swap) {
*out_stransfer = &_strided_to_strided_unicode_copyswap;
}
@@ -300,218 +484,10 @@ PyArray_GetStridedZeroPadCopyFn(int aligned, int unicode_swap,
else {
*out_stransfer = &_strided_to_strided_truncate_copy;
}
-
- *out_transferdata = (NpyAuxData *)d;
return NPY_SUCCEED;
}
}
-/***************** WRAP ALIGNED CONTIGUOUS TRANSFER FUNCTION **************/
-
-/* Wraps a transfer function + data in alignment code */
-typedef struct {
- NpyAuxData base;
- PyArray_StridedUnaryOp *wrapped,
- *tobuffer, *frombuffer;
- NpyAuxData *wrappeddata, *todata, *fromdata;
- npy_intp src_itemsize, dst_itemsize;
- char *bufferin, *bufferout;
- npy_bool init_dest, out_needs_api;
-} _align_wrap_data;
-
-/* transfer data free function */
-static void _align_wrap_data_free(NpyAuxData *data)
-{
- _align_wrap_data *d = (_align_wrap_data *)data;
- NPY_AUXDATA_FREE(d->wrappeddata);
- NPY_AUXDATA_FREE(d->todata);
- NPY_AUXDATA_FREE(d->fromdata);
- PyArray_free(data);
-}
-
-/* transfer data copy function */
-static NpyAuxData *_align_wrap_data_clone(NpyAuxData *data)
-{
- _align_wrap_data *d = (_align_wrap_data *)data;
- _align_wrap_data *newdata;
- npy_intp basedatasize, datasize;
-
- /* Round up the structure size to 16-byte boundary */
- basedatasize = (sizeof(_align_wrap_data)+15)&(-0x10);
- /* Add space for two low level buffers */
- datasize = basedatasize +
- NPY_LOWLEVEL_BUFFER_BLOCKSIZE*d->src_itemsize +
- NPY_LOWLEVEL_BUFFER_BLOCKSIZE*d->dst_itemsize;
-
- /* Allocate the data, and populate it */
- newdata = (_align_wrap_data *)PyArray_malloc(datasize);
- if (newdata == NULL) {
- return NULL;
- }
- memcpy(newdata, data, basedatasize);
- newdata->bufferin = (char *)newdata + basedatasize;
- newdata->bufferout = newdata->bufferin +
- NPY_LOWLEVEL_BUFFER_BLOCKSIZE*newdata->src_itemsize;
- if (newdata->wrappeddata != NULL) {
- newdata->wrappeddata = NPY_AUXDATA_CLONE(d->wrappeddata);
- if (newdata->wrappeddata == NULL) {
- PyArray_free(newdata);
- return NULL;
- }
- }
- if (newdata->todata != NULL) {
- newdata->todata = NPY_AUXDATA_CLONE(d->todata);
- if (newdata->todata == NULL) {
- NPY_AUXDATA_FREE(newdata->wrappeddata);
- PyArray_free(newdata);
- return NULL;
- }
- }
- if (newdata->fromdata != NULL) {
- newdata->fromdata = NPY_AUXDATA_CLONE(d->fromdata);
- if (newdata->fromdata == NULL) {
- NPY_AUXDATA_FREE(newdata->wrappeddata);
- NPY_AUXDATA_FREE(newdata->todata);
- PyArray_free(newdata);
- return NULL;
- }
- }
-
- newdata->init_dest = d->init_dest;
- newdata->out_needs_api = d->out_needs_api;
-
- return (NpyAuxData *)newdata;
-}
-
-static int
-_strided_to_strided_contig_align_wrap(char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp src_itemsize,
- NpyAuxData *data)
-{
- _align_wrap_data *d = (_align_wrap_data *)data;
- PyArray_StridedUnaryOp *wrapped = d->wrapped,
- *tobuffer = d->tobuffer,
- *frombuffer = d->frombuffer;
- npy_intp inner_src_itemsize = d->src_itemsize,
- dst_itemsize = d->dst_itemsize;
- NpyAuxData *wrappeddata = d->wrappeddata,
- *todata = d->todata,
- *fromdata = d->fromdata;
- char *bufferin = d->bufferin, *bufferout = d->bufferout;
- npy_bool init_dest = d->init_dest;
-
- for(;;) {
- if (N > NPY_LOWLEVEL_BUFFER_BLOCKSIZE) {
- if (tobuffer(
- bufferin, inner_src_itemsize, src, src_stride,
- NPY_LOWLEVEL_BUFFER_BLOCKSIZE, src_itemsize, todata) < 0) {
- return -1;
- }
- if (init_dest) {
- memset(bufferout, 0,
- dst_itemsize*NPY_LOWLEVEL_BUFFER_BLOCKSIZE);
- }
- if (wrapped(bufferout, dst_itemsize, bufferin, inner_src_itemsize,
- NPY_LOWLEVEL_BUFFER_BLOCKSIZE,
- inner_src_itemsize, wrappeddata) < 0) {
- return -1;
- }
- if (frombuffer(dst, dst_stride, bufferout, dst_itemsize,
- NPY_LOWLEVEL_BUFFER_BLOCKSIZE,
- dst_itemsize, fromdata) < 0) {
- return -1;
- }
- N -= NPY_LOWLEVEL_BUFFER_BLOCKSIZE;
- src += NPY_LOWLEVEL_BUFFER_BLOCKSIZE*src_stride;
- dst += NPY_LOWLEVEL_BUFFER_BLOCKSIZE*dst_stride;
- }
- else {
- if (tobuffer(bufferin, inner_src_itemsize, src, src_stride,
- N, src_itemsize, todata) < 0) {
- return -1;
- }
- if (init_dest) {
- memset(bufferout, 0, dst_itemsize*N);
- }
- if (wrapped(bufferout, dst_itemsize, bufferin, inner_src_itemsize,
- N, inner_src_itemsize, wrappeddata) < 0) {
- return -1;
- }
- if (frombuffer(dst, dst_stride, bufferout, dst_itemsize,
- N, dst_itemsize, fromdata) < 0) {
- return -1;
- }
- return 0;
- }
- }
-}
-
-/*
- * Wraps an aligned contig to contig transfer function between either
- * copies or byte swaps to temporary buffers.
- *
- * src_itemsize/dst_itemsize - The sizes of the src and dst datatypes.
- * tobuffer - copy/swap function from src to an aligned contiguous buffer.
- * todata - data for tobuffer
- * frombuffer - copy/swap function from an aligned contiguous buffer to dst.
- * fromdata - data for frombuffer
- * wrapped - contig to contig transfer function being wrapped
- * wrappeddata - data for wrapped
- * init_dest - 1 means to memset the dest buffer to 0 before calling wrapped.
- * out_needs_api - if NPY_TRUE, check for (and break on) Python API errors.
- *
- * Returns NPY_SUCCEED or NPY_FAIL.
- */
-NPY_NO_EXPORT int
-wrap_aligned_contig_transfer_function(
- npy_intp src_itemsize, npy_intp dst_itemsize,
- PyArray_StridedUnaryOp *tobuffer, NpyAuxData *todata,
- PyArray_StridedUnaryOp *frombuffer, NpyAuxData *fromdata,
- PyArray_StridedUnaryOp *wrapped, NpyAuxData *wrappeddata,
- int init_dest,
- int out_needs_api,
- PyArray_StridedUnaryOp **out_stransfer,
- NpyAuxData **out_transferdata)
-{
- _align_wrap_data *data;
- npy_intp basedatasize, datasize;
-
- /* Round up the structure size to 16-byte boundary */
- basedatasize = (sizeof(_align_wrap_data)+15)&(-0x10);
- /* Add space for two low level buffers */
- datasize = basedatasize +
- NPY_LOWLEVEL_BUFFER_BLOCKSIZE*src_itemsize +
- NPY_LOWLEVEL_BUFFER_BLOCKSIZE*dst_itemsize;
-
- /* Allocate the data, and populate it */
- data = (_align_wrap_data *)PyArray_malloc(datasize);
- if (data == NULL) {
- PyErr_NoMemory();
- return NPY_FAIL;
- }
- data->base.free = &_align_wrap_data_free;
- data->base.clone = &_align_wrap_data_clone;
- data->tobuffer = tobuffer;
- data->todata = todata;
- data->frombuffer = frombuffer;
- data->fromdata = fromdata;
- data->wrapped = wrapped;
- data->wrappeddata = wrappeddata;
- data->src_itemsize = src_itemsize;
- data->dst_itemsize = dst_itemsize;
- data->bufferin = (char *)data + basedatasize;
- data->bufferout = data->bufferin +
- NPY_LOWLEVEL_BUFFER_BLOCKSIZE*src_itemsize;
- data->init_dest = (npy_bool) init_dest;
- data->out_needs_api = (npy_bool) out_needs_api;
-
- /* Set the function and data */
- *out_stransfer = &_strided_to_strided_contig_align_wrap;
- *out_transferdata = (NpyAuxData *)data;
-
- return NPY_SUCCEED;
-}
/*************************** WRAP DTYPE COPY/SWAP *************************/
/* Wraps the dtype copy swap function */
@@ -527,14 +503,14 @@ static void _wrap_copy_swap_data_free(NpyAuxData *data)
{
_wrap_copy_swap_data *d = (_wrap_copy_swap_data *)data;
Py_DECREF(d->arr);
- PyArray_free(data);
+ PyMem_Free(data);
}
/* wrap copy swap data copy function */
static NpyAuxData *_wrap_copy_swap_data_clone(NpyAuxData *data)
{
_wrap_copy_swap_data *newdata =
- (_wrap_copy_swap_data *)PyArray_malloc(sizeof(_wrap_copy_swap_data));
+ (_wrap_copy_swap_data *)PyMem_Malloc(sizeof(_wrap_copy_swap_data));
if (newdata == NULL) {
return NULL;
}
@@ -546,32 +522,35 @@ static NpyAuxData *_wrap_copy_swap_data_clone(NpyAuxData *data)
}
static int
-_strided_to_strided_wrap_copy_swap(char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp NPY_UNUSED(src_itemsize),
- NpyAuxData *data)
+_strided_to_strided_wrap_copy_swap(
+ PyArrayMethod_Context *NPY_UNUSED(context), char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *auxdata)
{
- _wrap_copy_swap_data *d = (_wrap_copy_swap_data *)data;
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+
+ _wrap_copy_swap_data *d = (_wrap_copy_swap_data *)auxdata;
/* We assume that d->copyswapn should not be able to error. */
d->copyswapn(dst, dst_stride, src, src_stride, N, d->swap, d->arr);
return 0;
}
-/* This only gets used for custom data types and for Unicode when swapping */
+/*
+ * This function is used only via `get_wrapped_legacy_cast_function`
+ * when we wrap a legacy DType (or explicitly fall back to the legacy
+ * wrapping) for an internal cast.
+ */
static int
-wrap_copy_swap_function(int aligned,
- npy_intp src_stride, npy_intp dst_stride,
- PyArray_Descr *dtype,
- int should_swap,
- PyArray_StridedUnaryOp **out_stransfer,
- NpyAuxData **out_transferdata)
+wrap_copy_swap_function(
+ PyArray_Descr *dtype, int should_swap,
+ PyArrayMethod_StridedLoop **out_stransfer,
+ NpyAuxData **out_transferdata)
{
- _wrap_copy_swap_data *data;
- npy_intp shape = 1;
-
/* Allocate the data for the copy swap */
- data = (_wrap_copy_swap_data *)PyArray_malloc(sizeof(_wrap_copy_swap_data));
+ _wrap_copy_swap_data *data = PyMem_Malloc(sizeof(_wrap_copy_swap_data));
if (data == NULL) {
PyErr_NoMemory();
*out_stransfer = NULL;
@@ -589,13 +568,14 @@ wrap_copy_swap_function(int aligned,
* The copyswap functions shouldn't need that.
*/
Py_INCREF(dtype);
+ npy_intp shape = 1;
data->arr = (PyArrayObject *)PyArray_NewFromDescr_int(
&PyArray_Type, dtype,
1, &shape, NULL, NULL,
0, NULL, NULL,
0, 1);
if (data->arr == NULL) {
- PyArray_free(data);
+ PyMem_Free(data);
return NPY_FAIL;
}
@@ -621,14 +601,14 @@ static void _strided_cast_data_free(NpyAuxData *data)
_strided_cast_data *d = (_strided_cast_data *)data;
Py_DECREF(d->aip);
Py_DECREF(d->aop);
- PyArray_free(data);
+ PyMem_Free(data);
}
/* strided cast data copy function */
static NpyAuxData *_strided_cast_data_clone(NpyAuxData *data)
{
_strided_cast_data *newdata =
- (_strided_cast_data *)PyArray_malloc(sizeof(_strided_cast_data));
+ (_strided_cast_data *)PyMem_Malloc(sizeof(_strided_cast_data));
if (newdata == NULL) {
return NULL;
}
@@ -641,12 +621,16 @@ static NpyAuxData *_strided_cast_data_clone(NpyAuxData *data)
}
static int
-_aligned_strided_to_strided_cast(char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp src_itemsize,
- NpyAuxData *data)
+_aligned_strided_to_strided_cast(
+ PyArrayMethod_Context *NPY_UNUSED(context), char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *auxdata)
{
- _strided_cast_data *d = (_strided_cast_data *)data;
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+
+ _strided_cast_data *d = (_strided_cast_data *)auxdata;
PyArray_VectorUnaryFunc *castfunc = d->castfunc;
PyArrayObject *aip = d->aip, *aop = d->aop;
npy_bool needs_api = d->needs_api;
@@ -672,11 +656,16 @@ _aligned_strided_to_strided_cast(char *dst, npy_intp dst_stride,
/* This one requires src be of type NPY_OBJECT */
static int
-_aligned_strided_to_strided_cast_decref_src(char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp src_itemsize,
- NpyAuxData *data)
+_aligned_strided_to_strided_cast_decref_src(
+ PyArrayMethod_Context *NPY_UNUSED(context), char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *auxdata)
{
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+
+ _any_to_object_auxdata *data = (_any_to_object_auxdata *)auxdata;
_strided_cast_data *d = (_strided_cast_data *)data;
PyArray_VectorUnaryFunc *castfunc = d->castfunc;
PyArrayObject *aip = d->aip, *aop = d->aop;
@@ -706,12 +695,15 @@ _aligned_strided_to_strided_cast_decref_src(char *dst, npy_intp dst_stride,
}
static int
-_aligned_contig_to_contig_cast(char *dst, npy_intp NPY_UNUSED(dst_stride),
- char *src, npy_intp NPY_UNUSED(src_stride),
- npy_intp N, npy_intp NPY_UNUSED(itemsize),
- NpyAuxData *data)
+_aligned_contig_to_contig_cast(
+ PyArrayMethod_Context *NPY_UNUSED(context), char * const*args,
+ const npy_intp *dimensions, const npy_intp *NPY_UNUSED(strides),
+ NpyAuxData *auxdata)
{
- _strided_cast_data *d = (_strided_cast_data *)data;
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+
+ _strided_cast_data *d = (_strided_cast_data *)auxdata;
npy_bool needs_api = d->needs_api;
d->castfunc(src, dst, N, d->aip, d->aop);
@@ -725,43 +717,6 @@ _aligned_contig_to_contig_cast(char *dst, npy_intp NPY_UNUSED(dst_stride),
return 0;
}
-static int
-get_nbo_cast_numeric_transfer_function(int aligned,
- npy_intp src_stride, npy_intp dst_stride,
- int src_type_num, int dst_type_num,
- PyArray_StridedUnaryOp **out_stransfer,
- NpyAuxData **out_transferdata)
-{
- /* Emit a warning if complex imaginary is being cast away */
- if (PyTypeNum_ISCOMPLEX(src_type_num) &&
- !PyTypeNum_ISCOMPLEX(dst_type_num) &&
- !PyTypeNum_ISBOOL(dst_type_num)) {
- static PyObject *cls = NULL;
- int ret;
- npy_cache_import("numpy.core", "ComplexWarning", &cls);
- if (cls == NULL) {
- return NPY_FAIL;
- }
- ret = PyErr_WarnEx(cls,
- "Casting complex values to real discards "
- "the imaginary part", 1);
- if (ret < 0) {
- return NPY_FAIL;
- }
- }
-
- *out_stransfer = PyArray_GetStridedNumericCastFn(aligned,
- src_stride, dst_stride,
- src_type_num, dst_type_num);
- *out_transferdata = NULL;
- if (*out_stransfer == NULL) {
- PyErr_SetString(PyExc_ValueError,
- "unexpected error in GetStridedNumericCastFn");
- return NPY_FAIL;
- }
-
- return NPY_SUCCEED;
-}
/*
* Does a datetime->datetime, timedelta->timedelta,
@@ -791,15 +746,15 @@ typedef struct {
static void _strided_datetime_cast_data_free(NpyAuxData *data)
{
_strided_datetime_cast_data *d = (_strided_datetime_cast_data *)data;
- PyArray_free(d->tmp_buffer);
- PyArray_free(data);
+ PyMem_Free(d->tmp_buffer);
+ PyMem_Free(data);
}
/* strided datetime cast data copy function */
static NpyAuxData *_strided_datetime_cast_data_clone(NpyAuxData *data)
{
_strided_datetime_cast_data *newdata =
- (_strided_datetime_cast_data *)PyArray_malloc(
+ (_strided_datetime_cast_data *)PyMem_Malloc(
sizeof(_strided_datetime_cast_data));
if (newdata == NULL) {
return NULL;
@@ -807,9 +762,9 @@ static NpyAuxData *_strided_datetime_cast_data_clone(NpyAuxData *data)
memcpy(newdata, data, sizeof(_strided_datetime_cast_data));
if (newdata->tmp_buffer != NULL) {
- newdata->tmp_buffer = PyArray_malloc(newdata->src_itemsize + 1);
+ newdata->tmp_buffer = PyMem_Malloc(newdata->src_itemsize + 1);
if (newdata->tmp_buffer == NULL) {
- PyArray_free(newdata);
+ PyMem_Free(newdata);
return NULL;
}
}
@@ -818,12 +773,16 @@ static NpyAuxData *_strided_datetime_cast_data_clone(NpyAuxData *data)
}
static int
-_strided_to_strided_datetime_general_cast(char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp src_itemsize,
- NpyAuxData *data)
+_strided_to_strided_datetime_general_cast(
+ PyArrayMethod_Context *NPY_UNUSED(context), char * const*args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *auxdata)
{
- _strided_datetime_cast_data *d = (_strided_datetime_cast_data *)data;
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+
+ _strided_datetime_cast_data *d = (_strided_datetime_cast_data *)auxdata;
npy_int64 dt;
npy_datetimestruct dts;
@@ -851,12 +810,16 @@ _strided_to_strided_datetime_general_cast(char *dst, npy_intp dst_stride,
}
static int
-_strided_to_strided_datetime_cast(char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp src_itemsize,
- NpyAuxData *data)
+_strided_to_strided_datetime_cast(
+ PyArrayMethod_Context *NPY_UNUSED(context), char * const*args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *auxdata)
{
- _strided_datetime_cast_data *d = (_strided_datetime_cast_data *)data;
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+
+ _strided_datetime_cast_data *d = (_strided_datetime_cast_data *)auxdata;
npy_int64 num = d->num, denom = d->denom;
npy_int64 dt;
@@ -883,13 +846,16 @@ _strided_to_strided_datetime_cast(char *dst, npy_intp dst_stride,
}
static int
-_aligned_strided_to_strided_datetime_cast(char *dst,
- npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp src_itemsize,
- NpyAuxData *data)
+_aligned_strided_to_strided_datetime_cast(
+ PyArrayMethod_Context *NPY_UNUSED(context), char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *auxdata)
{
- _strided_datetime_cast_data *d = (_strided_datetime_cast_data *)data;
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+
+ _strided_datetime_cast_data *d = (_strided_datetime_cast_data *)auxdata;
npy_int64 num = d->num, denom = d->denom;
npy_int64 dt;
@@ -916,12 +882,16 @@ _aligned_strided_to_strided_datetime_cast(char *dst,
}
static int
-_strided_to_strided_datetime_to_string(char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp NPY_UNUSED(src_itemsize),
- NpyAuxData *data)
+_strided_to_strided_datetime_to_string(
+ PyArrayMethod_Context *NPY_UNUSED(context), char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *auxdata)
{
- _strided_datetime_cast_data *d = (_strided_datetime_cast_data *)data;
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+
+ _strided_datetime_cast_data *d = (_strided_datetime_cast_data *)auxdata;
npy_intp dst_itemsize = d->dst_itemsize;
npy_int64 dt;
npy_datetimestruct dts;
@@ -951,12 +921,17 @@ _strided_to_strided_datetime_to_string(char *dst, npy_intp dst_stride,
}
static int
-_strided_to_strided_string_to_datetime(char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp src_itemsize,
- NpyAuxData *data)
+_strided_to_strided_string_to_datetime(
+ PyArrayMethod_Context *context, char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *auxdata)
{
- _strided_datetime_cast_data *d = (_strided_datetime_cast_data *)data;
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_itemsize = context->descriptors[0]->elsize;
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+
+ _strided_datetime_cast_data *d = (_strided_datetime_cast_data *)auxdata;
npy_datetimestruct dts;
char *tmp_buffer = d->tmp_buffer;
char *tmp;
@@ -1009,7 +984,7 @@ _strided_to_strided_string_to_datetime(char *dst, npy_intp dst_stride,
NPY_NO_EXPORT int
get_nbo_cast_datetime_transfer_function(int aligned,
PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
- PyArray_StridedUnaryOp **out_stransfer,
+ PyArrayMethod_StridedLoop **out_stransfer,
NpyAuxData **out_transferdata)
{
PyArray_DatetimeMetaData *src_meta, *dst_meta;
@@ -1032,7 +1007,7 @@ get_nbo_cast_datetime_transfer_function(int aligned,
}
/* Allocate the data for the casting */
- data = (_strided_datetime_cast_data *)PyArray_malloc(
+ data = (_strided_datetime_cast_data *)PyMem_Malloc(
sizeof(_strided_datetime_cast_data));
if (data == NULL) {
PyErr_NoMemory();
@@ -1084,7 +1059,7 @@ get_nbo_cast_datetime_transfer_function(int aligned,
NPY_NO_EXPORT int
get_nbo_datetime_to_string_transfer_function(
PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
- PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata)
+ PyArrayMethod_StridedLoop **out_stransfer, NpyAuxData **out_transferdata)
{
PyArray_DatetimeMetaData *src_meta;
_strided_datetime_cast_data *data;
@@ -1095,7 +1070,7 @@ get_nbo_datetime_to_string_transfer_function(
}
/* Allocate the data for the casting */
- data = (_strided_datetime_cast_data *)PyArray_malloc(
+ data = (_strided_datetime_cast_data *)PyMem_Malloc(
sizeof(_strided_datetime_cast_data));
if (data == NULL) {
PyErr_NoMemory();
@@ -1124,80 +1099,53 @@ get_nbo_datetime_to_string_transfer_function(
return NPY_SUCCEED;
}
+
NPY_NO_EXPORT int
get_datetime_to_unicode_transfer_function(int aligned,
npy_intp src_stride, npy_intp dst_stride,
PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
- PyArray_StridedUnaryOp **out_stransfer,
+ PyArrayMethod_StridedLoop **out_stransfer,
NpyAuxData **out_transferdata,
int *out_needs_api)
{
- NpyAuxData *castdata = NULL, *todata = NULL, *fromdata = NULL;
- PyArray_StridedUnaryOp *caststransfer, *tobuffer, *frombuffer;
PyArray_Descr *str_dtype;
/* Get an ASCII string data type, adapted to match the UNICODE one */
str_dtype = PyArray_DescrNewFromType(NPY_STRING);
- str_dtype->elsize = dst_dtype->elsize / 4;
if (str_dtype == NULL) {
return NPY_FAIL;
}
+ str_dtype->elsize = dst_dtype->elsize / 4;
- /* Get the copy/swap operation to dst */
- if (PyArray_GetDTypeCopySwapFn(aligned,
- src_stride, src_dtype->elsize,
- src_dtype,
- &tobuffer, &todata) != NPY_SUCCEED) {
- Py_DECREF(str_dtype);
- return NPY_FAIL;
- }
+ /* ensured in resolve_descriptors for simplicity */
+ assert(PyDataType_ISNOTSWAPPED(src_dtype));
/* Get the NBO datetime to string aligned contig function */
if (get_nbo_datetime_to_string_transfer_function(
src_dtype, str_dtype,
- &caststransfer, &castdata) != NPY_SUCCEED) {
+ out_stransfer, out_transferdata) != NPY_SUCCEED) {
Py_DECREF(str_dtype);
- NPY_AUXDATA_FREE(todata);
return NPY_FAIL;
}
- /* Get the cast operation to dst */
- if (PyArray_GetDTypeTransferFunction(aligned,
- str_dtype->elsize, dst_stride,
- str_dtype, dst_dtype,
- 0,
- &frombuffer, &fromdata,
- out_needs_api) != NPY_SUCCEED) {
- Py_DECREF(str_dtype);
- NPY_AUXDATA_FREE(todata);
- NPY_AUXDATA_FREE(castdata);
- return NPY_FAIL;
- }
-
- /* Wrap it all up in a new transfer function + data */
- if (wrap_aligned_contig_transfer_function(
- src_dtype->elsize, str_dtype->elsize,
- tobuffer, todata,
- frombuffer, fromdata,
- caststransfer, castdata,
- PyDataType_FLAGCHK(str_dtype, NPY_NEEDS_INIT),
- *out_needs_api,
- out_stransfer, out_transferdata) != NPY_SUCCEED) {
- NPY_AUXDATA_FREE(castdata);
- NPY_AUXDATA_FREE(todata);
- NPY_AUXDATA_FREE(fromdata);
+ int res = wrap_aligned_transferfunction(
+ aligned, 0, /* no need to ensure contiguous */
+ src_stride, dst_stride,
+ src_dtype, dst_dtype,
+ src_dtype, str_dtype,
+ out_stransfer, out_transferdata, out_needs_api);
+ Py_DECREF(str_dtype);
+ if (res < 0) {
return NPY_FAIL;
}
- Py_DECREF(str_dtype);
-
return NPY_SUCCEED;
}
NPY_NO_EXPORT int
get_nbo_string_to_datetime_transfer_function(
PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
- PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata)
+ PyArrayMethod_StridedLoop **out_stransfer, NpyAuxData **out_transferdata)
{
PyArray_DatetimeMetaData *dst_meta;
_strided_datetime_cast_data *data;
@@ -1208,7 +1156,7 @@ get_nbo_string_to_datetime_transfer_function(
}
/* Allocate the data for the casting */
- data = (_strided_datetime_cast_data *)PyArray_malloc(
+ data = (_strided_datetime_cast_data *)PyMem_Malloc(
sizeof(_strided_datetime_cast_data));
if (data == NULL) {
PyErr_NoMemory();
@@ -1219,10 +1167,10 @@ get_nbo_string_to_datetime_transfer_function(
data->base.free = &_strided_datetime_cast_data_free;
data->base.clone = &_strided_datetime_cast_data_clone;
data->src_itemsize = src_dtype->elsize;
- data->tmp_buffer = PyArray_malloc(data->src_itemsize + 1);
+ data->tmp_buffer = PyMem_Malloc(data->src_itemsize + 1);
if (data->tmp_buffer == NULL) {
PyErr_NoMemory();
- PyArray_free(data);
+ PyMem_Free(data);
*out_stransfer = NULL;
*out_transferdata = NULL;
return NPY_FAIL;
@@ -1248,12 +1196,10 @@ NPY_NO_EXPORT int
get_unicode_to_datetime_transfer_function(int aligned,
npy_intp src_stride, npy_intp dst_stride,
PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
- PyArray_StridedUnaryOp **out_stransfer,
+ PyArrayMethod_StridedLoop **out_stransfer,
NpyAuxData **out_transferdata,
int *out_needs_api)
{
- NpyAuxData *castdata = NULL, *todata = NULL, *fromdata = NULL;
- PyArray_StridedUnaryOp *caststransfer, *tobuffer, *frombuffer;
PyArray_Descr *str_dtype;
/* Get an ASCII string data type, adapted to match the UNICODE one */
@@ -1264,55 +1210,25 @@ get_unicode_to_datetime_transfer_function(int aligned,
assert(src_dtype->type_num == NPY_UNICODE);
str_dtype->elsize = src_dtype->elsize / 4;
- /* Get the cast operation from src */
- if (PyArray_GetDTypeTransferFunction(aligned,
- src_stride, str_dtype->elsize,
- src_dtype, str_dtype,
- 0,
- &tobuffer, &todata,
- out_needs_api) != NPY_SUCCEED) {
- Py_DECREF(str_dtype);
- return NPY_FAIL;
- }
-
- /* Get the string to NBO datetime aligned contig function */
+ /* Get the string to NBO datetime aligned function */
if (get_nbo_string_to_datetime_transfer_function(
str_dtype, dst_dtype,
- &caststransfer, &castdata) != NPY_SUCCEED) {
+ out_stransfer, out_transferdata) != NPY_SUCCEED) {
Py_DECREF(str_dtype);
- NPY_AUXDATA_FREE(todata);
return NPY_FAIL;
}
- /* Get the copy/swap operation to dst */
- if (PyArray_GetDTypeCopySwapFn(aligned,
- dst_dtype->elsize, dst_stride,
- dst_dtype,
- &frombuffer, &fromdata) != NPY_SUCCEED) {
- Py_DECREF(str_dtype);
- NPY_AUXDATA_FREE(todata);
- NPY_AUXDATA_FREE(castdata);
- return NPY_FAIL;
- }
+ int res = wrap_aligned_transferfunction(
+ aligned, 0, /* no need to ensure contiguous */
+ src_stride, dst_stride,
+ src_dtype, dst_dtype,
+ str_dtype, dst_dtype,
+ out_stransfer, out_transferdata, out_needs_api);
+ Py_DECREF(str_dtype);
- /* Wrap it all up in a new transfer function + data */
- if (wrap_aligned_contig_transfer_function(
- str_dtype->elsize, dst_dtype->elsize,
- tobuffer, todata,
- frombuffer, fromdata,
- caststransfer, castdata,
- PyDataType_FLAGCHK(dst_dtype, NPY_NEEDS_INIT),
- *out_needs_api,
- out_stransfer, out_transferdata) != NPY_SUCCEED) {
- Py_DECREF(str_dtype);
- NPY_AUXDATA_FREE(castdata);
- NPY_AUXDATA_FREE(todata);
- NPY_AUXDATA_FREE(fromdata);
+ if (res < 0) {
return NPY_FAIL;
}
-
- Py_DECREF(str_dtype);
-
return NPY_SUCCEED;
}
@@ -1322,7 +1238,7 @@ get_legacy_dtype_cast_function(
int aligned, npy_intp src_stride, npy_intp dst_stride,
PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
int move_references,
- PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata,
+ PyArrayMethod_StridedLoop **out_stransfer, NpyAuxData **out_transferdata,
int *out_needs_api, int *out_needs_wrap)
{
_strided_cast_data *data;
@@ -1374,7 +1290,7 @@ get_legacy_dtype_cast_function(
}
/* Allocate the data for the casting */
- data = (_strided_cast_data *)PyArray_malloc(sizeof(_strided_cast_data));
+ data = (_strided_cast_data *)PyMem_Malloc(sizeof(_strided_cast_data));
if (data == NULL) {
PyErr_NoMemory();
*out_stransfer = NULL;
@@ -1398,7 +1314,7 @@ get_legacy_dtype_cast_function(
else {
tmp_dtype = PyArray_DescrNewByteorder(src_dtype, NPY_NATIVE);
if (tmp_dtype == NULL) {
- PyArray_free(data);
+ PyMem_Free(data);
return NPY_FAIL;
}
}
@@ -1408,7 +1324,7 @@ get_legacy_dtype_cast_function(
0, NULL, NULL,
0, 1);
if (data->aip == NULL) {
- PyArray_free(data);
+ PyMem_Free(data);
return NPY_FAIL;
}
/*
@@ -1425,7 +1341,7 @@ get_legacy_dtype_cast_function(
tmp_dtype = PyArray_DescrNewByteorder(dst_dtype, NPY_NATIVE);
if (tmp_dtype == NULL) {
Py_DECREF(data->aip);
- PyArray_free(data);
+ PyMem_Free(data);
return NPY_FAIL;
}
}
@@ -1436,7 +1352,7 @@ get_legacy_dtype_cast_function(
0, 1);
if (data->aop == NULL) {
Py_DECREF(data->aip);
- PyArray_free(data);
+ PyMem_Free(data);
return NPY_FAIL;
}
@@ -1464,224 +1380,24 @@ get_legacy_dtype_cast_function(
}
-static int
-get_nbo_cast_transfer_function(int aligned,
- npy_intp src_stride, npy_intp dst_stride,
- PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
- int move_references,
- PyArray_StridedUnaryOp **out_stransfer,
- NpyAuxData **out_transferdata,
- int *out_needs_api,
- int *out_needs_wrap)
-{
- if (PyTypeNum_ISNUMBER(src_dtype->type_num) &&
- PyTypeNum_ISNUMBER(dst_dtype->type_num)) {
- *out_needs_wrap = !PyArray_ISNBO(src_dtype->byteorder) ||
- !PyArray_ISNBO(dst_dtype->byteorder);
- return get_nbo_cast_numeric_transfer_function(aligned,
- src_stride, dst_stride,
- src_dtype->type_num, dst_dtype->type_num,
- out_stransfer, out_transferdata);
- }
-
- if (src_dtype->type_num == NPY_DATETIME ||
- src_dtype->type_num == NPY_TIMEDELTA ||
- dst_dtype->type_num == NPY_DATETIME ||
- dst_dtype->type_num == NPY_TIMEDELTA) {
- /* A parameterized type, datetime->datetime sometimes needs casting */
- if ((src_dtype->type_num == NPY_DATETIME &&
- dst_dtype->type_num == NPY_DATETIME) ||
- (src_dtype->type_num == NPY_TIMEDELTA &&
- dst_dtype->type_num == NPY_TIMEDELTA)) {
- *out_needs_wrap = !PyArray_ISNBO(src_dtype->byteorder) ||
- !PyArray_ISNBO(dst_dtype->byteorder);
- return get_nbo_cast_datetime_transfer_function(aligned,
- src_dtype, dst_dtype,
- out_stransfer, out_transferdata);
- }
-
- /*
- * Datetime <-> string conversions can be handled specially.
- * The functions may raise an error if the strings have no
- * space, or can't be parsed properly.
- */
- if (src_dtype->type_num == NPY_DATETIME) {
- switch (dst_dtype->type_num) {
- case NPY_STRING:
- *out_needs_api = 1;
- *out_needs_wrap = !PyArray_ISNBO(src_dtype->byteorder);
- return get_nbo_datetime_to_string_transfer_function(
- src_dtype, dst_dtype,
- out_stransfer, out_transferdata);
-
- case NPY_UNICODE:
- return get_datetime_to_unicode_transfer_function(
- aligned,
- src_stride, dst_stride,
- src_dtype, dst_dtype,
- out_stransfer, out_transferdata,
- out_needs_api);
- }
- }
- else if (dst_dtype->type_num == NPY_DATETIME) {
- switch (src_dtype->type_num) {
- case NPY_STRING:
- *out_needs_api = 1;
- *out_needs_wrap = !PyArray_ISNBO(dst_dtype->byteorder);
- return get_nbo_string_to_datetime_transfer_function(
- src_dtype, dst_dtype,
- out_stransfer, out_transferdata);
-
- case NPY_UNICODE:
- return get_unicode_to_datetime_transfer_function(
- aligned,
- src_stride, dst_stride,
- src_dtype, dst_dtype,
- out_stransfer, out_transferdata,
- out_needs_api);
- }
- }
- }
-
- return get_legacy_dtype_cast_function(
- aligned, src_stride, dst_stride, src_dtype, dst_dtype,
- move_references, out_stransfer, out_transferdata,
- out_needs_api, out_needs_wrap);
-}
-
-
-NPY_NO_EXPORT int
-wrap_aligned_contig_transfer_function_with_copyswapn(
- int aligned, npy_intp src_stride, npy_intp dst_stride,
- PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
- PyArray_StridedUnaryOp **out_stransfer, NpyAuxData **out_transferdata,
- int *out_needs_api,
- PyArray_StridedUnaryOp *caststransfer, NpyAuxData *castdata)
-{
- NpyAuxData *todata = NULL, *fromdata = NULL;
- PyArray_StridedUnaryOp *tobuffer = NULL, *frombuffer = NULL;
- npy_intp src_itemsize = src_dtype->elsize;
- npy_intp dst_itemsize = dst_dtype->elsize;
-
- /* Get the copy/swap operation from src */
- PyArray_GetDTypeCopySwapFn(
- aligned, src_stride, src_itemsize, src_dtype, &tobuffer, &todata);
-
- if (!PyDataType_REFCHK(dst_dtype)) {
- /* Copying from buffer is a simple copy/swap operation */
- PyArray_GetDTypeCopySwapFn(
- aligned, dst_itemsize, dst_stride, dst_dtype,
- &frombuffer, &fromdata);
- }
- else {
- /*
- * Since the buffer is initialized to NULL, need to move the
- * references in order to DECREF the existing data.
- */
- /* Object types cannot be byte swapped */
- assert(PyDataType_ISNOTSWAPPED(dst_dtype));
- /* The loop already needs the python api if this is reached */
- assert(*out_needs_api);
-
- if (PyArray_GetDTypeTransferFunction(
- aligned, dst_itemsize, dst_stride,
- dst_dtype, dst_dtype, 1,
- &frombuffer, &fromdata, out_needs_api) != NPY_SUCCEED) {
- return NPY_FAIL;
- }
- }
-
- if (frombuffer == NULL || tobuffer == NULL) {
- NPY_AUXDATA_FREE(castdata);
- NPY_AUXDATA_FREE(todata);
- NPY_AUXDATA_FREE(fromdata);
- return NPY_FAIL;
- }
-
- *out_stransfer = caststransfer;
-
- /* Wrap it all up in a new transfer function + data */
- if (wrap_aligned_contig_transfer_function(
- src_itemsize, dst_itemsize,
- tobuffer, todata,
- frombuffer, fromdata,
- caststransfer, castdata,
- PyDataType_FLAGCHK(dst_dtype, NPY_NEEDS_INIT),
- *out_needs_api,
- out_stransfer, out_transferdata) != NPY_SUCCEED) {
- NPY_AUXDATA_FREE(castdata);
- NPY_AUXDATA_FREE(todata);
- NPY_AUXDATA_FREE(fromdata);
- return NPY_FAIL;
- }
-
- return NPY_SUCCEED;
-}
-
-
-static int
-get_cast_transfer_function(int aligned,
- npy_intp src_stride, npy_intp dst_stride,
- PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
- int move_references,
- PyArray_StridedUnaryOp **out_stransfer,
- NpyAuxData **out_transferdata,
- int *out_needs_api)
-{
- PyArray_StridedUnaryOp *caststransfer;
- NpyAuxData *castdata;
- int needs_wrap = 0;
-
- if (get_nbo_cast_transfer_function(aligned,
- src_stride, dst_stride,
- src_dtype, dst_dtype,
- move_references,
- &caststransfer,
- &castdata,
- out_needs_api,
- &needs_wrap) != NPY_SUCCEED) {
- return NPY_FAIL;
- }
-
- /*
- * If all native byte order and doesn't need alignment wrapping,
- * return the function
- */
- if (!needs_wrap) {
- *out_stransfer = caststransfer;
- *out_transferdata = castdata;
-
- return NPY_SUCCEED;
- }
- /* Otherwise, we have to copy and/or swap to aligned temporaries */
- else {
- return wrap_aligned_contig_transfer_function_with_copyswapn(
- aligned, src_stride, dst_stride, src_dtype, dst_dtype,
- out_stransfer, out_transferdata, out_needs_api,
- caststransfer, castdata);
- }
-}
-
/**************************** COPY 1 TO N CONTIGUOUS ************************/
/* Copies 1 element to N contiguous elements */
typedef struct {
NpyAuxData base;
- PyArray_StridedUnaryOp *stransfer;
- NpyAuxData *data;
- npy_intp N, dst_itemsize;
- /* If this is non-NULL the source type has references needing a decref */
- PyArray_StridedUnaryOp *stransfer_finish_src;
- NpyAuxData *data_finish_src;
+ npy_intp N;
+ NPY_cast_info wrapped;
+ /* If finish->func is non-NULL the source needs a decref */
+ NPY_cast_info decref_src;
} _one_to_n_data;
/* transfer data free function */
static void _one_to_n_data_free(NpyAuxData *data)
{
_one_to_n_data *d = (_one_to_n_data *)data;
- NPY_AUXDATA_FREE(d->data);
- NPY_AUXDATA_FREE(d->data_finish_src);
- PyArray_free(data);
+ NPY_cast_info_xfree(&d->wrapped);
+ NPY_cast_info_xfree(&d->decref_src);
+ PyMem_Free(data);
}
/* transfer data copy function */
@@ -1691,44 +1407,51 @@ static NpyAuxData *_one_to_n_data_clone(NpyAuxData *data)
_one_to_n_data *newdata;
/* Allocate the data, and populate it */
- newdata = (_one_to_n_data *)PyArray_malloc(sizeof(_one_to_n_data));
+ newdata = (_one_to_n_data *)PyMem_Malloc(sizeof(_one_to_n_data));
if (newdata == NULL) {
return NULL;
}
- memcpy(newdata, data, sizeof(_one_to_n_data));
- if (d->data != NULL) {
- newdata->data = NPY_AUXDATA_CLONE(d->data);
- if (newdata->data == NULL) {
- PyArray_free(newdata);
- return NULL;
- }
+ newdata->base.free = &_one_to_n_data_free;
+ newdata->base.clone = &_one_to_n_data_clone;
+ newdata->N = d->N;
+ /* Initialize in case of error, or if it is unused */
+ NPY_cast_info_init(&newdata->decref_src);
+
+ if (NPY_cast_info_copy(&newdata->wrapped, &d->wrapped) < 0) {
+ _one_to_n_data_free((NpyAuxData *)newdata);
+ return NULL;
}
- if (d->data_finish_src != NULL) {
- newdata->data_finish_src = NPY_AUXDATA_CLONE(d->data_finish_src);
- if (newdata->data_finish_src == NULL) {
- NPY_AUXDATA_FREE(newdata->data);
- PyArray_free(newdata);
- return NULL;
- }
+ if (d->decref_src.func == NULL) {
+ return (NpyAuxData *)newdata;
+ }
+
+ if (NPY_cast_info_copy(&newdata->decref_src, &d->decref_src) < 0) {
+ _one_to_n_data_free((NpyAuxData *)newdata);
+ return NULL;
}
return (NpyAuxData *)newdata;
}
static int
-_strided_to_strided_one_to_n(char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp src_itemsize,
- NpyAuxData *data)
+_strided_to_strided_one_to_n(
+ PyArrayMethod_Context *NPY_UNUSED(context), char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *auxdata)
{
- _one_to_n_data *d = (_one_to_n_data *)data;
- PyArray_StridedUnaryOp *subtransfer = d->stransfer;
- NpyAuxData *subdata = d->data;
- npy_intp subN = d->N, dst_itemsize = d->dst_itemsize;
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+
+ _one_to_n_data *d = (_one_to_n_data *)auxdata;
+
+ const npy_intp subN = d->N;
+ npy_intp sub_strides[2] = {0, d->wrapped.descriptors[1]->elsize};
while (N > 0) {
- if (subtransfer(
- dst, dst_itemsize, src, 0, subN, src_itemsize, subdata) < 0) {
+ char *sub_args[2] = {src, dst};
+ if (d->wrapped.func(&d->wrapped.context,
+ sub_args, &subN, sub_strides, d->wrapped.auxdata) < 0) {
return -1;
}
@@ -1740,25 +1463,30 @@ _strided_to_strided_one_to_n(char *dst, npy_intp dst_stride,
}
static int
-_strided_to_strided_one_to_n_with_finish(char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp src_itemsize,
- NpyAuxData *data)
+_strided_to_strided_one_to_n_with_finish(
+ PyArrayMethod_Context *NPY_UNUSED(context), char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *auxdata)
{
- _one_to_n_data *d = (_one_to_n_data *)data;
- PyArray_StridedUnaryOp *subtransfer = d->stransfer,
- *stransfer_finish_src = d->stransfer_finish_src;
- NpyAuxData *subdata = d->data, *data_finish_src = d->data_finish_src;
- npy_intp subN = d->N, dst_itemsize = d->dst_itemsize;
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+
+ _one_to_n_data *d = (_one_to_n_data *)auxdata;
+
+ const npy_intp subN = d->N;
+ const npy_intp one_item = 1, zero_stride = 0;
+ npy_intp sub_strides[2] = {0, d->wrapped.descriptors[1]->elsize};
while (N > 0) {
- if (subtransfer(
- dst, dst_itemsize, src, 0, subN, src_itemsize, subdata) < 0) {
+ char *sub_args[2] = {src, dst};
+ if (d->wrapped.func(&d->wrapped.context,
+ sub_args, &subN, sub_strides, d->wrapped.auxdata) < 0) {
return -1;
}
- if (stransfer_finish_src(
- NULL, 0, src, 0, 1, src_itemsize, data_finish_src) < 0) {
+ if (d->decref_src.func(&d->decref_src.context,
+ &src, &one_item, &zero_stride, d->decref_src.auxdata) < 0) {
return -1;
}
@@ -1769,27 +1497,18 @@ _strided_to_strided_one_to_n_with_finish(char *dst, npy_intp dst_stride,
return 0;
}
-/*
- * Wraps a transfer function to produce one that copies one element
- * of src to N contiguous elements of dst. If stransfer_finish_src is
- * not NULL, it should be a transfer function which just affects
- * src, for example to do a final DECREF operation for references.
- */
+
static int
-wrap_transfer_function_one_to_n(
- PyArray_StridedUnaryOp *stransfer_inner,
- NpyAuxData *data_inner,
- PyArray_StridedUnaryOp *stransfer_finish_src,
- NpyAuxData *data_finish_src,
- npy_intp dst_itemsize,
+get_one_to_n_transfer_function(int aligned,
+ npy_intp src_stride, npy_intp dst_stride,
+ PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
+ int move_references,
npy_intp N,
- PyArray_StridedUnaryOp **out_stransfer,
- NpyAuxData **out_transferdata)
+ PyArrayMethod_StridedLoop **out_stransfer,
+ NpyAuxData **out_transferdata,
+ int *out_needs_api)
{
- _one_to_n_data *data;
-
-
- data = PyArray_malloc(sizeof(_one_to_n_data));
+ _one_to_n_data *data = PyMem_Malloc(sizeof(_one_to_n_data));
if (data == NULL) {
PyErr_NoMemory();
return NPY_FAIL;
@@ -1797,36 +1516,8 @@ wrap_transfer_function_one_to_n(
data->base.free = &_one_to_n_data_free;
data->base.clone = &_one_to_n_data_clone;
- data->stransfer = stransfer_inner;
- data->data = data_inner;
- data->stransfer_finish_src = stransfer_finish_src;
- data->data_finish_src = data_finish_src;
data->N = N;
- data->dst_itemsize = dst_itemsize;
-
- if (stransfer_finish_src == NULL) {
- *out_stransfer = &_strided_to_strided_one_to_n;
- }
- else {
- *out_stransfer = &_strided_to_strided_one_to_n_with_finish;
- }
- *out_transferdata = (NpyAuxData *)data;
-
- return NPY_SUCCEED;
-}
-
-static int
-get_one_to_n_transfer_function(int aligned,
- npy_intp src_stride, npy_intp dst_stride,
- PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
- int move_references,
- npy_intp N,
- PyArray_StridedUnaryOp **out_stransfer,
- NpyAuxData **out_transferdata,
- int *out_needs_api)
-{
- PyArray_StridedUnaryOp *stransfer, *stransfer_finish_src = NULL;
- NpyAuxData *data, *data_finish_src = NULL;
+ NPY_cast_info_init(&data->decref_src); /* In case of error */
/*
* move_references is set to 0, handled in the wrapping transfer fn,
@@ -1838,33 +1529,31 @@ get_one_to_n_transfer_function(int aligned,
0, dst_dtype->elsize,
src_dtype, dst_dtype,
0,
- &stransfer, &data,
+ &data->wrapped,
out_needs_api) != NPY_SUCCEED) {
+ NPY_AUXDATA_FREE((NpyAuxData *)data);
return NPY_FAIL;
}
/* If the src object will need a DECREF, set src_dtype */
if (move_references && PyDataType_REFCHK(src_dtype)) {
- if (get_decsrcref_transfer_function(aligned,
+ if (get_decref_transfer_function(aligned,
src_stride,
src_dtype,
- &stransfer_finish_src,
- &data_finish_src,
+ &data->decref_src,
out_needs_api) != NPY_SUCCEED) {
- NPY_AUXDATA_FREE(data);
+ NPY_AUXDATA_FREE((NpyAuxData *)data);
return NPY_FAIL;
}
}
- if (wrap_transfer_function_one_to_n(stransfer, data,
- stransfer_finish_src, data_finish_src,
- dst_dtype->elsize,
- N,
- out_stransfer, out_transferdata) != NPY_SUCCEED) {
- NPY_AUXDATA_FREE(data);
- NPY_AUXDATA_FREE(data_finish_src);
- return NPY_FAIL;
+ if (data->decref_src.func == NULL) {
+ *out_stransfer = &_strided_to_strided_one_to_n;
}
+ else {
+ *out_stransfer = &_strided_to_strided_one_to_n_with_finish;
+ }
+ *out_transferdata = (NpyAuxData *)data;
return NPY_SUCCEED;
}
@@ -1874,17 +1563,17 @@ get_one_to_n_transfer_function(int aligned,
/* Copies N contiguous elements to N contiguous elements */
typedef struct {
NpyAuxData base;
- PyArray_StridedUnaryOp *stransfer;
- NpyAuxData *data;
- npy_intp N, src_itemsize, dst_itemsize;
+ NPY_cast_info wrapped;
+ npy_intp N;
+ npy_intp strides[2]; /* avoid look up on the dtype (dst can be NULL) */
} _n_to_n_data;
/* transfer data free function */
static void _n_to_n_data_free(NpyAuxData *data)
{
_n_to_n_data *d = (_n_to_n_data *)data;
- NPY_AUXDATA_FREE(d->data);
- PyArray_free(data);
+ NPY_cast_info_xfree(&d->wrapped);
+ PyMem_Free(data);
}
/* transfer data copy function */
@@ -1894,38 +1583,47 @@ static NpyAuxData *_n_to_n_data_clone(NpyAuxData *data)
_n_to_n_data *newdata;
/* Allocate the data, and populate it */
- newdata = (_n_to_n_data *)PyArray_malloc(sizeof(_n_to_n_data));
+ newdata = (_n_to_n_data *)PyMem_Malloc(sizeof(_n_to_n_data));
if (newdata == NULL) {
return NULL;
}
- memcpy(newdata, data, sizeof(_n_to_n_data));
- if (newdata->data != NULL) {
- newdata->data = NPY_AUXDATA_CLONE(d->data);
- if (newdata->data == NULL) {
- PyArray_free(newdata);
- return NULL;
- }
+ *newdata = *d;
+
+ if (NPY_cast_info_copy(&newdata->wrapped, &d->wrapped) < 0) {
+ _n_to_n_data_free((NpyAuxData *)newdata);
}
return (NpyAuxData *)newdata;
}
static int
-_strided_to_strided_n_to_n(char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp src_itemsize,
- NpyAuxData *data)
+_strided_to_strided_1_to_1(
+ PyArrayMethod_Context *NPY_UNUSED(context), char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *auxdata)
{
- _n_to_n_data *d = (_n_to_n_data *)data;
- PyArray_StridedUnaryOp *subtransfer = d->stransfer;
- NpyAuxData *subdata = d->data;
- npy_intp subN = d->N, src_subitemsize = d->src_itemsize,
- dst_subitemsize = d->dst_itemsize;
+ _n_to_n_data *d = (_n_to_n_data *)auxdata;
+ return d->wrapped.func(&d->wrapped.context,
+ args, dimensions, strides, d->wrapped.auxdata);
+}
+
+static int
+_strided_to_strided_n_to_n(
+ PyArrayMethod_Context *NPY_UNUSED(context), char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *auxdata)
+{
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+
+ _n_to_n_data *d = (_n_to_n_data *)auxdata;
+ npy_intp subN = d->N;
while (N > 0) {
- if (subtransfer(
- dst, dst_subitemsize, src, src_subitemsize,
- subN, src_subitemsize, subdata) < 0) {
+ char *sub_args[2] = {src, dst};
+ if (d->wrapped.func(&d->wrapped.context,
+ sub_args, &subN, d->strides, d->wrapped.auxdata) < 0) {
return -1;
}
src += src_stride;
@@ -1936,106 +1634,93 @@ _strided_to_strided_n_to_n(char *dst, npy_intp dst_stride,
}
static int
-_contig_to_contig_n_to_n(char *dst, npy_intp NPY_UNUSED(dst_stride),
- char *src, npy_intp NPY_UNUSED(src_stride),
- npy_intp N, npy_intp NPY_UNUSED(src_itemsize),
- NpyAuxData *data)
+_contig_to_contig_n_to_n(
+ PyArrayMethod_Context *NPY_UNUSED(context), char *const *args,
+ const npy_intp *dimensions, const npy_intp *NPY_UNUSED(strides),
+ NpyAuxData *auxdata)
{
- _n_to_n_data *d = (_n_to_n_data *)data;
- PyArray_StridedUnaryOp *subtransfer = d->stransfer;
- NpyAuxData *subdata = d->data;
- npy_intp subN = d->N, src_subitemsize = d->src_itemsize,
- dst_subitemsize = d->dst_itemsize;
-
- if (subtransfer(
- dst, dst_subitemsize, src, src_subitemsize,
- subN*N, src_subitemsize, subdata) < 0) {
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+
+ _n_to_n_data *d = (_n_to_n_data *)auxdata;
+ /* Make one large transfer including both outer and inner iteration: */
+ npy_intp subN = N * d->N;
+
+ char *sub_args[2] = {src, dst};
+ if (d->wrapped.func(&d->wrapped.context,
+ sub_args, &subN, d->strides, d->wrapped.auxdata) < 0) {
return -1;
}
return 0;
}
+
/*
- * Wraps a transfer function to produce one that copies N contiguous elements
- * of src to N contiguous elements of dst.
+ * Note that this function is currently both used for structured dtype
+ * casting as well as a decref function (with `dst_dtype == NULL`)
*/
static int
-wrap_transfer_function_n_to_n(
- PyArray_StridedUnaryOp *stransfer_inner,
- NpyAuxData *data_inner,
+get_n_to_n_transfer_function(int aligned,
npy_intp src_stride, npy_intp dst_stride,
- npy_intp src_itemsize, npy_intp dst_itemsize,
+ PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
+ int move_references,
npy_intp N,
- PyArray_StridedUnaryOp **out_stransfer,
- NpyAuxData **out_transferdata)
+ PyArrayMethod_StridedLoop **out_stransfer,
+ NpyAuxData **out_transferdata,
+ int *out_needs_api)
{
- _n_to_n_data *data;
-
- data = PyArray_malloc(sizeof(_n_to_n_data));
+ _n_to_n_data *data = PyMem_Malloc(sizeof(_n_to_n_data));
if (data == NULL) {
PyErr_NoMemory();
return NPY_FAIL;
}
-
data->base.free = &_n_to_n_data_free;
data->base.clone = &_n_to_n_data_clone;
- data->stransfer = stransfer_inner;
- data->data = data_inner;
data->N = N;
- data->src_itemsize = src_itemsize;
- data->dst_itemsize = dst_itemsize;
- /*
- * If the N subarray elements exactly fit in the strides,
- * then can do a faster contiguous transfer.
- */
- if (src_stride == N * src_itemsize &&
- dst_stride == N * dst_itemsize) {
- *out_stransfer = &_contig_to_contig_n_to_n;
- }
- else {
- *out_stransfer = &_strided_to_strided_n_to_n;
+ if (N != 1) {
+ /*
+ * If N == 1, we can use the original strides,
+ * otherwise fields are contiguous
+ */
+ src_stride = src_dtype->elsize;
+ dst_stride = dst_dtype != NULL ? dst_dtype->elsize : 0;
+ /* Store the wrapped strides for easier access */
+ data->strides[0] = src_stride;
+ data->strides[1] = dst_stride;
}
- *out_transferdata = (NpyAuxData *)data;
-
- return NPY_SUCCEED;
-}
-
-static int
-get_n_to_n_transfer_function(int aligned,
- npy_intp src_stride, npy_intp dst_stride,
- PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
- int move_references,
- npy_intp N,
- PyArray_StridedUnaryOp **out_stransfer,
- NpyAuxData **out_transferdata,
- int *out_needs_api)
-{
- PyArray_StridedUnaryOp *stransfer;
- NpyAuxData *data;
/*
* src_stride and dst_stride are set to contiguous, because
* subarrays are always contiguous.
*/
if (PyArray_GetDTypeTransferFunction(aligned,
- src_dtype->elsize, dst_dtype->elsize,
+ src_stride, dst_stride,
src_dtype, dst_dtype,
move_references,
- &stransfer, &data,
+ &data->wrapped,
out_needs_api) != NPY_SUCCEED) {
+ NPY_AUXDATA_FREE((NpyAuxData *)data);
return NPY_FAIL;
}
- if (wrap_transfer_function_n_to_n(stransfer, data,
- src_stride, dst_stride,
- src_dtype->elsize, dst_dtype->elsize,
- N,
- out_stransfer,
- out_transferdata) != NPY_SUCCEED) {
- NPY_AUXDATA_FREE(data);
- return NPY_FAIL;
+ if (N == 1) {
+ /*
+ * No need for wrapping, we can just copy directly. In principle
+ * this step could be optimized away entirely, but it requires
+ * replacing the context (to have the unpacked dtypes).
+ */
+ *out_stransfer = &_strided_to_strided_1_to_1;
+ }
+ else if (src_stride == N * src_stride &&
+ dst_stride == N * dst_stride) {
+ /* The subarrays can be coalesced (probably very rarely) */
+ *out_stransfer = &_contig_to_contig_n_to_n;
+ }
+ else {
+ *out_stransfer = &_strided_to_strided_n_to_n;
}
+ *out_transferdata = (NpyAuxData *)data;
return NPY_SUCCEED;
}
@@ -2049,16 +1734,13 @@ typedef struct {
/* Copies element with subarray broadcasting */
typedef struct {
NpyAuxData base;
- PyArray_StridedUnaryOp *stransfer;
- NpyAuxData *data;
- npy_intp src_N, dst_N, src_itemsize, dst_itemsize;
- PyArray_StridedUnaryOp *stransfer_decsrcref;
- NpyAuxData *data_decsrcref;
- PyArray_StridedUnaryOp *stransfer_decdstref;
- NpyAuxData *data_decdstref;
+ NPY_cast_info wrapped;
+ NPY_cast_info decref_src;
+ NPY_cast_info decref_dst; /* The use-case should probably be deprecated */
+ npy_intp src_N, dst_N;
/* This gets a run-length encoded representation of the transfer */
npy_intp run_count;
- _subarray_broadcast_offsetrun offsetruns;
+ _subarray_broadcast_offsetrun offsetruns[];
} _subarray_broadcast_data;
@@ -2066,49 +1748,48 @@ typedef struct {
static void _subarray_broadcast_data_free(NpyAuxData *data)
{
_subarray_broadcast_data *d = (_subarray_broadcast_data *)data;
- NPY_AUXDATA_FREE(d->data);
- NPY_AUXDATA_FREE(d->data_decsrcref);
- NPY_AUXDATA_FREE(d->data_decdstref);
- PyArray_free(data);
+ NPY_cast_info_xfree(&d->wrapped);
+ NPY_cast_info_xfree(&d->decref_src);
+ NPY_cast_info_xfree(&d->decref_dst);
+ PyMem_Free(data);
}
/* transfer data copy function */
-static NpyAuxData *_subarray_broadcast_data_clone( NpyAuxData *data)
+static NpyAuxData *_subarray_broadcast_data_clone(NpyAuxData *data)
{
_subarray_broadcast_data *d = (_subarray_broadcast_data *)data;
- _subarray_broadcast_data *newdata;
- npy_intp run_count = d->run_count, structsize;
- structsize = sizeof(_subarray_broadcast_data) +
- run_count*sizeof(_subarray_broadcast_offsetrun);
+ npy_intp offsetruns_size = d->run_count*sizeof(_subarray_broadcast_offsetrun);
+ npy_intp structsize = sizeof(_subarray_broadcast_data) + offsetruns_size;
/* Allocate the data and populate it */
- newdata = (_subarray_broadcast_data *)PyArray_malloc(structsize);
+ _subarray_broadcast_data *newdata = PyMem_Malloc(structsize);
if (newdata == NULL) {
return NULL;
}
- memcpy(newdata, data, structsize);
- if (d->data != NULL) {
- newdata->data = NPY_AUXDATA_CLONE(d->data);
- if (newdata->data == NULL) {
- PyArray_free(newdata);
- return NULL;
- }
+ newdata->base.free = &_subarray_broadcast_data_free;
+ newdata->base.clone = &_subarray_broadcast_data_clone;
+ newdata->src_N = d->src_N;
+ newdata->dst_N = d->dst_N;
+ newdata->run_count = d->run_count;
+ memcpy(newdata->offsetruns, d->offsetruns, offsetruns_size);
+
+ NPY_cast_info_init(&newdata->decref_src);
+ NPY_cast_info_init(&newdata->decref_dst);
+
+ if (NPY_cast_info_copy(&newdata->wrapped, &d->wrapped) < 0) {
+ _subarray_broadcast_data_free((NpyAuxData *)newdata);
+ return NULL;
}
- if (d->data_decsrcref != NULL) {
- newdata->data_decsrcref = NPY_AUXDATA_CLONE(d->data_decsrcref);
- if (newdata->data_decsrcref == NULL) {
- NPY_AUXDATA_FREE(newdata->data);
- PyArray_free(newdata);
+ if (d->decref_src.func != NULL) {
+ if (NPY_cast_info_copy(&newdata->decref_src, &d->decref_src) < 0) {
+ _subarray_broadcast_data_free((NpyAuxData *) newdata);
return NULL;
}
}
- if (d->data_decdstref != NULL) {
- newdata->data_decdstref = NPY_AUXDATA_CLONE(d->data_decdstref);
- if (newdata->data_decdstref == NULL) {
- NPY_AUXDATA_FREE(newdata->data);
- NPY_AUXDATA_FREE(newdata->data_decsrcref);
- PyArray_free(newdata);
+ if (d->decref_dst.func != NULL) {
+ if (NPY_cast_info_copy(&newdata->decref_dst, &d->decref_dst) < 0) {
+ _subarray_broadcast_data_free((NpyAuxData *) newdata);
return NULL;
}
}
@@ -2117,31 +1798,34 @@ static NpyAuxData *_subarray_broadcast_data_clone( NpyAuxData *data)
}
static int
-_strided_to_strided_subarray_broadcast(char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp NPY_UNUSED(src_itemsize),
- NpyAuxData *data)
+_strided_to_strided_subarray_broadcast(
+ PyArrayMethod_Context *NPY_UNUSED(context), char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *auxdata)
{
- _subarray_broadcast_data *d = (_subarray_broadcast_data *)data;
- PyArray_StridedUnaryOp *subtransfer = d->stransfer;
- NpyAuxData *subdata = d->data;
- npy_intp run, run_count = d->run_count,
- src_subitemsize = d->src_itemsize,
- dst_subitemsize = d->dst_itemsize;
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+
+ _subarray_broadcast_data *d = (_subarray_broadcast_data *)auxdata;
+ npy_intp run, run_count = d->run_count;
npy_intp loop_index, offset, count;
- char *dst_ptr;
- _subarray_broadcast_offsetrun *offsetruns = &d->offsetruns;
+
+ npy_intp src_subitemsize = d->wrapped.descriptors[0]->elsize;
+ npy_intp dst_subitemsize = d->wrapped.descriptors[1]->elsize;
+
+ npy_intp sub_strides[2] = {src_subitemsize, dst_subitemsize};
while (N > 0) {
loop_index = 0;
for (run = 0; run < run_count; ++run) {
- offset = offsetruns[run].offset;
- count = offsetruns[run].count;
- dst_ptr = dst + loop_index*dst_subitemsize;
+ offset = d->offsetruns[run].offset;
+ count = d->offsetruns[run].count;
+ char *dst_ptr = dst + loop_index*dst_subitemsize;
+ char *sub_args[2] = {src + offset, dst_ptr};
if (offset != -1) {
- if (subtransfer(
- dst_ptr, dst_subitemsize, src + offset, src_subitemsize,
- count, src_subitemsize, subdata) < 0) {
+ if (d->wrapped.func(&d->wrapped.context,
+ sub_args, &count, sub_strides, d->wrapped.auxdata) < 0) {
return -1;
}
}
@@ -2160,44 +1844,42 @@ _strided_to_strided_subarray_broadcast(char *dst, npy_intp dst_stride,
static int
-_strided_to_strided_subarray_broadcast_withrefs(char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp NPY_UNUSED(src_itemsize),
- NpyAuxData *data)
+_strided_to_strided_subarray_broadcast_withrefs(
+ PyArrayMethod_Context *NPY_UNUSED(context), char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *auxdata)
{
- _subarray_broadcast_data *d = (_subarray_broadcast_data *)data;
- PyArray_StridedUnaryOp *subtransfer = d->stransfer;
- NpyAuxData *subdata = d->data;
- PyArray_StridedUnaryOp *stransfer_decsrcref = d->stransfer_decsrcref;
- NpyAuxData *data_decsrcref = d->data_decsrcref;
- PyArray_StridedUnaryOp *stransfer_decdstref = d->stransfer_decdstref;
- NpyAuxData *data_decdstref = d->data_decdstref;
- npy_intp run, run_count = d->run_count,
- src_subitemsize = d->src_itemsize,
- dst_subitemsize = d->dst_itemsize,
- src_subN = d->src_N;
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+
+ _subarray_broadcast_data *d = (_subarray_broadcast_data *)auxdata;
+ npy_intp run, run_count = d->run_count;
npy_intp loop_index, offset, count;
- char *dst_ptr;
- _subarray_broadcast_offsetrun *offsetruns = &d->offsetruns;
+
+ npy_intp src_subitemsize = d->wrapped.descriptors[0]->elsize;
+ npy_intp dst_subitemsize = d->wrapped.descriptors[1]->elsize;
+
+ npy_intp sub_strides[2] = {src_subitemsize, dst_subitemsize};
while (N > 0) {
loop_index = 0;
for (run = 0; run < run_count; ++run) {
- offset = offsetruns[run].offset;
- count = offsetruns[run].count;
- dst_ptr = dst + loop_index*dst_subitemsize;
+ offset = d->offsetruns[run].offset;
+ count = d->offsetruns[run].count;
+ char *dst_ptr = dst + loop_index*dst_subitemsize;
+ char *sub_args[2] = {src + offset, dst_ptr};
if (offset != -1) {
- if (subtransfer(
- dst_ptr, dst_subitemsize, src + offset, src_subitemsize,
- count, src_subitemsize, subdata) < 0) {
+ if (d->wrapped.func(&d->wrapped.context,
+ sub_args, &count, sub_strides, d->wrapped.auxdata) < 0) {
return -1;
}
}
else {
- if (stransfer_decdstref != NULL) {
- if (stransfer_decdstref(
- NULL, 0, dst_ptr, dst_subitemsize,
- count, dst_subitemsize, data_decdstref) < 0) {
+ if (d->decref_dst.func != NULL) {
+ if (d->decref_dst.func(&d->decref_dst.context,
+ &dst_ptr, &count, &dst_subitemsize,
+ d->decref_dst.auxdata) < 0) {
return -1;
}
}
@@ -2206,10 +1888,10 @@ _strided_to_strided_subarray_broadcast_withrefs(char *dst, npy_intp dst_stride,
loop_index += count;
}
- if (stransfer_decsrcref != NULL) {
- if (stransfer_decsrcref(
- NULL, 0, src, src_subitemsize,
- src_subN, src_subitemsize, data_decsrcref) < 0) {
+ if (d->decref_src.func != NULL) {
+ if (d->decref_src.func(&d->decref_src.context,
+ &src, &d->src_N, &src_subitemsize,
+ d->decref_src.auxdata) < 0) {
return -1;
}
}
@@ -2229,24 +1911,30 @@ get_subarray_broadcast_transfer_function(int aligned,
npy_intp src_size, npy_intp dst_size,
PyArray_Dims src_shape, PyArray_Dims dst_shape,
int move_references,
- PyArray_StridedUnaryOp **out_stransfer,
+ PyArrayMethod_StridedLoop **out_stransfer,
NpyAuxData **out_transferdata,
int *out_needs_api)
{
_subarray_broadcast_data *data;
npy_intp structsize, loop_index, run, run_size,
src_index, dst_index, i, ndim;
- _subarray_broadcast_offsetrun *offsetruns;
structsize = sizeof(_subarray_broadcast_data) +
dst_size*sizeof(_subarray_broadcast_offsetrun);
/* Allocate the data and populate it */
- data = (_subarray_broadcast_data *)PyArray_malloc(structsize);
+ data = (_subarray_broadcast_data *)PyMem_Malloc(structsize);
if (data == NULL) {
PyErr_NoMemory();
return NPY_FAIL;
}
+ data->base.free = &_subarray_broadcast_data_free;
+ data->base.clone = &_subarray_broadcast_data_clone;
+ data->src_N = src_size;
+ data->dst_N = dst_size;
+
+ NPY_cast_info_init(&data->decref_src);
+ NPY_cast_info_init(&data->decref_dst);
/*
* move_references is set to 0, handled in the wrapping transfer fn,
@@ -2257,17 +1945,11 @@ get_subarray_broadcast_transfer_function(int aligned,
src_dtype->elsize, dst_dtype->elsize,
src_dtype, dst_dtype,
0,
- &data->stransfer, &data->data,
+ &data->wrapped,
out_needs_api) != NPY_SUCCEED) {
- PyArray_free(data);
+ NPY_AUXDATA_FREE((NpyAuxData *)data);
return NPY_FAIL;
}
- data->base.free = &_subarray_broadcast_data_free;
- data->base.clone = &_subarray_broadcast_data_clone;
- data->src_N = src_size;
- data->dst_N = dst_size;
- data->src_itemsize = src_dtype->elsize;
- data->dst_itemsize = dst_dtype->elsize;
/* If the src object will need a DECREF */
if (move_references && PyDataType_REFCHK(src_dtype)) {
@@ -2275,18 +1957,12 @@ get_subarray_broadcast_transfer_function(int aligned,
src_dtype->elsize, 0,
src_dtype, NULL,
1,
- &data->stransfer_decsrcref,
- &data->data_decsrcref,
+ &data->decref_src,
out_needs_api) != NPY_SUCCEED) {
- NPY_AUXDATA_FREE(data->data);
- PyArray_free(data);
+ NPY_AUXDATA_FREE((NpyAuxData *)data);
return NPY_FAIL;
}
}
- else {
- data->stransfer_decsrcref = NULL;
- data->data_decsrcref = NULL;
- }
/* If the dst object needs a DECREF to set it to NULL */
if (PyDataType_REFCHK(dst_dtype)) {
@@ -2294,22 +1970,15 @@ get_subarray_broadcast_transfer_function(int aligned,
dst_dtype->elsize, 0,
dst_dtype, NULL,
1,
- &data->stransfer_decdstref,
- &data->data_decdstref,
+ &data->decref_dst,
out_needs_api) != NPY_SUCCEED) {
- NPY_AUXDATA_FREE(data->data);
- NPY_AUXDATA_FREE(data->data_decsrcref);
- PyArray_free(data);
+ NPY_AUXDATA_FREE((NpyAuxData *)data);
return NPY_FAIL;
}
}
- else {
- data->stransfer_decdstref = NULL;
- data->data_decdstref = NULL;
- }
/* Calculate the broadcasting and set the offsets */
- offsetruns = &data->offsetruns;
+ _subarray_broadcast_offsetrun *offsetruns = data->offsetruns;
ndim = (src_shape.len > dst_shape.len) ? src_shape.len : dst_shape.len;
for (loop_index = 0; loop_index < dst_size; ++loop_index) {
npy_intp src_factor = 1;
@@ -2395,8 +2064,8 @@ get_subarray_broadcast_transfer_function(int aligned,
}
}
- if (data->stransfer_decsrcref == NULL &&
- data->stransfer_decdstref == NULL) {
+ if (data->decref_src.func == NULL &&
+ data->decref_dst.func == NULL) {
*out_stransfer = &_strided_to_strided_subarray_broadcast;
}
else {
@@ -2411,12 +2080,12 @@ get_subarray_broadcast_transfer_function(int aligned,
* Handles subarray transfer. To call this, at least one of the dtype's
* subarrays must be non-NULL
*/
-static int
+NPY_NO_EXPORT int
get_subarray_transfer_function(int aligned,
npy_intp src_stride, npy_intp dst_stride,
PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
int move_references,
- PyArray_StridedUnaryOp **out_stransfer,
+ PyArrayMethod_StridedLoop **out_stransfer,
NpyAuxData **out_transferdata,
int *out_needs_api)
{
@@ -2447,46 +2116,36 @@ get_subarray_transfer_function(int aligned,
}
/*
- * Just a straight one-element copy.
+ * Copy the src value to all the dst values, the size one can be
+ * special cased for speed.
*/
- if (dst_size == 1 && src_size == 1) {
- npy_free_cache_dim_obj(src_shape);
- npy_free_cache_dim_obj(dst_shape);
+ if ((dst_size == 1 && src_size == 1) || (
+ src_shape.len == dst_shape.len && PyArray_CompareLists(
+ src_shape.ptr, dst_shape.ptr, src_shape.len))) {
- return PyArray_GetDTypeTransferFunction(aligned,
- src_stride, dst_stride,
- src_dtype, dst_dtype,
- move_references,
- out_stransfer, out_transferdata,
- out_needs_api);
- }
- /* Copy the src value to all the dst values */
- else if (src_size == 1) {
npy_free_cache_dim_obj(src_shape);
npy_free_cache_dim_obj(dst_shape);
- return get_one_to_n_transfer_function(aligned,
+ return get_n_to_n_transfer_function(aligned,
src_stride, dst_stride,
src_dtype, dst_dtype,
move_references,
- dst_size,
+ src_size,
out_stransfer, out_transferdata,
out_needs_api);
}
- /* If the shapes match exactly, do an n to n copy */
- else if (src_shape.len == dst_shape.len &&
- PyArray_CompareLists(src_shape.ptr, dst_shape.ptr,
- src_shape.len)) {
+ /* Copy the src value to all the dst values */
+ else if (src_size == 1) {
npy_free_cache_dim_obj(src_shape);
npy_free_cache_dim_obj(dst_shape);
- return get_n_to_n_transfer_function(aligned,
- src_stride, dst_stride,
- src_dtype, dst_dtype,
- move_references,
- src_size,
- out_stransfer, out_transferdata,
- out_needs_api);
+ return get_one_to_n_transfer_function(aligned,
+ src_stride, dst_stride,
+ src_dtype, dst_dtype,
+ move_references,
+ dst_size,
+ out_stransfer, out_transferdata,
+ out_needs_api);
}
/*
* Copy the subarray with broadcasting, truncating, and zero-padding
@@ -2510,91 +2169,82 @@ get_subarray_transfer_function(int aligned,
/**************************** COPY FIELDS *******************************/
typedef struct {
- npy_intp src_offset, dst_offset, src_itemsize;
- PyArray_StridedUnaryOp *stransfer;
- NpyAuxData *data;
+ npy_intp src_offset, dst_offset;
+ NPY_cast_info info;
} _single_field_transfer;
typedef struct {
NpyAuxData base;
npy_intp field_count;
-
- _single_field_transfer fields;
+ _single_field_transfer fields[];
} _field_transfer_data;
+
/* transfer data free function */
static void _field_transfer_data_free(NpyAuxData *data)
{
_field_transfer_data *d = (_field_transfer_data *)data;
- npy_intp i, field_count;
- _single_field_transfer *fields;
-
- field_count = d->field_count;
- fields = &d->fields;
- for (i = 0; i < field_count; ++i) {
- NPY_AUXDATA_FREE(fields[i].data);
+ for (npy_intp i = 0; i < d->field_count; ++i) {
+ NPY_cast_info_xfree(&d->fields[i].info);
}
- PyArray_free(d);
+ PyMem_Free(d);
}
/* transfer data copy function */
static NpyAuxData *_field_transfer_data_clone(NpyAuxData *data)
{
_field_transfer_data *d = (_field_transfer_data *)data;
- _field_transfer_data *newdata;
- npy_intp i, field_count = d->field_count, structsize;
- _single_field_transfer *fields, *newfields;
- structsize = sizeof(_field_transfer_data) +
+ npy_intp field_count = d->field_count;
+ npy_intp structsize = sizeof(_field_transfer_data) +
field_count * sizeof(_single_field_transfer);
/* Allocate the data and populate it */
- newdata = (_field_transfer_data *)PyArray_malloc(structsize);
+ _field_transfer_data *newdata = PyMem_Malloc(structsize);
if (newdata == NULL) {
return NULL;
}
- memcpy(newdata, d, structsize);
+ newdata->base = d->base;
+ newdata->field_count = 0;
+
/* Copy all the fields transfer data */
- fields = &d->fields;
- newfields = &newdata->fields;
- for (i = 0; i < field_count; ++i) {
- if (fields[i].data != NULL) {
- newfields[i].data = NPY_AUXDATA_CLONE(fields[i].data);
- if (newfields[i].data == NULL) {
- for (i = i-1; i >= 0; --i) {
- NPY_AUXDATA_FREE(newfields[i].data);
- }
- PyArray_free(newdata);
- return NULL;
- }
+ for (npy_intp i = 0; i < field_count; ++i) {
+ if (NPY_cast_info_copy(&newdata->fields[i].info, &d->fields[i].info) < 0) {
+ NPY_AUXDATA_FREE((NpyAuxData *)newdata);
+ return NULL;
}
-
+ newdata->fields[i].src_offset = d->fields[i].src_offset;
+ newdata->fields[i].dst_offset = d->fields[i].dst_offset;
+ newdata->field_count++;
}
return (NpyAuxData *)newdata;
}
+
static int
-_strided_to_strided_field_transfer(char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp NPY_UNUSED(src_itemsize),
- NpyAuxData *data)
+_strided_to_strided_field_transfer(
+ PyArrayMethod_Context *NPY_UNUSED(context), char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *auxdata)
{
- _field_transfer_data *d = (_field_transfer_data *)data;
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+
+ _field_transfer_data *d = (_field_transfer_data *)auxdata;
npy_intp i, field_count = d->field_count;
- _single_field_transfer *field;
+ const npy_intp blocksize = NPY_LOWLEVEL_BUFFER_BLOCKSIZE;
/* Do the transfer a block at a time */
for (;;) {
- field = &d->fields;
- if (N > NPY_LOWLEVEL_BUFFER_BLOCKSIZE) {
- for (i = 0; i < field_count; ++i, ++field) {
- if (field->stransfer(
- dst + field->dst_offset, dst_stride,
- src + field->src_offset, src_stride,
- NPY_LOWLEVEL_BUFFER_BLOCKSIZE,
- field->src_itemsize, field->data) < 0) {
+ if (N > blocksize) {
+ for (i = 0; i < field_count; ++i) {
+ _single_field_transfer field = d->fields[i];
+ char *fargs[2] = {src + field.src_offset, dst + field.dst_offset};
+ if (field.info.func(&field.info.context,
+ fargs, &blocksize, strides, field.info.auxdata) < 0) {
return -1;
}
}
@@ -2603,12 +2253,11 @@ _strided_to_strided_field_transfer(char *dst, npy_intp dst_stride,
dst += NPY_LOWLEVEL_BUFFER_BLOCKSIZE*dst_stride;
}
else {
- for (i = 0; i < field_count; ++i, ++field) {
- if (field->stransfer(
- dst + field->dst_offset, dst_stride,
- src + field->src_offset, src_stride,
- N,
- field->src_itemsize, field->data) < 0) {
+ for (i = 0; i < field_count; ++i) {
+ _single_field_transfer field = d->fields[i];
+ char *fargs[2] = {src + field.src_offset, dst + field.dst_offset};
+ if (field.info.func(&field.info.context,
+ fargs, &N, strides, field.info.auxdata) < 0) {
return -1;
}
}
@@ -2621,22 +2270,22 @@ _strided_to_strided_field_transfer(char *dst, npy_intp dst_stride,
* Handles fields transfer. To call this, at least one of the dtypes
* must have fields. Does not take care of object<->structure conversion
*/
-static int
-get_fields_transfer_function(int aligned,
+NPY_NO_EXPORT int
+get_fields_transfer_function(int NPY_UNUSED(aligned),
npy_intp src_stride, npy_intp dst_stride,
PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
int move_references,
- PyArray_StridedUnaryOp **out_stransfer,
+ PyArrayMethod_StridedLoop **out_stransfer,
NpyAuxData **out_transferdata,
int *out_needs_api)
{
PyObject *key, *tup, *title;
PyArray_Descr *src_fld_dtype, *dst_fld_dtype;
- npy_int i, field_count, structsize;
+ npy_int i;
+ size_t structsize;
+ Py_ssize_t field_count;
int src_offset, dst_offset;
_field_transfer_data *data;
- _single_field_transfer *fields;
- int failed = 0;
/*
* There are three cases to take care of: 1. src is non-structured,
@@ -2650,64 +2299,55 @@ get_fields_transfer_function(int aligned,
/* Allocate the field-data structure and populate it */
structsize = sizeof(_field_transfer_data) +
(field_count + 1) * sizeof(_single_field_transfer);
- data = (_field_transfer_data *)PyArray_malloc(structsize);
+ data = PyMem_Malloc(structsize);
if (data == NULL) {
PyErr_NoMemory();
return NPY_FAIL;
}
data->base.free = &_field_transfer_data_free;
data->base.clone = &_field_transfer_data_clone;
- fields = &data->fields;
+ data->field_count = 0;
for (i = 0; i < field_count; ++i) {
key = PyTuple_GET_ITEM(dst_dtype->names, i);
tup = PyDict_GetItem(dst_dtype->fields, key);
if (!PyArg_ParseTuple(tup, "Oi|O", &dst_fld_dtype,
&dst_offset, &title)) {
- PyArray_free(data);
+ PyMem_Free(data);
return NPY_FAIL;
}
if (PyArray_GetDTypeTransferFunction(0,
src_stride, dst_stride,
src_dtype, dst_fld_dtype,
0,
- &fields[i].stransfer,
- &fields[i].data,
+ &data->fields[i].info,
out_needs_api) != NPY_SUCCEED) {
- for (i = i-1; i >= 0; --i) {
- NPY_AUXDATA_FREE(fields[i].data);
- }
- PyArray_free(data);
+ NPY_AUXDATA_FREE((NpyAuxData *)data);
return NPY_FAIL;
}
- fields[i].src_offset = 0;
- fields[i].dst_offset = dst_offset;
- fields[i].src_itemsize = src_dtype->elsize;
+ data->fields[i].src_offset = 0;
+ data->fields[i].dst_offset = dst_offset;
+ data->field_count++;
}
/*
- * If references should be decrefd in src, add
- * another transfer function to do that.
+ * If references should be decrefd in src, add another transfer
+ * function to do that. Since a decref function only uses a single
+ * input, the second one (normally output) just does not matter here.
*/
if (move_references && PyDataType_REFCHK(src_dtype)) {
- if (get_decsrcref_transfer_function(0,
+ if (get_decref_transfer_function(0,
src_stride,
src_dtype,
- &fields[field_count].stransfer,
- &fields[field_count].data,
+ &data->fields[field_count].info,
out_needs_api) != NPY_SUCCEED) {
- for (i = 0; i < field_count; ++i) {
- NPY_AUXDATA_FREE(fields[i].data);
- }
- PyArray_free(data);
+ NPY_AUXDATA_FREE((NpyAuxData *)data);
return NPY_FAIL;
}
- fields[field_count].src_offset = 0;
- fields[field_count].dst_offset = 0;
- fields[field_count].src_itemsize = src_dtype->elsize;
- field_count++;
+ data->fields[field_count].src_offset = 0;
+ data->fields[field_count].dst_offset = 0;
+ data->field_count = field_count;
}
- data->field_count = field_count;
*out_stransfer = &_strided_to_strided_field_transfer;
*out_transferdata = (NpyAuxData *)data;
@@ -2727,19 +2367,19 @@ get_fields_transfer_function(int aligned,
/* Allocate the field-data structure and populate it */
structsize = sizeof(_field_transfer_data) +
1 * sizeof(_single_field_transfer);
- data = (_field_transfer_data *)PyArray_malloc(structsize);
+ data = PyMem_Malloc(structsize);
if (data == NULL) {
PyErr_NoMemory();
return NPY_FAIL;
}
data->base.free = &_field_transfer_data_free;
data->base.clone = &_field_transfer_data_clone;
- fields = &data->fields;
key = PyTuple_GET_ITEM(src_dtype->names, 0);
tup = PyDict_GetItem(src_dtype->fields, key);
if (!PyArg_ParseTuple(tup, "Oi|O",
&src_fld_dtype, &src_offset, &title)) {
+ PyMem_Free(data);
return NPY_FAIL;
}
@@ -2747,16 +2387,13 @@ get_fields_transfer_function(int aligned,
src_stride, dst_stride,
src_fld_dtype, dst_dtype,
move_references,
- &fields[0].stransfer,
- &fields[0].data,
+ &data->fields[0].info,
out_needs_api) != NPY_SUCCEED) {
- PyArray_free(data);
+ PyMem_Free(data);
return NPY_FAIL;
}
- fields[0].src_offset = src_offset;
- fields[0].dst_offset = 0;
- fields[0].src_itemsize = src_fld_dtype->elsize;
-
+ data->fields[0].src_offset = src_offset;
+ data->fields[0].dst_offset = 0;
data->field_count = 1;
*out_stransfer = &_strided_to_strided_field_transfer;
@@ -2777,14 +2414,14 @@ get_fields_transfer_function(int aligned,
/* Allocate the field-data structure and populate it */
structsize = sizeof(_field_transfer_data) +
field_count * sizeof(_single_field_transfer);
- data = (_field_transfer_data *)PyArray_malloc(structsize);
+ data = PyMem_Malloc(structsize);
if (data == NULL) {
PyErr_NoMemory();
return NPY_FAIL;
}
data->base.free = &_field_transfer_data_free;
data->base.clone = &_field_transfer_data_clone;
- fields = &data->fields;
+ data->field_count = 0;
/* set up the transfer function for each field */
for (i = 0; i < field_count; ++i) {
@@ -2792,42 +2429,31 @@ get_fields_transfer_function(int aligned,
tup = PyDict_GetItem(dst_dtype->fields, key);
if (!PyArg_ParseTuple(tup, "Oi|O", &dst_fld_dtype,
&dst_offset, &title)) {
- failed = 1;
- break;
+ NPY_AUXDATA_FREE((NpyAuxData *)data);
+ return NPY_FAIL;
}
key = PyTuple_GET_ITEM(src_dtype->names, i);
tup = PyDict_GetItem(src_dtype->fields, key);
if (!PyArg_ParseTuple(tup, "Oi|O", &src_fld_dtype,
&src_offset, &title)) {
- failed = 1;
- break;
+ NPY_AUXDATA_FREE((NpyAuxData *)data);
+ return NPY_FAIL;
}
if (PyArray_GetDTypeTransferFunction(0,
src_stride, dst_stride,
src_fld_dtype, dst_fld_dtype,
move_references,
- &fields[i].stransfer,
- &fields[i].data,
+ &data->fields[i].info,
out_needs_api) != NPY_SUCCEED) {
- failed = 1;
- break;
- }
- fields[i].src_offset = src_offset;
- fields[i].dst_offset = dst_offset;
- fields[i].src_itemsize = src_fld_dtype->elsize;
- }
-
- if (failed) {
- for (i = i-1; i >= 0; --i) {
- NPY_AUXDATA_FREE(fields[i].data);
+ NPY_AUXDATA_FREE((NpyAuxData *)data);
+ return NPY_FAIL;
}
- PyArray_free(data);
- return NPY_FAIL;
+ data->fields[i].src_offset = src_offset;
+ data->fields[i].dst_offset = dst_offset;
+ data->field_count++;
}
- data->field_count = field_count;
-
*out_stransfer = &_strided_to_strided_field_transfer;
*out_transferdata = (NpyAuxData *)data;
@@ -2835,190 +2461,110 @@ get_fields_transfer_function(int aligned,
}
static int
-get_decsrcref_fields_transfer_function(int aligned,
+get_decref_fields_transfer_function(int NPY_UNUSED(aligned),
npy_intp src_stride,
PyArray_Descr *src_dtype,
- PyArray_StridedUnaryOp **out_stransfer,
+ PyArrayMethod_StridedLoop **out_stransfer,
NpyAuxData **out_transferdata,
int *out_needs_api)
{
PyObject *names, *key, *tup, *title;
PyArray_Descr *src_fld_dtype;
- npy_int i, names_size, field_count, structsize;
+ npy_int i, structsize;
+ Py_ssize_t field_count;
int src_offset;
- _field_transfer_data *data;
- _single_field_transfer *fields;
names = src_dtype->names;
- names_size = PyTuple_GET_SIZE(src_dtype->names);
+ field_count = PyTuple_GET_SIZE(src_dtype->names);
- field_count = names_size;
+ /* Over-allocating here: less fields may be used */
structsize = sizeof(_field_transfer_data) +
field_count * sizeof(_single_field_transfer);
/* Allocate the data and populate it */
- data = (_field_transfer_data *)PyArray_malloc(structsize);
+ _field_transfer_data *data = PyMem_Malloc(structsize);
if (data == NULL) {
PyErr_NoMemory();
return NPY_FAIL;
}
data->base.free = &_field_transfer_data_free;
data->base.clone = &_field_transfer_data_clone;
- fields = &data->fields;
+ data->field_count = 0;
- field_count = 0;
- for (i = 0; i < names_size; ++i) {
+ _single_field_transfer *field = data->fields;
+ for (i = 0; i < field_count; ++i) {
key = PyTuple_GET_ITEM(names, i);
tup = PyDict_GetItem(src_dtype->fields, key);
if (!PyArg_ParseTuple(tup, "Oi|O", &src_fld_dtype,
&src_offset, &title)) {
- PyArray_free(data);
+ NPY_AUXDATA_FREE((NpyAuxData *)data);
return NPY_FAIL;
}
if (PyDataType_REFCHK(src_fld_dtype)) {
if (out_needs_api) {
*out_needs_api = 1;
}
- if (get_decsrcref_transfer_function(0,
+ if (get_decref_transfer_function(0,
src_stride,
src_fld_dtype,
- &fields[field_count].stransfer,
- &fields[field_count].data,
+ &field->info,
out_needs_api) != NPY_SUCCEED) {
- for (i = field_count-1; i >= 0; --i) {
- NPY_AUXDATA_FREE(fields[i].data);
- }
- PyArray_free(data);
+ NPY_AUXDATA_FREE((NpyAuxData *)data);
return NPY_FAIL;
}
- fields[field_count].src_offset = src_offset;
- fields[field_count].dst_offset = 0;
- fields[field_count].src_itemsize = src_dtype->elsize;
- field_count++;
+ field->src_offset = src_offset;
+ data->field_count++;
+ field++;
}
}
- data->field_count = field_count;
-
*out_stransfer = &_strided_to_strided_field_transfer;
*out_transferdata = (NpyAuxData *)data;
return NPY_SUCCEED;
}
-static int
-get_setdestzero_fields_transfer_function(int aligned,
- npy_intp dst_stride,
- PyArray_Descr *dst_dtype,
- PyArray_StridedUnaryOp **out_stransfer,
- NpyAuxData **out_transferdata,
- int *out_needs_api)
-{
- PyObject *names, *key, *tup, *title;
- PyArray_Descr *dst_fld_dtype;
- npy_int i, names_size, field_count, structsize;
- int dst_offset;
- _field_transfer_data *data;
- _single_field_transfer *fields;
-
- names = dst_dtype->names;
- names_size = PyTuple_GET_SIZE(dst_dtype->names);
-
- field_count = names_size;
- structsize = sizeof(_field_transfer_data) +
- field_count * sizeof(_single_field_transfer);
- /* Allocate the data and populate it */
- data = (_field_transfer_data *)PyArray_malloc(structsize);
- if (data == NULL) {
- PyErr_NoMemory();
- return NPY_FAIL;
- }
- data->base.free = &_field_transfer_data_free;
- data->base.clone = &_field_transfer_data_clone;
- fields = &data->fields;
-
- for (i = 0; i < names_size; ++i) {
- key = PyTuple_GET_ITEM(names, i);
- tup = PyDict_GetItem(dst_dtype->fields, key);
- if (!PyArg_ParseTuple(tup, "Oi|O", &dst_fld_dtype,
- &dst_offset, &title)) {
- PyArray_free(data);
- return NPY_FAIL;
- }
- if (get_setdstzero_transfer_function(0,
- dst_stride,
- dst_fld_dtype,
- &fields[i].stransfer,
- &fields[i].data,
- out_needs_api) != NPY_SUCCEED) {
- for (i = i-1; i >= 0; --i) {
- NPY_AUXDATA_FREE(fields[i].data);
- }
- PyArray_free(data);
- return NPY_FAIL;
- }
- fields[i].src_offset = 0;
- fields[i].dst_offset = dst_offset;
- fields[i].src_itemsize = 0;
- }
-
- data->field_count = field_count;
-
- *out_stransfer = &_strided_to_strided_field_transfer;
- *out_transferdata = (NpyAuxData *)data;
-
- return NPY_SUCCEED;
-}
/************************* MASKED TRANSFER WRAPPER *************************/
typedef struct {
NpyAuxData base;
- /* The transfer function being wrapped */
- PyArray_StridedUnaryOp *stransfer;
- NpyAuxData *transferdata;
-
+ /* The transfer function being wrapped (could likely be stored directly) */
+ NPY_cast_info wrapped;
/* The src decref function if necessary */
- PyArray_StridedUnaryOp *decsrcref_stransfer;
- NpyAuxData *decsrcref_transferdata;
+ NPY_cast_info decref_src;
} _masked_wrapper_transfer_data;
/* transfer data free function */
-static void _masked_wrapper_transfer_data_free(NpyAuxData *data)
+static void
+_masked_wrapper_transfer_data_free(NpyAuxData *data)
{
_masked_wrapper_transfer_data *d = (_masked_wrapper_transfer_data *)data;
- NPY_AUXDATA_FREE(d->transferdata);
- NPY_AUXDATA_FREE(d->decsrcref_transferdata);
- PyArray_free(data);
+ NPY_cast_info_xfree(&d->wrapped);
+ NPY_cast_info_xfree(&d->decref_src);
+ PyMem_Free(data);
}
/* transfer data copy function */
-static NpyAuxData *_masked_wrapper_transfer_data_clone(NpyAuxData *data)
+static NpyAuxData *
+_masked_wrapper_transfer_data_clone(NpyAuxData *data)
{
_masked_wrapper_transfer_data *d = (_masked_wrapper_transfer_data *)data;
_masked_wrapper_transfer_data *newdata;
/* Allocate the data and populate it */
- newdata = (_masked_wrapper_transfer_data *)PyArray_malloc(
- sizeof(_masked_wrapper_transfer_data));
+ newdata = PyMem_Malloc(sizeof(*newdata));
if (newdata == NULL) {
return NULL;
}
- memcpy(newdata, d, sizeof(_masked_wrapper_transfer_data));
+ newdata->base = d->base;
- /* Clone all the owned auxdata as well */
- if (newdata->transferdata != NULL) {
- newdata->transferdata = NPY_AUXDATA_CLONE(newdata->transferdata);
- if (newdata->transferdata == NULL) {
- PyArray_free(newdata);
- return NULL;
- }
+ if (NPY_cast_info_copy(&newdata->wrapped, &d->wrapped) < 0) {
+ PyMem_Free(newdata);
+ return NULL;
}
- if (newdata->decsrcref_transferdata != NULL) {
- newdata->decsrcref_transferdata =
- NPY_AUXDATA_CLONE(newdata->decsrcref_transferdata);
- if (newdata->decsrcref_transferdata == NULL) {
- NPY_AUXDATA_FREE(newdata->transferdata);
- PyArray_free(newdata);
+ if (d->decref_src.func != NULL) {
+ if (NPY_cast_info_copy(&newdata->decref_src, &d->decref_src) < 0) {
+ NPY_AUXDATA_FREE((NpyAuxData *)newdata);
return NULL;
}
}
@@ -3027,31 +2573,25 @@ static NpyAuxData *_masked_wrapper_transfer_data_clone(NpyAuxData *data)
}
static int
-_strided_masked_wrapper_decsrcref_transfer_function(
- char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_bool *mask, npy_intp mask_stride,
- npy_intp N, npy_intp src_itemsize,
- NpyAuxData *transferdata)
+_strided_masked_wrapper_decref_transfer_function(
+ PyArrayMethod_Context *NPY_UNUSED(context), char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ npy_bool *mask, npy_intp mask_stride,
+ NpyAuxData *auxdata)
{
- _masked_wrapper_transfer_data *d =
- (_masked_wrapper_transfer_data *)transferdata;
- npy_intp subloopsize;
- PyArray_StridedUnaryOp *unmasked_stransfer, *decsrcref_stransfer;
- NpyAuxData *unmasked_transferdata, *decsrcref_transferdata;
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
- unmasked_stransfer = d->stransfer;
- unmasked_transferdata = d->transferdata;
- decsrcref_stransfer = d->decsrcref_stransfer;
- decsrcref_transferdata = d->decsrcref_transferdata;
+ _masked_wrapper_transfer_data *d = (_masked_wrapper_transfer_data *)auxdata;
+ npy_intp subloopsize;
while (N > 0) {
- /* Skip masked values, still calling decsrcref for move_references */
+ /* Skip masked values, still calling decref for move_references */
mask = (npy_bool*)npy_memchr((char *)mask, 0, mask_stride, N,
&subloopsize, 1);
- if (decsrcref_stransfer(
- NULL, 0, src, src_stride,
- subloopsize, src_itemsize, decsrcref_transferdata) < 0) {
+ if (d->decref_src.func(&d->decref_src.context,
+ &src, &subloopsize, &src_stride, d->decref_src.auxdata) < 0) {
return -1;
}
dst += subloopsize * dst_stride;
@@ -3064,9 +2604,9 @@ _strided_masked_wrapper_decsrcref_transfer_function(
/* Process unmasked values */
mask = (npy_bool*)npy_memchr((char *)mask, 0, mask_stride, N,
&subloopsize, 0);
- if (unmasked_stransfer(
- dst, dst_stride, src, src_stride,
- subloopsize, src_itemsize, unmasked_transferdata) < 0) {
+ char *wrapped_args[2] = {src, dst};
+ if (d->wrapped.func(&d->wrapped.context,
+ wrapped_args, &subloopsize, strides, d->wrapped.auxdata) < 0) {
return -1;
}
dst += subloopsize * dst_stride;
@@ -3078,21 +2618,17 @@ _strided_masked_wrapper_decsrcref_transfer_function(
static int
_strided_masked_wrapper_transfer_function(
- char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_bool *mask, npy_intp mask_stride,
- npy_intp N, npy_intp src_itemsize,
- NpyAuxData *transferdata)
+ PyArrayMethod_Context *NPY_UNUSED(context), char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ npy_bool *mask, npy_intp mask_stride,
+ NpyAuxData *auxdata)
{
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
- _masked_wrapper_transfer_data *d =
- (_masked_wrapper_transfer_data *)transferdata;
+ _masked_wrapper_transfer_data *d = (_masked_wrapper_transfer_data *)auxdata;
npy_intp subloopsize;
- PyArray_StridedUnaryOp *unmasked_stransfer;
- NpyAuxData *unmasked_transferdata;
-
- unmasked_stransfer = d->stransfer;
- unmasked_transferdata = d->transferdata;
while (N > 0) {
/* Skip masked values */
@@ -3108,9 +2644,9 @@ _strided_masked_wrapper_transfer_function(
/* Process unmasked values */
mask = (npy_bool*)npy_memchr((char *)mask, 0, mask_stride, N,
&subloopsize, 0);
- if (unmasked_stransfer(
- dst, dst_stride, src, src_stride,
- subloopsize, src_itemsize, unmasked_transferdata) < 0) {
+ char *wrapped_args[2] = {src, dst};
+ if (d->wrapped.func(&d->wrapped.context,
+ wrapped_args, &subloopsize, strides, d->wrapped.auxdata) < 0) {
return -1;
}
dst += subloopsize * dst_stride;
@@ -3121,658 +2657,749 @@ _strided_masked_wrapper_transfer_function(
}
-/************************* DEST BOOL SETONE *******************************/
+/*************************** CLEAR SRC *******************************/
+
+static int
+_dec_src_ref_nop(
+ PyArrayMethod_Context *NPY_UNUSED(context),
+ char *const *NPY_UNUSED(args), const npy_intp *NPY_UNUSED(dimensions),
+ const npy_intp *NPY_UNUSED(strides), NpyAuxData *NPY_UNUSED(auxdata))
+{
+ /* NOP */
+ return 0;
+}
static int
-_null_to_strided_set_bool_one(char *dst,
- npy_intp dst_stride,
- char *NPY_UNUSED(src), npy_intp NPY_UNUSED(src_stride),
- npy_intp N, npy_intp NPY_UNUSED(src_itemsize),
- NpyAuxData *NPY_UNUSED(data))
+_strided_to_null_dec_src_ref_reference(
+ PyArrayMethod_Context *NPY_UNUSED(context),
+ char *const *args, const npy_intp *dimensions,
+ const npy_intp *strides, NpyAuxData *NPY_UNUSED(auxdata))
{
- /* bool type is one byte, so can just use the char */
+ char *src = args[0];
+ npy_intp N = dimensions[0];
+ npy_intp stride = strides[0];
+ PyObject *src_ref = NULL;
while (N > 0) {
- *dst = 1;
+ /* Release the reference in src and set it to NULL */
+ NPY_DT_DBG_REFTRACE("dec src ref (null dst)", src_ref);
+ memcpy(&src_ref, src, sizeof(src_ref));
+ Py_XDECREF(src_ref);
+ memset(src, 0, sizeof(PyObject *));
- dst += dst_stride;
+ src += stride;
--N;
}
return 0;
}
+
+/*
+ * Get a function to decref. Currently, this uses a cast info slot, which
+ * means that the second (destination) descriptor is always set to NULL
+ * and generally does not have to be passed.
+ * Since we do not currently have an `ArrayMethod` representing this, the
+ * method is also set to NULL.
+ *
+ * TODO: this function should probably be moved onto the DType eventually,
+ * which would allow for user DTypes to include dynamic allocated
+ * memory or Python objects.
+ */
static int
-_null_to_contig_set_bool_one(char *dst,
- npy_intp NPY_UNUSED(dst_stride),
- char *NPY_UNUSED(src), npy_intp NPY_UNUSED(src_stride),
- npy_intp N, npy_intp NPY_UNUSED(src_itemsize),
- NpyAuxData *NPY_UNUSED(data))
+get_decref_transfer_function(int aligned,
+ npy_intp src_stride,
+ PyArray_Descr *src_dtype,
+ NPY_cast_info *cast_info,
+ int *out_needs_api)
{
- /* bool type is one byte, so can just use the char */
+ NPY_cast_info_init(cast_info);
- memset(dst, 1, N);
- return 0;
-}
+ /* If there are no references, it's a nop */
+ if (!PyDataType_REFCHK(src_dtype)) {
+ cast_info->func = &_dec_src_ref_nop;
+ cast_info->auxdata = NULL;
+ goto finalize;
+ }
+ /* If it's a single reference, it's one decref */
+ else if (src_dtype->type_num == NPY_OBJECT) {
+ if (out_needs_api) {
+ *out_needs_api = 1;
+ }
-/* Only for the bool type, sets the destination to 1 */
-NPY_NO_EXPORT int
-get_bool_setdstone_transfer_function(npy_intp dst_stride,
- PyArray_StridedUnaryOp **out_stransfer,
- NpyAuxData **out_transferdata,
- int *NPY_UNUSED(out_needs_api))
-{
- if (dst_stride == 1) {
- *out_stransfer = &_null_to_contig_set_bool_one;
+ cast_info->func = &_strided_to_null_dec_src_ref_reference;
+ cast_info->auxdata = NULL;
+ goto finalize;
+ }
+ /* If there are subarrays, need to wrap it */
+ else if (PyDataType_HASSUBARRAY(src_dtype)) {
+ PyArray_Dims src_shape = {NULL, -1};
+ npy_intp src_size;
+
+ if (out_needs_api) {
+ *out_needs_api = 1;
+ }
+
+ if (!(PyArray_IntpConverter(src_dtype->subarray->shape,
+ &src_shape))) {
+ PyErr_SetString(PyExc_ValueError,
+ "invalid subarray shape");
+ return NPY_FAIL;
+ }
+ src_size = PyArray_MultiplyList(src_shape.ptr, src_shape.len);
+ npy_free_cache_dim_obj(src_shape);
+
+ if (get_n_to_n_transfer_function(aligned,
+ src_stride, 0,
+ src_dtype->subarray->base, NULL, 1, src_size,
+ &cast_info->func, &cast_info->auxdata,
+ out_needs_api) != NPY_SUCCEED) {
+ return NPY_FAIL;
+ }
+
+ goto finalize;
+ }
+ /* If there are fields, need to do each field */
+ else if (PyDataType_HASFIELDS(src_dtype)) {
+ if (out_needs_api) {
+ *out_needs_api = 1;
+ }
+
+ if (get_decref_fields_transfer_function(aligned,
+ src_stride, src_dtype,
+ &cast_info->func, &cast_info->auxdata,
+ out_needs_api) < 0) {
+ return NPY_FAIL;
+ }
+ goto finalize;
}
else {
- *out_stransfer = &_null_to_strided_set_bool_one;
+ PyErr_Format(PyExc_RuntimeError,
+ "Internal error, tried to fetch decref function for the "
+ "unsupported DType '%S'.", src_dtype);
+ return NPY_FAIL;
}
- *out_transferdata = NULL;
+ finalize:
+ /* Make sure all important fields are either set or cleared */
+ Py_INCREF(src_dtype);
+ cast_info->descriptors[0] = src_dtype;
+ cast_info->descriptors[1] = NULL;
+ cast_info->context.method = NULL;
+ cast_info->context.caller = NULL;
return NPY_SUCCEED;
}
-/*************************** DEST SETZERO *******************************/
-/* Sets dest to zero */
+/*
+ * ********************* Generalized Multistep Cast ************************
+ *
+ * New general purpose multiple step cast function when resolve descriptors
+ * implies that multiple cast steps are necessary.
+ */
+
typedef struct {
NpyAuxData base;
- npy_intp dst_itemsize;
-} _dst_memset_zero_data;
+ /* Information for main cast */
+ NPY_cast_info main;
+ /* Information for input preparation cast */
+ NPY_cast_info from;
+ /* Information for output finalization cast */
+ NPY_cast_info to;
+ char *from_buffer;
+ char *to_buffer;
+} _multistep_castdata;
+
/* zero-padded data copy function */
-static NpyAuxData *_dst_memset_zero_data_clone(NpyAuxData *data)
+static void
+_multistep_cast_auxdata_free(NpyAuxData *auxdata)
{
- _dst_memset_zero_data *newdata =
- (_dst_memset_zero_data *)PyArray_malloc(
- sizeof(_dst_memset_zero_data));
- if (newdata == NULL) {
- return NULL;
+ _multistep_castdata *data = (_multistep_castdata *)auxdata;
+ NPY_cast_info_xfree(&data->main);
+ if (data->from.func != NULL) {
+ NPY_cast_info_xfree(&data->from);
+ }
+ if (data->to.func != NULL) {
+ NPY_cast_info_xfree(&data->to);
}
+ PyMem_Free(data);
+}
- memcpy(newdata, data, sizeof(_dst_memset_zero_data));
- return (NpyAuxData *)newdata;
-}
+static NpyAuxData *
+_multistep_cast_auxdata_clone(NpyAuxData *auxdata_old);
-static int
-_null_to_strided_memset_zero(char *dst,
- npy_intp dst_stride,
- char *NPY_UNUSED(src), npy_intp NPY_UNUSED(src_stride),
- npy_intp N, npy_intp NPY_UNUSED(src_itemsize),
- NpyAuxData *data)
+
+static NpyAuxData *
+_multistep_cast_auxdata_clone_int(_multistep_castdata *castdata, int move_info)
{
- _dst_memset_zero_data *d = (_dst_memset_zero_data *)data;
- npy_intp dst_itemsize = d->dst_itemsize;
+ /* Round up the structure size to 16-byte boundary for the buffers */
+ Py_ssize_t datasize = (sizeof(_multistep_castdata) + 15) & ~0xf;
- while (N > 0) {
- memset(dst, 0, dst_itemsize);
- dst += dst_stride;
- --N;
+ Py_ssize_t from_buffer_offset = datasize;
+ if (castdata->from.func != NULL) {
+ Py_ssize_t src_itemsize = castdata->main.context.descriptors[0]->elsize;
+ datasize += NPY_LOWLEVEL_BUFFER_BLOCKSIZE * src_itemsize;
+ datasize = (datasize + 15) & ~0xf;
+ }
+ Py_ssize_t to_buffer_offset = datasize;
+ if (castdata->to.func != NULL) {
+ Py_ssize_t dst_itemsize = castdata->main.context.descriptors[1]->elsize;
+ datasize += NPY_LOWLEVEL_BUFFER_BLOCKSIZE * dst_itemsize;
}
- return 0;
-}
-
-static int
-_null_to_contig_memset_zero(char *dst,
- npy_intp dst_stride,
- char *NPY_UNUSED(src), npy_intp NPY_UNUSED(src_stride),
- npy_intp N, npy_intp NPY_UNUSED(src_itemsize),
- NpyAuxData *data)
-{
- _dst_memset_zero_data *d = (_dst_memset_zero_data *)data;
- npy_intp dst_itemsize = d->dst_itemsize;
- memset(dst, 0, N*dst_itemsize);
- return 0;
-}
+ char *char_data = PyMem_Malloc(datasize);
+ if (char_data == NULL) {
+ return NULL;
+ }
-static int
-_null_to_strided_reference_setzero(char *dst,
- npy_intp dst_stride,
- char *NPY_UNUSED(src), npy_intp NPY_UNUSED(src_stride),
- npy_intp N, npy_intp NPY_UNUSED(src_itemsize),
- NpyAuxData *NPY_UNUSED(data))
-{
- PyObject *dst_ref = NULL;
+ _multistep_castdata *newdata = (_multistep_castdata *)char_data;
- while (N > 0) {
- memcpy(&dst_ref, dst, sizeof(dst_ref));
+ /* Fix up the basic information: */
+ newdata->base.free = &_multistep_cast_auxdata_free;
+ newdata->base.clone = &_multistep_cast_auxdata_clone;
+ /* And buffer information: */
+ newdata->from_buffer = char_data + from_buffer_offset;
+ newdata->to_buffer = char_data + to_buffer_offset;
- /* Release the reference in dst and set it to NULL */
- NPY_DT_DBG_REFTRACE("dec dest ref (to set zero)", dst_ref);
- Py_XDECREF(dst_ref);
- memset(dst, 0, sizeof(PyObject *));
+ /* Initialize funcs to NULL to signal no-cleanup in case of an error. */
+ newdata->from.func = NULL;
+ newdata->to.func = NULL;
- dst += dst_stride;
- --N;
+ if (move_info) {
+ NPY_cast_info_move(&newdata->main, &castdata->main);
+ }
+ else if (NPY_cast_info_copy(&newdata->main, &castdata->main) < 0) {
+ goto fail;
}
- return 0;
-}
-
-NPY_NO_EXPORT int
-get_setdstzero_transfer_function(int aligned,
- npy_intp dst_stride,
- PyArray_Descr *dst_dtype,
- PyArray_StridedUnaryOp **out_stransfer,
- NpyAuxData **out_transferdata,
- int *out_needs_api)
-{
- _dst_memset_zero_data *data;
- /* If there are no references, just set the whole thing to zero */
- if (!PyDataType_REFCHK(dst_dtype)) {
- data = (_dst_memset_zero_data *)
- PyArray_malloc(sizeof(_dst_memset_zero_data));
- if (data == NULL) {
- PyErr_NoMemory();
- return NPY_FAIL;
+ if (castdata->from.func != NULL) {
+ if (move_info) {
+ NPY_cast_info_move(&newdata->from, &castdata->from);
}
-
- data->base.free = (NpyAuxData_FreeFunc *)(&PyArray_free);
- data->base.clone = &_dst_memset_zero_data_clone;
- data->dst_itemsize = dst_dtype->elsize;
-
- if (dst_stride == data->dst_itemsize) {
- *out_stransfer = &_null_to_contig_memset_zero;
+ else if (NPY_cast_info_copy(&newdata->from, &castdata->from) < 0) {
+ goto fail;
}
- else {
- *out_stransfer = &_null_to_strided_memset_zero;
+
+ if (PyDataType_FLAGCHK(newdata->main.descriptors[0], NPY_NEEDS_INIT)) {
+ memset(newdata->from_buffer, 0, to_buffer_offset - from_buffer_offset);
}
- *out_transferdata = (NpyAuxData *)data;
}
- /* If it's exactly one reference, use the decref function */
- else if (dst_dtype->type_num == NPY_OBJECT) {
- if (out_needs_api) {
- *out_needs_api = 1;
+ if (castdata->to.func != NULL) {
+ if (move_info) {
+ NPY_cast_info_move(&newdata->to, &castdata->to);
+ }
+ else if (NPY_cast_info_copy(&newdata->to, &castdata->to) < 0) {
+ goto fail;
}
- *out_stransfer = &_null_to_strided_reference_setzero;
- *out_transferdata = NULL;
+ if (PyDataType_FLAGCHK(newdata->main.descriptors[1], NPY_NEEDS_INIT)) {
+ memset(newdata->to_buffer, 0, datasize - to_buffer_offset);
+ }
}
- /* If there are subarrays, need to wrap it */
- else if (PyDataType_HASSUBARRAY(dst_dtype)) {
- PyArray_Dims dst_shape = {NULL, -1};
- npy_intp dst_size = 1;
- PyArray_StridedUnaryOp *contig_stransfer;
- NpyAuxData *contig_data;
- if (out_needs_api) {
- *out_needs_api = 1;
- }
+ return (NpyAuxData *)newdata;
- if (!(PyArray_IntpConverter(dst_dtype->subarray->shape,
- &dst_shape))) {
- PyErr_SetString(PyExc_ValueError,
- "invalid subarray shape");
- return NPY_FAIL;
+ fail:
+ NPY_AUXDATA_FREE((NpyAuxData *)newdata);
+ return NULL;
+}
+
+
+static NpyAuxData *
+_multistep_cast_auxdata_clone(NpyAuxData *auxdata_old)
+{
+ return _multistep_cast_auxdata_clone_int(
+ (_multistep_castdata *)auxdata_old, 0);
+}
+
+
+static int
+_strided_to_strided_multistep_cast(
+ /* The context is always stored explicitly in auxdata */
+ PyArrayMethod_Context *NPY_UNUSED(context), char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *auxdata)
+{
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ _multistep_castdata *castdata = (_multistep_castdata *)auxdata;
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+
+ char *main_src, *main_dst;
+ npy_intp main_src_stride, main_dst_stride;
+
+ npy_intp block_size = NPY_LOWLEVEL_BUFFER_BLOCKSIZE;
+ while (N > 0) {
+ if (block_size > N) {
+ block_size = N;
}
- dst_size = PyArray_MultiplyList(dst_shape.ptr, dst_shape.len);
- npy_free_cache_dim_obj(dst_shape);
- /* Get a function for contiguous dst of the subarray type */
- if (get_setdstzero_transfer_function(aligned,
- dst_dtype->subarray->base->elsize,
- dst_dtype->subarray->base,
- &contig_stransfer, &contig_data,
- out_needs_api) != NPY_SUCCEED) {
- return NPY_FAIL;
+ if (castdata->from.func != NULL) {
+ npy_intp out_stride = castdata->from.descriptors[1]->elsize;
+ if (castdata->from.func(&castdata->from.context,
+ (char *[2]){src, castdata->from_buffer}, &block_size,
+ (npy_intp [2]){src_stride, out_stride},
+ castdata->from.auxdata) != 0) {
+ /* TODO: Internal buffer may require cleanup on error. */
+ return -1;
+ }
+ main_src = castdata->from_buffer;
+ main_src_stride = out_stride;
+ }
+ else {
+ main_src = src;
+ main_src_stride = src_stride;
}
- if (wrap_transfer_function_n_to_n(contig_stransfer, contig_data,
- 0, dst_stride,
- 0, dst_dtype->subarray->base->elsize,
- dst_size,
- out_stransfer, out_transferdata) != NPY_SUCCEED) {
- NPY_AUXDATA_FREE(contig_data);
- return NPY_FAIL;
+ if (castdata->to.func != NULL) {
+ main_dst = castdata->to_buffer;
+ main_dst_stride = castdata->main.descriptors[1]->elsize;
}
- }
- /* If there are fields, need to do each field */
- else if (PyDataType_HASFIELDS(dst_dtype)) {
- if (out_needs_api) {
- *out_needs_api = 1;
+ else {
+ main_dst = dst;
+ main_dst_stride = dst_stride;
}
- return get_setdestzero_fields_transfer_function(aligned,
- dst_stride, dst_dtype,
- out_stransfer,
- out_transferdata,
- out_needs_api);
- }
+ if (castdata->main.func(&castdata->main.context,
+ (char *[2]){main_src, main_dst}, &block_size,
+ (npy_intp [2]){main_src_stride, main_dst_stride},
+ castdata->main.auxdata) != 0) {
+ /* TODO: Internal buffer may require cleanup on error. */
+ return -1;
+ }
- return NPY_SUCCEED;
-}
+ if (castdata->to.func != NULL) {
+ if (castdata->to.func(&castdata->to.context,
+ (char *[2]){main_dst, dst}, &block_size,
+ (npy_intp [2]){main_dst_stride, dst_stride},
+ castdata->to.auxdata) != 0) {
+ return -1;
+ }
+ }
-static int
-_dec_src_ref_nop(char *NPY_UNUSED(dst),
- npy_intp NPY_UNUSED(dst_stride),
- char *NPY_UNUSED(src), npy_intp NPY_UNUSED(src_stride),
- npy_intp NPY_UNUSED(N),
- npy_intp NPY_UNUSED(src_itemsize),
- NpyAuxData *NPY_UNUSED(data))
-{
- /* NOP */
+ N -= block_size;
+ src += block_size * src_stride;
+ dst += block_size * dst_stride;
+ }
return 0;
}
-static int
-_strided_to_null_dec_src_ref_reference(char *NPY_UNUSED(dst),
- npy_intp NPY_UNUSED(dst_stride),
- char *src, npy_intp src_stride,
- npy_intp N,
- npy_intp NPY_UNUSED(src_itemsize),
- NpyAuxData *NPY_UNUSED(data))
+
+/*
+ * Initialize most of a cast-info structure, this step does not fetch the
+ * transferfunction and transferdata.
+ */
+static NPY_INLINE int
+init_cast_info(NPY_cast_info *cast_info, NPY_CASTING *casting,
+ PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype, int main_step)
{
- PyObject *src_ref = NULL;
- while (N > 0) {
- /* Release the reference in src and set it to NULL */
- NPY_DT_DBG_REFTRACE("dec src ref (null dst)", src_ref);
- memcpy(&src_ref, src, sizeof(src_ref));
- Py_XDECREF(src_ref);
- memset(src, 0, sizeof(PyObject *));
+ PyObject *meth = PyArray_GetCastingImpl(
+ NPY_DTYPE(src_dtype), NPY_DTYPE(dst_dtype));
+ if (meth == NULL) {
+ return -1;
+ }
+ if (meth == Py_None) {
+ Py_DECREF(Py_None);
+ PyErr_Format(PyExc_TypeError,
+ "Cannot cast data from %S to %S.", src_dtype, dst_dtype);
+ return -1;
+ }
+ /* Initialize the context and related data */
+ NPY_cast_info_init(cast_info);
+ cast_info->auxdata = NULL;
- src += src_stride;
- --N;
+ cast_info->context.caller = NULL;
+ cast_info->context.method = (PyArrayMethodObject *)meth;
+
+ PyArray_DTypeMeta *dtypes[2] = {NPY_DTYPE(src_dtype), NPY_DTYPE(dst_dtype)};
+ PyArray_Descr *in_descr[2] = {src_dtype, dst_dtype};
+
+ *casting = cast_info->context.method->resolve_descriptors(
+ cast_info->context.method, dtypes, in_descr, cast_info->descriptors);
+ if (NPY_UNLIKELY(*casting < 0)) {
+ if (!PyErr_Occurred()) {
+ PyErr_Format(PyExc_TypeError,
+ "Cannot cast array data from %R to %R.", src_dtype, dst_dtype);
+ Py_DECREF(meth);
+ return -1;
+ }
}
+ assert(PyArray_DescrCheck(cast_info->descriptors[0]));
+ assert(PyArray_DescrCheck(cast_info->descriptors[1]));
+
+ if (!main_step && NPY_UNLIKELY(src_dtype != cast_info->descriptors[0] ||
+ dst_dtype != cast_info->descriptors[1])) {
+ /*
+ * We currently do not resolve recursively, but require a non
+ * main cast (within the same DType) to be done in a single step.
+ * This could be expanded at some point if the need arises.
+ */
+ PyErr_Format(PyExc_RuntimeError,
+ "Required internal cast from %R to %R was not done in a single "
+ "step (a secondary cast must currently be between instances of "
+ "the same DType class and such a cast must currently return "
+ "the input descriptors unmodified).",
+ src_dtype, dst_dtype);
+ NPY_cast_info_xfree(cast_info);
+ return -1;
+ }
+
return 0;
}
-NPY_NO_EXPORT int
-get_decsrcref_transfer_function(int aligned,
- npy_intp src_stride,
- PyArray_Descr *src_dtype,
- PyArray_StridedUnaryOp **out_stransfer,
- NpyAuxData **out_transferdata,
- int *out_needs_api)
+/*
+ * When there is a failure in ArrayMethod.get_loop(...) we still have
+ * to clean up references, but assume that `auxdata` and `func`
+ * have undefined values.
+ * NOTE: This should possibly be moved, but is only necessary here
+ */
+static void
+_clear_cast_info_after_get_loop_failure(NPY_cast_info *cast_info)
{
- /* If there are no references, it's a nop */
- if (!PyDataType_REFCHK(src_dtype)) {
- *out_stransfer = &_dec_src_ref_nop;
- *out_transferdata = NULL;
+ /* As public API we could choose to clear auxdata != NULL */
+ assert(cast_info->auxdata == NULL);
+ /* Set func to be non-null so that `NPY_cats_info_xfree` does not skip */
+ cast_info->func = &_dec_src_ref_nop;
+ NPY_cast_info_xfree(cast_info);
+}
- return NPY_SUCCEED;
- }
- /* If it's a single reference, it's one decref */
- else if (src_dtype->type_num == NPY_OBJECT) {
- if (out_needs_api) {
- *out_needs_api = 1;
- }
- *out_stransfer = &_strided_to_null_dec_src_ref_reference;
- *out_transferdata = NULL;
+/*
+ * Helper for PyArray_GetDTypeTransferFunction, which fetches a single
+ * transfer function from the each casting implementation (ArrayMethod).
+ * May set the transfer function to NULL when the cast can be achieved using
+ * a view.
+ * The `out_needs_api` flag must be initialized.
+ *
+ * NOTE: In theory casting errors here could be slightly misleading in case
+ * of a multi-step casting scenario. It should be possible to improve
+ * this in the future.
+ *
+ * Note about `move_references`: Move references means stealing of
+ * references. It is useful to clear buffers immediately. No matter the
+ * input all copies from a buffer must use `move_references`. Move references
+ * is thus used:
+ * * For the added initial "from" cast if it was passed in
+ * * Always in the main step if a "from" cast is made (it casts from a buffer)
+ * * Always for the "to" cast, as it always cast from a buffer to the output.
+ *
+ * Returns -1 on failure, 0 on success
+ */
+static int
+define_cast_for_descrs(
+ int aligned,
+ npy_intp src_stride, npy_intp dst_stride,
+ PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
+ int move_references,
+ NPY_cast_info *cast_info, int *out_needs_api)
+{
+ /* Storage for all cast info in case multi-step casting is necessary */
+ _multistep_castdata castdata;
+ /* Initialize funcs to NULL to simplify cleanup on error. */
+ castdata.main.func = NULL;
+ castdata.to.func = NULL;
+ castdata.from.func = NULL;
+ NPY_CASTING casting = -1;
- return NPY_SUCCEED;
+ if (init_cast_info(cast_info, &casting, src_dtype, dst_dtype, 1) < 0) {
+ return -1;
}
- /* If there are subarrays, need to wrap it */
- else if (PyDataType_HASSUBARRAY(src_dtype)) {
- PyArray_Dims src_shape = {NULL, -1};
- npy_intp src_size;
- PyArray_StridedUnaryOp *stransfer;
- NpyAuxData *data;
- if (out_needs_api) {
- *out_needs_api = 1;
- }
-
- if (!(PyArray_IntpConverter(src_dtype->subarray->shape,
- &src_shape))) {
- PyErr_SetString(PyExc_ValueError,
- "invalid subarray shape");
- return NPY_FAIL;
- }
- src_size = PyArray_MultiplyList(src_shape.ptr, src_shape.len);
- npy_free_cache_dim_obj(src_shape);
+ /*
+ * Both input and output must be wrapped in case they may be unaligned
+ * and the method does not support unaligned data.
+ * NOTE: It is probable that most/all legacy loops actually do support
+ * unaligned output, we could move the wrapping there if we wanted
+ * to. It probably isn't speed relevant though and they should be
+ * deleted in any case.
+ */
+ int must_wrap = (!aligned &&
+ (cast_info->context.method->flags & NPY_METH_SUPPORTS_UNALIGNED) == 0);
- /* Get a function for contiguous src of the subarray type */
- if (get_decsrcref_transfer_function(aligned,
- src_dtype->subarray->base->elsize,
- src_dtype->subarray->base,
- &stransfer, &data,
- out_needs_api) != NPY_SUCCEED) {
- return NPY_FAIL;
+ /*
+ * Wrap the input with an additional cast if necessary.
+ */
+ if (NPY_UNLIKELY(src_dtype != cast_info->descriptors[0] || must_wrap)) {
+ NPY_CASTING from_casting = -1;
+ /* Cast function may not support the input, wrap if necessary */
+ if (init_cast_info(
+ &castdata.from, &from_casting,
+ src_dtype, cast_info->descriptors[0], 0) < 0) {
+ goto fail;
+ }
+ casting = PyArray_MinCastSafety(casting, from_casting);
+
+ /* Prepare the actual cast (if necessary): */
+ if (from_casting & _NPY_CAST_IS_VIEW && !must_wrap) {
+ /* This step is not necessary and can be skipped. */
+ castdata.from.func = &_dec_src_ref_nop; /* avoid NULL */
+ NPY_cast_info_xfree(&castdata.from);
}
+ else {
+ /* Fetch the cast function and set up */
+ PyArrayMethod_Context *context = &castdata.from.context;
+ npy_intp strides[2] = {src_stride, cast_info->descriptors[0]->elsize};
+ NPY_ARRAYMETHOD_FLAGS flags;
+ if (context->method->get_strided_loop(
+ context, aligned, move_references, strides,
+ &castdata.from.func, &castdata.from.auxdata, &flags) < 0) {
+ _clear_cast_info_after_get_loop_failure(&castdata.from);
+ goto fail;
+ }
+ assert(castdata.from.func != NULL);
- if (wrap_transfer_function_n_to_n(stransfer, data,
- src_stride, 0,
- src_dtype->subarray->base->elsize, 0,
- src_size,
- out_stransfer, out_transferdata) != NPY_SUCCEED) {
- NPY_AUXDATA_FREE(data);
- return NPY_FAIL;
+ *out_needs_api |= (flags & NPY_METH_REQUIRES_PYAPI) != 0;
+ /* The main cast now uses a buffered input: */
+ src_stride = strides[1];
+ move_references = 1; /* main cast has to clear the buffer */
}
-
- return NPY_SUCCEED;
}
- /* If there are fields, need to do each field */
- else {
- if (out_needs_api) {
- *out_needs_api = 1;
+ /*
+ * Wrap the output with an additional cast if necessary.
+ */
+ if (NPY_UNLIKELY(dst_dtype != cast_info->descriptors[1] || must_wrap)) {
+ NPY_CASTING to_casting = -1;
+ /* Cast function may not support the output, wrap if necessary */
+ if (init_cast_info(
+ &castdata.to, &to_casting,
+ cast_info->descriptors[1], dst_dtype, 0) < 0) {
+ goto fail;
+ }
+ casting = PyArray_MinCastSafety(casting, to_casting);
+
+ /* Prepare the actual cast (if necessary): */
+ if (to_casting & _NPY_CAST_IS_VIEW && !must_wrap) {
+ /* This step is not necessary and can be skipped. */
+ castdata.to.func = &_dec_src_ref_nop; /* avoid NULL */
+ NPY_cast_info_xfree(&castdata.to);
+ }
+ else {
+ /* Fetch the cast function and set up */
+ PyArrayMethod_Context *context = &castdata.to.context;
+ npy_intp strides[2] = {cast_info->descriptors[1]->elsize, dst_stride};
+ NPY_ARRAYMETHOD_FLAGS flags;
+ if (context->method->get_strided_loop(
+ context, aligned, 1 /* clear buffer */, strides,
+ &castdata.to.func, &castdata.to.auxdata, &flags) < 0) {
+ _clear_cast_info_after_get_loop_failure(&castdata.to);
+ goto fail;
+ }
+ assert(castdata.to.func != NULL);
+
+ *out_needs_api |= (flags & NPY_METH_REQUIRES_PYAPI) != 0;
+ /* The main cast now uses a buffered input: */
+ dst_stride = strides[0];
+ if (castdata.from.func != NULL) {
+ /* Both input and output are wrapped, now always aligned */
+ aligned = 1;
+ }
}
+ }
- return get_decsrcref_fields_transfer_function(aligned,
- src_stride, src_dtype,
- out_stransfer,
- out_transferdata,
- out_needs_api);
+ /* Fetch the main cast function (with updated values) */
+ PyArrayMethod_Context *context = &cast_info->context;
+ npy_intp strides[2] = {src_stride, dst_stride};
+ NPY_ARRAYMETHOD_FLAGS flags;
+ if (context->method->get_strided_loop(
+ context, aligned, move_references, strides,
+ &cast_info->func, &cast_info->auxdata, &flags) < 0) {
+ _clear_cast_info_after_get_loop_failure(cast_info);
+ goto fail;
}
-}
-/********************* DTYPE COPY SWAP FUNCTION ***********************/
+ *out_needs_api |= (flags & NPY_METH_REQUIRES_PYAPI) != 0;
-NPY_NO_EXPORT int
-PyArray_GetDTypeCopySwapFn(int aligned,
- npy_intp src_stride, npy_intp dst_stride,
- PyArray_Descr *dtype,
- PyArray_StridedUnaryOp **outstransfer,
- NpyAuxData **outtransferdata)
-{
- npy_intp itemsize = dtype->elsize;
-
- /* If it's a custom data type, wrap its copy swap function */
- if (dtype->type_num >= NPY_NTYPES) {
- *outstransfer = NULL;
- wrap_copy_swap_function(aligned,
- src_stride, dst_stride,
- dtype,
- !PyArray_ISNBO(dtype->byteorder),
- outstransfer, outtransferdata);
- }
- /* A straight copy */
- else if (itemsize == 1 || PyArray_ISNBO(dtype->byteorder)) {
- *outstransfer = PyArray_GetStridedCopyFn(aligned,
- src_stride, dst_stride,
- itemsize);
- *outtransferdata = NULL;
- }
- else if (dtype->kind == 'U') {
- return wrap_copy_swap_function(aligned,
- src_stride, dst_stride, dtype, 1,
- outstransfer, outtransferdata);
- }
- /* If it's not complex, one swap */
- else if (dtype->kind != 'c') {
- *outstransfer = PyArray_GetStridedCopySwapFn(aligned,
- src_stride, dst_stride,
- itemsize);
- *outtransferdata = NULL;
+ if (castdata.from.func == NULL && castdata.to.func == NULL) {
+ /* Most of the time, there will be only one step required. */
+ return 0;
}
- /* If complex, a paired swap */
- else {
- *outstransfer = PyArray_GetStridedCopySwapPairFn(aligned,
- src_stride, dst_stride,
- itemsize);
- *outtransferdata = NULL;
+ /* The full cast passed in is only the "main" step, copy cast_info there */
+ NPY_cast_info_move(&castdata.main, cast_info);
+ Py_INCREF(src_dtype);
+ cast_info->descriptors[0] = src_dtype;
+ Py_INCREF(dst_dtype);
+ cast_info->descriptors[1] = dst_dtype;
+ cast_info->context.method = NULL;
+
+ cast_info->func = &_strided_to_strided_multistep_cast;
+ cast_info->auxdata = _multistep_cast_auxdata_clone_int(&castdata, 1);
+ if (cast_info->auxdata == NULL) {
+ PyErr_NoMemory();
+ goto fail;
}
- return (*outstransfer == NULL) ? NPY_FAIL : NPY_SUCCEED;
+ return 0;
+
+ fail:
+ NPY_cast_info_xfree(&castdata.main);
+ NPY_cast_info_xfree(&castdata.from);
+ NPY_cast_info_xfree(&castdata.to);
+ return -1;
}
-/********************* MAIN DTYPE TRANSFER FUNCTION ***********************/
NPY_NO_EXPORT int
PyArray_GetDTypeTransferFunction(int aligned,
npy_intp src_stride, npy_intp dst_stride,
PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
int move_references,
- PyArray_StridedUnaryOp **out_stransfer,
- NpyAuxData **out_transferdata,
+ NPY_cast_info *cast_info,
int *out_needs_api)
{
- npy_intp src_itemsize, dst_itemsize;
- int src_type_num, dst_type_num;
- int is_builtin;
-
-#if NPY_DT_DBG_TRACING
- printf("Calculating dtype transfer from ");
- if (PyObject_Print((PyObject *)src_dtype, stdout, 0) < 0) {
- return NPY_FAIL;
- }
- printf(" to ");
- if (PyObject_Print((PyObject *)dst_dtype, stdout, 0) < 0) {
- return NPY_FAIL;
- }
- printf("\n");
-#endif
+ assert(src_dtype != NULL);
/*
* If one of the dtypes is NULL, we give back either a src decref
* function or a dst setzero function
+ *
+ * TODO: Eventually, we may wish to support user dtype with references
+ * (including and beyond bare `PyObject *` this may require extending
+ * the ArrayMethod API and those paths should likely be split out
+ * from this function.)
*/
if (dst_dtype == NULL) {
- if (move_references) {
- return get_decsrcref_transfer_function(aligned,
+ assert(move_references);
+ return get_decref_transfer_function(aligned,
src_dtype->elsize,
src_dtype,
- out_stransfer, out_transferdata,
+ cast_info,
out_needs_api);
- }
- else {
- *out_stransfer = &_dec_src_ref_nop;
- *out_transferdata = NULL;
- return NPY_SUCCEED;
- }
}
- else if (src_dtype == NULL) {
- return get_setdstzero_transfer_function(aligned,
- dst_dtype->elsize,
- dst_dtype,
- out_stransfer, out_transferdata,
- out_needs_api);
+
+ if (define_cast_for_descrs(aligned,
+ src_stride, dst_stride,
+ src_dtype, dst_dtype, move_references,
+ cast_info, out_needs_api) < 0) {
+ return NPY_FAIL;
}
- src_itemsize = src_dtype->elsize;
- dst_itemsize = dst_dtype->elsize;
- src_type_num = src_dtype->type_num;
- dst_type_num = dst_dtype->type_num;
- is_builtin = src_type_num < NPY_NTYPES && dst_type_num < NPY_NTYPES;
+ return NPY_SUCCEED;
+}
- /* Common special case - number -> number NBO cast */
- if (PyTypeNum_ISNUMBER(src_type_num) &&
- PyTypeNum_ISNUMBER(dst_type_num) &&
- PyArray_ISNBO(src_dtype->byteorder) &&
- PyArray_ISNBO(dst_dtype->byteorder)) {
- if (PyArray_EquivTypenums(src_type_num, dst_type_num)) {
- *out_stransfer = PyArray_GetStridedCopyFn(aligned,
- src_stride, dst_stride,
- src_itemsize);
- *out_transferdata = NULL;
- return (*out_stransfer == NULL) ? NPY_FAIL : NPY_SUCCEED;
- }
- else {
- return get_nbo_cast_numeric_transfer_function (aligned,
- src_stride, dst_stride,
- src_type_num, dst_type_num,
- out_stransfer, out_transferdata);
- }
+/*
+ * Internal wrapping of casts that have to be performed in a "single"
+ * function (i.e. not by the generic multi-step-cast), but rely on it
+ * internally. There are only two occasions where this is used:
+ *
+ * 1. Void advertises that it handles unaligned casts, but has to wrap the
+ * legacy cast which (probably) does not.
+ * 2. Datetime to unicode casts are implemented via bytes "U" vs. "S". If
+ * we relax the chaining rules to allow "recursive" cast chaining where
+ * `resolve_descriptors` can return a descriptor with a different type,
+ * this would become unnecessary.
+ * 3. Time <-> Time casts, which currently must support byte swapping, but
+ * have a non-trivial inner-loop (due to units) which does not support
+ * it.
+ *
+ * When wrapping is performed (guaranteed for `aligned == 0` and if the
+ * wrapped dtype is not identical to the input dtype), the wrapped transfer
+ * function can assume a contiguous input.
+ * Otherwise use `must_wrap` to ensure that wrapping occurs, which guarantees
+ * a contiguous, aligned, call of the wrapped function.
+ */
+NPY_NO_EXPORT int
+wrap_aligned_transferfunction(
+ int aligned, int must_wrap,
+ npy_intp src_stride, npy_intp dst_stride,
+ PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
+ PyArray_Descr *src_wrapped_dtype, PyArray_Descr *dst_wrapped_dtype,
+ PyArrayMethod_StridedLoop **out_stransfer,
+ NpyAuxData **out_transferdata, int *out_needs_api)
+{
+ must_wrap = must_wrap | !aligned;
+
+ _multistep_castdata castdata;
+ NPY_cast_info_init(&castdata.main);
+ NPY_cast_info_init(&castdata.from);
+ NPY_cast_info_init(&castdata.to);
+
+ /* Finalize the existing cast information: */
+ castdata.main.func = *out_stransfer;
+ *out_stransfer = NULL;
+ castdata.main.auxdata = *out_transferdata;
+ *out_transferdata = NULL;
+ castdata.main.context.method = NULL;
+ /* These are always legacy casts that only support native-byte-order: */
+ Py_INCREF(src_wrapped_dtype);
+ castdata.main.descriptors[0] = src_wrapped_dtype;
+ if (castdata.main.descriptors[0] == NULL) {
+ castdata.main.descriptors[1] = NULL;
+ goto fail;
+ }
+ Py_INCREF(dst_wrapped_dtype);
+ castdata.main.descriptors[1] = dst_wrapped_dtype;
+ if (castdata.main.descriptors[1] == NULL) {
+ goto fail;
}
/*
- * If there are no references and the data types are equivalent and builtin,
- * return a simple copy
+ * Similar to the normal multi-step cast, but we always have to wrap
+ * it all up, but we can simply do this via a "recursive" call.
+ * TODO: This is slightly wasteful, since it unnecessarily checks casting,
+ * but this whole function is about corner cases, which should rather
+ * have an explicit implementation instead if we want performance.
*/
- if (PyArray_EquivTypes(src_dtype, dst_dtype) &&
- !PyDataType_REFCHK(src_dtype) && !PyDataType_REFCHK(dst_dtype) &&
- ( !PyDataType_HASFIELDS(dst_dtype) ||
- is_dtype_struct_simple_unaligned_layout(dst_dtype)) &&
- is_builtin) {
- /*
- * We can't pass through the aligned flag because it's not
- * appropriate. Consider a size-8 string, it will say it's
- * aligned because strings only need alignment 1, but the
- * copy function wants to know if it's alignment 8.
- *
- * TODO: Change align from a flag to a "best power of 2 alignment"
- * which holds the strongest alignment value for all
- * the data which will be used.
- */
- *out_stransfer = PyArray_GetStridedCopyFn(0,
- src_stride, dst_stride,
- src_dtype->elsize);
- *out_transferdata = NULL;
- return NPY_SUCCEED;
- }
-
- /* First look at the possibilities of just a copy or swap */
- if (src_itemsize == dst_itemsize && src_dtype->kind == dst_dtype->kind &&
- !PyDataType_HASFIELDS(src_dtype) &&
- !PyDataType_HASFIELDS(dst_dtype) &&
- !PyDataType_HASSUBARRAY(src_dtype) &&
- !PyDataType_HASSUBARRAY(dst_dtype) &&
- src_type_num != NPY_DATETIME && src_type_num != NPY_TIMEDELTA) {
- /* A custom data type requires that we use its copy/swap */
- if (!is_builtin) {
- /*
- * If the sizes and kinds are identical, but they're different
- * custom types, then get a cast function
- */
- if (src_type_num != dst_type_num) {
- return get_cast_transfer_function(aligned,
- src_stride, dst_stride,
- src_dtype, dst_dtype,
- move_references,
- out_stransfer, out_transferdata,
- out_needs_api);
- }
- else {
- return wrap_copy_swap_function(aligned,
- src_stride, dst_stride,
- src_dtype,
- PyArray_ISNBO(src_dtype->byteorder) !=
- PyArray_ISNBO(dst_dtype->byteorder),
- out_stransfer, out_transferdata);
- }
- }
-
- /* The special types, which have no or subelement byte-order */
- switch (src_type_num) {
- case NPY_UNICODE:
- /* Wrap the copy swap function when swapping is necessary */
- if (PyArray_ISNBO(src_dtype->byteorder) !=
- PyArray_ISNBO(dst_dtype->byteorder)) {
- return wrap_copy_swap_function(aligned,
- src_stride, dst_stride,
- src_dtype, 1,
- out_stransfer, out_transferdata);
- }
- case NPY_VOID:
- case NPY_STRING:
- *out_stransfer = PyArray_GetStridedCopyFn(0,
- src_stride, dst_stride,
- src_itemsize);
- *out_transferdata = NULL;
- return NPY_SUCCEED;
- case NPY_OBJECT:
- if (out_needs_api) {
- *out_needs_api = 1;
- }
- if (move_references) {
- *out_stransfer = &_strided_to_strided_move_references;
- *out_transferdata = NULL;
- }
- else {
- *out_stransfer = &_strided_to_strided_copy_references;
- *out_transferdata = NULL;
- }
- return NPY_SUCCEED;
- }
-
- /* This is a straight copy */
- if (src_itemsize == 1 || PyArray_ISNBO(src_dtype->byteorder) ==
- PyArray_ISNBO(dst_dtype->byteorder)) {
- *out_stransfer = PyArray_GetStridedCopyFn(aligned,
- src_stride, dst_stride,
- src_itemsize);
- *out_transferdata = NULL;
- return (*out_stransfer == NULL) ? NPY_FAIL : NPY_SUCCEED;
- }
- /* This is a straight copy + byte swap */
- else if (!PyTypeNum_ISCOMPLEX(src_type_num)) {
- *out_stransfer = PyArray_GetStridedCopySwapFn(aligned,
- src_stride, dst_stride,
- src_itemsize);
- *out_transferdata = NULL;
- return (*out_stransfer == NULL) ? NPY_FAIL : NPY_SUCCEED;
- }
- /* This is a straight copy + element pair byte swap */
- else {
- *out_stransfer = PyArray_GetStridedCopySwapPairFn(aligned,
- src_stride, dst_stride,
- src_itemsize);
- *out_transferdata = NULL;
- return (*out_stransfer == NULL) ? NPY_FAIL : NPY_SUCCEED;
+ if (must_wrap || src_wrapped_dtype != src_dtype) {
+ if (PyArray_GetDTypeTransferFunction(aligned,
+ src_stride, castdata.main.descriptors[0]->elsize,
+ src_dtype, castdata.main.descriptors[0], 0,
+ &castdata.from, out_needs_api) != NPY_SUCCEED) {
+ goto fail;
}
}
-
- /* Handle subarrays */
- if (PyDataType_HASSUBARRAY(src_dtype) ||
- PyDataType_HASSUBARRAY(dst_dtype)) {
- return get_subarray_transfer_function(aligned,
- src_stride, dst_stride,
- src_dtype, dst_dtype,
- move_references,
- out_stransfer, out_transferdata,
- out_needs_api);
+ if (must_wrap || dst_wrapped_dtype != dst_dtype) {
+ if (PyArray_GetDTypeTransferFunction(aligned,
+ castdata.main.descriptors[1]->elsize, dst_stride,
+ castdata.main.descriptors[1], dst_dtype,
+ 1, /* clear buffer if it includes references */
+ &castdata.to, out_needs_api) != NPY_SUCCEED) {
+ goto fail;
+ }
}
- /* Handle fields */
- if ((PyDataType_HASFIELDS(src_dtype) || PyDataType_HASFIELDS(dst_dtype)) &&
- src_type_num != NPY_OBJECT && dst_type_num != NPY_OBJECT) {
- return get_fields_transfer_function(aligned,
- src_stride, dst_stride,
- src_dtype, dst_dtype,
- move_references,
- out_stransfer, out_transferdata,
- out_needs_api);
+ *out_transferdata = _multistep_cast_auxdata_clone_int(&castdata, 1);
+ if (*out_transferdata == NULL) {
+ PyErr_NoMemory();
+ goto fail;
}
+ *out_stransfer = &_strided_to_strided_multistep_cast;
+ return 0;
- /* Check for different-sized strings, unicodes, or voids */
- if (src_type_num == dst_type_num) {
- switch (src_type_num) {
- case NPY_UNICODE:
- if (PyArray_ISNBO(src_dtype->byteorder) !=
- PyArray_ISNBO(dst_dtype->byteorder)) {
- return PyArray_GetStridedZeroPadCopyFn(0, 1,
- src_stride, dst_stride,
- src_dtype->elsize, dst_dtype->elsize,
- out_stransfer, out_transferdata);
- }
- case NPY_STRING:
- case NPY_VOID:
- return PyArray_GetStridedZeroPadCopyFn(0, 0,
- src_stride, dst_stride,
- src_dtype->elsize, dst_dtype->elsize,
- out_stransfer, out_transferdata);
- }
- }
+ fail:
+ NPY_cast_info_xfree(&castdata.main);
+ NPY_cast_info_xfree(&castdata.from);
+ NPY_cast_info_xfree(&castdata.to);
- /* Otherwise a cast is necessary */
- return get_cast_transfer_function(aligned,
- src_stride, dst_stride,
- src_dtype, dst_dtype,
- move_references,
- out_stransfer, out_transferdata,
- out_needs_api);
+ return -1;
}
/*
- * Basic version of PyArray_GetDTypeTransferFunction for legacy dtype
- * support.
- * It supports only wrapping the copyswapn functions and the legacy
- * cast functions registered with `PyArray_RegisterCastFunc`.
- * This function takes the easy way out: It does not wrap
+ * This function wraps the legacy casts stored on the `dtype->f->cast`
+ * or registered with `PyArray_RegisterCastFunc`.
+ * For casts between two dtypes with the same type (within DType casts)
+ * it also wraps the `copyswapn` function.
+ *
+ * This function is called called from `ArrayMethod.get_loop()` when a
+ * specialized cast function is missing.
+ *
+ * In general, the legacy cast functions do not support unaligned access,
+ * so an ArrayMethod using this must signal that. In a few places we do
+ * signal support for unaligned access (or byte swapping).
+ * In this case `allow_wrapped=1` will wrap it into an additional multi-step
+ * cast as necessary.
*/
NPY_NO_EXPORT int
-PyArray_GetLegacyDTypeTransferFunction(int aligned,
+get_wrapped_legacy_cast_function(int aligned,
npy_intp src_stride, npy_intp dst_stride,
PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
int move_references,
- PyArray_StridedUnaryOp **out_stransfer,
+ PyArrayMethod_StridedLoop **out_stransfer,
NpyAuxData **out_transferdata,
- int *out_needs_api)
+ int *out_needs_api, int allow_wrapped)
{
/* Note: We ignore `needs_wrap`; needs-wrap is handled by another cast */
int needs_wrap = 0;
@@ -3782,15 +3409,14 @@ PyArray_GetLegacyDTypeTransferFunction(int aligned,
* This is a cast within the same dtype. For legacy user-dtypes,
* it is always valid to handle this using the copy swap function.
*/
- return wrap_copy_swap_function(aligned,
- src_stride, dst_stride,
- src_dtype,
- PyArray_ISNBO(src_dtype->byteorder) !=
- PyArray_ISNBO(dst_dtype->byteorder),
+ return wrap_copy_swap_function(src_dtype,
+ PyDataType_ISNOTSWAPPED(src_dtype) !=
+ PyDataType_ISNOTSWAPPED(dst_dtype),
out_stransfer, out_transferdata);
}
- if (get_legacy_dtype_cast_function(aligned,
+ if (get_legacy_dtype_cast_function(
+ aligned,
src_stride, dst_stride,
src_dtype, dst_dtype,
move_references,
@@ -3798,9 +3424,51 @@ PyArray_GetLegacyDTypeTransferFunction(int aligned,
out_transferdata,
out_needs_api,
&needs_wrap) != NPY_SUCCEED) {
- return NPY_FAIL;
+ return -1;
}
- return NPY_SUCCEED;
+ if (!needs_wrap) {
+ return 0;
+ }
+ if (NPY_UNLIKELY(!allow_wrapped)) {
+ /*
+ * Legacy casts do not support unaligned which requires wrapping.
+ * However, normally we ensure that wrapping happens before calling
+ * this function, so this path should never happen.
+ */
+ PyErr_Format(PyExc_RuntimeError,
+ "Internal NumPy error, casting %S to %S required wrapping, "
+ "probably it incorrectly flagged support for unaligned data. "
+ "(aligned passed to discovery is %d)",
+ src_dtype, dst_dtype, aligned);
+ goto fail;
+ }
+
+ /*
+ * If we are here, use the legacy code to wrap the above cast (which
+ * does not support unaligned data) into copyswapn.
+ */
+ PyArray_Descr *src_wrapped_dtype = ensure_dtype_nbo(src_dtype);
+ if (src_wrapped_dtype == NULL) {
+ goto fail;
+ }
+ PyArray_Descr *dst_wrapped_dtype = ensure_dtype_nbo(dst_dtype);
+ if (dst_wrapped_dtype == NULL) {
+ goto fail;
+ }
+ int res = wrap_aligned_transferfunction(
+ aligned, 1, /* We assume wrapped is contiguous here */
+ src_stride, dst_stride,
+ src_dtype, dst_dtype,
+ src_wrapped_dtype, dst_wrapped_dtype,
+ out_stransfer, out_transferdata, out_needs_api);
+ Py_DECREF(src_wrapped_dtype);
+ Py_DECREF(dst_wrapped_dtype);
+ return res;
+
+ fail:
+ NPY_AUXDATA_FREE(*out_transferdata);
+ *out_transferdata = NULL;
+ return -1;
}
@@ -3813,71 +3481,66 @@ PyArray_GetMaskedDTypeTransferFunction(int aligned,
PyArray_Descr *dst_dtype,
PyArray_Descr *mask_dtype,
int move_references,
- PyArray_MaskedStridedUnaryOp **out_stransfer,
- NpyAuxData **out_transferdata,
+ NPY_cast_info *cast_info,
int *out_needs_api)
{
- PyArray_StridedUnaryOp *stransfer = NULL;
- NpyAuxData *transferdata = NULL;
- _masked_wrapper_transfer_data *data;
+ NPY_cast_info_init(cast_info);
- /* TODO: Add struct-based mask_dtype support later */
if (mask_dtype->type_num != NPY_BOOL &&
mask_dtype->type_num != NPY_UINT8) {
PyErr_SetString(PyExc_TypeError,
- "Only bool and uint8 masks are supported at the moment, "
- "structs of bool/uint8 is planned for the future");
+ "Only bool and uint8 masks are supported.");
return NPY_FAIL;
}
- /* TODO: Special case some important cases so they're fast */
+ /* Create the wrapper function's auxdata */
+ _masked_wrapper_transfer_data *data;
+ data = PyMem_Malloc(sizeof(_masked_wrapper_transfer_data));
+ if (data == NULL) {
+ PyErr_NoMemory();
+ return NPY_FAIL;
+ }
+ data->base.free = &_masked_wrapper_transfer_data_free;
+ data->base.clone = &_masked_wrapper_transfer_data_clone;
/* Fall back to wrapping a non-masked transfer function */
+ assert(dst_dtype != NULL);
if (PyArray_GetDTypeTransferFunction(aligned,
src_stride, dst_stride,
src_dtype, dst_dtype,
move_references,
- &stransfer, &transferdata,
+ &data->wrapped,
out_needs_api) != NPY_SUCCEED) {
+ PyMem_Free(data);
return NPY_FAIL;
}
- /* Create the wrapper function's auxdata */
- data = (_masked_wrapper_transfer_data *)PyArray_malloc(
- sizeof(_masked_wrapper_transfer_data));
- if (data == NULL) {
- PyErr_NoMemory();
- NPY_AUXDATA_FREE(transferdata);
- return NPY_FAIL;
- }
-
- /* Fill in the auxdata object */
- memset(data, 0, sizeof(_masked_wrapper_transfer_data));
- data->base.free = &_masked_wrapper_transfer_data_free;
- data->base.clone = &_masked_wrapper_transfer_data_clone;
-
- data->stransfer = stransfer;
- data->transferdata = transferdata;
-
/* If the src object will need a DECREF, get a function to handle that */
if (move_references && PyDataType_REFCHK(src_dtype)) {
- if (get_decsrcref_transfer_function(aligned,
+ if (get_decref_transfer_function(aligned,
src_stride,
src_dtype,
- &data->decsrcref_stransfer,
- &data->decsrcref_transferdata,
+ &data->decref_src,
out_needs_api) != NPY_SUCCEED) {
NPY_AUXDATA_FREE((NpyAuxData *)data);
return NPY_FAIL;
}
-
- *out_stransfer = &_strided_masked_wrapper_decsrcref_transfer_function;
+ cast_info->func = (PyArrayMethod_StridedLoop *)
+ &_strided_masked_wrapper_decref_transfer_function;
}
else {
- *out_stransfer = &_strided_masked_wrapper_transfer_function;
- }
-
- *out_transferdata = (NpyAuxData *)data;
+ NPY_cast_info_init(&data->decref_src);
+ cast_info->func = (PyArrayMethod_StridedLoop *)
+ &_strided_masked_wrapper_transfer_function;
+ }
+ cast_info->auxdata = (NpyAuxData *)data;
+ /* The context is almost unused, but clear it for cleanup. */
+ Py_INCREF(src_dtype);
+ cast_info->descriptors[0] = src_dtype;
+ Py_INCREF(dst_dtype);
+ cast_info->descriptors[1] = dst_dtype;
+ cast_info->context.caller = NULL;
+ cast_info->context.method = NULL;
return NPY_SUCCEED;
}
@@ -3889,8 +3552,6 @@ PyArray_CastRawArrays(npy_intp count,
PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
int move_references)
{
- PyArray_StridedUnaryOp *stransfer = NULL;
- NpyAuxData *transferdata = NULL;
int aligned = 1, needs_api = 0;
/* Make sure the copy is reasonable */
@@ -3914,21 +3575,23 @@ PyArray_CastRawArrays(npy_intp count,
src_dtype->alignment);
/* Get the function to do the casting */
+ NPY_cast_info cast_info;
if (PyArray_GetDTypeTransferFunction(aligned,
src_stride, dst_stride,
src_dtype, dst_dtype,
move_references,
- &stransfer, &transferdata,
+ &cast_info,
&needs_api) != NPY_SUCCEED) {
return NPY_FAIL;
}
/* Cast */
- stransfer(dst, dst_stride, src, src_stride, count,
- src_dtype->elsize, transferdata);
+ char *args[2] = {src, dst};
+ npy_intp strides[2] = {src_stride, dst_stride};
+ cast_info.func(&cast_info.context, args, &count, strides, cast_info.auxdata);
/* Cleanup */
- NPY_AUXDATA_FREE(transferdata);
+ NPY_cast_info_xfree(&cast_info);
/* If needs_api was set to 1, it may have raised a Python exception */
return (needs_api && PyErr_Occurred()) ? NPY_FAIL : NPY_SUCCEED;
diff --git a/numpy/core/src/multiarray/dtype_transfer.h b/numpy/core/src/multiarray/dtype_transfer.h
new file mode 100644
index 000000000..e29ac40b8
--- /dev/null
+++ b/numpy/core/src/multiarray/dtype_transfer.h
@@ -0,0 +1,205 @@
+#ifndef _NPY_DTYPE_TRANSFER_H
+#define _NPY_DTYPE_TRANSFER_H
+
+#include "array_method.h"
+
+
+/*
+ * More than for most functions, cast information needs to be stored in
+ * a few places. Most importantly, in many cases we need to chain or wrap
+ * casts (e.g. structured dtypes).
+ *
+ * This struct provides a place to store all necessary information as
+ * compact as possible. It must be used with the inline functions below
+ * to ensure correct setup and teardown.
+ *
+ * In general, the casting machinery currently handles the correct set up
+ * of the struct.
+ */
+typedef struct {
+ PyArrayMethod_StridedLoop *func;
+ NpyAuxData *auxdata;
+ PyArrayMethod_Context context;
+ /* Storage to be linked from "context" */
+ PyArray_Descr *descriptors[2];
+} NPY_cast_info;
+
+
+/*
+ * Create a new cast-info struct with cast_info->context.descriptors linked.
+ * Compilers should inline this to ensure the whole struct is not actually
+ * copied.
+ * If set up otherwise, func must be NULL'ed to indicate no-cleanup necessary.
+ */
+static NPY_INLINE void
+NPY_cast_info_init(NPY_cast_info *cast_info)
+{
+ cast_info->func = NULL; /* mark as uninitialized. */
+ /*
+ * Support for auxdata being unchanged, in the future, we might add
+ * a scratch space to `NPY_cast_info` and link to that instead.
+ */
+ cast_info->auxdata = NULL;
+ cast_info->context.descriptors = cast_info->descriptors;
+
+ // TODO: Delete this again probably maybe create a new minimal init macro
+ cast_info->context.caller = NULL;
+}
+
+
+/*
+ * Free's all references and data held inside the struct (not the struct).
+ * First checks whether `cast_info.func == NULL`, and assume it is
+ * uninitialized in that case.
+ */
+static NPY_INLINE void
+NPY_cast_info_xfree(NPY_cast_info *cast_info)
+{
+ if (cast_info->func == NULL) {
+ return;
+ }
+ assert(cast_info->context.descriptors == cast_info->descriptors);
+ NPY_AUXDATA_FREE(cast_info->auxdata);
+ Py_DECREF(cast_info->descriptors[0]);
+ Py_XDECREF(cast_info->descriptors[1]);
+ Py_XDECREF(cast_info->context.method);
+ cast_info->func = NULL;
+}
+
+
+/*
+ * Move the data from `original` to `cast_info`. Original is cleared
+ * (its func set to NULL).
+ */
+static NPY_INLINE void
+NPY_cast_info_move(NPY_cast_info *cast_info, NPY_cast_info *original)
+{
+ *cast_info = *original;
+ /* Fix internal pointer: */
+ cast_info->context.descriptors = cast_info->descriptors;
+ /* Mark original to not be cleaned up: */
+ original->func = NULL;
+}
+
+/*
+ * Finalize a copy (INCREF+auxdata clone). This assumes a previous `memcpy`
+ * of the struct.
+ * NOTE: It is acceptable to call this with the same struct if the struct
+ * has been filled by a valid memcpy from an initialized one.
+ */
+static NPY_INLINE int
+NPY_cast_info_copy(NPY_cast_info *cast_info, NPY_cast_info *original)
+{
+ cast_info->context.descriptors = cast_info->descriptors;
+
+ assert(original->func != NULL);
+ cast_info->func = original->func;
+ cast_info->descriptors[0] = original->descriptors[0];
+ Py_XINCREF(cast_info->descriptors[0]);
+ cast_info->descriptors[1] = original->descriptors[1];
+ Py_XINCREF(cast_info->descriptors[1]);
+ cast_info->context.caller = original->context.caller;
+ Py_XINCREF(cast_info->context.caller);
+ cast_info->context.method = original->context.method;
+ Py_XINCREF(cast_info->context.method);
+ if (original->auxdata == NULL) {
+ cast_info->auxdata = NULL;
+ return 0;
+ }
+ cast_info->auxdata = NPY_AUXDATA_CLONE(original->auxdata);
+ if (NPY_UNLIKELY(cast_info->auxdata == NULL)) {
+ /* No need for cleanup, everything but auxdata is initialized fine. */
+ return -1;
+ }
+ return 0;
+}
+
+
+NPY_NO_EXPORT int
+_strided_to_strided_move_references(
+ PyArrayMethod_Context *NPY_UNUSED(context), char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *NPY_UNUSED(auxdata));
+
+NPY_NO_EXPORT int
+_strided_to_strided_copy_references(
+ PyArrayMethod_Context *NPY_UNUSED(context), char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *NPY_UNUSED(auxdata));
+
+
+NPY_NO_EXPORT int
+any_to_object_get_loop(
+ PyArrayMethod_Context *context,
+ int aligned, int move_references,
+ npy_intp *strides,
+ PyArrayMethod_StridedLoop **out_loop,
+ NpyAuxData **out_transferdata,
+ NPY_ARRAYMETHOD_FLAGS *flags);
+
+NPY_NO_EXPORT int
+object_to_any_get_loop(
+ PyArrayMethod_Context *context,
+ int NPY_UNUSED(aligned), int move_references,
+ npy_intp *NPY_UNUSED(strides),
+ PyArrayMethod_StridedLoop **out_loop,
+ NpyAuxData **out_transferdata,
+ NPY_ARRAYMETHOD_FLAGS *flags);
+
+
+NPY_NO_EXPORT int
+wrap_aligned_transferfunction(
+ int aligned, int must_wrap,
+ npy_intp src_stride, npy_intp dst_stride,
+ PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
+ PyArray_Descr *src_wrapped_dtype, PyArray_Descr *dst_wrapped_dtype,
+ PyArrayMethod_StridedLoop **out_stransfer,
+ NpyAuxData **out_transferdata, int *out_needs_api);
+
+
+NPY_NO_EXPORT int
+get_nbo_cast_datetime_transfer_function(int aligned,
+ PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
+ PyArrayMethod_StridedLoop **out_stransfer,
+ NpyAuxData **out_transferdata);
+
+NPY_NO_EXPORT int
+get_nbo_datetime_to_string_transfer_function(
+ PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
+ PyArrayMethod_StridedLoop **out_stransfer,
+ NpyAuxData **out_transferdata);
+
+NPY_NO_EXPORT int
+get_nbo_string_to_datetime_transfer_function(
+ PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
+ PyArrayMethod_StridedLoop **out_stransfer,
+ NpyAuxData **out_transferdata);
+
+NPY_NO_EXPORT int
+get_datetime_to_unicode_transfer_function(int aligned,
+ npy_intp src_stride, npy_intp dst_stride,
+ PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
+ PyArrayMethod_StridedLoop **out_stransfer,
+ NpyAuxData **out_transferdata,
+ int *out_needs_api);
+
+NPY_NO_EXPORT int
+get_unicode_to_datetime_transfer_function(int aligned,
+ npy_intp src_stride, npy_intp dst_stride,
+ PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
+ PyArrayMethod_StridedLoop **out_stransfer,
+ NpyAuxData **out_transferdata,
+ int *out_needs_api);
+
+/* Creates a wrapper around copyswapn or legacy cast functions */
+NPY_NO_EXPORT int
+get_wrapped_legacy_cast_function(int aligned,
+ npy_intp src_stride, npy_intp dst_stride,
+ PyArray_Descr *src_dtype, PyArray_Descr *dst_dtype,
+ int move_references,
+ PyArrayMethod_StridedLoop **out_stransfer,
+ NpyAuxData **out_transferdata,
+ int *out_needs_api, int allow_wrapped);
+
+
+#endif /* _NPY_DTYPE_TRANSFER_H */
diff --git a/numpy/core/src/multiarray/dtypemeta.c b/numpy/core/src/multiarray/dtypemeta.c
index 4c11723e7..597468c50 100644
--- a/numpy/core/src/multiarray/dtypemeta.c
+++ b/numpy/core/src/multiarray/dtypemeta.c
@@ -27,11 +27,20 @@ dtypemeta_dealloc(PyArray_DTypeMeta *self) {
Py_XDECREF(self->scalar_type);
Py_XDECREF(self->singleton);
- Py_XDECREF(self->castingimpls);
+ Py_XDECREF(NPY_DT_SLOTS(self)->castingimpls);
+ PyMem_Free(self->dt_slots);
PyType_Type.tp_dealloc((PyObject *) self);
}
static PyObject *
+dtypemeta_alloc(PyTypeObject *NPY_UNUSED(type), Py_ssize_t NPY_UNUSED(items))
+{
+ PyErr_SetString(PyExc_TypeError,
+ "DTypes can only be created using the NumPy API.");
+ return NULL;
+}
+
+static PyObject *
dtypemeta_new(PyTypeObject *NPY_UNUSED(type),
PyObject *NPY_UNUSED(args), PyObject *NPY_UNUSED(kwds))
{
@@ -81,7 +90,7 @@ dtypemeta_traverse(PyArray_DTypeMeta *type, visitproc visit, void *arg)
* defined types). It should be revised at that time.
*/
assert(0);
- assert(!type->legacy && (PyTypeObject *)type != &PyArrayDescr_Type);
+ assert(!NPY_DT_is_legacy(type) && (PyTypeObject *)type != &PyArrayDescr_Type);
Py_VISIT(type->singleton);
Py_VISIT(type->scalar_type);
return PyType_Type.tp_traverse((PyObject *)type, visit, arg);
@@ -93,7 +102,7 @@ legacy_dtype_default_new(PyArray_DTypeMeta *self,
PyObject *args, PyObject *kwargs)
{
/* TODO: This should allow endianess and possibly metadata */
- if (self->parametric) {
+ if (NPY_DT_is_parametric(self)) {
/* reject parametric ones since we would need to get unit, etc. info */
PyErr_Format(PyExc_TypeError,
"Preliminary-API: Flexible/Parametric legacy DType '%S' can "
@@ -118,7 +127,7 @@ nonparametric_discover_descr_from_pyobject(
PyArray_DTypeMeta *cls, PyObject *obj)
{
/* If the object is of the correct scalar type return our singleton */
- assert(!cls->parametric);
+ assert(!NPY_DT_is_parametric(cls));
Py_INCREF(cls->singleton);
return cls->singleton;
}
@@ -162,12 +171,12 @@ void_discover_descr_from_pyobject(
}
if (PyBytes_Check(obj)) {
PyArray_Descr *descr = PyArray_DescrNewFromType(NPY_VOID);
- Py_ssize_t itemsize = (int)PyBytes_Size(obj);
+ Py_ssize_t itemsize = PyBytes_Size(obj);
if (itemsize > NPY_MAX_INT) {
PyErr_SetString(PyExc_TypeError,
"byte-like to large to store inside array.");
}
- descr->elsize = itemsize;
+ descr->elsize = (int)itemsize;
return descr;
}
PyErr_Format(PyExc_TypeError,
@@ -374,8 +383,11 @@ static PyArray_DTypeMeta *
default_builtin_common_dtype(PyArray_DTypeMeta *cls, PyArray_DTypeMeta *other)
{
assert(cls->type_num < NPY_NTYPES);
- if (!other->legacy || other->type_num > cls->type_num) {
- /* Let the more generic (larger type number) DType handle this */
+ if (!NPY_DT_is_legacy(other) || other->type_num > cls->type_num) {
+ /*
+ * Let the more generic (larger type number) DType handle this
+ * (note that half is after all others, which works out here.)
+ */
Py_INCREF(Py_NotImplemented);
return (PyArray_DTypeMeta *)Py_NotImplemented;
}
@@ -397,10 +409,10 @@ default_builtin_common_dtype(PyArray_DTypeMeta *cls, PyArray_DTypeMeta *other)
static PyArray_DTypeMeta *
string_unicode_common_dtype(PyArray_DTypeMeta *cls, PyArray_DTypeMeta *other)
{
- assert(cls->type_num < NPY_NTYPES);
- if (!other->legacy || other->type_num > cls->type_num ||
- other->type_num == NPY_OBJECT) {
- /* Let the more generic (larger type number) DType handle this */
+ assert(cls->type_num < NPY_NTYPES && cls != other);
+ if (!NPY_DT_is_legacy(other) || (!PyTypeNum_ISNUMBER(other->type_num) &&
+ /* Not numeric so defer unless cls is unicode and other is string */
+ !(cls->type_num == NPY_UNICODE && other->type_num == NPY_STRING))) {
Py_INCREF(Py_NotImplemented);
return (PyArray_DTypeMeta *)Py_NotImplemented;
}
@@ -523,9 +535,9 @@ dtypemeta_wrap_legacy_descriptor(PyArray_Descr *descr)
if (dot) {
scalar_name = dot + 1;
}
- ssize_t name_length = strlen(scalar_name) + 14;
+ Py_ssize_t name_length = strlen(scalar_name) + 14;
- char *tp_name = malloc(name_length);
+ char *tp_name = PyMem_Malloc(name_length);
if (tp_name == NULL) {
PyErr_NoMemory();
return -1;
@@ -533,11 +545,20 @@ dtypemeta_wrap_legacy_descriptor(PyArray_Descr *descr)
snprintf(tp_name, name_length, "numpy.dtype[%s]", scalar_name);
- PyArray_DTypeMeta *dtype_class = malloc(sizeof(PyArray_DTypeMeta));
+ NPY_DType_Slots *dt_slots = PyMem_Malloc(sizeof(NPY_DType_Slots));
+ if (dt_slots == NULL) {
+ PyMem_Free(tp_name);
+ return -1;
+ }
+ memset(dt_slots, '\0', sizeof(NPY_DType_Slots));
+
+ PyArray_DTypeMeta *dtype_class = PyMem_Malloc(sizeof(PyArray_DTypeMeta));
if (dtype_class == NULL) {
- PyDataMem_FREE(tp_name);
+ PyMem_Free(tp_name);
+ PyMem_Free(dt_slots);
return -1;
}
+
/*
* Initialize the struct fields identically to static code by copying
* a prototype instances for everything except our own fields which
@@ -556,21 +577,21 @@ dtypemeta_wrap_legacy_descriptor(PyArray_Descr *descr)
.tp_base = &PyArrayDescr_Type,
.tp_new = (newfunc)legacy_dtype_default_new,
},},
- .legacy = 1,
- .abstract = 0, /* this is a concrete DType */
+ .flags = NPY_DT_LEGACY,
/* Further fields are not common between DTypes */
};
memcpy(dtype_class, &prototype, sizeof(PyArray_DTypeMeta));
/* Fix name of the Type*/
((PyTypeObject *)dtype_class)->tp_name = tp_name;
+ dtype_class->dt_slots = dt_slots;
/* Let python finish the initialization (probably unnecessary) */
if (PyType_Ready((PyTypeObject *)dtype_class) < 0) {
Py_DECREF(dtype_class);
return -1;
}
- dtype_class->castingimpls = PyDict_New();
- if (dtype_class->castingimpls == NULL) {
+ dt_slots->castingimpls = PyDict_New();
+ if (dt_slots->castingimpls == NULL) {
Py_DECREF(dtype_class);
return -1;
}
@@ -583,56 +604,54 @@ dtypemeta_wrap_legacy_descriptor(PyArray_Descr *descr)
Py_INCREF(descr->typeobj);
dtype_class->scalar_type = descr->typeobj;
dtype_class->type_num = descr->type_num;
- dtype_class->type = descr->type;
- dtype_class->f = descr->f;
- dtype_class->kind = descr->kind;
+ dt_slots->f = *(descr->f);
/* Set default functions (correct for most dtypes, override below) */
- dtype_class->default_descr = nonparametric_default_descr;
- dtype_class->discover_descr_from_pyobject = (
+ dt_slots->default_descr = nonparametric_default_descr;
+ dt_slots->discover_descr_from_pyobject = (
nonparametric_discover_descr_from_pyobject);
- dtype_class->is_known_scalar_type = python_builtins_are_known_scalar_types;
- dtype_class->common_dtype = default_builtin_common_dtype;
- dtype_class->common_instance = NULL;
+ dt_slots->is_known_scalar_type = python_builtins_are_known_scalar_types;
+ dt_slots->common_dtype = default_builtin_common_dtype;
+ dt_slots->common_instance = NULL;
if (PyTypeNum_ISSIGNED(dtype_class->type_num)) {
/* Convert our scalars (raise on too large unsigned and NaN, etc.) */
- dtype_class->is_known_scalar_type = signed_integers_is_known_scalar_types;
+ dt_slots->is_known_scalar_type = signed_integers_is_known_scalar_types;
}
if (PyTypeNum_ISUSERDEF(descr->type_num)) {
- dtype_class->common_dtype = legacy_userdtype_common_dtype_function;
+ dt_slots->common_dtype = legacy_userdtype_common_dtype_function;
}
else if (descr->type_num == NPY_OBJECT) {
- dtype_class->common_dtype = object_common_dtype;
+ dt_slots->common_dtype = object_common_dtype;
}
else if (PyTypeNum_ISDATETIME(descr->type_num)) {
/* Datetimes are flexible, but were not considered previously */
- dtype_class->parametric = NPY_TRUE;
- dtype_class->default_descr = datetime_and_timedelta_default_descr;
- dtype_class->discover_descr_from_pyobject = (
+ dtype_class->flags |= NPY_DT_PARAMETRIC;
+ dt_slots->default_descr = datetime_and_timedelta_default_descr;
+ dt_slots->discover_descr_from_pyobject = (
discover_datetime_and_timedelta_from_pyobject);
- dtype_class->common_dtype = datetime_common_dtype;
- dtype_class->common_instance = datetime_type_promotion;
+ dt_slots->common_dtype = datetime_common_dtype;
+ dt_slots->common_instance = datetime_type_promotion;
if (descr->type_num == NPY_DATETIME) {
- dtype_class->is_known_scalar_type = datetime_known_scalar_types;
+ dt_slots->is_known_scalar_type = datetime_known_scalar_types;
}
}
else if (PyTypeNum_ISFLEXIBLE(descr->type_num)) {
- dtype_class->parametric = NPY_TRUE;
+ dtype_class->flags |= NPY_DT_PARAMETRIC;
if (descr->type_num == NPY_VOID) {
- dtype_class->default_descr = void_default_descr;
- dtype_class->discover_descr_from_pyobject = (
+ dt_slots->default_descr = void_default_descr;
+ dt_slots->discover_descr_from_pyobject = (
void_discover_descr_from_pyobject);
- dtype_class->common_instance = void_common_instance;
+ dt_slots->common_instance = void_common_instance;
}
else {
- dtype_class->default_descr = string_and_unicode_default_descr;
- dtype_class->is_known_scalar_type = string_known_scalar_types;
- dtype_class->discover_descr_from_pyobject = (
+ dt_slots->default_descr = string_and_unicode_default_descr;
+ dt_slots->is_known_scalar_type = string_known_scalar_types;
+ dt_slots->discover_descr_from_pyobject = (
string_discover_descr_from_pyobject);
- dtype_class->common_dtype = string_unicode_common_dtype;
- dtype_class->common_instance = string_unicode_common_instance;
+ dt_slots->common_dtype = string_unicode_common_dtype;
+ dt_slots->common_instance = string_unicode_common_instance;
}
}
@@ -649,17 +668,28 @@ dtypemeta_wrap_legacy_descriptor(PyArray_Descr *descr)
}
+static PyObject *
+dtypemeta_get_abstract(PyArray_DTypeMeta *self) {
+ return PyBool_FromLong(NPY_DT_is_abstract(self));
+}
+
+static PyObject *
+dtypemeta_get_parametric(PyArray_DTypeMeta *self) {
+ return PyBool_FromLong(NPY_DT_is_parametric(self));
+}
+
/*
- * Simple exposed information, defined for each DType (class). This is
- * preliminary (the flags should also return bools).
+ * Simple exposed information, defined for each DType (class).
*/
+static PyGetSetDef dtypemeta_getset[] = {
+ {"_abstract", (getter)dtypemeta_get_abstract, NULL, NULL, NULL},
+ {"_parametric", (getter)dtypemeta_get_parametric, NULL, NULL, NULL},
+ {NULL, NULL, NULL, NULL, NULL}
+};
+
static PyMemberDef dtypemeta_members[] = {
- {"_abstract",
- T_BYTE, offsetof(PyArray_DTypeMeta, abstract), READONLY, NULL},
{"type",
T_OBJECT, offsetof(PyArray_DTypeMeta, scalar_type), READONLY, NULL},
- {"_parametric",
- T_BYTE, offsetof(PyArray_DTypeMeta, parametric), READONLY, NULL},
{NULL, 0, 0, 0, NULL},
};
@@ -672,8 +702,10 @@ NPY_NO_EXPORT PyTypeObject PyArrayDTypeMeta_Type = {
/* Types are garbage collected (see dtypemeta_is_gc documentation) */
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
.tp_doc = "Preliminary NumPy API: The Type of NumPy DTypes (metaclass)",
+ .tp_getset = dtypemeta_getset,
.tp_members = dtypemeta_members,
.tp_base = NULL, /* set to PyType_Type at import time */
+ .tp_alloc = dtypemeta_alloc,
.tp_init = (initproc)dtypemeta_init,
.tp_new = dtypemeta_new,
.tp_is_gc = dtypemeta_is_gc,
diff --git a/numpy/core/src/multiarray/dtypemeta.h b/numpy/core/src/multiarray/dtypemeta.h
index 83cf7c07e..200111ac2 100644
--- a/numpy/core/src/multiarray/dtypemeta.h
+++ b/numpy/core/src/multiarray/dtypemeta.h
@@ -1,7 +1,65 @@
#ifndef _NPY_DTYPEMETA_H
#define _NPY_DTYPEMETA_H
+
+/* DType flags, currently private, since we may just expose functions */
+#define NPY_DT_LEGACY 1 << 0
+#define NPY_DT_ABSTRACT 1 << 1
+#define NPY_DT_PARAMETRIC 1 << 2
+
+
+typedef struct {
+ /* DType methods, these could be moved into its own struct */
+ discover_descr_from_pyobject_function *discover_descr_from_pyobject;
+ is_known_scalar_type_function *is_known_scalar_type;
+ default_descr_function *default_descr;
+ common_dtype_function *common_dtype;
+ common_instance_function *common_instance;
+ /*
+ * The casting implementation (ArrayMethod) to convert between two
+ * instances of this DType, stored explicitly for fast access:
+ */
+ PyObject *within_dtype_castingimpl;
+ /*
+ * Dictionary of ArrayMethods representing most possible casts
+ * (structured and object are exceptions).
+ * This should potentially become a weak mapping in the future.
+ */
+ PyObject *castingimpls;
+
+ /*
+ * Storage for `descr->f`, since we may need to allow some customizatoin
+ * here at least in a transition period and we need to set it on every
+ * dtype instance for backward compatibility. (Keep this at end)
+ */
+ PyArray_ArrFuncs f;
+} NPY_DType_Slots;
+
+
#define NPY_DTYPE(descr) ((PyArray_DTypeMeta *)Py_TYPE(descr))
+#define NPY_DT_SLOTS(dtype) ((NPY_DType_Slots *)(dtype)->dt_slots)
+
+#define NPY_DT_is_legacy(dtype) ((dtype)->flags & NPY_DT_LEGACY)
+#define NPY_DT_is_abstract(dtype) ((dtype)->flags & NPY_DT_ABSTRACT)
+#define NPY_DT_is_parametric(dtype) ((dtype)->flags & NPY_DT_PARAMETRIC)
+
+/*
+ * Macros for convenient classmethod calls, since these require
+ * the DType both for the slot lookup and as first arguments.
+ *
+ * (Macros may include NULL checks where appropriate)
+ */
+#define NPY_DT_CALL_discover_descr_from_pyobject(dtype, obj) \
+ NPY_DT_SLOTS(dtype)->discover_descr_from_pyobject(dtype, obj)
+#define NPY_DT_CALL_is_known_scalar_type(dtype, obj) \
+ (NPY_DT_SLOTS(dtype)->is_known_scalar_type != NULL \
+ && NPY_DT_SLOTS(dtype)->is_known_scalar_type(dtype, obj))
+#define NPY_DT_CALL_default_descr(dtype) \
+ NPY_DT_SLOTS(dtype)->default_descr(dtype)
+#define NPY_DT_CALL_common_dtype(dtype, other) \
+ NPY_DT_SLOTS(dtype)->common_dtype(dtype, other)
+
+
/*
* This function will hopefully be phased out or replaced, but was convenient
* for incremental implementation of new DTypes based on DTypeMeta.
diff --git a/numpy/core/src/multiarray/einsum.c.src b/numpy/core/src/multiarray/einsum.c.src
index 6ad375f67..85806fab3 100644
--- a/numpy/core/src/multiarray/einsum.c.src
+++ b/numpy/core/src/multiarray/einsum.c.src
@@ -1100,6 +1100,7 @@ PyArray_EinsteinSum(char *subscripts, npy_intp nop,
char **dataptr;
npy_intp *stride;
npy_intp *countptr;
+ int needs_api;
NPY_BEGIN_THREADS_DEF;
iternext = NpyIter_GetIterNext(iter, NULL);
@@ -1110,12 +1111,13 @@ PyArray_EinsteinSum(char *subscripts, npy_intp nop,
dataptr = NpyIter_GetDataPtrArray(iter);
stride = NpyIter_GetInnerStrideArray(iter);
countptr = NpyIter_GetInnerLoopSizePtr(iter);
+ needs_api = NpyIter_IterationNeedsAPI(iter);
NPY_BEGIN_THREADS_NDITER(iter);
NPY_EINSUM_DBG_PRINT("Einsum loop\n");
do {
sop(nop, dataptr, stride, *countptr);
- } while(iternext(iter));
+ } while (!(needs_api && PyErr_Occurred()) && iternext(iter));
NPY_END_THREADS;
/* If the API was needed, it may have thrown an error */
diff --git a/numpy/core/src/multiarray/einsum_sumprod.c.src b/numpy/core/src/multiarray/einsum_sumprod.c.src
index c58e74287..333b8e188 100644
--- a/numpy/core/src/multiarray/einsum_sumprod.c.src
+++ b/numpy/core/src/multiarray/einsum_sumprod.c.src
@@ -17,30 +17,16 @@
#include "einsum_sumprod.h"
#include "einsum_debug.h"
+#include "simd/simd.h"
+#include "common.h"
-
-#ifdef NPY_HAVE_SSE_INTRINSICS
-#define EINSUM_USE_SSE1 1
-#else
-#define EINSUM_USE_SSE1 0
-#endif
-
-#ifdef NPY_HAVE_SSE2_INTRINSICS
-#define EINSUM_USE_SSE2 1
+// ARM/Neon don't have instructions for aligned memory access
+#ifdef NPY_HAVE_NEON
+ #define EINSUM_IS_ALIGNED(x) 0
#else
-#define EINSUM_USE_SSE2 0
-#endif
-
-#if EINSUM_USE_SSE1
-#include <xmmintrin.h>
-#endif
-
-#if EINSUM_USE_SSE2
-#include <emmintrin.h>
+ #define EINSUM_IS_ALIGNED(x) npy_is_aligned(x, NPY_SIMD_WIDTH)
#endif
-#define EINSUM_IS_SSE_ALIGNED(x) ((((npy_intp)x)&0xf) == 0)
-
/**********************************************/
/**begin repeat
@@ -56,6 +42,10 @@
* npy_ubyte, npy_ushort, npy_uint, npy_ulong, npy_ulonglong,
* npy_float, npy_float, npy_double, npy_longdouble,
* npy_float, npy_double, npy_longdouble#
+ * #sfx = s8, s16, s32, long, s64,
+ * u8, u16, u32, ulong, u64,
+ * half, f32, f64, longdouble,
+ * f32, f64, clongdouble#
* #to = ,,,,,
* ,,,,,
* npy_float_to_half,,,,
@@ -76,8 +66,64 @@
* 0*5,
* 0,0,1,0,
* 0*3#
+ * #NPYV_CHK = 0*5,
+ * 0*5,
+ * 0, NPY_SIMD, NPY_SIMD_F64, 0,
+ * 0*3#
*/
+#if !@complex@
+static NPY_GCC_OPT_3 @temptype@ @name@_sum_of_arr(@type@ *data, npy_intp count)
+{
+ @temptype@ accum = 0;
+#if @NPYV_CHK@ // NPYV check for @type@
+ /* Use aligned instructions if possible */
+ const int is_aligned = EINSUM_IS_ALIGNED(data);
+ const int vstep = npyv_nlanes_@sfx@;
+ npyv_@sfx@ vaccum = npyv_zero_@sfx@();
+ const npy_intp vstepx4 = vstep * 4;
+
+ /**begin repeat1
+ * #cond = if(is_aligned), else#
+ * #ld = loada, load#
+ * #st = storea, store#
+ */
+ @cond@ {
+ for (; count >= vstepx4; count -= vstepx4, data += vstepx4) {
+ /**begin repeat2
+ * #i = 0, 1, 2, 3#
+ */
+ npyv_@sfx@ a@i@ = npyv_@ld@_@sfx@(data + vstep * @i@);
+ /**end repeat2**/
+ npyv_@sfx@ a01 = npyv_add_@sfx@(a0, a1);
+ npyv_@sfx@ a23 = npyv_add_@sfx@(a2, a3);
+ npyv_@sfx@ a0123 = npyv_add_@sfx@(a01, a23);
+ vaccum = npyv_add_@sfx@(a0123, vaccum);
+ }
+ }
+ /**end repeat1**/
+ for (; count > 0; count -= vstep, data += vstep) {
+ npyv_@sfx@ a = npyv_load_tillz_@sfx@(data, count);
+ vaccum = npyv_add_@sfx@(a, vaccum);
+ }
+ accum = npyv_sum_@sfx@(vaccum);
+ npyv_cleanup();
+#else
+#ifndef NPY_DISABLE_OPTIMIZATION
+ for (; count > 4; count -= 4, data += 4) {
+ const @temptype@ a01 = @from@(*data) + @from@(data[1]);
+ const @temptype@ a23 = @from@(data[2]) + @from@(data[3]);
+ accum += a01 + a23;
+ }
+#endif // !NPY_DISABLE_OPTIMIZATION
+ for (; count > 0; --count, data++) {
+ accum += @from@(*data);
+ }
+#endif // NPYV check for @type@
+ return accum;
+}
+#endif
+
/**begin repeat1
* #nop = 1, 2, 3, 1000#
* #noplabel = one, two, three, any#
@@ -243,6 +289,77 @@ finish_after_unrolled_loop:
#elif @nop@ == 2 && !@complex@
+// calculate the multiply and add operation such as dataout = data*scalar+dataout
+static NPY_GCC_OPT_3 void
+@name@_sum_of_products_muladd(@type@ *data, @type@ *data_out, @temptype@ scalar, npy_intp count)
+{
+#if @NPYV_CHK@ // NPYV check for @type@
+ /* Use aligned instructions if possible */
+ const int is_aligned = EINSUM_IS_ALIGNED(data) && EINSUM_IS_ALIGNED(data_out);
+ const int vstep = npyv_nlanes_@sfx@;
+ const npyv_@sfx@ v_scalar = npyv_setall_@sfx@(scalar);
+ /**begin repeat2
+ * #cond = if(is_aligned), else#
+ * #ld = loada, load#
+ * #st = storea, store#
+ */
+ @cond@ {
+ const npy_intp vstepx4 = vstep * 4;
+ for (; count >= vstepx4; count -= vstepx4, data += vstepx4, data_out += vstepx4) {
+ /**begin repeat3
+ * #i = 0, 1, 2, 3#
+ */
+ npyv_@sfx@ b@i@ = npyv_@ld@_@sfx@(data + vstep * @i@);
+ npyv_@sfx@ c@i@ = npyv_@ld@_@sfx@(data_out + vstep * @i@);
+ /**end repeat3**/
+ /**begin repeat3
+ * #i = 0, 1, 2, 3#
+ */
+ npyv_@sfx@ abc@i@ = npyv_muladd_@sfx@(v_scalar, b@i@, c@i@);
+ /**end repeat3**/
+ /**begin repeat3
+ * #i = 0, 1, 2, 3#
+ */
+ npyv_@st@_@sfx@(data_out + vstep * @i@, abc@i@);
+ /**end repeat3**/
+ }
+ }
+ /**end repeat2**/
+ for (; count > 0; count -= vstep, data += vstep, data_out += vstep) {
+ npyv_@sfx@ a = npyv_load_tillz_@sfx@(data, count);
+ npyv_@sfx@ b = npyv_load_tillz_@sfx@(data_out, count);
+ npyv_store_till_@sfx@(data_out, count, npyv_muladd_@sfx@(a, v_scalar, b));
+ }
+ npyv_cleanup();
+#else
+#ifndef NPY_DISABLE_OPTIMIZATION
+ for (; count >= 4; count -= 4, data += 4, data_out += 4) {
+ /**begin repeat2
+ * #i = 0, 1, 2, 3#
+ */
+ const @type@ b@i@ = @from@(data[@i@]);
+ const @type@ c@i@ = @from@(data_out[@i@]);
+ /**end repeat2**/
+ /**begin repeat2
+ * #i = 0, 1, 2, 3#
+ */
+ const @type@ abc@i@ = scalar * b@i@ + c@i@;
+ /**end repeat2**/
+ /**begin repeat2
+ * #i = 0, 1, 2, 3#
+ */
+ data_out[@i@] = @to@(abc@i@);
+ /**end repeat2**/
+ }
+#endif // !NPY_DISABLE_OPTIMIZATION
+ for (; count > 0; --count, ++data, ++data_out) {
+ const @type@ b = @from@(*data);
+ const @type@ c = @from@(*data_out);
+ *data_out = @to@(scalar * b + c);
+ }
+#endif // NPYV check for @type@
+}
+
static void
@name@_sum_of_products_contig_two(int nop, char **dataptr,
npy_intp const *NPY_UNUSED(strides), npy_intp count)
@@ -250,115 +367,80 @@ static void
@type@ *data0 = (@type@ *)dataptr[0];
@type@ *data1 = (@type@ *)dataptr[1];
@type@ *data_out = (@type@ *)dataptr[2];
-
-#if EINSUM_USE_SSE1 && @float32@
- __m128 a, b;
-#elif EINSUM_USE_SSE2 && @float64@
- __m128d a, b;
-#endif
-
NPY_EINSUM_DBG_PRINT1("@name@_sum_of_products_contig_two (%d)\n",
(int)count);
-
-/* This is placed before the main loop to make small counts faster */
-finish_after_unrolled_loop:
- switch (count) {
-/**begin repeat2
- * #i = 6, 5, 4, 3, 2, 1, 0#
- */
- case @i@+1:
- data_out[@i@] = @to@(@from@(data0[@i@]) *
- @from@(data1[@i@]) +
- @from@(data_out[@i@]));
-/**end repeat2**/
- case 0:
- return;
- }
-
-#if EINSUM_USE_SSE1 && @float32@
+ // NPYV check for @type@
+#if @NPYV_CHK@
/* Use aligned instructions if possible */
- if (EINSUM_IS_SSE_ALIGNED(data0) && EINSUM_IS_SSE_ALIGNED(data1) &&
- EINSUM_IS_SSE_ALIGNED(data_out)) {
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-/**begin repeat2
- * #i = 0, 4#
- */
- a = _mm_mul_ps(_mm_load_ps(data0+@i@), _mm_load_ps(data1+@i@));
- b = _mm_add_ps(a, _mm_load_ps(data_out+@i@));
- _mm_store_ps(data_out+@i@, b);
-/**end repeat2**/
- data0 += 8;
- data1 += 8;
- data_out += 8;
+ const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1) &&
+ EINSUM_IS_ALIGNED(data_out);
+ const int vstep = npyv_nlanes_@sfx@;
+
+ /**begin repeat2
+ * #cond = if(is_aligned), else#
+ * #ld = loada, load#
+ * #st = storea, store#
+ */
+ @cond@ {
+ const npy_intp vstepx4 = vstep * 4;
+ for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4, data_out += vstepx4) {
+ /**begin repeat3
+ * #i = 0, 1, 2, 3#
+ */
+ npyv_@sfx@ a@i@ = npyv_@ld@_@sfx@(data0 + vstep * @i@);
+ npyv_@sfx@ b@i@ = npyv_@ld@_@sfx@(data1 + vstep * @i@);
+ npyv_@sfx@ c@i@ = npyv_@ld@_@sfx@(data_out + vstep * @i@);
+ /**end repeat3**/
+ /**begin repeat3
+ * #i = 0, 1, 2, 3#
+ */
+ npyv_@sfx@ abc@i@ = npyv_muladd_@sfx@(a@i@, b@i@, c@i@);
+ /**end repeat3**/
+ /**begin repeat3
+ * #i = 0, 1, 2, 3#
+ */
+ npyv_@st@_@sfx@(data_out + vstep * @i@, abc@i@);
+ /**end repeat3**/
}
-
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
}
-#elif EINSUM_USE_SSE2 && @float64@
- /* Use aligned instructions if possible */
- if (EINSUM_IS_SSE_ALIGNED(data0) && EINSUM_IS_SSE_ALIGNED(data1) &&
- EINSUM_IS_SSE_ALIGNED(data_out)) {
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-/**begin repeat2
- * #i = 0, 2, 4, 6#
- */
- a = _mm_mul_pd(_mm_load_pd(data0+@i@), _mm_load_pd(data1+@i@));
- b = _mm_add_pd(a, _mm_load_pd(data_out+@i@));
- _mm_store_pd(data_out+@i@, b);
-/**end repeat2**/
- data0 += 8;
- data1 += 8;
- data_out += 8;
- }
-
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
+ /**end repeat2**/
+ for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep, data_out += vstep) {
+ npyv_@sfx@ a = npyv_load_tillz_@sfx@(data0, count);
+ npyv_@sfx@ b = npyv_load_tillz_@sfx@(data1, count);
+ npyv_@sfx@ c = npyv_load_tillz_@sfx@(data_out, count);
+ npyv_store_till_@sfx@(data_out, count, npyv_muladd_@sfx@(a, b, c));
}
-#endif
-
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-#if EINSUM_USE_SSE1 && @float32@
-/**begin repeat2
- * #i = 0, 4#
- */
- a = _mm_mul_ps(_mm_loadu_ps(data0+@i@), _mm_loadu_ps(data1+@i@));
- b = _mm_add_ps(a, _mm_loadu_ps(data_out+@i@));
- _mm_storeu_ps(data_out+@i@, b);
-/**end repeat2**/
-#elif EINSUM_USE_SSE2 && @float64@
-/**begin repeat2
- * #i = 0, 2, 4, 6#
- */
- a = _mm_mul_pd(_mm_loadu_pd(data0+@i@), _mm_loadu_pd(data1+@i@));
- b = _mm_add_pd(a, _mm_loadu_pd(data_out+@i@));
- _mm_storeu_pd(data_out+@i@, b);
-/**end repeat2**/
+ npyv_cleanup();
#else
-/**begin repeat2
- * #i = 0, 1, 2, 3, 4, 5, 6, 7#
- */
- data_out[@i@] = @to@(@from@(data0[@i@]) *
- @from@(data1[@i@]) +
- @from@(data_out[@i@]));
-/**end repeat2**/
-#endif
- data0 += 8;
- data1 += 8;
- data_out += 8;
+#ifndef NPY_DISABLE_OPTIMIZATION
+ for (; count >= 4; count -= 4, data0 += 4, data1 += 4, data_out += 4) {
+ /**begin repeat2
+ * #i = 0, 1, 2, 3#
+ */
+ const @type@ a@i@ = @from@(data0[@i@]);
+ const @type@ b@i@ = @from@(data1[@i@]);
+ const @type@ c@i@ = @from@(data_out[@i@]);
+ /**end repeat2**/
+ /**begin repeat2
+ * #i = 0, 1, 2, 3#
+ */
+ const @type@ abc@i@ = a@i@ * b@i@ + c@i@;
+ /**end repeat2**/
+ /**begin repeat2
+ * #i = 0, 1, 2, 3#
+ */
+ data_out[@i@] = @to@(abc@i@);
+ /**end repeat2**/
+ }
+#endif // !NPY_DISABLE_OPTIMIZATION
+ for (; count > 0; --count, ++data0, ++data1, ++data_out) {
+ const @type@ a = @from@(*data0);
+ const @type@ b = @from@(*data1);
+ const @type@ c = @from@(*data_out);
+ *data_out = @to@(a * b + c);
}
+#endif // NPYV check for @type@
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
}
/* Some extra specializations for the two operand case */
@@ -370,245 +452,26 @@ static void
@type@ *data1 = (@type@ *)dataptr[1];
@type@ *data_out = (@type@ *)dataptr[2];
-#if EINSUM_USE_SSE1 && @float32@
- __m128 a, b, value0_sse;
-#elif EINSUM_USE_SSE2 && @float64@
- __m128d a, b, value0_sse;
-#endif
-
NPY_EINSUM_DBG_PRINT1("@name@_sum_of_products_stride0_contig_outcontig_two (%d)\n",
(int)count);
-
-/* This is placed before the main loop to make small counts faster */
-finish_after_unrolled_loop:
- switch (count) {
-/**begin repeat2
- * #i = 6, 5, 4, 3, 2, 1, 0#
- */
- case @i@+1:
- data_out[@i@] = @to@(value0 *
- @from@(data1[@i@]) +
- @from@(data_out[@i@]));
-/**end repeat2**/
- case 0:
- return;
- }
-
-#if EINSUM_USE_SSE1 && @float32@
- value0_sse = _mm_set_ps1(value0);
-
- /* Use aligned instructions if possible */
- if (EINSUM_IS_SSE_ALIGNED(data1) && EINSUM_IS_SSE_ALIGNED(data_out)) {
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-/**begin repeat2
- * #i = 0, 4#
- */
- a = _mm_mul_ps(value0_sse, _mm_load_ps(data1+@i@));
- b = _mm_add_ps(a, _mm_load_ps(data_out+@i@));
- _mm_store_ps(data_out+@i@, b);
-/**end repeat2**/
- data1 += 8;
- data_out += 8;
- }
-
- /* Finish off the loop */
- if (count > 0) {
- goto finish_after_unrolled_loop;
- }
- else {
- return;
- }
- }
-#elif EINSUM_USE_SSE2 && @float64@
- value0_sse = _mm_set1_pd(value0);
-
- /* Use aligned instructions if possible */
- if (EINSUM_IS_SSE_ALIGNED(data1) && EINSUM_IS_SSE_ALIGNED(data_out)) {
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-/**begin repeat2
- * #i = 0, 2, 4, 6#
- */
- a = _mm_mul_pd(value0_sse, _mm_load_pd(data1+@i@));
- b = _mm_add_pd(a, _mm_load_pd(data_out+@i@));
- _mm_store_pd(data_out+@i@, b);
-/**end repeat2**/
- data1 += 8;
- data_out += 8;
- }
-
- /* Finish off the loop */
- if (count > 0) {
- goto finish_after_unrolled_loop;
- }
- else {
- return;
- }
- }
-#endif
-
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-#if EINSUM_USE_SSE1 && @float32@
-/**begin repeat2
- * #i = 0, 4#
- */
- a = _mm_mul_ps(value0_sse, _mm_loadu_ps(data1+@i@));
- b = _mm_add_ps(a, _mm_loadu_ps(data_out+@i@));
- _mm_storeu_ps(data_out+@i@, b);
-/**end repeat2**/
-#elif EINSUM_USE_SSE2 && @float64@
-/**begin repeat2
- * #i = 0, 2, 4, 6#
- */
- a = _mm_mul_pd(value0_sse, _mm_loadu_pd(data1+@i@));
- b = _mm_add_pd(a, _mm_loadu_pd(data_out+@i@));
- _mm_storeu_pd(data_out+@i@, b);
-/**end repeat2**/
-#else
-/**begin repeat2
- * #i = 0, 1, 2, 3, 4, 5, 6, 7#
- */
- data_out[@i@] = @to@(value0 *
- @from@(data1[@i@]) +
- @from@(data_out[@i@]));
-/**end repeat2**/
-#endif
- data1 += 8;
- data_out += 8;
- }
-
- /* Finish off the loop */
- if (count > 0) {
- goto finish_after_unrolled_loop;
- }
+ @name@_sum_of_products_muladd(data1, data_out, value0, count);
+
}
static void
@name@_sum_of_products_contig_stride0_outcontig_two(int nop, char **dataptr,
npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
- @type@ *data0 = (@type@ *)dataptr[0];
@temptype@ value1 = @from@(*(@type@ *)dataptr[1]);
+ @type@ *data0 = (@type@ *)dataptr[0];
@type@ *data_out = (@type@ *)dataptr[2];
-#if EINSUM_USE_SSE1 && @float32@
- __m128 a, b, value1_sse;
-#elif EINSUM_USE_SSE2 && @float64@
- __m128d a, b, value1_sse;
-#endif
-
NPY_EINSUM_DBG_PRINT1("@name@_sum_of_products_contig_stride0_outcontig_two (%d)\n",
(int)count);
-
-/* This is placed before the main loop to make small counts faster */
-finish_after_unrolled_loop:
- switch (count) {
-/**begin repeat2
- * #i = 6, 5, 4, 3, 2, 1, 0#
- */
- case @i@+1:
- data_out[@i@] = @to@(@from@(data0[@i@])*
- value1 +
- @from@(data_out[@i@]));
-/**end repeat2**/
- case 0:
- return;
- }
-
-#if EINSUM_USE_SSE1 && @float32@
- value1_sse = _mm_set_ps1(value1);
-
- /* Use aligned instructions if possible */
- if (EINSUM_IS_SSE_ALIGNED(data0) && EINSUM_IS_SSE_ALIGNED(data_out)) {
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-/**begin repeat2
- * #i = 0, 4#
- */
- a = _mm_mul_ps(_mm_load_ps(data0+@i@), value1_sse);
- b = _mm_add_ps(a, _mm_load_ps(data_out+@i@));
- _mm_store_ps(data_out+@i@, b);
-/**end repeat2**/
- data0 += 8;
- data_out += 8;
- }
-
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
- }
-#elif EINSUM_USE_SSE2 && @float64@
- value1_sse = _mm_set1_pd(value1);
-
- /* Use aligned instructions if possible */
- if (EINSUM_IS_SSE_ALIGNED(data0) && EINSUM_IS_SSE_ALIGNED(data_out)) {
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-/**begin repeat2
- * #i = 0, 2, 4, 6#
- */
- a = _mm_mul_pd(_mm_load_pd(data0+@i@), value1_sse);
- b = _mm_add_pd(a, _mm_load_pd(data_out+@i@));
- _mm_store_pd(data_out+@i@, b);
-/**end repeat2**/
- data0 += 8;
- data_out += 8;
- }
-
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
- }
-#endif
-
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-#if EINSUM_USE_SSE1 && @float32@
-/**begin repeat2
- * #i = 0, 4#
- */
- a = _mm_mul_ps(_mm_loadu_ps(data0+@i@), value1_sse);
- b = _mm_add_ps(a, _mm_loadu_ps(data_out+@i@));
- _mm_storeu_ps(data_out+@i@, b);
-/**end repeat2**/
-#elif EINSUM_USE_SSE2 && @float64@
-/**begin repeat2
- * #i = 0, 2, 4, 6#
- */
- a = _mm_mul_pd(_mm_loadu_pd(data0+@i@), value1_sse);
- b = _mm_add_pd(a, _mm_loadu_pd(data_out+@i@));
- _mm_storeu_pd(data_out+@i@, b);
-/**end repeat2**/
-#else
-/**begin repeat2
- * #i = 0, 1, 2, 3, 4, 5, 6, 7#
- */
- data_out[@i@] = @to@(@from@(data0[@i@])*
- value1 +
- @from@(data_out[@i@]));
-/**end repeat2**/
-#endif
- data0 += 8;
- data_out += 8;
- }
-
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
+ @name@_sum_of_products_muladd(data0, data_out, value1, count);
}
-static void
+static NPY_GCC_OPT_3 void
@name@_sum_of_products_contig_contig_outstride0_two(int nop, char **dataptr,
npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
@@ -616,432 +479,80 @@ static void
@type@ *data1 = (@type@ *)dataptr[1];
@temptype@ accum = 0;
-#if EINSUM_USE_SSE1 && @float32@
- __m128 a, accum_sse = _mm_setzero_ps();
-#elif EINSUM_USE_SSE2 && @float64@
- __m128d a, accum_sse = _mm_setzero_pd();
-#endif
-
NPY_EINSUM_DBG_PRINT1("@name@_sum_of_products_contig_contig_outstride0_two (%d)\n",
(int)count);
-
-/* This is placed before the main loop to make small counts faster */
-finish_after_unrolled_loop:
- switch (count) {
-/**begin repeat2
- * #i = 6, 5, 4, 3, 2, 1, 0#
- */
- case @i@+1:
- accum += @from@(data0[@i@]) * @from@(data1[@i@]);
-/**end repeat2**/
- case 0:
- *(@type@ *)dataptr[2] = @to@(@from@(*(@type@ *)dataptr[2]) + accum);
- return;
- }
-
-#if EINSUM_USE_SSE1 && @float32@
+#if @NPYV_CHK@ // NPYV check for @type@
/* Use aligned instructions if possible */
- if (EINSUM_IS_SSE_ALIGNED(data0) && EINSUM_IS_SSE_ALIGNED(data1)) {
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
- _mm_prefetch(data0 + 512, _MM_HINT_T0);
- _mm_prefetch(data1 + 512, _MM_HINT_T0);
-
-/**begin repeat2
- * #i = 0, 4#
- */
- /*
- * NOTE: This accumulation changes the order, so will likely
- * produce slightly different results.
+ const int is_aligned = EINSUM_IS_ALIGNED(data0) && EINSUM_IS_ALIGNED(data1);
+ const int vstep = npyv_nlanes_@sfx@;
+ npyv_@sfx@ vaccum = npyv_zero_@sfx@();
+
+ /**begin repeat2
+ * #cond = if(is_aligned), else#
+ * #ld = loada, load#
+ * #st = storea, store#
+ */
+ @cond@ {
+ const npy_intp vstepx4 = vstep * 4;
+ for (; count >= vstepx4; count -= vstepx4, data0 += vstepx4, data1 += vstepx4) {
+ /**begin repeat3
+ * #i = 0, 1, 2, 3#
*/
- a = _mm_mul_ps(_mm_load_ps(data0+@i@), _mm_load_ps(data1+@i@));
- accum_sse = _mm_add_ps(accum_sse, a);
-/**end repeat2**/
- data0 += 8;
- data1 += 8;
+ npyv_@sfx@ a@i@ = npyv_@ld@_@sfx@(data0 + vstep * @i@);
+ npyv_@sfx@ b@i@ = npyv_@ld@_@sfx@(data1 + vstep * @i@);
+ /**end repeat3**/
+ npyv_@sfx@ ab3 = npyv_muladd_@sfx@(a3, b3, vaccum);
+ npyv_@sfx@ ab2 = npyv_muladd_@sfx@(a2, b2, ab3);
+ npyv_@sfx@ ab1 = npyv_muladd_@sfx@(a1, b1, ab2);
+ vaccum = npyv_muladd_@sfx@(a0, b0, ab1);
}
-
- /* Add the four SSE values and put in accum */
- a = _mm_shuffle_ps(accum_sse, accum_sse, _MM_SHUFFLE(2,3,0,1));
- accum_sse = _mm_add_ps(a, accum_sse);
- a = _mm_shuffle_ps(accum_sse, accum_sse, _MM_SHUFFLE(1,0,3,2));
- accum_sse = _mm_add_ps(a, accum_sse);
- _mm_store_ss(&accum, accum_sse);
-
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
}
-#elif EINSUM_USE_SSE2 && @float64@
- /* Use aligned instructions if possible */
- if (EINSUM_IS_SSE_ALIGNED(data0) && EINSUM_IS_SSE_ALIGNED(data1)) {
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
- _mm_prefetch(data0 + 512, _MM_HINT_T0);
- _mm_prefetch(data1 + 512, _MM_HINT_T0);
-
-/**begin repeat2
- * #i = 0, 2, 4, 6#
- */
- /*
- * NOTE: This accumulation changes the order, so will likely
- * produce slightly different results.
- */
- a = _mm_mul_pd(_mm_load_pd(data0+@i@), _mm_load_pd(data1+@i@));
- accum_sse = _mm_add_pd(accum_sse, a);
-/**end repeat2**/
- data0 += 8;
- data1 += 8;
- }
-
- /* Add the two SSE2 values and put in accum */
- a = _mm_shuffle_pd(accum_sse, accum_sse, _MM_SHUFFLE2(0,1));
- accum_sse = _mm_add_pd(a, accum_sse);
- _mm_store_sd(&accum, accum_sse);
-
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
+ /**end repeat2**/
+ for (; count > 0; count -= vstep, data0 += vstep, data1 += vstep) {
+ npyv_@sfx@ a = npyv_load_tillz_@sfx@(data0, count);
+ npyv_@sfx@ b = npyv_load_tillz_@sfx@(data1, count);
+ vaccum = npyv_muladd_@sfx@(a, b, vaccum);
}
-#endif
-
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-#if EINSUM_USE_SSE1 && @float32@
- _mm_prefetch(data0 + 512, _MM_HINT_T0);
- _mm_prefetch(data1 + 512, _MM_HINT_T0);
-
-/**begin repeat2
- * #i = 0, 4#
- */
- /*
- * NOTE: This accumulation changes the order, so will likely
- * produce slightly different results.
- */
- a = _mm_mul_ps(_mm_loadu_ps(data0+@i@), _mm_loadu_ps(data1+@i@));
- accum_sse = _mm_add_ps(accum_sse, a);
-/**end repeat2**/
-#elif EINSUM_USE_SSE2 && @float64@
- _mm_prefetch(data0 + 512, _MM_HINT_T0);
- _mm_prefetch(data1 + 512, _MM_HINT_T0);
-
-/**begin repeat2
- * #i = 0, 2, 4, 6#
- */
- /*
- * NOTE: This accumulation changes the order, so will likely
- * produce slightly different results.
- */
- a = _mm_mul_pd(_mm_loadu_pd(data0+@i@), _mm_loadu_pd(data1+@i@));
- accum_sse = _mm_add_pd(accum_sse, a);
-/**end repeat2**/
+ accum = npyv_sum_@sfx@(vaccum);
+ npyv_cleanup();
#else
-/**begin repeat2
- * #i = 0, 1, 2, 3, 4, 5, 6, 7#
- */
- accum += @from@(data0[@i@]) * @from@(data1[@i@]);
-/**end repeat2**/
-#endif
- data0 += 8;
- data1 += 8;
+#ifndef NPY_DISABLE_OPTIMIZATION
+ for (; count >= 4; count -= 4, data0 += 4, data1 += 4) {
+ /**begin repeat2
+ * #i = 0, 1, 2, 3#
+ */
+ const @type@ ab@i@ = @from@(data0[@i@]) * @from@(data1[@i@]);
+ /**end repeat2**/
+ accum += ab0 + ab1 + ab2 + ab3;
}
-
-#if EINSUM_USE_SSE1 && @float32@
- /* Add the four SSE values and put in accum */
- a = _mm_shuffle_ps(accum_sse, accum_sse, _MM_SHUFFLE(2,3,0,1));
- accum_sse = _mm_add_ps(a, accum_sse);
- a = _mm_shuffle_ps(accum_sse, accum_sse, _MM_SHUFFLE(1,0,3,2));
- accum_sse = _mm_add_ps(a, accum_sse);
- _mm_store_ss(&accum, accum_sse);
-#elif EINSUM_USE_SSE2 && @float64@
- /* Add the two SSE2 values and put in accum */
- a = _mm_shuffle_pd(accum_sse, accum_sse, _MM_SHUFFLE2(0,1));
- accum_sse = _mm_add_pd(a, accum_sse);
- _mm_store_sd(&accum, accum_sse);
-#endif
-
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
+#endif // !NPY_DISABLE_OPTIMIZATION
+ for (; count > 0; --count, ++data0, ++data1) {
+ const @type@ a = @from@(*data0);
+ const @type@ b = @from@(*data1);
+ accum += a * b;
+ }
+#endif // NPYV check for @type@
+ *(@type@ *)dataptr[2] = @to@(@from@(*(@type@ *)dataptr[2]) + accum);
}
-static void
+static NPY_GCC_OPT_3 void
@name@_sum_of_products_stride0_contig_outstride0_two(int nop, char **dataptr,
npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
- @temptype@ value0 = @from@(*(@type@ *)dataptr[0]);
@type@ *data1 = (@type@ *)dataptr[1];
- @temptype@ accum = 0;
-
-#if EINSUM_USE_SSE1 && @float32@
- __m128 a, accum_sse = _mm_setzero_ps();
-#elif EINSUM_USE_SSE2 && @float64@
- __m128d a, accum_sse = _mm_setzero_pd();
-#endif
-
- NPY_EINSUM_DBG_PRINT1("@name@_sum_of_products_stride0_contig_outstride0_two (%d)\n",
- (int)count);
-
-/* This is placed before the main loop to make small counts faster */
-finish_after_unrolled_loop:
- switch (count) {
-/**begin repeat2
- * #i = 6, 5, 4, 3, 2, 1, 0#
- */
- case @i@+1:
- accum += @from@(data1[@i@]);
-/**end repeat2**/
- case 0:
- *(@type@ *)dataptr[2] = @to@(@from@(*(@type@ *)dataptr[2]) + value0 * accum);
- return;
- }
-
-#if EINSUM_USE_SSE1 && @float32@
- /* Use aligned instructions if possible */
- if (EINSUM_IS_SSE_ALIGNED(data1)) {
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-/**begin repeat2
- * #i = 0, 4#
- */
- /*
- * NOTE: This accumulation changes the order, so will likely
- * produce slightly different results.
- */
- accum_sse = _mm_add_ps(accum_sse, _mm_load_ps(data1+@i@));
-/**end repeat2**/
- data1 += 8;
- }
- /* Add the four SSE values and put in accum */
- a = _mm_shuffle_ps(accum_sse, accum_sse, _MM_SHUFFLE(2,3,0,1));
- accum_sse = _mm_add_ps(a, accum_sse);
- a = _mm_shuffle_ps(accum_sse, accum_sse, _MM_SHUFFLE(1,0,3,2));
- accum_sse = _mm_add_ps(a, accum_sse);
- _mm_store_ss(&accum, accum_sse);
-
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
- }
-#elif EINSUM_USE_SSE2 && @float64@
- /* Use aligned instructions if possible */
- if (EINSUM_IS_SSE_ALIGNED(data1)) {
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-/**begin repeat2
- * #i = 0, 2, 4, 6#
- */
- /*
- * NOTE: This accumulation changes the order, so will likely
- * produce slightly different results.
- */
- accum_sse = _mm_add_pd(accum_sse, _mm_load_pd(data1+@i@));
-/**end repeat2**/
- data1 += 8;
- }
- /* Add the two SSE2 values and put in accum */
- a = _mm_shuffle_pd(accum_sse, accum_sse, _MM_SHUFFLE2(0,1));
- accum_sse = _mm_add_pd(a, accum_sse);
- _mm_store_sd(&accum, accum_sse);
-
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
- }
-#endif
-
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-#if EINSUM_USE_SSE1 && @float32@
-/**begin repeat2
- * #i = 0, 4#
- */
- /*
- * NOTE: This accumulation changes the order, so will likely
- * produce slightly different results.
- */
- accum_sse = _mm_add_ps(accum_sse, _mm_loadu_ps(data1+@i@));
-/**end repeat2**/
-#elif EINSUM_USE_SSE2 && @float64@
-/**begin repeat2
- * #i = 0, 2, 4, 6#
- */
- /*
- * NOTE: This accumulation changes the order, so will likely
- * produce slightly different results.
- */
- accum_sse = _mm_add_pd(accum_sse, _mm_loadu_pd(data1+@i@));
-/**end repeat2**/
-#else
-/**begin repeat2
- * #i = 0, 1, 2, 3, 4, 5, 6, 7#
- */
- accum += @from@(data1[@i@]);
-/**end repeat2**/
-#endif
- data1 += 8;
- }
-
-#if EINSUM_USE_SSE1 && @float32@
- /* Add the four SSE values and put in accum */
- a = _mm_shuffle_ps(accum_sse, accum_sse, _MM_SHUFFLE(2,3,0,1));
- accum_sse = _mm_add_ps(a, accum_sse);
- a = _mm_shuffle_ps(accum_sse, accum_sse, _MM_SHUFFLE(1,0,3,2));
- accum_sse = _mm_add_ps(a, accum_sse);
- _mm_store_ss(&accum, accum_sse);
-#elif EINSUM_USE_SSE2 && @float64@
- /* Add the two SSE2 values and put in accum */
- a = _mm_shuffle_pd(accum_sse, accum_sse, _MM_SHUFFLE2(0,1));
- accum_sse = _mm_add_pd(a, accum_sse);
- _mm_store_sd(&accum, accum_sse);
-#endif
-
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
+ @temptype@ value0 = @from@(*(@type@ *)dataptr[0]);
+ @temptype@ accum = @name@_sum_of_arr(data1, count);
+ *(@type@ *)dataptr[2] = @to@(@from@(*(@type@ *)dataptr[2]) + value0 * accum);
}
-static void
+static NPY_GCC_OPT_3 void
@name@_sum_of_products_contig_stride0_outstride0_two(int nop, char **dataptr,
npy_intp const *NPY_UNUSED(strides), npy_intp count)
{
@type@ *data0 = (@type@ *)dataptr[0];
@temptype@ value1 = @from@(*(@type@ *)dataptr[1]);
- @temptype@ accum = 0;
-
-#if EINSUM_USE_SSE1 && @float32@
- __m128 a, accum_sse = _mm_setzero_ps();
-#elif EINSUM_USE_SSE2 && @float64@
- __m128d a, accum_sse = _mm_setzero_pd();
-#endif
-
- NPY_EINSUM_DBG_PRINT1("@name@_sum_of_products_contig_stride0_outstride0_two (%d)\n",
- (int)count);
-
-/* This is placed before the main loop to make small counts faster */
-finish_after_unrolled_loop:
- switch (count) {
-/**begin repeat2
- * #i = 6, 5, 4, 3, 2, 1, 0#
- */
- case @i@+1:
- accum += @from@(data0[@i@]);
-/**end repeat2**/
- case 0:
- *(@type@ *)dataptr[2] = @to@(@from@(*(@type@ *)dataptr[2]) + accum * value1);
- return;
- }
-
-#if EINSUM_USE_SSE1 && @float32@
- /* Use aligned instructions if possible */
- if (EINSUM_IS_SSE_ALIGNED(data0)) {
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-/**begin repeat2
- * #i = 0, 4#
- */
- /*
- * NOTE: This accumulation changes the order, so will likely
- * produce slightly different results.
- */
- accum_sse = _mm_add_ps(accum_sse, _mm_load_ps(data0+@i@));
-/**end repeat2**/
- data0 += 8;
- }
- /* Add the four SSE values and put in accum */
- a = _mm_shuffle_ps(accum_sse, accum_sse, _MM_SHUFFLE(2,3,0,1));
- accum_sse = _mm_add_ps(a, accum_sse);
- a = _mm_shuffle_ps(accum_sse, accum_sse, _MM_SHUFFLE(1,0,3,2));
- accum_sse = _mm_add_ps(a, accum_sse);
- _mm_store_ss(&accum, accum_sse);
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
- }
-#elif EINSUM_USE_SSE2 && @float64@
- /* Use aligned instructions if possible */
- if (EINSUM_IS_SSE_ALIGNED(data0)) {
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-/**begin repeat2
- * #i = 0, 2, 4, 6#
- */
- /*
- * NOTE: This accumulation changes the order, so will likely
- * produce slightly different results.
- */
- accum_sse = _mm_add_pd(accum_sse, _mm_load_pd(data0+@i@));
-/**end repeat2**/
- data0 += 8;
- }
- /* Add the two SSE2 values and put in accum */
- a = _mm_shuffle_pd(accum_sse, accum_sse, _MM_SHUFFLE2(0,1));
- accum_sse = _mm_add_pd(a, accum_sse);
- _mm_store_sd(&accum, accum_sse);
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
- }
-#endif
-
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-#if EINSUM_USE_SSE1 && @float32@
-/**begin repeat2
- * #i = 0, 4#
- */
- /*
- * NOTE: This accumulation changes the order, so will likely
- * produce slightly different results.
- */
- accum_sse = _mm_add_ps(accum_sse, _mm_loadu_ps(data0+@i@));
-/**end repeat2**/
-#elif EINSUM_USE_SSE2 && @float64@
-/**begin repeat2
- * #i = 0, 2, 4, 6#
- */
- /*
- * NOTE: This accumulation changes the order, so will likely
- * produce slightly different results.
- */
- accum_sse = _mm_add_pd(accum_sse, _mm_loadu_pd(data0+@i@));
-/**end repeat2**/
-#else
-/**begin repeat2
- * #i = 0, 1, 2, 3, 4, 5, 6, 7#
- */
- accum += @from@(data0[@i@]);
-/**end repeat2**/
-#endif
- data0 += 8;
- }
-
-#if EINSUM_USE_SSE1 && @float32@
- /* Add the four SSE values and put in accum */
- a = _mm_shuffle_ps(accum_sse, accum_sse, _MM_SHUFFLE(2,3,0,1));
- accum_sse = _mm_add_ps(a, accum_sse);
- a = _mm_shuffle_ps(accum_sse, accum_sse, _MM_SHUFFLE(1,0,3,2));
- accum_sse = _mm_add_ps(a, accum_sse);
- _mm_store_ss(&accum, accum_sse);
-#elif EINSUM_USE_SSE2 && @float64@
- /* Add the two SSE2 values and put in accum */
- a = _mm_shuffle_pd(accum_sse, accum_sse, _MM_SHUFFLE2(0,1));
- accum_sse = _mm_add_pd(a, accum_sse);
- _mm_store_sd(&accum, accum_sse);
-#endif
-
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
+ @temptype@ accum = @name@_sum_of_arr(data0, count);
+ *(@type@ *)dataptr[2] = @to@(@from@(*(@type@ *)dataptr[2]) + value1 * accum);
}
#elif @nop@ == 3 && !@complex@
@@ -1143,179 +654,35 @@ static void
#if @nop@ == 1
-static void
+static NPY_GCC_OPT_3 void
@name@_sum_of_products_contig_outstride0_one(int nop, char **dataptr,
npy_intp const *strides, npy_intp count)
{
-#if @complex@
- @temptype@ accum_re = 0, accum_im = 0;
- @temptype@ *data0 = (@temptype@ *)dataptr[0];
-#else
- @temptype@ accum = 0;
- @type@ *data0 = (@type@ *)dataptr[0];
-#endif
-
-#if EINSUM_USE_SSE1 && @float32@
- __m128 a, accum_sse = _mm_setzero_ps();
-#elif EINSUM_USE_SSE2 && @float64@
- __m128d a, accum_sse = _mm_setzero_pd();
-#endif
-
-
- NPY_EINSUM_DBG_PRINT1("@name@_sum_of_products_contig_outstride0_one (%d)\n",
- (int)count);
-
-/* This is placed before the main loop to make small counts faster */
-finish_after_unrolled_loop:
- switch (count) {
-/**begin repeat2
- * #i = 6, 5, 4, 3, 2, 1, 0#
- */
- case @i@+1:
+ NPY_EINSUM_DBG_PRINT1("@name@_sum_of_products_contig_outstride0_one (%d)\n", (int)count);
#if !@complex@
- accum += @from@(data0[@i@]);
-#else /* complex */
- accum_re += data0[2*@i@+0];
- accum_im += data0[2*@i@+1];
-#endif
-/**end repeat2**/
- case 0:
-#if @complex@
- ((@temptype@ *)dataptr[1])[0] += accum_re;
- ((@temptype@ *)dataptr[1])[1] += accum_im;
+ @type@ *data = (@type@ *)dataptr[0];
+ @temptype@ accum = @name@_sum_of_arr(data, count);
+ *((@type@ *)dataptr[1]) = @to@(accum + @from@(*((@type@ *)dataptr[1])));
#else
- *((@type@ *)dataptr[1]) = @to@(accum +
- @from@(*((@type@ *)dataptr[1])));
-#endif
- return;
- }
-
-#if EINSUM_USE_SSE1 && @float32@
- /* Use aligned instructions if possible */
- if (EINSUM_IS_SSE_ALIGNED(data0)) {
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
- _mm_prefetch(data0 + 512, _MM_HINT_T0);
-
-/**begin repeat2
- * #i = 0, 4#
- */
- /*
- * NOTE: This accumulation changes the order, so will likely
- * produce slightly different results.
- */
- accum_sse = _mm_add_ps(accum_sse, _mm_load_ps(data0+@i@));
-/**end repeat2**/
- data0 += 8;
- }
-
- /* Add the four SSE values and put in accum */
- a = _mm_shuffle_ps(accum_sse, accum_sse, _MM_SHUFFLE(2,3,0,1));
- accum_sse = _mm_add_ps(a, accum_sse);
- a = _mm_shuffle_ps(accum_sse, accum_sse, _MM_SHUFFLE(1,0,3,2));
- accum_sse = _mm_add_ps(a, accum_sse);
- _mm_store_ss(&accum, accum_sse);
-
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
- }
-#elif EINSUM_USE_SSE2 && @float64@
- /* Use aligned instructions if possible */
- if (EINSUM_IS_SSE_ALIGNED(data0)) {
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
- _mm_prefetch(data0 + 512, _MM_HINT_T0);
-
-/**begin repeat2
- * #i = 0, 2, 4, 6#
- */
- /*
- * NOTE: This accumulation changes the order, so will likely
- * produce slightly different results.
- */
- accum_sse = _mm_add_pd(accum_sse, _mm_load_pd(data0+@i@));
-/**end repeat2**/
- data0 += 8;
- }
-
- /* Add the two SSE2 values and put in accum */
- a = _mm_shuffle_pd(accum_sse, accum_sse, _MM_SHUFFLE2(0,1));
- accum_sse = _mm_add_pd(a, accum_sse);
- _mm_store_sd(&accum, accum_sse);
-
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
+ @temptype@ accum_re = 0, accum_im = 0;
+ @temptype@ *data0 = (@temptype@ *)dataptr[0];
+#ifndef NPY_DISABLE_OPTIMIZATION
+ for (; count > 4; count -= 4, data0 += 4*2) {
+ const @temptype@ re01 = data0[0] + data0[2];
+ const @temptype@ re23 = data0[4] + data0[6];
+ const @temptype@ im13 = data0[1] + data0[3];
+ const @temptype@ im57 = data0[5] + data0[7];
+ accum_re += re01 + re23;
+ accum_im += im13 + im57;
}
-#endif
-
- /* Unroll the loop by 8 */
- while (count >= 8) {
- count -= 8;
-
-#if EINSUM_USE_SSE1 && @float32@
- _mm_prefetch(data0 + 512, _MM_HINT_T0);
-
-/**begin repeat2
- * #i = 0, 4#
- */
- /*
- * NOTE: This accumulation changes the order, so will likely
- * produce slightly different results.
- */
- accum_sse = _mm_add_ps(accum_sse, _mm_loadu_ps(data0+@i@));
-/**end repeat2**/
-#elif EINSUM_USE_SSE2 && @float64@
- _mm_prefetch(data0 + 512, _MM_HINT_T0);
-
-/**begin repeat2
- * #i = 0, 2, 4, 6#
- */
- /*
- * NOTE: This accumulation changes the order, so will likely
- * produce slightly different results.
- */
- accum_sse = _mm_add_pd(accum_sse, _mm_loadu_pd(data0+@i@));
-/**end repeat2**/
-#else
-/**begin repeat2
- * #i = 0, 1, 2, 3, 4, 5, 6, 7#
- */
-# if !@complex@
- accum += @from@(data0[@i@]);
-# else /* complex */
- accum_re += data0[2*@i@+0];
- accum_im += data0[2*@i@+1];
-# endif
-/**end repeat2**/
-#endif
-
-#if !@complex@
- data0 += 8;
-#else
- data0 += 8*2;
-#endif
+#endif // !NPY_DISABLE_OPTIMIZATION
+ for (; count > 0; --count, data0 += 2) {
+ accum_re += data0[0];
+ accum_im += data0[1];
}
-
-#if EINSUM_USE_SSE1 && @float32@
- /* Add the four SSE values and put in accum */
- a = _mm_shuffle_ps(accum_sse, accum_sse, _MM_SHUFFLE(2,3,0,1));
- accum_sse = _mm_add_ps(a, accum_sse);
- a = _mm_shuffle_ps(accum_sse, accum_sse, _MM_SHUFFLE(1,0,3,2));
- accum_sse = _mm_add_ps(a, accum_sse);
- _mm_store_ss(&accum, accum_sse);
-#elif EINSUM_USE_SSE2 && @float64@
- /* Add the two SSE2 values and put in accum */
- a = _mm_shuffle_pd(accum_sse, accum_sse, _MM_SHUFFLE2(0,1));
- accum_sse = _mm_add_pd(a, accum_sse);
- _mm_store_sd(&accum, accum_sse);
-#endif
-
- /* Finish off the loop */
- goto finish_after_unrolled_loop;
+ ((@temptype@ *)dataptr[1])[0] += accum_re;
+ ((@temptype@ *)dataptr[1])[1] += accum_im;
+#endif // !@complex@
}
#endif /* @nop@ == 1 */
diff --git a/numpy/core/src/multiarray/flagsobject.c b/numpy/core/src/multiarray/flagsobject.c
index 9b7d8deae..fe73c18ee 100644
--- a/numpy/core/src/multiarray/flagsobject.c
+++ b/numpy/core/src/multiarray/flagsobject.c
@@ -200,7 +200,8 @@ arrayflags_dealloc(PyArrayFlagsObject *self)
#define _define_get(UPPER, lower) \
static PyObject * \
- arrayflags_ ## lower ## _get(PyArrayFlagsObject *self) \
+ arrayflags_ ## lower ## _get( \
+ PyArrayFlagsObject *self, void *NPY_UNUSED(ignored)) \
{ \
return PyBool_FromLong((self->flags & (UPPER)) == (UPPER)); \
}
@@ -211,7 +212,8 @@ static char *msg = "future versions will not create a writeable "
#define _define_get_warn(UPPER, lower) \
static PyObject * \
- arrayflags_ ## lower ## _get(PyArrayFlagsObject *self) \
+ arrayflags_ ## lower ## _get( \
+ PyArrayFlagsObject *self, void *NPY_UNUSED(ignored)) \
{ \
if (self->flags & NPY_ARRAY_WARN_ON_WRITE) { \
if (PyErr_Warn(PyExc_FutureWarning, msg) < 0) {\
@@ -236,7 +238,7 @@ _define_get_warn(NPY_ARRAY_ALIGNED|
NPY_ARRAY_C_CONTIGUOUS, carray)
static PyObject *
-arrayflags_updateifcopy_get(PyArrayFlagsObject *self)
+arrayflags_updateifcopy_get(PyArrayFlagsObject *self, void *NPY_UNUSED(ignored))
{
PyObject *item;
/* 2017-Nov-10 1.14 */
@@ -255,7 +257,7 @@ arrayflags_updateifcopy_get(PyArrayFlagsObject *self)
static PyObject *
-arrayflags_forc_get(PyArrayFlagsObject *self)
+arrayflags_forc_get(PyArrayFlagsObject *self, void *NPY_UNUSED(ignored))
{
PyObject *item;
@@ -271,7 +273,7 @@ arrayflags_forc_get(PyArrayFlagsObject *self)
}
static PyObject *
-arrayflags_fnc_get(PyArrayFlagsObject *self)
+arrayflags_fnc_get(PyArrayFlagsObject *self, void *NPY_UNUSED(ignored))
{
PyObject *item;
@@ -287,7 +289,7 @@ arrayflags_fnc_get(PyArrayFlagsObject *self)
}
static PyObject *
-arrayflags_farray_get(PyArrayFlagsObject *self)
+arrayflags_farray_get(PyArrayFlagsObject *self, void *NPY_UNUSED(ignored))
{
PyObject *item;
@@ -305,14 +307,15 @@ arrayflags_farray_get(PyArrayFlagsObject *self)
}
static PyObject *
-arrayflags_num_get(PyArrayFlagsObject *self)
+arrayflags_num_get(PyArrayFlagsObject *self, void *NPY_UNUSED(ignored))
{
return PyLong_FromLong(self->flags);
}
/* relies on setflags order being write, align, uic */
static int
-arrayflags_updateifcopy_set(PyArrayFlagsObject *self, PyObject *obj)
+arrayflags_updateifcopy_set(
+ PyArrayFlagsObject *self, PyObject *obj, void *NPY_UNUSED(ignored))
{
PyObject *res;
@@ -341,7 +344,8 @@ arrayflags_updateifcopy_set(PyArrayFlagsObject *self, PyObject *obj)
/* relies on setflags order being write, align, uic */
static int
-arrayflags_writebackifcopy_set(PyArrayFlagsObject *self, PyObject *obj)
+arrayflags_writebackifcopy_set(
+ PyArrayFlagsObject *self, PyObject *obj, void *NPY_UNUSED(ignored))
{
PyObject *res;
@@ -365,7 +369,8 @@ arrayflags_writebackifcopy_set(PyArrayFlagsObject *self, PyObject *obj)
}
static int
-arrayflags_aligned_set(PyArrayFlagsObject *self, PyObject *obj)
+arrayflags_aligned_set(
+ PyArrayFlagsObject *self, PyObject *obj, void *NPY_UNUSED(ignored))
{
PyObject *res;
@@ -390,7 +395,8 @@ arrayflags_aligned_set(PyArrayFlagsObject *self, PyObject *obj)
}
static int
-arrayflags_writeable_set(PyArrayFlagsObject *self, PyObject *obj)
+arrayflags_writeable_set(
+ PyArrayFlagsObject *self, PyObject *obj, void *NPY_UNUSED(ignored))
{
PyObject *res;
@@ -415,7 +421,8 @@ arrayflags_writeable_set(PyArrayFlagsObject *self, PyObject *obj)
}
static int
-arrayflags_warn_on_write_set(PyArrayFlagsObject *self, PyObject *obj)
+arrayflags_warn_on_write_set(
+ PyArrayFlagsObject *self, PyObject *obj, void *NPY_UNUSED(ignored))
{
/*
* This code should go away in a future release, so do not mangle the
@@ -554,89 +561,89 @@ arrayflags_getitem(PyArrayFlagsObject *self, PyObject *ind)
case 1:
switch(key[0]) {
case 'C':
- return arrayflags_contiguous_get(self);
+ return arrayflags_contiguous_get(self, NULL);
case 'F':
- return arrayflags_fortran_get(self);
+ return arrayflags_fortran_get(self, NULL);
case 'W':
- return arrayflags_writeable_get(self);
+ return arrayflags_writeable_get(self, NULL);
case 'B':
- return arrayflags_behaved_get(self);
+ return arrayflags_behaved_get(self, NULL);
case 'O':
- return arrayflags_owndata_get(self);
+ return arrayflags_owndata_get(self, NULL);
case 'A':
- return arrayflags_aligned_get(self);
+ return arrayflags_aligned_get(self, NULL);
case 'X':
- return arrayflags_writebackifcopy_get(self);
+ return arrayflags_writebackifcopy_get(self, NULL);
case 'U':
- return arrayflags_updateifcopy_get(self);
+ return arrayflags_updateifcopy_get(self, NULL);
default:
goto fail;
}
break;
case 2:
if (strncmp(key, "CA", n) == 0) {
- return arrayflags_carray_get(self);
+ return arrayflags_carray_get(self, NULL);
}
if (strncmp(key, "FA", n) == 0) {
- return arrayflags_farray_get(self);
+ return arrayflags_farray_get(self, NULL);
}
break;
case 3:
if (strncmp(key, "FNC", n) == 0) {
- return arrayflags_fnc_get(self);
+ return arrayflags_fnc_get(self, NULL);
}
break;
case 4:
if (strncmp(key, "FORC", n) == 0) {
- return arrayflags_forc_get(self);
+ return arrayflags_forc_get(self, NULL);
}
break;
case 6:
if (strncmp(key, "CARRAY", n) == 0) {
- return arrayflags_carray_get(self);
+ return arrayflags_carray_get(self, NULL);
}
if (strncmp(key, "FARRAY", n) == 0) {
- return arrayflags_farray_get(self);
+ return arrayflags_farray_get(self, NULL);
}
break;
case 7:
if (strncmp(key,"FORTRAN",n) == 0) {
- return arrayflags_fortran_get(self);
+ return arrayflags_fortran_get(self, NULL);
}
if (strncmp(key,"BEHAVED",n) == 0) {
- return arrayflags_behaved_get(self);
+ return arrayflags_behaved_get(self, NULL);
}
if (strncmp(key,"OWNDATA",n) == 0) {
- return arrayflags_owndata_get(self);
+ return arrayflags_owndata_get(self, NULL);
}
if (strncmp(key,"ALIGNED",n) == 0) {
- return arrayflags_aligned_get(self);
+ return arrayflags_aligned_get(self, NULL);
}
break;
case 9:
if (strncmp(key,"WRITEABLE",n) == 0) {
- return arrayflags_writeable_get(self);
+ return arrayflags_writeable_get(self, NULL);
}
break;
case 10:
if (strncmp(key,"CONTIGUOUS",n) == 0) {
- return arrayflags_contiguous_get(self);
+ return arrayflags_contiguous_get(self, NULL);
}
break;
case 12:
if (strncmp(key, "UPDATEIFCOPY", n) == 0) {
- return arrayflags_updateifcopy_get(self);
+ return arrayflags_updateifcopy_get(self, NULL);
}
if (strncmp(key, "C_CONTIGUOUS", n) == 0) {
- return arrayflags_contiguous_get(self);
+ return arrayflags_contiguous_get(self, NULL);
}
if (strncmp(key, "F_CONTIGUOUS", n) == 0) {
- return arrayflags_fortran_get(self);
+ return arrayflags_fortran_get(self, NULL);
}
break;
case 15:
if (strncmp(key, "WRITEBACKIFCOPY", n) == 0) {
- return arrayflags_writebackifcopy_get(self);
+ return arrayflags_writebackifcopy_get(self, NULL);
}
break;
}
@@ -671,19 +678,19 @@ arrayflags_setitem(PyArrayFlagsObject *self, PyObject *ind, PyObject *item)
}
if (((n==9) && (strncmp(key, "WRITEABLE", n) == 0)) ||
((n==1) && (strncmp(key, "W", n) == 0))) {
- return arrayflags_writeable_set(self, item);
+ return arrayflags_writeable_set(self, item, NULL);
}
else if (((n==7) && (strncmp(key, "ALIGNED", n) == 0)) ||
((n==1) && (strncmp(key, "A", n) == 0))) {
- return arrayflags_aligned_set(self, item);
+ return arrayflags_aligned_set(self, item, NULL);
}
else if (((n==12) && (strncmp(key, "UPDATEIFCOPY", n) == 0)) ||
((n==1) && (strncmp(key, "U", n) == 0))) {
- return arrayflags_updateifcopy_set(self, item);
+ return arrayflags_updateifcopy_set(self, item, NULL);
}
else if (((n==15) && (strncmp(key, "WRITEBACKIFCOPY", n) == 0)) ||
((n==1) && (strncmp(key, "X", n) == 0))) {
- return arrayflags_writebackifcopy_set(self, item);
+ return arrayflags_writebackifcopy_set(self, item, NULL);
}
fail:
@@ -772,7 +779,7 @@ arrayflags_new(PyTypeObject *NPY_UNUSED(self), PyObject *args, PyObject *NPY_UNU
NPY_NO_EXPORT PyTypeObject PyArrayFlags_Type = {
PyVarObject_HEAD_INIT(NULL, 0)
- .tp_name = "numpy.flagsobj",
+ .tp_name = "numpy.core.multiarray.flagsobj",
.tp_basicsize = sizeof(PyArrayFlagsObject),
.tp_dealloc = (destructor)arrayflags_dealloc,
.tp_repr = (reprfunc)arrayflags_print,
diff --git a/numpy/core/src/multiarray/getset.c b/numpy/core/src/multiarray/getset.c
index 3575d6fad..de2a8c14e 100644
--- a/numpy/core/src/multiarray/getset.c
+++ b/numpy/core/src/multiarray/getset.c
@@ -26,26 +26,26 @@
/******************* array attribute get and set routines ******************/
static PyObject *
-array_ndim_get(PyArrayObject *self)
+array_ndim_get(PyArrayObject *self, void *NPY_UNUSED(ignored))
{
return PyLong_FromLong(PyArray_NDIM(self));
}
static PyObject *
-array_flags_get(PyArrayObject *self)
+array_flags_get(PyArrayObject *self, void *NPY_UNUSED(ignored))
{
return PyArray_NewFlagsObject((PyObject *)self);
}
static PyObject *
-array_shape_get(PyArrayObject *self)
+array_shape_get(PyArrayObject *self, void *NPY_UNUSED(ignored))
{
return PyArray_IntTupleFromIntp(PyArray_NDIM(self), PyArray_DIMS(self));
}
static int
-array_shape_set(PyArrayObject *self, PyObject *val)
+array_shape_set(PyArrayObject *self, PyObject *val, void* NPY_UNUSED(ignored))
{
int nd;
PyArrayObject *ret;
@@ -103,13 +103,13 @@ array_shape_set(PyArrayObject *self, PyObject *val)
static PyObject *
-array_strides_get(PyArrayObject *self)
+array_strides_get(PyArrayObject *self, void *NPY_UNUSED(ignored))
{
return PyArray_IntTupleFromIntp(PyArray_NDIM(self), PyArray_STRIDES(self));
}
static int
-array_strides_set(PyArrayObject *self, PyObject *obj)
+array_strides_set(PyArrayObject *self, PyObject *obj, void *NPY_UNUSED(ignored))
{
PyArray_Dims newstrides = {NULL, -1};
PyArrayObject *new;
@@ -182,7 +182,7 @@ array_strides_set(PyArrayObject *self, PyObject *obj)
static PyObject *
-array_priority_get(PyArrayObject *NPY_UNUSED(self))
+array_priority_get(PyArrayObject *NPY_UNUSED(self), void *NPY_UNUSED(ignored))
{
return PyFloat_FromDouble(NPY_PRIORITY);
}
@@ -190,11 +190,11 @@ array_priority_get(PyArrayObject *NPY_UNUSED(self))
static PyObject *
array_typestr_get(PyArrayObject *self)
{
- return arraydescr_protocol_typestr_get(PyArray_DESCR(self));
+ return arraydescr_protocol_typestr_get(PyArray_DESCR(self), NULL);
}
static PyObject *
-array_descr_get(PyArrayObject *self)
+array_descr_get(PyArrayObject *self, void *NPY_UNUSED(ignored))
{
Py_INCREF(PyArray_DESCR(self));
return (PyObject *)PyArray_DESCR(self);
@@ -206,7 +206,7 @@ array_protocol_descr_get(PyArrayObject *self)
PyObject *res;
PyObject *dobj;
- res = arraydescr_protocol_descr_get(PyArray_DESCR(self));
+ res = arraydescr_protocol_descr_get(PyArray_DESCR(self), NULL);
if (res) {
return res;
}
@@ -240,7 +240,7 @@ array_protocol_strides_get(PyArrayObject *self)
static PyObject *
-array_dataptr_get(PyArrayObject *self)
+array_dataptr_get(PyArrayObject *self, void *NPY_UNUSED(ignored))
{
return Py_BuildValue("NO",
PyLong_FromVoidPtr(PyArray_DATA(self)),
@@ -250,7 +250,7 @@ array_dataptr_get(PyArrayObject *self)
}
static PyObject *
-array_ctypes_get(PyArrayObject *self)
+array_ctypes_get(PyArrayObject *self, void *NPY_UNUSED(ignored))
{
PyObject *_numpy_internal;
PyObject *ret;
@@ -265,7 +265,7 @@ array_ctypes_get(PyArrayObject *self)
}
static PyObject *
-array_interface_get(PyArrayObject *self)
+array_interface_get(PyArrayObject *self, void *NPY_UNUSED(ignored))
{
PyObject *dict;
PyObject *obj;
@@ -278,7 +278,7 @@ array_interface_get(PyArrayObject *self)
int ret;
/* dataptr */
- obj = array_dataptr_get(self);
+ obj = array_dataptr_get(self, NULL);
ret = PyDict_SetItemString(dict, "data", obj);
Py_DECREF(obj);
if (ret < 0) {
@@ -302,7 +302,7 @@ array_interface_get(PyArrayObject *self)
return NULL;
}
- obj = arraydescr_protocol_typestr_get(PyArray_DESCR(self));
+ obj = arraydescr_protocol_typestr_get(PyArray_DESCR(self), NULL);
ret = PyDict_SetItemString(dict, "typestr", obj);
Py_DECREF(obj);
if (ret < 0) {
@@ -310,7 +310,7 @@ array_interface_get(PyArrayObject *self)
return NULL;
}
- obj = array_shape_get(self);
+ obj = array_shape_get(self, NULL);
ret = PyDict_SetItemString(dict, "shape", obj);
Py_DECREF(obj);
if (ret < 0) {
@@ -330,13 +330,13 @@ array_interface_get(PyArrayObject *self)
}
static PyObject *
-array_data_get(PyArrayObject *self)
+array_data_get(PyArrayObject *self, void *NPY_UNUSED(ignored))
{
return PyMemoryView_FromObject((PyObject *)self);
}
static int
-array_data_set(PyArrayObject *self, PyObject *op)
+array_data_set(PyArrayObject *self, PyObject *op, void *NPY_UNUSED(ignored))
{
void *buf;
Py_ssize_t buf_len;
@@ -411,41 +411,21 @@ array_data_set(PyArrayObject *self, PyObject *op)
static PyObject *
-array_itemsize_get(PyArrayObject *self)
+array_itemsize_get(PyArrayObject *self, void* NPY_UNUSED(ignored))
{
return PyLong_FromLong((long) PyArray_DESCR(self)->elsize);
}
static PyObject *
-array_size_get(PyArrayObject *self)
+array_size_get(PyArrayObject *self, void* NPY_UNUSED(ignored))
{
- npy_intp size=PyArray_SIZE(self);
-#if NPY_SIZEOF_INTP <= NPY_SIZEOF_LONG
- return PyLong_FromLong((long) size);
-#else
- if (size > NPY_MAX_LONG || size < NPY_MIN_LONG) {
- return PyLong_FromLongLong(size);
- }
- else {
- return PyLong_FromLong((long) size);
- }
-#endif
+ return PyArray_PyIntFromIntp(PyArray_SIZE(self));
}
static PyObject *
-array_nbytes_get(PyArrayObject *self)
+array_nbytes_get(PyArrayObject *self, void *NPY_UNUSED(ignored))
{
- npy_intp nbytes = PyArray_NBYTES(self);
-#if NPY_SIZEOF_INTP <= NPY_SIZEOF_LONG
- return PyLong_FromLong((long) nbytes);
-#else
- if (nbytes > NPY_MAX_LONG || nbytes < NPY_MIN_LONG) {
- return PyLong_FromLongLong(nbytes);
- }
- else {
- return PyLong_FromLong((long) nbytes);
- }
-#endif
+ return PyArray_PyIntFromIntp(PyArray_NBYTES(self));
}
@@ -458,7 +438,7 @@ array_nbytes_get(PyArrayObject *self)
* will be adjusted in that case as well.
*/
static int
-array_descr_set(PyArrayObject *self, PyObject *arg)
+array_descr_set(PyArrayObject *self, PyObject *arg, void *NPY_UNUSED(ignored))
{
PyArray_Descr *newtype = NULL;
@@ -618,7 +598,7 @@ array_descr_set(PyArrayObject *self, PyObject *arg)
}
static PyObject *
-array_struct_get(PyArrayObject *self)
+array_struct_get(PyArrayObject *self, void *NPY_UNUSED(ignored))
{
PyArrayInterface *inter;
@@ -661,7 +641,7 @@ array_struct_get(PyArrayObject *self)
}
inter->data = PyArray_DATA(self);
if (PyDataType_HASFIELDS(PyArray_DESCR(self))) {
- inter->descr = arraydescr_protocol_descr_get(PyArray_DESCR(self));
+ inter->descr = arraydescr_protocol_descr_get(PyArray_DESCR(self), NULL);
if (inter->descr == NULL) {
PyErr_Clear();
}
@@ -684,7 +664,7 @@ array_struct_get(PyArrayObject *self)
}
static PyObject *
-array_base_get(PyArrayObject *self)
+array_base_get(PyArrayObject *self, void *NPY_UNUSED(ignored))
{
if (PyArray_BASE(self) == NULL) {
Py_RETURN_NONE;
@@ -754,7 +734,7 @@ _get_part(PyArrayObject *self, int imag)
*/
static PyObject *
-array_real_get(PyArrayObject *self)
+array_real_get(PyArrayObject *self, void *NPY_UNUSED(ignored))
{
PyArrayObject *ret;
@@ -770,7 +750,7 @@ array_real_get(PyArrayObject *self)
static int
-array_real_set(PyArrayObject *self, PyObject *val)
+array_real_set(PyArrayObject *self, PyObject *val, void *NPY_UNUSED(ignored))
{
PyArrayObject *ret;
PyArrayObject *new;
@@ -808,7 +788,7 @@ array_real_set(PyArrayObject *self, PyObject *val)
*/
static PyObject *
-array_imag_get(PyArrayObject *self)
+array_imag_get(PyArrayObject *self, void *NPY_UNUSED(ignored))
{
PyArrayObject *ret;
@@ -836,7 +816,7 @@ array_imag_get(PyArrayObject *self)
}
static int
-array_imag_set(PyArrayObject *self, PyObject *val)
+array_imag_set(PyArrayObject *self, PyObject *val, void *NPY_UNUSED(ignored))
{
if (val == NULL) {
PyErr_SetString(PyExc_AttributeError,
@@ -870,13 +850,13 @@ array_imag_set(PyArrayObject *self, PyObject *val)
}
static PyObject *
-array_flat_get(PyArrayObject *self)
+array_flat_get(PyArrayObject *self, void *NPY_UNUSED(ignored))
{
return PyArray_IterNew((PyObject *)self);
}
static int
-array_flat_set(PyArrayObject *self, PyObject *val)
+array_flat_set(PyArrayObject *self, PyObject *val, void *NPY_UNUSED(ignored))
{
PyArrayObject *arr = NULL;
int retval = -1;
@@ -948,7 +928,7 @@ array_flat_set(PyArrayObject *self, PyObject *val)
}
static PyObject *
-array_transpose_get(PyArrayObject *self)
+array_transpose_get(PyArrayObject *self, void *NPY_UNUSED(ignored))
{
return PyArray_Transpose(self, NULL);
}
@@ -957,7 +937,7 @@ array_transpose_get(PyArrayObject *self)
--- default sub-class behavior
*/
static PyObject *
-array_finalize_get(PyArrayObject *NPY_UNUSED(self))
+array_finalize_get(PyArrayObject *NPY_UNUSED(self), void *NPY_UNUSED(ignored))
{
Py_RETURN_NONE;
}
diff --git a/numpy/core/src/multiarray/item_selection.c b/numpy/core/src/multiarray/item_selection.c
index 8052e24e4..2b8ea9e79 100644
--- a/numpy/core/src/multiarray/item_selection.c
+++ b/numpy/core/src/multiarray/item_selection.c
@@ -4,6 +4,7 @@
#define NPY_NO_DEPRECATED_API NPY_API_VERSION
#define _MULTIARRAYMODULE
+
#include "numpy/arrayobject.h"
#include "numpy/arrayscalars.h"
@@ -27,7 +28,7 @@
#include "alloc.h"
#include "arraytypes.h"
#include "array_coercion.h"
-
+#include "simd/simd.h"
static NPY_GCC_OPT_3 NPY_INLINE int
npy_fasttake_impl(
@@ -576,6 +577,10 @@ PyArray_PutMask(PyArrayObject *self, PyObject* values0, PyObject* mask0)
return NULL;
}
+ if (PyArray_FailUnlessWriteable(self, "putmask: output array") < 0) {
+ return NULL;
+ }
+
mask = (PyArrayObject *)PyArray_FROM_OTF(mask0, NPY_BOOL,
NPY_ARRAY_CARRAY | NPY_ARRAY_FORCECAST);
if (mask == NULL) {
@@ -2124,22 +2129,199 @@ count_nonzero_bytes_384(const npy_uint64 * w)
return r;
}
+#if NPY_SIMD
+/* Count the zero bytes between `*d` and `end`, updating `*d` to point to where to keep counting from. */
+NPY_FINLINE NPY_GCC_OPT_3 npyv_u8
+count_zero_bytes_u8(const npy_uint8 **d, const npy_uint8 *end, npy_uint8 max_count)
+{
+ const npyv_u8 vone = npyv_setall_u8(1);
+ const npyv_u8 vzero = npyv_zero_u8();
+
+ npy_intp lane_max = 0;
+ npyv_u8 vsum8 = npyv_zero_u8();
+ while (*d < end && lane_max <= max_count - 1) {
+ // we count zeros because `cmpeq` cheaper than `cmpneq` for most archs
+ npyv_u8 vt = npyv_cvt_u8_b8(npyv_cmpeq_u8(npyv_load_u8(*d), vzero));
+ vt = npyv_and_u8(vt, vone);
+ vsum8 = npyv_add_u8(vsum8, vt);
+ *d += npyv_nlanes_u8;
+ lane_max += 1;
+ }
+ return vsum8;
+}
+
+NPY_FINLINE NPY_GCC_OPT_3 npyv_u16x2
+count_zero_bytes_u16(const npy_uint8 **d, const npy_uint8 *end, npy_uint16 max_count)
+{
+ npyv_u16x2 vsum16;
+ vsum16.val[0] = vsum16.val[1] = npyv_zero_u16();
+ npy_intp lane_max = 0;
+ while (*d < end && lane_max <= max_count - NPY_MAX_UINT8) {
+ npyv_u8 vsum8 = count_zero_bytes_u8(d, end, NPY_MAX_UINT8);
+ npyv_u16x2 part = npyv_expand_u16_u8(vsum8);
+ vsum16.val[0] = npyv_add_u16(vsum16.val[0], part.val[0]);
+ vsum16.val[1] = npyv_add_u16(vsum16.val[1], part.val[1]);
+ lane_max += NPY_MAX_UINT8;
+ }
+ return vsum16;
+}
+#endif // NPY_SIMD
+/*
+ * Counts the number of non-zero values in a raw array.
+ * The one loop process is shown below(take SSE2 with 128bits vector for example):
+ * |------------16 lanes---------|
+ *[vsum8] 255 255 255 ... 255 255 255 255 count_zero_bytes_u8: counting 255*16 elements
+ * !!
+ * |------------8 lanes---------|
+ *[vsum16] 65535 65535 65535 ... 65535 count_zero_bytes_u16: counting (2*16-1)*16 elements
+ * 65535 65535 65535 ... 65535
+ * !!
+ * |------------4 lanes---------|
+ *[sum_32_0] 65535 65535 65535 65535 count_nonzero_bytes
+ * 65535 65535 65535 65535
+ *[sum_32_1] 65535 65535 65535 65535
+ * 65535 65535 65535 65535
+ * !!
+ * (2*16-1)*16
+*/
+static NPY_INLINE NPY_GCC_OPT_3 npy_intp
+count_nonzero_u8(const char *data, npy_intp bstride, npy_uintp len)
+{
+ npy_intp count = 0;
+ if (bstride == 1) {
+ #if NPY_SIMD
+ npy_uintp len_m = len & -npyv_nlanes_u8;
+ npy_uintp zcount = 0;
+ for (const char *end = data + len_m; data < end;) {
+ npyv_u16x2 vsum16 = count_zero_bytes_u16((const npy_uint8**)&data, (const npy_uint8*)end, NPY_MAX_UINT16);
+ npyv_u32x2 sum_32_0 = npyv_expand_u32_u16(vsum16.val[0]);
+ npyv_u32x2 sum_32_1 = npyv_expand_u32_u16(vsum16.val[1]);
+ zcount += npyv_sum_u32(npyv_add_u32(
+ npyv_add_u32(sum_32_0.val[0], sum_32_0.val[1]),
+ npyv_add_u32(sum_32_1.val[0], sum_32_1.val[1])
+ ));
+ }
+ len -= len_m;
+ count = len_m - zcount;
+ #else
+ if (!NPY_ALIGNMENT_REQUIRED || npy_is_aligned(data, sizeof(npy_uint64))) {
+ int step = 6 * sizeof(npy_uint64);
+ int left_bytes = len % step;
+ for (const char *end = data + len; data < end - left_bytes; data += step) {
+ count += count_nonzero_bytes_384((const npy_uint64 *)data);
+ }
+ len = left_bytes;
+ }
+ #endif // NPY_SIMD
+ }
+ for (; len > 0; --len, data += bstride) {
+ count += (*data != 0);
+ }
+ return count;
+}
+
+static NPY_INLINE NPY_GCC_OPT_3 npy_intp
+count_nonzero_u16(const char *data, npy_intp bstride, npy_uintp len)
+{
+ npy_intp count = 0;
+#if NPY_SIMD
+ if (bstride == sizeof(npy_uint16)) {
+ npy_uintp zcount = 0, len_m = len & -npyv_nlanes_u16;
+ const npyv_u16 vone = npyv_setall_u16(1);
+ const npyv_u16 vzero = npyv_zero_u16();
+
+ for (npy_uintp lenx = len_m; lenx > 0;) {
+ npyv_u16 vsum16 = npyv_zero_u16();
+ npy_uintp max16 = PyArray_MIN(lenx, NPY_MAX_UINT16*npyv_nlanes_u16);
+
+ for (const char *end = data + max16*bstride; data < end; data += NPY_SIMD_WIDTH) {
+ npyv_u16 mask = npyv_cvt_u16_b16(npyv_cmpeq_u16(npyv_load_u16((npy_uint16*)data), vzero));
+ mask = npyv_and_u16(mask, vone);
+ vsum16 = npyv_add_u16(vsum16, mask);
+ }
+ lenx -= max16;
+ zcount += npyv_sumup_u16(vsum16);
+ }
+ len -= len_m;
+ count = len_m - zcount;
+ }
+#endif
+ for (; len > 0; --len, data += bstride) {
+ count += (*(npy_uint16*)data != 0);
+ }
+ return count;
+}
+
+static NPY_INLINE NPY_GCC_OPT_3 npy_intp
+count_nonzero_u32(const char *data, npy_intp bstride, npy_uintp len)
+{
+ npy_intp count = 0;
+#if NPY_SIMD
+ if (bstride == sizeof(npy_uint32)) {
+ const npy_uintp max_iter = NPY_MAX_UINT32*npyv_nlanes_u32;
+ const npy_uintp len_m = (len > max_iter ? max_iter : len) & -npyv_nlanes_u32;
+ const npyv_u32 vone = npyv_setall_u32(1);
+ const npyv_u32 vzero = npyv_zero_u32();
+
+ npyv_u32 vsum32 = npyv_zero_u32();
+ for (const char *end = data + len_m*bstride; data < end; data += NPY_SIMD_WIDTH) {
+ npyv_u32 mask = npyv_cvt_u32_b32(npyv_cmpeq_u32(npyv_load_u32((npy_uint32*)data), vzero));
+ mask = npyv_and_u32(mask, vone);
+ vsum32 = npyv_add_u32(vsum32, mask);
+ }
+ const npyv_u32 maskevn = npyv_reinterpret_u32_u64(npyv_setall_u64(0xffffffffULL));
+ npyv_u64 odd = npyv_shri_u64(npyv_reinterpret_u64_u32(vsum32), 32);
+ npyv_u64 even = npyv_reinterpret_u64_u32(npyv_and_u32(vsum32, maskevn));
+ count = len_m - npyv_sum_u64(npyv_add_u64(odd, even));
+ len -= len_m;
+ }
+#endif
+ for (; len > 0; --len, data += bstride) {
+ count += (*(npy_uint32*)data != 0);
+ }
+ return count;
+}
+
+static NPY_INLINE NPY_GCC_OPT_3 npy_intp
+count_nonzero_u64(const char *data, npy_intp bstride, npy_uintp len)
+{
+ npy_intp count = 0;
+#if NPY_SIMD
+ if (bstride == sizeof(npy_uint64)) {
+ const npy_uintp len_m = len & -npyv_nlanes_u64;
+ const npyv_u64 vone = npyv_setall_u64(1);
+ const npyv_u64 vzero = npyv_zero_u64();
+
+ npyv_u64 vsum64 = npyv_zero_u64();
+ for (const char *end = data + len_m*bstride; data < end; data += NPY_SIMD_WIDTH) {
+ npyv_u64 mask = npyv_cvt_u64_b64(npyv_cmpeq_u64(npyv_load_u64((npy_uint64*)data), vzero));
+ mask = npyv_and_u64(mask, vone);
+ vsum64 = npyv_add_u64(vsum64, mask);
+ }
+ len -= len_m;
+ count = len_m - npyv_sum_u64(vsum64);
+ }
+#endif
+ for (; len > 0; --len, data += bstride) {
+ count += (*(npy_uint64*)data != 0);
+ }
+ return count;
+}
/*
* Counts the number of True values in a raw boolean array. This
* is a low-overhead function which does no heap allocations.
*
* Returns -1 on error.
*/
-NPY_NO_EXPORT npy_intp
-count_boolean_trues(int ndim, char *data, npy_intp const *ashape, npy_intp const *astrides)
+static NPY_GCC_OPT_3 npy_intp
+count_nonzero_int(int ndim, char *data, const npy_intp *ashape, const npy_intp *astrides, int elsize)
{
+ assert(elsize <= 8);
int idim;
npy_intp shape[NPY_MAXDIMS], strides[NPY_MAXDIMS];
- npy_intp i, coord[NPY_MAXDIMS];
- npy_intp count = 0;
- NPY_BEGIN_THREADS_DEF;
+ npy_intp coord[NPY_MAXDIMS];
- /* Use raw iteration with no heap memory allocation */
+ // Use raw iteration with no heap memory allocation
if (PyArray_PrepareOneRawArrayIter(
ndim, ashape,
data, astrides,
@@ -2148,46 +2330,44 @@ count_boolean_trues(int ndim, char *data, npy_intp const *ashape, npy_intp const
return -1;
}
- /* Handle zero-sized array */
+ // Handle zero-sized array
if (shape[0] == 0) {
return 0;
}
+ NPY_BEGIN_THREADS_DEF;
NPY_BEGIN_THREADS_THRESHOLDED(shape[0]);
- /* Special case for contiguous inner loop */
- if (strides[0] == 1) {
- NPY_RAW_ITER_START(idim, ndim, coord, shape) {
- /* Process the innermost dimension */
- const char *d = data;
- const char *e = data + shape[0];
- if (NPY_CPU_HAVE_UNALIGNED_ACCESS ||
- npy_is_aligned(d, sizeof(npy_uint64))) {
- npy_uintp stride = 6 * sizeof(npy_uint64);
- for (; d < e - (shape[0] % stride); d += stride) {
- count += count_nonzero_bytes_384((const npy_uint64 *)d);
- }
- }
- for (; d < e; ++d) {
- count += (*d != 0);
- }
- } NPY_RAW_ITER_ONE_NEXT(idim, ndim, coord, shape, data, strides);
- }
- /* General inner loop */
- else {
- NPY_RAW_ITER_START(idim, ndim, coord, shape) {
- char *d = data;
- /* Process the innermost dimension */
- for (i = 0; i < shape[0]; ++i, d += strides[0]) {
- count += (*d != 0);
- }
- } NPY_RAW_ITER_ONE_NEXT(idim, ndim, coord, shape, data, strides);
+ #define NONZERO_CASE(LEN, SFX) \
+ case LEN: \
+ NPY_RAW_ITER_START(idim, ndim, coord, shape) { \
+ count += count_nonzero_##SFX(data, strides[0], shape[0]); \
+ } NPY_RAW_ITER_ONE_NEXT(idim, ndim, coord, shape, data, strides); \
+ break
+
+ npy_intp count = 0;
+ switch(elsize) {
+ NONZERO_CASE(1, u8);
+ NONZERO_CASE(2, u16);
+ NONZERO_CASE(4, u32);
+ NONZERO_CASE(8, u64);
}
+ #undef NONZERO_CASE
NPY_END_THREADS;
-
return count;
}
+/*
+ * Counts the number of True values in a raw boolean array. This
+ * is a low-overhead function which does no heap allocations.
+ *
+ * Returns -1 on error.
+ */
+NPY_NO_EXPORT NPY_GCC_OPT_3 npy_intp
+count_boolean_trues(int ndim, char *data, npy_intp const *ashape, npy_intp const *astrides)
+{
+ return count_nonzero_int(ndim, data, ashape, astrides, 1);
+}
/*NUMPY_API
* Counts the number of non-zero elements in the array.
@@ -2210,14 +2390,22 @@ PyArray_CountNonzero(PyArrayObject *self)
npy_intp *strideptr, *innersizeptr;
NPY_BEGIN_THREADS_DEF;
- /* Special low-overhead version specific to the boolean type */
+ // Special low-overhead version specific to the boolean/int types
dtype = PyArray_DESCR(self);
- if (dtype->type_num == NPY_BOOL) {
- return count_boolean_trues(PyArray_NDIM(self), PyArray_DATA(self),
- PyArray_DIMS(self), PyArray_STRIDES(self));
+ switch(dtype->kind) {
+ case 'u':
+ case 'i':
+ case 'b':
+ if (dtype->elsize > 8) {
+ break;
+ }
+ return count_nonzero_int(
+ PyArray_NDIM(self), PyArray_BYTES(self), PyArray_DIMS(self),
+ PyArray_STRIDES(self), dtype->elsize
+ );
}
- nonzero = PyArray_DESCR(self)->f->nonzero;
+ nonzero = PyArray_DESCR(self)->f->nonzero;
/* If it's a trivial one-dimensional loop, don't use an iterator */
if (PyArray_TRIVIALLY_ITERABLE(self)) {
needs_api = PyDataType_FLAGCHK(dtype, NPY_NEEDS_PYAPI);
diff --git a/numpy/core/src/multiarray/iterators.c b/numpy/core/src/multiarray/iterators.c
index 3ebd4c858..f724837ce 100644
--- a/numpy/core/src/multiarray/iterators.c
+++ b/numpy/core/src/multiarray/iterators.c
@@ -15,6 +15,7 @@
#include "iterators.h"
#include "ctors.h"
#include "common.h"
+#include "conversion_utils.h"
#include "array_coercion.h"
#define NEWAXIS_INDEX -1
@@ -1062,15 +1063,17 @@ static PyMemberDef iter_members[] = {
T_OBJECT,
offsetof(PyArrayIterObject, ao),
READONLY, NULL},
- {"index",
- T_INT,
- offsetof(PyArrayIterObject, index),
- READONLY, NULL},
{NULL, 0, 0, 0, NULL},
};
static PyObject *
-iter_coords_get(PyArrayIterObject *self)
+iter_index_get(PyArrayIterObject *self, void *NPY_UNUSED(ignored))
+{
+ return PyArray_PyIntFromIntp(self->index);
+}
+
+static PyObject *
+iter_coords_get(PyArrayIterObject *self, void *NPY_UNUSED(ignored))
{
int nd;
nd = PyArray_NDIM(self->ao);
@@ -1095,10 +1098,12 @@ iter_coords_get(PyArrayIterObject *self)
}
static PyGetSetDef iter_getsets[] = {
+ {"index",
+ (getter)iter_index_get,
+ NULL, NULL, NULL},
{"coords",
(getter)iter_coords_get,
- NULL,
- NULL, NULL},
+ NULL, NULL, NULL},
{NULL, NULL, NULL, NULL, NULL},
};
@@ -1408,43 +1413,25 @@ arraymultiter_dealloc(PyArrayMultiIterObject *multi)
}
static PyObject *
-arraymultiter_size_get(PyArrayMultiIterObject *self)
+arraymultiter_size_get(PyArrayMultiIterObject *self, void *NPY_UNUSED(ignored))
{
-#if NPY_SIZEOF_INTP <= NPY_SIZEOF_LONG
- return PyLong_FromLong((long) self->size);
-#else
- if (self->size < NPY_MAX_LONG) {
- return PyLong_FromLong((long) self->size);
- }
- else {
- return PyLong_FromLongLong((npy_longlong) self->size);
- }
-#endif
+ return PyArray_PyIntFromIntp(self->size);
}
static PyObject *
-arraymultiter_index_get(PyArrayMultiIterObject *self)
+arraymultiter_index_get(PyArrayMultiIterObject *self, void *NPY_UNUSED(ignored))
{
-#if NPY_SIZEOF_INTP <= NPY_SIZEOF_LONG
- return PyLong_FromLong((long) self->index);
-#else
- if (self->size < NPY_MAX_LONG) {
- return PyLong_FromLong((long) self->index);
- }
- else {
- return PyLong_FromLongLong((npy_longlong) self->index);
- }
-#endif
+ return PyArray_PyIntFromIntp(self->index);
}
static PyObject *
-arraymultiter_shape_get(PyArrayMultiIterObject *self)
+arraymultiter_shape_get(PyArrayMultiIterObject *self, void *NPY_UNUSED(ignored))
{
return PyArray_IntTupleFromIntp(self->nd, self->dimensions);
}
static PyObject *
-arraymultiter_iters_get(PyArrayMultiIterObject *self)
+arraymultiter_iters_get(PyArrayMultiIterObject *self, void *NPY_UNUSED(ignored))
{
PyObject *res;
int i, n;
diff --git a/numpy/core/src/multiarray/legacy_dtype_implementation.c b/numpy/core/src/multiarray/legacy_dtype_implementation.c
index 3ce4710fd..9b4946da3 100644
--- a/numpy/core/src/multiarray/legacy_dtype_implementation.c
+++ b/numpy/core/src/multiarray/legacy_dtype_implementation.c
@@ -1,10 +1,10 @@
/*
- * This file hosts legacy implementations of certain functions for
- * which alternatives exists, but the old functions are still required
- * in certain code paths, or until the code transition is finalized.
+ * The only function exported here is `PyArray_LegacyCanCastTypeTo`, which
+ * is currently still in use when first registering a userdtype.
*
- * This code should typically not require modification, and if modified
- * similar changes may be necessary in the new version.
+ * The extremely limited use means that it can probably remain unmaintained
+ * until such a time where legay user dtypes are deprecated and removed
+ * entirely.
*/
#define NPY_NO_DEPRECATED_API NPY_API_VERSION
@@ -78,7 +78,7 @@ _equivalent_subarrays(PyArray_ArrayDescr *sub1, PyArray_ArrayDescr *sub2)
}
-NPY_NO_EXPORT unsigned char
+static unsigned char
PyArray_LegacyEquivTypes(PyArray_Descr *type1, PyArray_Descr *type2)
{
int type_num1, type_num2, size1, size2;
@@ -116,7 +116,7 @@ PyArray_LegacyEquivTypes(PyArray_Descr *type1, PyArray_Descr *type2)
}
-NPY_NO_EXPORT unsigned char
+static unsigned char
PyArray_LegacyEquivTypenums(int typenum1, int typenum2)
{
PyArray_Descr *d1, *d2;
@@ -135,7 +135,7 @@ PyArray_LegacyEquivTypenums(int typenum1, int typenum2)
}
-NPY_NO_EXPORT int
+static int
PyArray_LegacyCanCastSafely(int fromtype, int totype)
{
PyArray_Descr *from;
@@ -161,15 +161,17 @@ PyArray_LegacyCanCastSafely(int fromtype, int totype)
while (*curtype != NPY_NOTYPE) {
if (*curtype++ == totype) {
+ Py_DECREF(from);
return 1;
}
}
}
+ Py_DECREF(from);
return 0;
}
-NPY_NO_EXPORT npy_bool
+static npy_bool
PyArray_LegacyCanCastTo(PyArray_Descr *from, PyArray_Descr *to)
{
int from_type_num = from->type_num;
@@ -549,168 +551,3 @@ PyArray_LegacyCanCastTypeTo(PyArray_Descr *from, PyArray_Descr *to,
}
}
-
-/*
- * Legacy function to find the correct dtype when casting from any built-in
- * dtype to NPY_STRING, NPY_UNICODE, NPY_VOID, and NPY_DATETIME with generic
- * units.
- *
- * This function returns a dtype based on flex_dtype and the values in
- * data_dtype. It also calls Py_DECREF on the flex_dtype. If the
- * flex_dtype is not flexible, it returns it as-is.
- *
- * Usually, if data_obj is not an array, dtype should be the result
- * given by the PyArray_GetArrayParamsFromObject function.
- *
- * If *flex_dtype is NULL, returns immediately, without setting an
- * exception, leaving any previous error handling intact.
- */
-NPY_NO_EXPORT PyArray_Descr *
-PyArray_AdaptFlexibleDType(PyArray_Descr *data_dtype, PyArray_Descr *flex_dtype)
-{
- PyArray_DatetimeMetaData *meta;
- PyArray_Descr *retval = NULL;
- int flex_type_num;
-
- if (flex_dtype == NULL) {
- return retval;
- }
-
- flex_type_num = flex_dtype->type_num;
-
- /* Flexible types with expandable size */
- if (PyDataType_ISUNSIZED(flex_dtype)) {
- /* First replace the flex_dtype */
- retval = PyArray_DescrNew(flex_dtype);
- Py_DECREF(flex_dtype);
- if (retval == NULL) {
- return retval;
- }
-
- if (data_dtype->type_num == flex_type_num ||
- flex_type_num == NPY_VOID) {
- (retval)->elsize = data_dtype->elsize;
- }
- else if (flex_type_num == NPY_STRING || flex_type_num == NPY_UNICODE) {
- npy_intp size = 8;
-
- /*
- * Get a string-size estimate of the input. These
- * are generallly the size needed, rounded up to
- * a multiple of eight.
- */
- switch (data_dtype->type_num) {
- case NPY_BOOL:
- case NPY_UBYTE:
- case NPY_BYTE:
- case NPY_USHORT:
- case NPY_SHORT:
- case NPY_UINT:
- case NPY_INT:
- case NPY_ULONG:
- case NPY_LONG:
- case NPY_ULONGLONG:
- case NPY_LONGLONG:
- if (data_dtype->kind == 'b') {
- /* 5 chars needed for cast to 'True' or 'False' */
- size = 5;
- }
- else if (data_dtype->elsize > 8 ||
- data_dtype->elsize < 0) {
- /*
- * Element size should never be greater than 8 or
- * less than 0 for integer type, but just in case...
- */
- break;
- }
- else if (data_dtype->kind == 'u') {
- size = REQUIRED_STR_LEN[data_dtype->elsize];
- }
- else if (data_dtype->kind == 'i') {
- /* Add character for sign symbol */
- size = REQUIRED_STR_LEN[data_dtype->elsize] + 1;
- }
- break;
- case NPY_HALF:
- case NPY_FLOAT:
- case NPY_DOUBLE:
- size = 32;
- break;
- case NPY_LONGDOUBLE:
- size = 48;
- break;
- case NPY_CFLOAT:
- case NPY_CDOUBLE:
- size = 2 * 32;
- break;
- case NPY_CLONGDOUBLE:
- size = 2 * 48;
- break;
- case NPY_OBJECT:
- size = 64;
- break;
- case NPY_STRING:
- case NPY_VOID:
- size = data_dtype->elsize;
- break;
- case NPY_UNICODE:
- size = data_dtype->elsize / 4;
- break;
- case NPY_DATETIME:
- meta = get_datetime_metadata_from_dtype(data_dtype);
- if (meta == NULL) {
- Py_DECREF(retval);
- return NULL;
- }
- size = get_datetime_iso_8601_strlen(0, meta->base);
- break;
- case NPY_TIMEDELTA:
- size = 21;
- break;
- }
-
- if (flex_type_num == NPY_STRING) {
- retval->elsize = size;
- }
- else if (flex_type_num == NPY_UNICODE) {
- retval->elsize = size * 4;
- }
- }
- else {
- /*
- * We should never get here, but just in case someone adds
- * a new flex dtype...
- */
- PyErr_SetString(PyExc_TypeError,
- "don't know how to adapt flex dtype");
- Py_DECREF(retval);
- return NULL;
- }
- }
- /* Flexible type with generic time unit that adapts */
- else if (flex_type_num == NPY_DATETIME ||
- flex_type_num == NPY_TIMEDELTA) {
- meta = get_datetime_metadata_from_dtype(flex_dtype);
- retval = flex_dtype;
- if (meta == NULL) {
- return NULL;
- }
-
- if (meta->base == NPY_FR_GENERIC) {
- if (data_dtype->type_num == NPY_DATETIME ||
- data_dtype->type_num == NPY_TIMEDELTA) {
- meta = get_datetime_metadata_from_dtype(data_dtype);
- if (meta == NULL) {
- return NULL;
- }
-
- retval = create_datetime_dtype(flex_type_num, meta);
- Py_DECREF(flex_dtype);
- }
- }
- }
- else {
- retval = flex_dtype;
- }
- return retval;
-}
diff --git a/numpy/core/src/multiarray/legacy_dtype_implementation.h b/numpy/core/src/multiarray/legacy_dtype_implementation.h
index ca171d773..b36eb019a 100644
--- a/numpy/core/src/multiarray/legacy_dtype_implementation.h
+++ b/numpy/core/src/multiarray/legacy_dtype_implementation.h
@@ -1,40 +1,8 @@
#ifndef _NPY_LEGACY_DTYPE_IMPLEMENTATION_H
#define _NPY_LEGACY_DTYPE_IMPLEMENTATION_H
-
-NPY_NO_EXPORT unsigned char
-PyArray_LegacyEquivTypes(PyArray_Descr *type1, PyArray_Descr *type2);
-
-NPY_NO_EXPORT unsigned char
-PyArray_LegacyEquivTypenums(int typenum1, int typenum2);
-
-NPY_NO_EXPORT int
-PyArray_LegacyCanCastSafely(int fromtype, int totype);
-
-NPY_NO_EXPORT npy_bool
-PyArray_LegacyCanCastTo(PyArray_Descr *from, PyArray_Descr *to);
-
NPY_NO_EXPORT npy_bool
PyArray_LegacyCanCastTypeTo(PyArray_Descr *from, PyArray_Descr *to,
NPY_CASTING casting);
-/*
- * This function calls Py_DECREF on flex_dtype, and replaces it with
- * a new dtype that has been adapted based on the values in data_dtype
- * and data_obj. If the flex_dtype is not flexible, it returns it as-is.
- *
- * Usually, if data_obj is not an array, dtype should be the result
- * given by the PyArray_GetArrayParamsFromObject function.
- *
- * The data_obj may be NULL if just a dtype is known for the source.
- *
- * If *flex_dtype is NULL, returns immediately, without setting an
- * exception, leaving any previous error handling intact.
- *
- * The current flexible dtypes include NPY_STRING, NPY_UNICODE, NPY_VOID,
- * and NPY_DATETIME with generic units.
- */
-NPY_NO_EXPORT PyArray_Descr *
-PyArray_AdaptFlexibleDType(PyArray_Descr *data_dtype, PyArray_Descr *flex_dtype);
-
#endif /*_NPY_LEGACY_DTYPE_IMPLEMENTATION_H*/
diff --git a/numpy/core/src/multiarray/lowlevel_strided_loops.c.src b/numpy/core/src/multiarray/lowlevel_strided_loops.c.src
index 0590558be..e533e4932 100644
--- a/numpy/core/src/multiarray/lowlevel_strided_loops.c.src
+++ b/numpy/core/src/multiarray/lowlevel_strided_loops.c.src
@@ -19,6 +19,8 @@
#include "lowlevel_strided_loops.h"
#include "array_assign.h"
+#include "array_method.h"
+#include "usertypes.h"
/*
@@ -29,7 +31,7 @@
* instructions (16 byte).
* So this flag can only be enabled if autovectorization is disabled.
*/
-#if NPY_CPU_HAVE_UNALIGNED_ACCESS
+#if NPY_ALIGNMENT_REQUIRED
# define NPY_USE_UNALIGNED_ACCESS 0
#else
# define NPY_USE_UNALIGNED_ACCESS 0
@@ -114,11 +116,20 @@ static int
#if @is_aligned@ && @is_swap@ == 0 && @elsize@ <= NPY_SIZEOF_INTP
NPY_GCC_UNROLL_LOOPS
#endif
-@prefix@_@oper@_size@elsize@(char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp NPY_UNUSED(src_itemsize),
- NpyAuxData *NPY_UNUSED(data))
+@prefix@_@oper@_size@elsize@(
+ PyArrayMethod_Context *context, char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *NPY_UNUSED(auxdata))
{
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+#if !@src_contig@
+ npy_intp src_stride = strides[0];
+#endif
+#if !@dst_contig@
+ npy_intp dst_stride = strides[1];
+#endif
+
#if @is_aligned@
/* sanity check */
assert(N == 0 || npy_is_aligned(dst, _UINT_ALIGN(@type@)));
@@ -184,12 +195,17 @@ static int
*/
#if (@src_contig@ == 0) && @is_aligned@
static NPY_GCC_OPT_3 int
-@prefix@_@oper@_size@elsize@_srcstride0(char *dst,
- npy_intp dst_stride,
- char *src, npy_intp NPY_UNUSED(src_stride),
- npy_intp N, npy_intp NPY_UNUSED(src_itemsize),
- NpyAuxData *NPY_UNUSED(data))
+@prefix@_@oper@_size@elsize@_srcstride0(
+ PyArrayMethod_Context *context, char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *NPY_UNUSED(auxdata))
{
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+#if !@dst_contig@
+ npy_intp dst_stride = strides[1];
+#endif
+
#if @elsize@ != 16
# if !(@elsize@ == 1 && @dst_contig@)
@type@ temp;
@@ -250,11 +266,16 @@ static NPY_GCC_OPT_3 int
/**end repeat**/
static int
-_strided_to_strided(char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp src_itemsize,
- NpyAuxData *NPY_UNUSED(data))
+_strided_to_strided(
+ PyArrayMethod_Context *context, char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *NPY_UNUSED(data))
{
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+ npy_intp src_itemsize = context->descriptors[0]->elsize;
+
while (N > 0) {
memmove(dst, src, src_itemsize);
dst += dst_stride;
@@ -264,12 +285,22 @@ _strided_to_strided(char *dst, npy_intp dst_stride,
return 0;
}
+/*
+ * NOTE: This function is currently unused. It would currently be used for
+ * builtin dtypes that have an elsize other than 2, 4, 8, or 16 bytes.
+ * Since unicode and complex swap differently, no such dtype exists.
+ */
static int
-_swap_strided_to_strided(char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp src_itemsize,
- NpyAuxData *NPY_UNUSED(data))
+_swap_strided_to_strided(
+ PyArrayMethod_Context *context, char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *NPY_UNUSED(data))
{
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+ npy_intp src_itemsize = context->descriptors[0]->elsize;
+
char *a, *b, c;
while (N > 0) {
@@ -291,11 +322,16 @@ _swap_strided_to_strided(char *dst, npy_intp dst_stride,
}
static int
-_swap_pair_strided_to_strided(char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp src_itemsize,
- NpyAuxData *NPY_UNUSED(data))
+_swap_pair_strided_to_strided(
+ PyArrayMethod_Context *context, char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *NPY_UNUSED(data))
{
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+ npy_intp src_itemsize = context->descriptors[0]->elsize;
+
char *a, *b, c;
npy_intp itemsize_half = src_itemsize / 2;
@@ -327,17 +363,21 @@ _swap_pair_strided_to_strided(char *dst, npy_intp dst_stride,
}
static int
-_contig_to_contig(char *dst, npy_intp NPY_UNUSED(dst_stride),
- char *src, npy_intp NPY_UNUSED(src_stride),
- npy_intp N, npy_intp src_itemsize,
- NpyAuxData *NPY_UNUSED(data))
+_contig_to_contig(
+ PyArrayMethod_Context *context, char *const *args,
+ const npy_intp *dimensions, const npy_intp *NPY_UNUSED(strides),
+ NpyAuxData *NPY_UNUSED(data))
{
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+ npy_intp src_itemsize = context->descriptors[0]->elsize;
+
memmove(dst, src, src_itemsize*N);
return 0;
}
-NPY_NO_EXPORT PyArray_StridedUnaryOp *
+NPY_NO_EXPORT PyArrayMethod_StridedLoop *
PyArray_GetStridedCopyFn(int aligned, npy_intp src_stride,
npy_intp dst_stride, npy_intp itemsize)
{
@@ -491,7 +531,7 @@ PyArray_GetStridedCopyFn(int aligned, npy_intp src_stride,
* #not_pair = 1, 0#
*/
-NPY_NO_EXPORT PyArray_StridedUnaryOp *
+NPY_NO_EXPORT PyArrayMethod_StridedLoop *
@function@(int aligned, npy_intp src_stride,
npy_intp dst_stride, npy_intp itemsize)
{
@@ -795,11 +835,16 @@ NPY_NO_EXPORT PyArray_StridedUnaryOp *
static NPY_GCC_OPT_3 int
@prefix@_cast_@name1@_to_@name2@(
- char *dst, npy_intp dst_stride,
- char *src, npy_intp src_stride,
- npy_intp N, npy_intp NPY_UNUSED(src_itemsize),
- NpyAuxData *NPY_UNUSED(data))
+ PyArrayMethod_Context *context, char *const *args,
+ const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *NPY_UNUSED(data))
{
+ npy_intp N = dimensions[0];
+ char *src = args[0], *dst = args[1];
+#if !@contig@
+ npy_intp src_stride = strides[0], dst_stride = strides[1];
+#endif
+
#if @is_complex1@
_TYPE1 src_value[2];
#elif !@aligned@
@@ -894,7 +939,7 @@ static NPY_GCC_OPT_3 int
/**end repeat**/
-NPY_NO_EXPORT PyArray_StridedUnaryOp *
+NPY_NO_EXPORT PyArrayMethod_StridedLoop *
PyArray_GetStridedNumericCastFn(int aligned, npy_intp src_stride,
npy_intp dst_stride,
int src_type_num, int dst_type_num)
@@ -985,8 +1030,7 @@ PyArray_TransferNDimToStrided(npy_intp ndim,
npy_intp const *coords, npy_intp coords_inc,
npy_intp const *shape, npy_intp shape_inc,
npy_intp count, npy_intp src_itemsize,
- PyArray_StridedUnaryOp *stransfer,
- NpyAuxData *data)
+ NPY_cast_info *cast_info)
{
npy_intp i, M, N, coord0, shape0, src_stride0, coord1, shape1, src_stride1;
@@ -995,12 +1039,17 @@ PyArray_TransferNDimToStrided(npy_intp ndim,
shape0 = shape[0];
src_stride0 = src_strides[0];
N = shape0 - coord0;
+
+ npy_intp strides[2] = {src_stride0, dst_stride};
+
+ char *args[2] = {src, dst};
if (N >= count) {
- return stransfer(dst, dst_stride, src, src_stride0,
- count, src_itemsize, data);
+ return cast_info->func(&cast_info->context,
+ args, &count, strides, cast_info->auxdata);
}
- int res = stransfer(dst, dst_stride, src, src_stride0,
- N, src_itemsize, data);
+ int res = cast_info->func(&cast_info->context,
+ args, &N, strides, cast_info->auxdata);
+
if (res < 0) {
return -1;
}
@@ -1022,13 +1071,14 @@ PyArray_TransferNDimToStrided(npy_intp ndim,
M = (shape1 - coord1 - 1);
N = shape0*M;
for (i = 0; i < M; ++i) {
+ args[0] = src; args[1] = dst;
if (shape0 >= count) {
- return stransfer(dst, dst_stride, src, src_stride0,
- count, src_itemsize, data);
+ return cast_info->func(&cast_info->context,
+ args, &count, strides, cast_info->auxdata);
}
else {
- res = stransfer(dst, dst_stride, src, src_stride0,
- shape0, src_itemsize, data);
+ res = cast_info->func(&cast_info->context,
+ args, &shape0, strides, cast_info->auxdata);
if (res < 0) {
return -1;
}
@@ -1085,13 +1135,14 @@ PyArray_TransferNDimToStrided(npy_intp ndim,
/* A loop for dimensions 0 and 1 */
for (i = 0; i < shape1; ++i) {
+ args[0] = src; args[1] = dst;
if (shape0 >= count) {
- return stransfer(dst, dst_stride, src, src_stride0,
- count, src_itemsize, data);
+ return cast_info->func(&cast_info->context,
+ args, &count, strides, cast_info->auxdata);
}
else {
- res = stransfer(dst, dst_stride, src, src_stride0,
- shape0, src_itemsize, data);
+ res = cast_info->func(&cast_info->context,
+ args, &shape0, strides, cast_info->auxdata);
if (res < 0) {
return -1;
}
@@ -1112,8 +1163,7 @@ PyArray_TransferStridedToNDim(npy_intp ndim,
npy_intp const *coords, npy_intp coords_inc,
npy_intp const *shape, npy_intp shape_inc,
npy_intp count, npy_intp src_itemsize,
- PyArray_StridedUnaryOp *stransfer,
- NpyAuxData *data)
+ NPY_cast_info *cast_info)
{
npy_intp i, M, N, coord0, shape0, dst_stride0, coord1, shape1, dst_stride1;
@@ -1122,12 +1172,16 @@ PyArray_TransferStridedToNDim(npy_intp ndim,
shape0 = shape[0];
dst_stride0 = dst_strides[0];
N = shape0 - coord0;
+
+ npy_intp strides[2] = {src_stride, dst_stride0};
+
+ char *args[2] = {src, dst};
if (N >= count) {
- return stransfer(dst, dst_stride0, src, src_stride,
- count, src_itemsize, data);
+ return cast_info->func(&cast_info->context,
+ args, &count, strides, cast_info->auxdata);
}
- int res = stransfer(dst, dst_stride0, src, src_stride,
- N, src_itemsize, data);
+ int res = cast_info->func(&cast_info->context,
+ args, &N, strides, cast_info->auxdata);
if (res < 0) {
return -1;
}
@@ -1149,13 +1203,14 @@ PyArray_TransferStridedToNDim(npy_intp ndim,
M = (shape1 - coord1 - 1);
N = shape0*M;
for (i = 0; i < M; ++i) {
+ args[0] = src; args[1] = dst;
if (shape0 >= count) {
- return stransfer(dst, dst_stride0, src, src_stride,
- count, src_itemsize, data);
+ return cast_info->func(&cast_info->context,
+ args, &count, strides, cast_info->auxdata);
}
else {
- res = stransfer(dst, dst_stride0, src, src_stride,
- shape0, src_itemsize, data);
+ res = cast_info->func(&cast_info->context,
+ args, &shape0, strides, cast_info->auxdata);
if (res < 0) {
return -1;
}
@@ -1212,13 +1267,14 @@ PyArray_TransferStridedToNDim(npy_intp ndim,
/* A loop for dimensions 0 and 1 */
for (i = 0; i < shape1; ++i) {
+ args[0] = src; args[1] = dst;
if (shape0 >= count) {
- return stransfer(dst, dst_stride0, src, src_stride,
- count, src_itemsize, data);
+ return cast_info->func(&cast_info->context,
+ args, &count, strides, cast_info->auxdata);
}
else {
- res = stransfer(dst, dst_stride0, src, src_stride,
- shape0, src_itemsize, data);
+ res = cast_info->func(&cast_info->context,
+ args, &shape0, strides, cast_info->auxdata);
if (res < 0) {
return -1;
}
@@ -1240,26 +1296,27 @@ PyArray_TransferMaskedStridedToNDim(npy_intp ndim,
npy_intp const *coords, npy_intp coords_inc,
npy_intp const *shape, npy_intp shape_inc,
npy_intp count, npy_intp src_itemsize,
- PyArray_MaskedStridedUnaryOp *stransfer,
- NpyAuxData *data)
+ NPY_cast_info *cast_info)
{
npy_intp i, M, N, coord0, shape0, dst_stride0, coord1, shape1, dst_stride1;
+ PyArray_MaskedStridedUnaryOp *stransfer =
+ (PyArray_MaskedStridedUnaryOp*)cast_info->func;
/* Finish off dimension 0 */
coord0 = coords[0];
shape0 = shape[0];
dst_stride0 = dst_strides[0];
N = shape0 - coord0;
+
+ npy_intp strides[2] = {src_stride, dst_stride0};
+
+ char *args[2] = {src, dst};
if (N >= count) {
- return stransfer(
- dst, dst_stride0, src, src_stride,
- mask, mask_stride,
- count, src_itemsize, data);
+ return stransfer(&cast_info->context,
+ args, &count, strides, mask, mask_stride, cast_info->auxdata);
}
- int res = stransfer(
- dst, dst_stride0, src, src_stride,
- mask, mask_stride,
- N, src_itemsize, data);
+ int res = stransfer(&cast_info->context,
+ args, &N, strides, mask, mask_stride, cast_info->auxdata);
if (res < 0) {
return -1;
}
@@ -1282,17 +1339,16 @@ PyArray_TransferMaskedStridedToNDim(npy_intp ndim,
M = (shape1 - coord1 - 1);
N = shape0*M;
for (i = 0; i < M; ++i) {
+ args[0] = src; args[1] = dst;
if (shape0 >= count) {
- return stransfer(
- dst, dst_stride0, src, src_stride,
- mask, mask_stride,
- count, src_itemsize, data);
+ return stransfer(&cast_info->context,
+ args, &count, strides,
+ mask, mask_stride, cast_info->auxdata);
}
else {
- int res = stransfer(
- dst, dst_stride0, src, src_stride,
- mask, mask_stride,
- shape0, src_itemsize, data);
+ int res = stransfer(&cast_info->context,
+ args, &shape0, strides,
+ mask, mask_stride, cast_info->auxdata);
if (res < 0) {
return -1;
}
@@ -1350,17 +1406,16 @@ PyArray_TransferMaskedStridedToNDim(npy_intp ndim,
/* A loop for dimensions 0 and 1 */
for (i = 0; i < shape1; ++i) {
+ args[0] = src; args[1] = dst;
if (shape0 >= count) {
- return stransfer(
- dst, dst_stride0, src, src_stride,
- mask, mask_stride,
- count, src_itemsize, data);
+ return stransfer(&cast_info->context,
+ args, &count, strides, mask,
+ mask_stride, cast_info->auxdata);
}
else {
- res = stransfer(
- dst, dst_stride0, src, src_stride,
- mask, mask_stride,
- shape0, src_itemsize, data);
+ int res = stransfer(&cast_info->context,
+ args, &shape0, strides,
+ mask, mask_stride, cast_info->auxdata);
if (res < 0) {
return -1;
}
@@ -1657,22 +1712,15 @@ mapiter_@name@(PyArrayMapIterObject *mit)
npy_intp reset_offsets[2] = {0, 0};
/* Use strided transfer functions for the inner loop */
- PyArray_StridedUnaryOp *stransfer = NULL;
- NpyAuxData *transferdata = NULL;
npy_intp fixed_strides[2];
-#if @isget@
- npy_intp src_itemsize = PyArray_ITEMSIZE(array);
-#else
- npy_intp src_itemsize = PyArray_ITEMSIZE(mit->extra_op);
-#endif
-
/*
* Get a dtype transfer function, since there are no
* buffers, this is safe.
*/
NpyIter_GetInnerFixedStrideArray(mit->subspace_iter, fixed_strides);
+ NPY_cast_info cast_info;
if (PyArray_GetDTypeTransferFunction(is_aligned,
#if @isget@
fixed_strides[0], fixed_strides[1],
@@ -1682,7 +1730,7 @@ mapiter_@name@(PyArrayMapIterObject *mit)
PyArray_DESCR(mit->extra_op), PyArray_DESCR(array),
#endif
0,
- &stransfer, &transferdata,
+ &cast_info,
&needs_api) != NPY_SUCCEED) {
return -1;
}
@@ -1719,7 +1767,7 @@ mapiter_@name@(PyArrayMapIterObject *mit)
#if @isget@ && @one_iter@
if (check_and_adjust_index(&indval, fancy_dims[i],
iteraxis, _save) < 0 ) {
- NPY_AUXDATA_FREE(transferdata);
+ NPY_cast_info_xfree(&cast_info);
return -1;
}
#else
@@ -1751,7 +1799,7 @@ mapiter_@name@(PyArrayMapIterObject *mit)
&errmsg)) {
NPY_END_THREADS;
PyErr_SetString(PyExc_ValueError, errmsg);
- NPY_AUXDATA_FREE(transferdata);
+ NPY_cast_info_xfree(&cast_info);
return -1;
}
if (is_subiter_trivial != 0) {
@@ -1781,7 +1829,7 @@ mapiter_@name@(PyArrayMapIterObject *mit)
* not at all...
*/
if (needs_api && PyErr_Occurred()) {
- NPY_AUXDATA_FREE(transferdata);
+ NPY_cast_info_xfree(&cast_info);
return -1;
}
#endif
@@ -1789,21 +1837,21 @@ mapiter_@name@(PyArrayMapIterObject *mit)
do {
#if @isget@
- if (NPY_UNLIKELY(stransfer(
- subspace_ptrs[1], subspace_strides[1],
- subspace_ptrs[0], subspace_strides[0],
- *counter, src_itemsize, transferdata) < 0)) {
+ if (NPY_UNLIKELY(cast_info.func(&cast_info.context,
+ subspace_ptrs, counter, subspace_strides,
+ cast_info.auxdata) < 0)) {
NPY_END_THREADS;
- NPY_AUXDATA_FREE(transferdata);
+ NPY_cast_info_xfree(&cast_info);
return -1;
}
#else
- if (NPY_UNLIKELY(stransfer(
- subspace_ptrs[0], subspace_strides[0],
- subspace_ptrs[1], subspace_strides[1],
- *counter, src_itemsize, transferdata) < 0)) {
+ /* The operand order is reveresed here */
+ char *args[2] = {subspace_ptrs[1], subspace_ptrs[0]};
+ npy_intp strides[2] = {subspace_strides[1], subspace_strides[0]};
+ if (NPY_UNLIKELY(cast_info.func(&cast_info.context,
+ args, counter, strides, cast_info.auxdata) < 0)) {
NPY_END_THREADS;
- NPY_AUXDATA_FREE(transferdata);
+ NPY_cast_info_xfree(&cast_info);
return -1;
}
#endif
@@ -1815,7 +1863,7 @@ mapiter_@name@(PyArrayMapIterObject *mit)
}
/**end repeat1**/
- NPY_AUXDATA_FREE(transferdata);
+ NPY_cast_info_xfree(&cast_info);
}
return 0;
}
diff --git a/numpy/core/src/multiarray/mapping.c b/numpy/core/src/multiarray/mapping.c
index d64962f87..41311b03f 100644
--- a/numpy/core/src/multiarray/mapping.c
+++ b/numpy/core/src/multiarray/mapping.c
@@ -63,15 +63,61 @@ array_length(PyArrayObject *self)
/* -------------------------------------------------------------- */
+
+/*
+ * Helper for `PyArray_MapIterSwapAxes` (and related), see its documentation.
+ */
+static void
+_get_transpose(int fancy_ndim, int consec, int ndim, int getmap, npy_intp *dims)
+{
+ /*
+ * For getting the array the tuple for transpose is
+ * (n1,...,n1+n2-1,0,...,n1-1,n1+n2,...,n3-1)
+ * n1 is the number of dimensions of the broadcast index array
+ * n2 is the number of dimensions skipped at the start
+ * n3 is the number of dimensions of the result
+ */
+
+ /*
+ * For setting the array the tuple for transpose is
+ * (n2,...,n1+n2-1,0,...,n2-1,n1+n2,...n3-1)
+ */
+ int n1 = fancy_ndim;
+ int n2 = consec; /* axes to insert at */
+ int n3 = ndim;
+
+ /* use n1 as the boundary if getting but n2 if setting */
+ int bnd = getmap ? n1 : n2;
+ int val = bnd;
+ int i = 0;
+ while (val < n1 + n2) {
+ dims[i++] = val++;
+ }
+ val = 0;
+ while (val < bnd) {
+ dims[i++] = val++;
+ }
+ val = n1 + n2;
+ while (val < n3) {
+ dims[i++] = val++;
+ }
+}
+
+
/*NUMPY_API
*
+ * Swap the axes to or from their inserted form. MapIter always puts the
+ * advanced (array) indices first in the iteration. But if they are
+ * consecutive, will insert/transpose them back before returning.
+ * This is stored as `mit->consec != 0` (the place where they are inserted)
+ * For assignments, the opposite happens: The values to be assigned are
+ * transposed (getmap=1 instead of getmap=0). `getmap=0` and `getmap=1`
+ * undo the other operation.
*/
NPY_NO_EXPORT void
PyArray_MapIterSwapAxes(PyArrayMapIterObject *mit, PyArrayObject **ret, int getmap)
{
PyObject *new;
- int n1, n2, n3, val, bnd;
- int i;
PyArray_Dims permute;
npy_intp d[NPY_MAXDIMS];
PyArrayObject *arr;
@@ -85,10 +131,10 @@ PyArray_MapIterSwapAxes(PyArrayMapIterObject *mit, PyArrayObject **ret, int getm
*/
arr = *ret;
if (PyArray_NDIM(arr) != mit->nd) {
- for (i = 1; i <= PyArray_NDIM(arr); i++) {
+ for (int i = 1; i <= PyArray_NDIM(arr); i++) {
permute.ptr[mit->nd-i] = PyArray_DIMS(arr)[PyArray_NDIM(arr)-i];
}
- for (i = 0; i < mit->nd-PyArray_NDIM(arr); i++) {
+ for (int i = 0; i < mit->nd-PyArray_NDIM(arr); i++) {
permute.ptr[i] = 1;
}
new = PyArray_Newshape(arr, &permute, NPY_ANYORDER);
@@ -99,44 +145,8 @@ PyArray_MapIterSwapAxes(PyArrayMapIterObject *mit, PyArrayObject **ret, int getm
}
}
- /*
- * Setting and getting need to have different permutations.
- * On the get we are permuting the returned object, but on
- * setting we are permuting the object-to-be-set.
- * The set permutation is the inverse of the get permutation.
- */
+ _get_transpose(mit->nd_fancy, mit->consec, mit->nd, getmap, permute.ptr);
- /*
- * For getting the array the tuple for transpose is
- * (n1,...,n1+n2-1,0,...,n1-1,n1+n2,...,n3-1)
- * n1 is the number of dimensions of the broadcast index array
- * n2 is the number of dimensions skipped at the start
- * n3 is the number of dimensions of the result
- */
-
- /*
- * For setting the array the tuple for transpose is
- * (n2,...,n1+n2-1,0,...,n2-1,n1+n2,...n3-1)
- */
- n1 = mit->nd_fancy;
- n2 = mit->consec; /* axes to insert at */
- n3 = mit->nd;
-
- /* use n1 as the boundary if getting but n2 if setting */
- bnd = getmap ? n1 : n2;
- val = bnd;
- i = 0;
- while (val < n1 + n2) {
- permute.ptr[i++] = val++;
- }
- val = 0;
- while (val < bnd) {
- permute.ptr[i++] = val++;
- }
- val = n1 + n2;
- while (val < n3) {
- permute.ptr[i++] = val++;
- }
new = PyArray_Transpose(*ret, &permute);
Py_DECREF(*ret);
*ret = (PyArrayObject *)new;
@@ -1037,8 +1047,6 @@ array_boolean_subscript(PyArrayObject *self,
PyArrayObject *op[2] = {self, bmask};
npy_uint32 flags, op_flags[2];
npy_intp fixed_strides[3];
- PyArray_StridedUnaryOp *stransfer = NULL;
- NpyAuxData *transferdata = NULL;
NpyIter_IterNextFunc *iternext;
npy_intp innersize, *innerstrides;
@@ -1063,12 +1071,13 @@ array_boolean_subscript(PyArrayObject *self,
/* Get a dtype transfer function */
NpyIter_GetInnerFixedStrideArray(iter, fixed_strides);
+ NPY_cast_info cast_info;
if (PyArray_GetDTypeTransferFunction(
IsUintAligned(self) && IsAligned(self),
fixed_strides[0], itemsize,
dtype, dtype,
0,
- &stransfer, &transferdata,
+ &cast_info,
&needs_api) != NPY_SUCCEED) {
Py_DECREF(ret);
NpyIter_Deallocate(iter);
@@ -1080,7 +1089,7 @@ array_boolean_subscript(PyArrayObject *self,
if (iternext == NULL) {
Py_DECREF(ret);
NpyIter_Deallocate(iter);
- NPY_AUXDATA_FREE(transferdata);
+ NPY_cast_info_xfree(&cast_info);
return NULL;
}
@@ -1091,6 +1100,8 @@ array_boolean_subscript(PyArrayObject *self,
self_stride = innerstrides[0];
bmask_stride = innerstrides[1];
+ npy_intp strides[2] = {self_stride, itemsize};
+
int res = 0;
do {
innersize = *NpyIter_GetInnerLoopSizePtr(iter);
@@ -1106,8 +1117,9 @@ array_boolean_subscript(PyArrayObject *self,
/* Process unmasked values */
bmask_data = npy_memchr(bmask_data, 0, bmask_stride, innersize,
&subloopsize, 0);
- res = stransfer(ret_data, itemsize, self_data, self_stride,
- subloopsize, itemsize, transferdata);
+ char *args[2] = {self_data, ret_data};
+ res = cast_info.func(&cast_info.context,
+ args, &subloopsize, strides, cast_info.auxdata);
if (res < 0) {
break;
}
@@ -1122,7 +1134,7 @@ array_boolean_subscript(PyArrayObject *self,
if (!NpyIter_Deallocate(iter)) {
res = -1;
}
- NPY_AUXDATA_FREE(transferdata);
+ NPY_cast_info_xfree(&cast_info);
if (res < 0) {
/* Should be practically impossible, since there is no cast */
Py_DECREF(ret);
@@ -1164,7 +1176,7 @@ NPY_NO_EXPORT int
array_assign_boolean_subscript(PyArrayObject *self,
PyArrayObject *bmask, PyArrayObject *v, NPY_ORDER order)
{
- npy_intp size, src_itemsize, v_stride;
+ npy_intp size, v_stride;
char *v_data;
int needs_api = 0;
npy_intp bmask_size;
@@ -1216,7 +1228,6 @@ array_assign_boolean_subscript(PyArrayObject *self,
v_stride = 0;
}
- src_itemsize = PyArray_DESCR(v)->elsize;
v_data = PyArray_DATA(v);
/* Create an iterator for the data */
@@ -1231,8 +1242,6 @@ array_assign_boolean_subscript(PyArrayObject *self,
npy_intp innersize, *innerstrides;
char **dataptrs;
- PyArray_StridedUnaryOp *stransfer = NULL;
- NpyAuxData *transferdata = NULL;
npy_intp self_stride, bmask_stride, subloopsize;
char *self_data;
char *bmask_data;
@@ -1264,13 +1273,14 @@ array_assign_boolean_subscript(PyArrayObject *self,
/* Get a dtype transfer function */
NpyIter_GetInnerFixedStrideArray(iter, fixed_strides);
+ NPY_cast_info cast_info;
if (PyArray_GetDTypeTransferFunction(
IsUintAligned(self) && IsAligned(self) &&
IsUintAligned(v) && IsAligned(v),
v_stride, fixed_strides[0],
PyArray_DESCR(v), PyArray_DESCR(self),
0,
- &stransfer, &transferdata,
+ &cast_info,
&needs_api) != NPY_SUCCEED) {
NpyIter_Deallocate(iter);
return -1;
@@ -1280,6 +1290,8 @@ array_assign_boolean_subscript(PyArrayObject *self,
NPY_BEGIN_THREADS_NDITER(iter);
}
+ npy_intp strides[2] = {v_stride, self_stride};
+
do {
innersize = *NpyIter_GetInnerLoopSizePtr(iter);
self_data = dataptrs[0];
@@ -1294,8 +1306,10 @@ array_assign_boolean_subscript(PyArrayObject *self,
/* Process unmasked values */
bmask_data = npy_memchr(bmask_data, 0, bmask_stride, innersize,
&subloopsize, 0);
- res = stransfer(self_data, self_stride, v_data, v_stride,
- subloopsize, src_itemsize, transferdata);
+
+ char *args[2] = {v_data, self_data};
+ res = cast_info.func(&cast_info.context,
+ args, &subloopsize, strides, cast_info.auxdata);
if (res < 0) {
break;
}
@@ -1309,7 +1323,7 @@ array_assign_boolean_subscript(PyArrayObject *self,
NPY_END_THREADS;
}
- NPY_AUXDATA_FREE(transferdata);
+ NPY_cast_info_xfree(&cast_info);
if (!NpyIter_Deallocate(iter)) {
res = -1;
}
@@ -2328,7 +2342,7 @@ PyArray_MapIterNext(PyArrayMapIterObject *mit)
* @param Number of indices
* @param The array that is being iterated
*
- * @return 0 on success -1 on failure
+ * @return 0 on success -1 on failure (broadcasting or too many fancy indices)
*/
static int
mapiter_fill_info(PyArrayMapIterObject *mit, npy_index_info *indices,
@@ -2369,6 +2383,17 @@ mapiter_fill_info(PyArrayMapIterObject *mit, npy_index_info *indices,
}
}
+ /* Before contunuing, ensure that there are not too fancy indices */
+ if (indices[i].type & HAS_FANCY) {
+ if (NPY_UNLIKELY(j >= NPY_MAXDIMS)) {
+ PyErr_Format(PyExc_IndexError,
+ "too many advanced (array) indices. This probably "
+ "means you are indexing with too many booleans. "
+ "(more than %d found)", NPY_MAXDIMS);
+ return -1;
+ }
+ }
+
/* (iterating) fancy index, store the iterator */
if (indices[i].type == HAS_FANCY) {
mit->fancy_strides[j] = PyArray_STRIDE(arr, curr_dim);
@@ -2655,6 +2680,7 @@ PyArray_MapIterNew(npy_index_info *indices , int index_num, int index_type,
/* For shape reporting on error */
PyArrayObject *original_extra_op = extra_op;
+ /* NOTE: MAXARGS is the actual limit (2*NPY_MAXDIMS is index number one) */
PyArrayObject *index_arrays[NPY_MAXDIMS];
PyArray_Descr *intp_descr;
PyArray_Descr *dtypes[NPY_MAXDIMS]; /* borrowed references */
@@ -3188,12 +3214,19 @@ PyArray_MapIterNew(npy_index_info *indices , int index_num, int index_type,
int extra_ndim = PyArray_NDIM(original_extra_op);
npy_intp *extra_dims = PyArray_DIMS(original_extra_op);
- PyObject *shape1 = convert_shape_to_string(extra_ndim, extra_dims, " ");
+ PyObject *shape1 = convert_shape_to_string(extra_ndim, extra_dims, "");
if (shape1 == NULL) {
goto finish;
}
- PyObject *shape2 = convert_shape_to_string(mit->nd, mit->dimensions, "");
+ /* Unscramble the iterator shape for reporting when `mit->consec` is used */
+ npy_intp transposed[NPY_MAXDIMS];
+ _get_transpose(mit->nd_fancy, mit->consec, mit->nd, 1, transposed);
+ for (i = 0; i < mit->nd; i++) {
+ transposed[i] = mit->dimensions[transposed[i]];
+ }
+
+ PyObject *shape2 = convert_shape_to_string(mit->nd, transposed, "");
if (shape2 == NULL) {
Py_DECREF(shape1);
goto finish;
diff --git a/numpy/core/src/multiarray/methods.c b/numpy/core/src/multiarray/methods.c
index 9c8bb4135..dc23b3471 100644
--- a/numpy/core/src/multiarray/methods.c
+++ b/numpy/core/src/multiarray/methods.c
@@ -10,6 +10,7 @@
#include "numpy/arrayscalars.h"
#include "arrayfunction_override.h"
+#include "npy_argparse.h"
#include "npy_config.h"
#include "npy_pycompat.h"
#include "npy_import.h"
@@ -103,20 +104,23 @@ forward_ndarray_method(PyArrayObject *self, PyObject *args, PyObject *kwds,
static PyObject *
-array_take(PyArrayObject *self, PyObject *args, PyObject *kwds)
+array_take(PyArrayObject *self,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
int dimension = NPY_MAXDIMS;
PyObject *indices;
PyArrayObject *out = NULL;
NPY_CLIPMODE mode = NPY_RAISE;
- static char *kwlist[] = {"indices", "axis", "out", "mode", NULL};
+ NPY_PREPARE_ARGPARSER;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O&O&O&:take", kwlist,
- &indices,
- PyArray_AxisConverter, &dimension,
- PyArray_OutputConverter, &out,
- PyArray_ClipmodeConverter, &mode))
+ if (npy_parse_arguments("take", args, len_args, kwnames,
+ "indices", NULL, &indices,
+ "|axis", &PyArray_AxisConverter, &dimension,
+ "|out", &PyArray_OutputConverter, &out,
+ "|mode", &PyArray_ClipmodeConverter, &mode,
+ NULL, NULL, NULL) < 0) {
return NULL;
+ }
PyObject *ret = PyArray_TakeFrom(self, indices, dimension, out, mode);
@@ -199,14 +203,16 @@ array_reshape(PyArrayObject *self, PyObject *args, PyObject *kwds)
}
static PyObject *
-array_squeeze(PyArrayObject *self, PyObject *args, PyObject *kwds)
+array_squeeze(PyArrayObject *self,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
PyObject *axis_in = NULL;
npy_bool axis_flags[NPY_MAXDIMS];
+ NPY_PREPARE_ARGPARSER;
- static char *kwlist[] = {"axis", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:squeeze", kwlist,
- &axis_in)) {
+ if (npy_parse_arguments("squeeze", args, len_args, kwnames,
+ "|axis", NULL, &axis_in,
+ NULL, NULL, NULL) < 0) {
return NULL;
}
@@ -224,16 +230,18 @@ array_squeeze(PyArrayObject *self, PyObject *args, PyObject *kwds)
}
static PyObject *
-array_view(PyArrayObject *self, PyObject *args, PyObject *kwds)
+array_view(PyArrayObject *self,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
PyObject *out_dtype = NULL;
PyObject *out_type = NULL;
PyArray_Descr *dtype = NULL;
+ NPY_PREPARE_ARGPARSER;
- static char *kwlist[] = {"dtype", "type", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO:view", kwlist,
- &out_dtype,
- &out_type)) {
+ if (npy_parse_arguments("view", args, len_args, kwnames,
+ "|dtype", NULL, &out_dtype,
+ "|type", NULL, &out_type,
+ NULL, NULL, NULL) < 0) {
return NULL;
}
@@ -271,18 +279,23 @@ array_view(PyArrayObject *self, PyObject *args, PyObject *kwds)
}
static PyObject *
-array_argmax(PyArrayObject *self, PyObject *args, PyObject *kwds)
+array_argmax(PyArrayObject *self,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
int axis = NPY_MAXDIMS;
PyArrayObject *out = NULL;
- static char *kwlist[] = {"axis", "out", NULL};
+ npy_bool keepdims = NPY_FALSE;
+ NPY_PREPARE_ARGPARSER;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&O&:argmax", kwlist,
- PyArray_AxisConverter, &axis,
- PyArray_OutputConverter, &out))
+ if (npy_parse_arguments("argmax", args, len_args, kwnames,
+ "|axis", &PyArray_AxisConverter, &axis,
+ "|out", &PyArray_OutputConverter, &out,
+ "$keepdims", &PyArray_BoolConverter, &keepdims,
+ NULL, NULL, NULL) < 0) {
return NULL;
+ }
- PyObject *ret = PyArray_ArgMax(self, axis, out);
+ PyObject *ret = _PyArray_ArgMaxWithKeepdims(self, axis, out, keepdims);
/* this matches the unpacking behavior of ufuncs */
if (out == NULL) {
@@ -294,18 +307,22 @@ array_argmax(PyArrayObject *self, PyObject *args, PyObject *kwds)
}
static PyObject *
-array_argmin(PyArrayObject *self, PyObject *args, PyObject *kwds)
+array_argmin(PyArrayObject *self,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
int axis = NPY_MAXDIMS;
PyArrayObject *out = NULL;
- static char *kwlist[] = {"axis", "out", NULL};
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&O&:argmin", kwlist,
- PyArray_AxisConverter, &axis,
- PyArray_OutputConverter, &out))
+ npy_bool keepdims = NPY_FALSE;
+ NPY_PREPARE_ARGPARSER;
+ if (npy_parse_arguments("argmin", args, len_args, kwnames,
+ "|axis", &PyArray_AxisConverter, &axis,
+ "|out", &PyArray_OutputConverter, &out,
+ "$keepdims", &PyArray_BoolConverter, &keepdims,
+ NULL, NULL, NULL) < 0) {
return NULL;
+ }
- PyObject *ret = PyArray_ArgMin(self, axis, out);
+ PyObject *ret = _PyArray_ArgMinWithKeepdims(self, axis, out, keepdims);
/* this matches the unpacking behavior of ufuncs */
if (out == NULL) {
@@ -804,10 +821,9 @@ array_setscalar(PyArrayObject *self, PyObject *args)
static PyObject *
-array_astype(PyArrayObject *self, PyObject *args, PyObject *kwds)
+array_astype(PyArrayObject *self,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
- static char *kwlist[] = {"dtype", "order", "casting",
- "subok", "copy", NULL};
PyArray_Descr *dtype = NULL;
/*
* TODO: UNSAFE default for compatibility, I think
@@ -816,13 +832,15 @@ array_astype(PyArrayObject *self, PyObject *args, PyObject *kwds)
NPY_CASTING casting = NPY_UNSAFE_CASTING;
NPY_ORDER order = NPY_KEEPORDER;
int forcecopy = 1, subok = 1;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|O&O&ii:astype", kwlist,
- PyArray_DescrConverter, &dtype,
- PyArray_OrderConverter, &order,
- PyArray_CastingConverter, &casting,
- &subok,
- &forcecopy)) {
+ NPY_PREPARE_ARGPARSER;
+
+ if (npy_parse_arguments("astype", args, len_args, kwnames,
+ "dtype", &PyArray_DescrConverter, &dtype,
+ "|order", &PyArray_OrderConverter, &order,
+ "|casting", &PyArray_CastingConverter, &casting,
+ "|subok", &PyArray_PythonPyIntFromInt, &subok,
+ "|copy", &PyArray_PythonPyIntFromInt, &forcecopy,
+ NULL, NULL, NULL) < 0) {
Py_XDECREF(dtype);
return NULL;
}
@@ -852,44 +870,44 @@ array_astype(PyArrayObject *self, PyObject *args, PyObject *kwds)
Py_INCREF(self);
return (PyObject *)self;
}
- else if (PyArray_CanCastArrayTo(self, dtype, casting)) {
- PyArrayObject *ret;
-
- /* This steals the reference to dtype, so no DECREF of dtype */
- ret = (PyArrayObject *)PyArray_NewLikeArray(
- self, order, dtype, subok);
- if (ret == NULL) {
- return NULL;
- }
- /* NumPy 1.20, 2020-10-01 */
- if ((PyArray_NDIM(self) != PyArray_NDIM(ret)) &&
- DEPRECATE_FUTUREWARNING(
- "casting an array to a subarray dtype "
- "will not using broadcasting in the future, but cast each "
- "element to the new dtype and then append the dtype's shape "
- "to the new array. You can opt-in to the new behaviour, by "
- "additional field to the cast: "
- "`arr.astype(np.dtype([('f', dtype)]))['f']`.\n"
- "This may lead to a different result or to current failures "
- "succeeding. "
- "(FutureWarning since NumPy 1.20)") < 0) {
- Py_DECREF(ret);
- return NULL;
- }
-
- if (PyArray_CopyInto(ret, self) < 0) {
- Py_DECREF(ret);
- return NULL;
- }
-
- return (PyObject *)ret;
- }
- else {
+ if (!PyArray_CanCastArrayTo(self, dtype, casting)) {
+ PyErr_Clear();
npy_set_invalid_cast_error(
PyArray_DESCR(self), dtype, casting, PyArray_NDIM(self) == 0);
Py_DECREF(dtype);
return NULL;
}
+
+ PyArrayObject *ret;
+
+ /* This steals the reference to dtype, so no DECREF of dtype */
+ ret = (PyArrayObject *)PyArray_NewLikeArray(
+ self, order, dtype, subok);
+ if (ret == NULL) {
+ return NULL;
+ }
+ /* NumPy 1.20, 2020-10-01 */
+ if ((PyArray_NDIM(self) != PyArray_NDIM(ret)) &&
+ DEPRECATE_FUTUREWARNING(
+ "casting an array to a subarray dtype "
+ "will not use broadcasting in the future, but cast each "
+ "element to the new dtype and then append the dtype's shape "
+ "to the new array. You can opt-in to the new behaviour, by "
+ "additional field to the cast: "
+ "`arr.astype(np.dtype([('f', dtype)]))['f']`.\n"
+ "This may lead to a different result or to current failures "
+ "succeeding. "
+ "(FutureWarning since NumPy 1.20)") < 0) {
+ Py_DECREF(ret);
+ return NULL;
+ }
+
+ if (PyArray_CopyInto(ret, self) < 0) {
+ Py_DECREF(ret);
+ return NULL;
+ }
+
+ return (PyObject *)ret;
}
/* default sub-type implementation */
@@ -1019,7 +1037,7 @@ array_getarray(PyArrayObject *self, PyObject *args)
}
/*
- * Check whether any of a set of input and output args have a non-default
+ * Check whether any of the input and output args have a non-default
* __array_ufunc__ method. Return 1 if so, 0 if not, and -1 on error.
*
* This function primarily exists to help ndarray.__array_ufunc__ determine
@@ -1143,13 +1161,15 @@ array_function(PyArrayObject *NPY_UNUSED(self), PyObject *c_args, PyObject *c_kw
}
static PyObject *
-array_copy(PyArrayObject *self, PyObject *args, PyObject *kwds)
+array_copy(PyArrayObject *self,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
NPY_ORDER order = NPY_CORDER;
- static char *kwlist[] = {"order", NULL};
+ NPY_PREPARE_ARGPARSER;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&:copy", kwlist,
- PyArray_OrderConverter, &order)) {
+ if (npy_parse_arguments("copy", args, len_args, kwnames,
+ "|order", PyArray_OrderConverter, &order,
+ NULL, NULL, NULL) < 0) {
return NULL;
}
@@ -1257,7 +1277,8 @@ array_choose(PyArrayObject *self, PyObject *args, PyObject *kwds)
}
static PyObject *
-array_sort(PyArrayObject *self, PyObject *args, PyObject *kwds)
+array_sort(PyArrayObject *self,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
int axis=-1;
int val;
@@ -1265,12 +1286,13 @@ array_sort(PyArrayObject *self, PyObject *args, PyObject *kwds)
PyObject *order = NULL;
PyArray_Descr *saved = NULL;
PyArray_Descr *newd;
- static char *kwlist[] = {"axis", "kind", "order", NULL};
+ NPY_PREPARE_ARGPARSER;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO&O:sort", kwlist,
- &axis,
- PyArray_SortkindConverter, &sortkind,
- &order)) {
+ if (npy_parse_arguments("sort", args, len_args, kwnames,
+ "|axis", &PyArray_PythonPyIntFromInt, &axis,
+ "|kind", &PyArray_SortkindConverter, &sortkind,
+ "|order", NULL, &order,
+ NULL, NULL, NULL) < 0) {
return NULL;
}
if (order == Py_None) {
@@ -1313,7 +1335,8 @@ array_sort(PyArrayObject *self, PyObject *args, PyObject *kwds)
}
static PyObject *
-array_partition(PyArrayObject *self, PyObject *args, PyObject *kwds)
+array_partition(PyArrayObject *self,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
int axis=-1;
int val;
@@ -1321,16 +1344,16 @@ array_partition(PyArrayObject *self, PyObject *args, PyObject *kwds)
PyObject *order = NULL;
PyArray_Descr *saved = NULL;
PyArray_Descr *newd;
- static char *kwlist[] = {"kth", "axis", "kind", "order", NULL};
PyArrayObject * ktharray;
PyObject * kthobj;
+ NPY_PREPARE_ARGPARSER;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|iO&O:partition", kwlist,
- &kthobj,
- &axis,
- PyArray_SelectkindConverter, &sortkind,
- &order)) {
+ if (npy_parse_arguments("partition", args, len_args, kwnames,
+ "kth", NULL, &kthobj,
+ "|axis", &PyArray_PythonPyIntFromInt, &axis,
+ "|kind", &PyArray_SelectkindConverter, &sortkind,
+ "|order", NULL, &order,
+ NULL, NULL, NULL) < 0) {
return NULL;
}
@@ -1381,18 +1404,20 @@ array_partition(PyArrayObject *self, PyObject *args, PyObject *kwds)
}
static PyObject *
-array_argsort(PyArrayObject *self, PyObject *args, PyObject *kwds)
+array_argsort(PyArrayObject *self,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
int axis = -1;
NPY_SORTKIND sortkind = NPY_QUICKSORT;
PyObject *order = NULL, *res;
PyArray_Descr *newd, *saved=NULL;
- static char *kwlist[] = {"axis", "kind", "order", NULL};
+ NPY_PREPARE_ARGPARSER;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&O&O:argsort", kwlist,
- PyArray_AxisConverter, &axis,
- PyArray_SortkindConverter, &sortkind,
- &order)) {
+ if (npy_parse_arguments("argsort", args, len_args, kwnames,
+ "|axis", &PyArray_AxisConverter, &axis,
+ "|kind", &PyArray_SortkindConverter, &sortkind,
+ "|order", NULL, &order,
+ NULL, NULL, NULL) < 0) {
return NULL;
}
if (order == Py_None) {
@@ -1433,21 +1458,23 @@ array_argsort(PyArrayObject *self, PyObject *args, PyObject *kwds)
static PyObject *
-array_argpartition(PyArrayObject *self, PyObject *args, PyObject *kwds)
+array_argpartition(PyArrayObject *self,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
int axis = -1;
NPY_SELECTKIND sortkind = NPY_INTROSELECT;
PyObject *order = NULL, *res;
PyArray_Descr *newd, *saved=NULL;
- static char *kwlist[] = {"kth", "axis", "kind", "order", NULL};
PyObject * kthobj;
PyArrayObject * ktharray;
+ NPY_PREPARE_ARGPARSER;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O&O&O:argpartition", kwlist,
- &kthobj,
- PyArray_AxisConverter, &axis,
- PyArray_SelectkindConverter, &sortkind,
- &order)) {
+ if (npy_parse_arguments("argpartition", args, len_args, kwnames,
+ "kth", NULL, &kthobj,
+ "|axis", &PyArray_AxisConverter, &axis,
+ "|kind", &PyArray_SelectkindConverter, &sortkind,
+ "|order", NULL, &order,
+ NULL, NULL, NULL) < 0) {
return NULL;
}
if (order == Py_None) {
@@ -1494,17 +1521,20 @@ array_argpartition(PyArrayObject *self, PyObject *args, PyObject *kwds)
}
static PyObject *
-array_searchsorted(PyArrayObject *self, PyObject *args, PyObject *kwds)
+array_searchsorted(PyArrayObject *self,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
- static char *kwlist[] = {"v", "side", "sorter", NULL};
PyObject *keys;
PyObject *sorter;
NPY_SEARCHSIDE side = NPY_SEARCHLEFT;
+ NPY_PREPARE_ARGPARSER;
sorter = NULL;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O&O:searchsorted",
- kwlist, &keys,
- PyArray_SearchsideConverter, &side, &sorter)) {
+ if (npy_parse_arguments("searchsorted", args, len_args, kwnames,
+ "v", NULL, &keys,
+ "|side", &PyArray_SearchsideConverter, &side,
+ "|sorter", NULL, &sorter,
+ NULL, NULL, NULL) < 0) {
return NULL;
}
if (sorter == Py_None) {
@@ -2285,14 +2315,17 @@ array_cumprod(PyArrayObject *self, PyObject *args, PyObject *kwds)
static PyObject *
-array_dot(PyArrayObject *self, PyObject *args, PyObject *kwds)
+array_dot(PyArrayObject *self,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
PyObject *a = (PyObject *)self, *b, *o = NULL;
PyArrayObject *ret;
- char* kwlist[] = {"b", "out", NULL };
+ NPY_PREPARE_ARGPARSER;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|O:dot", kwlist, &b, &o)) {
+ if (npy_parse_arguments("dot", args, len_args, kwnames,
+ "b", NULL, &b,
+ "|out", NULL, &o,
+ NULL, NULL, NULL) < 0) {
return NULL;
}
@@ -2374,20 +2407,22 @@ array_nonzero(PyArrayObject *self, PyObject *args)
static PyObject *
-array_trace(PyArrayObject *self, PyObject *args, PyObject *kwds)
+array_trace(PyArrayObject *self,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
int axis1 = 0, axis2 = 1, offset = 0;
PyArray_Descr *dtype = NULL;
PyArrayObject *out = NULL;
int rtype;
- static char *kwlist[] = {"offset", "axis1", "axis2", "dtype", "out", NULL};
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iiiO&O&:trace", kwlist,
- &offset,
- &axis1,
- &axis2,
- PyArray_DescrConverter2, &dtype,
- PyArray_OutputConverter, &out)) {
+ NPY_PREPARE_ARGPARSER;
+
+ if (npy_parse_arguments("trace", args, len_args, kwnames,
+ "|offset", &PyArray_PythonPyIntFromInt, &offset,
+ "|axis1", &PyArray_PythonPyIntFromInt, &axis1,
+ "|axis2", &PyArray_PythonPyIntFromInt, &axis2,
+ "|dtype", &PyArray_DescrConverter2, &dtype,
+ "|out", &PyArray_OutputConverter, &out,
+ NULL, NULL, NULL) < 0) {
Py_XDECREF(dtype);
return NULL;
}
@@ -2448,13 +2483,15 @@ array_diagonal(PyArrayObject *self, PyObject *args, PyObject *kwds)
static PyObject *
-array_flatten(PyArrayObject *self, PyObject *args, PyObject *kwds)
+array_flatten(PyArrayObject *self,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
NPY_ORDER order = NPY_CORDER;
- static char *kwlist[] = {"order", NULL};
+ NPY_PREPARE_ARGPARSER;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&:flatten", kwlist,
- PyArray_OrderConverter, &order)) {
+ if (npy_parse_arguments("flatten", args, len_args, kwnames,
+ "|order", PyArray_OrderConverter, &order,
+ NULL, NULL, NULL) < 0) {
return NULL;
}
return PyArray_Flatten(self, order);
@@ -2462,13 +2499,15 @@ array_flatten(PyArrayObject *self, PyObject *args, PyObject *kwds)
static PyObject *
-array_ravel(PyArrayObject *self, PyObject *args, PyObject *kwds)
+array_ravel(PyArrayObject *self,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
NPY_ORDER order = NPY_CORDER;
- static char *kwlist[] = {"order", NULL};
+ NPY_PREPARE_ARGPARSER;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O&:ravel", kwlist,
- PyArray_OrderConverter, &order)) {
+ if (npy_parse_arguments("ravel", args, len_args, kwnames,
+ "|order", PyArray_OrderConverter, &order,
+ NULL, NULL, NULL) < 0) {
return NULL;
}
return PyArray_Ravel(self, order);
@@ -2724,19 +2763,19 @@ NPY_NO_EXPORT PyMethodDef array_methods[] = {
METH_VARARGS | METH_KEYWORDS, NULL},
{"argmax",
(PyCFunction)array_argmax,
- METH_VARARGS | METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"argmin",
(PyCFunction)array_argmin,
- METH_VARARGS | METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"argpartition",
(PyCFunction)array_argpartition,
- METH_VARARGS | METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"argsort",
(PyCFunction)array_argsort,
- METH_VARARGS | METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"astype",
(PyCFunction)array_astype,
- METH_VARARGS | METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"byteswap",
(PyCFunction)array_byteswap,
METH_VARARGS | METH_KEYWORDS, NULL},
@@ -2757,7 +2796,7 @@ NPY_NO_EXPORT PyMethodDef array_methods[] = {
METH_VARARGS, NULL},
{"copy",
(PyCFunction)array_copy,
- METH_VARARGS | METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"cumprod",
(PyCFunction)array_cumprod,
METH_VARARGS | METH_KEYWORDS, NULL},
@@ -2769,13 +2808,13 @@ NPY_NO_EXPORT PyMethodDef array_methods[] = {
METH_VARARGS | METH_KEYWORDS, NULL},
{"dot",
(PyCFunction)array_dot,
- METH_VARARGS | METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"fill",
(PyCFunction)array_fill,
METH_VARARGS, NULL},
{"flatten",
(PyCFunction)array_flatten,
- METH_VARARGS | METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"getfield",
(PyCFunction)array_getfield,
METH_VARARGS | METH_KEYWORDS, NULL},
@@ -2802,7 +2841,7 @@ NPY_NO_EXPORT PyMethodDef array_methods[] = {
METH_VARARGS, NULL},
{"partition",
(PyCFunction)array_partition,
- METH_VARARGS | METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"prod",
(PyCFunction)array_prod,
METH_VARARGS | METH_KEYWORDS, NULL},
@@ -2814,7 +2853,7 @@ NPY_NO_EXPORT PyMethodDef array_methods[] = {
METH_VARARGS | METH_KEYWORDS, NULL},
{"ravel",
(PyCFunction)array_ravel,
- METH_VARARGS | METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"repeat",
(PyCFunction)array_repeat,
METH_VARARGS | METH_KEYWORDS, NULL},
@@ -2829,7 +2868,7 @@ NPY_NO_EXPORT PyMethodDef array_methods[] = {
METH_VARARGS | METH_KEYWORDS, NULL},
{"searchsorted",
(PyCFunction)array_searchsorted,
- METH_VARARGS | METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"setfield",
(PyCFunction)array_setfield,
METH_VARARGS | METH_KEYWORDS, NULL},
@@ -2838,10 +2877,10 @@ NPY_NO_EXPORT PyMethodDef array_methods[] = {
METH_VARARGS | METH_KEYWORDS, NULL},
{"sort",
(PyCFunction)array_sort,
- METH_VARARGS | METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"squeeze",
(PyCFunction)array_squeeze,
- METH_VARARGS | METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"std",
(PyCFunction)array_stddev,
METH_VARARGS | METH_KEYWORDS, NULL},
@@ -2853,7 +2892,7 @@ NPY_NO_EXPORT PyMethodDef array_methods[] = {
METH_VARARGS, NULL},
{"take",
(PyCFunction)array_take,
- METH_VARARGS | METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"tobytes",
(PyCFunction)array_tobytes,
METH_VARARGS | METH_KEYWORDS, NULL},
@@ -2868,7 +2907,7 @@ NPY_NO_EXPORT PyMethodDef array_methods[] = {
METH_VARARGS | METH_KEYWORDS, NULL},
{"trace",
(PyCFunction)array_trace,
- METH_VARARGS | METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"transpose",
(PyCFunction)array_transpose,
METH_VARARGS, NULL},
@@ -2877,6 +2916,6 @@ NPY_NO_EXPORT PyMethodDef array_methods[] = {
METH_VARARGS | METH_KEYWORDS, NULL},
{"view",
(PyCFunction)array_view,
- METH_VARARGS | METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{NULL, NULL, 0, NULL} /* sentinel */
};
diff --git a/numpy/core/src/multiarray/multiarraymodule.c b/numpy/core/src/multiarray/multiarraymodule.c
index af5949e73..ea9c10543 100644
--- a/numpy/core/src/multiarray/multiarraymodule.c
+++ b/numpy/core/src/multiarray/multiarraymodule.c
@@ -26,7 +26,7 @@
#include "numpy/arrayscalars.h"
#include "numpy/npy_math.h"
-
+#include "npy_argparse.h"
#include "npy_config.h"
#include "npy_pycompat.h"
#include "npy_import.h"
@@ -448,17 +448,10 @@ PyArray_ConcatenateArrays(int narrays, PyArrayObject **arrays, int axis,
/* Get the priority subtype for the array */
PyTypeObject *subtype = PyArray_GetSubType(narrays, arrays);
-
- if (dtype == NULL) {
- /* Get the resulting dtype from combining all the arrays */
- dtype = (PyArray_Descr *)PyArray_ResultType(
- narrays, arrays, 0, NULL);
- if (dtype == NULL) {
- return NULL;
- }
- }
- else {
- Py_INCREF(dtype);
+ PyArray_Descr *descr = PyArray_FindConcatenationDescriptor(
+ narrays, arrays, (PyObject *)dtype);
+ if (descr == NULL) {
+ return NULL;
}
/*
@@ -467,7 +460,7 @@ PyArray_ConcatenateArrays(int narrays, PyArrayObject **arrays, int axis,
* resolution rules matching that of the NpyIter.
*/
PyArray_CreateMultiSortedStridePerm(narrays, arrays, ndim, strideperm);
- s = dtype->elsize;
+ s = descr->elsize;
for (idim = ndim-1; idim >= 0; --idim) {
int iperm = strideperm[idim];
strides[iperm] = s;
@@ -475,17 +468,13 @@ PyArray_ConcatenateArrays(int narrays, PyArrayObject **arrays, int axis,
}
/* Allocate the array for the result. This steals the 'dtype' reference. */
- ret = (PyArrayObject *)PyArray_NewFromDescr(subtype,
- dtype,
- ndim,
- shape,
- strides,
- NULL,
- 0,
- NULL);
+ ret = (PyArrayObject *)PyArray_NewFromDescr_int(
+ subtype, descr, ndim, shape, strides, NULL, 0, NULL,
+ NULL, 0, 1);
if (ret == NULL) {
return NULL;
}
+ assert(PyArray_DESCR(ret) == descr);
}
/*
@@ -575,32 +564,22 @@ PyArray_ConcatenateFlattenedArrays(int narrays, PyArrayObject **arrays,
/* Get the priority subtype for the array */
PyTypeObject *subtype = PyArray_GetSubType(narrays, arrays);
- if (dtype == NULL) {
- /* Get the resulting dtype from combining all the arrays */
- dtype = (PyArray_Descr *)PyArray_ResultType(
- narrays, arrays, 0, NULL);
- if (dtype == NULL) {
- return NULL;
- }
- }
- else {
- Py_INCREF(dtype);
+ PyArray_Descr *descr = PyArray_FindConcatenationDescriptor(
+ narrays, arrays, (PyObject *)dtype);
+ if (descr == NULL) {
+ return NULL;
}
- stride = dtype->elsize;
+ stride = descr->elsize;
/* Allocate the array for the result. This steals the 'dtype' reference. */
- ret = (PyArrayObject *)PyArray_NewFromDescr(subtype,
- dtype,
- 1,
- &shape,
- &stride,
- NULL,
- 0,
- NULL);
+ ret = (PyArrayObject *)PyArray_NewFromDescr_int(
+ subtype, descr, 1, &shape, &stride, NULL, 0, NULL,
+ NULL, 0, 1);
if (ret == NULL) {
return NULL;
}
+ assert(PyArray_DESCR(ret) == descr);
}
/*
@@ -1491,7 +1470,9 @@ array_putmask(PyObject *NPY_UNUSED(module), PyObject *args, PyObject *kwds)
NPY_NO_EXPORT unsigned char
PyArray_EquivTypes(PyArray_Descr *type1, PyArray_Descr *type2)
{
-#if NPY_USE_NEW_CASTINGIMPL
+ if (type1 == type2) {
+ return 1;
+ }
/*
* Do not use PyArray_CanCastTypeTo because it supports legacy flexible
* dtypes as input.
@@ -1503,9 +1484,6 @@ PyArray_EquivTypes(PyArray_Descr *type1, PyArray_Descr *type2)
}
/* If casting is "no casting" this dtypes are considered equivalent. */
return PyArray_MinCastSafety(safety, NPY_NO_CASTING) == NPY_NO_CASTING;
-#else
- return PyArray_LegacyEquivTypes(type1, type2);
-#endif
}
@@ -1577,135 +1555,23 @@ _prepend_ones(PyArrayObject *arr, int nd, int ndmin, NPY_ORDER order)
((order) == NPY_CORDER && PyArray_IS_C_CONTIGUOUS(op)) || \
((order) == NPY_FORTRANORDER && PyArray_IS_F_CONTIGUOUS(op)))
-static PyObject *
-_array_fromobject(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kws)
+static NPY_INLINE PyObject *
+_array_fromobject_generic(
+ PyObject *op, PyArray_Descr *type, npy_bool copy, NPY_ORDER order,
+ npy_bool subok, int ndmin)
{
- PyObject *op;
PyArrayObject *oparr = NULL, *ret = NULL;
- npy_bool subok = NPY_FALSE;
- npy_bool copy = NPY_TRUE;
- int ndmin = 0, nd;
- PyObject* like;
- PyArray_Descr *type = NULL;
PyArray_Descr *oldtype = NULL;
- NPY_ORDER order = NPY_KEEPORDER;
- int flags = 0;
-
- PyObject* array_function_result = NULL;
-
- static char *kwd[] = {"object", "dtype", "copy", "order", "subok",
- "ndmin", "like", NULL};
-
- if (PyTuple_GET_SIZE(args) > 2) {
- PyErr_Format(PyExc_TypeError,
- "array() takes from 1 to 2 positional arguments but "
- "%zd were given", PyTuple_GET_SIZE(args));
- return NULL;
- }
-
- array_function_result = array_implement_c_array_function_creation(
- "array", args, kws);
- if (array_function_result != Py_NotImplemented) {
- return array_function_result;
- }
-
- /* super-fast path for ndarray argument calls */
- if (PyTuple_GET_SIZE(args) == 0) {
- goto full_path;
- }
- op = PyTuple_GET_ITEM(args, 0);
- if (PyArray_CheckExact(op)) {
- PyObject * dtype_obj = Py_None;
- oparr = (PyArrayObject *)op;
- /* get dtype which can be positional */
- if (PyTuple_GET_SIZE(args) == 2) {
- dtype_obj = PyTuple_GET_ITEM(args, 1);
- }
- else if (kws) {
- dtype_obj = PyDict_GetItemWithError(kws, npy_ma_str_dtype);
- if (dtype_obj == NULL && PyErr_Occurred()) {
- return NULL;
- }
- if (dtype_obj == NULL) {
- dtype_obj = Py_None;
- }
- }
- if (dtype_obj != Py_None) {
- goto full_path;
- }
-
- /* array(ndarray) */
- if (kws == NULL) {
- ret = (PyArrayObject *)PyArray_NewCopy(oparr, order);
- goto finish;
- }
- else {
- /* fast path for copy=False rest default (np.asarray) */
- PyObject * copy_obj, * order_obj, *ndmin_obj;
- copy_obj = PyDict_GetItemWithError(kws, npy_ma_str_copy);
- if (copy_obj == NULL && PyErr_Occurred()) {
- return NULL;
- }
- if (copy_obj != Py_False) {
- goto full_path;
- }
- copy = NPY_FALSE;
-
- /* order does not matter for contiguous 1d arrays */
- if (PyArray_NDIM((PyArrayObject*)op) > 1 ||
- !PyArray_IS_C_CONTIGUOUS((PyArrayObject*)op)) {
- order_obj = PyDict_GetItemWithError(kws, npy_ma_str_order);
- if (order_obj == NULL && PyErr_Occurred()) {
- return NULL;
- }
- else if (order_obj != Py_None && order_obj != NULL) {
- goto full_path;
- }
- }
-
- ndmin_obj = PyDict_GetItemWithError(kws, npy_ma_str_ndmin);
- if (ndmin_obj == NULL && PyErr_Occurred()) {
- return NULL;
- }
- else if (ndmin_obj) {
- long t = PyLong_AsLong(ndmin_obj);
- if (error_converting(t)) {
- goto clean_type;
- }
- else if (t > NPY_MAXDIMS) {
- goto full_path;
- }
- ndmin = t;
- }
-
- /* copy=False with default dtype, order (any is OK) and ndim */
- ret = oparr;
- Py_INCREF(ret);
- goto finish;
- }
- }
-
-full_path:
- if (!PyArg_ParseTupleAndKeywords(args, kws, "O|O&O&O&O&i$O:array", kwd,
- &op,
- PyArray_DescrConverter2, &type,
- PyArray_BoolConverter, &copy,
- PyArray_OrderConverter, &order,
- PyArray_BoolConverter, &subok,
- &ndmin,
- &like)) {
- goto clean_type;
- }
+ int nd, flags = 0;
if (ndmin > NPY_MAXDIMS) {
PyErr_Format(PyExc_ValueError,
"ndmin bigger than allowable number of dimensions "
"NPY_MAXDIMS (=%d)", NPY_MAXDIMS);
- goto clean_type;
+ return NULL;
}
/* fast exit if simple call */
- if ((subok && PyArray_Check(op)) ||
- (!subok && PyArray_CheckExact(op))) {
+ if (PyArray_CheckExact(op) || (subok && PyArray_Check(op))) {
oparr = (PyArrayObject *)op;
if (type == NULL) {
if (!copy && STRIDING_OK(oparr, order)) {
@@ -1760,8 +1626,7 @@ full_path:
ret = (PyArrayObject *)PyArray_CheckFromAny(op, type,
0, 0, flags, NULL);
- finish:
- Py_XDECREF(type);
+finish:
if (ret == NULL) {
return NULL;
}
@@ -1775,16 +1640,215 @@ full_path:
* steals a reference to ret
*/
return _prepend_ones(ret, nd, ndmin, order);
+}
-clean_type:
+#undef STRIDING_OK
+
+
+static PyObject *
+array_array(PyObject *NPY_UNUSED(ignored),
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
+{
+ PyObject *op;
+ npy_bool subok = NPY_FALSE;
+ npy_bool copy = NPY_TRUE;
+ int ndmin = 0;
+ PyArray_Descr *type = NULL;
+ NPY_ORDER order = NPY_KEEPORDER;
+ PyObject *like = NULL;
+ NPY_PREPARE_ARGPARSER;
+
+ if (len_args != 1 || (kwnames != NULL)) {
+ if (npy_parse_arguments("array", args, len_args, kwnames,
+ "object", NULL, &op,
+ "|dtype", &PyArray_DescrConverter2, &type,
+ "$copy", &PyArray_BoolConverter, &copy,
+ "$order", &PyArray_OrderConverter, &order,
+ "$subok", &PyArray_BoolConverter, &subok,
+ "$ndmin", &PyArray_PythonPyIntFromInt, &ndmin,
+ "$like", NULL, &like,
+ NULL, NULL, NULL) < 0) {
+ Py_XDECREF(type);
+ return NULL;
+ }
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "array", like, NULL, NULL, args, len_args, kwnames);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(type);
+ return deferred;
+ }
+ }
+ }
+ else {
+ /* Fast path for symmetry (we copy by default which is slow) */
+ op = args[0];
+ }
+
+ PyObject *res = _array_fromobject_generic(
+ op, type, copy, order, subok, ndmin);
Py_XDECREF(type);
- return NULL;
+ return res;
}
static PyObject *
-array_copyto(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kwds)
+array_asarray(PyObject *NPY_UNUSED(ignored),
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
+{
+ PyObject *op;
+ PyArray_Descr *type = NULL;
+ NPY_ORDER order = NPY_KEEPORDER;
+ PyObject *like = NULL;
+ NPY_PREPARE_ARGPARSER;
+
+ if (len_args != 1 || (kwnames != NULL)) {
+ if (npy_parse_arguments("asarray", args, len_args, kwnames,
+ "a", NULL, &op,
+ "|dtype", &PyArray_DescrConverter2, &type,
+ "|order", &PyArray_OrderConverter, &order,
+ "$like", NULL, &like,
+ NULL, NULL, NULL) < 0) {
+ Py_XDECREF(type);
+ return NULL;
+ }
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "asarray", like, NULL, NULL, args, len_args, kwnames);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(type);
+ return deferred;
+ }
+ }
+ }
+ else {
+ op = args[0];
+ }
+
+ PyObject *res = _array_fromobject_generic(
+ op, type, NPY_FALSE, order, NPY_FALSE, 0);
+ Py_XDECREF(type);
+ return res;
+}
+
+static PyObject *
+array_asanyarray(PyObject *NPY_UNUSED(ignored),
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
+{
+ PyObject *op;
+ PyArray_Descr *type = NULL;
+ NPY_ORDER order = NPY_KEEPORDER;
+ PyObject *like = NULL;
+ NPY_PREPARE_ARGPARSER;
+
+ if (len_args != 1 || (kwnames != NULL)) {
+ if (npy_parse_arguments("asanyarray", args, len_args, kwnames,
+ "a", NULL, &op,
+ "|dtype", &PyArray_DescrConverter2, &type,
+ "|order", &PyArray_OrderConverter, &order,
+ "$like", NULL, &like,
+ NULL, NULL, NULL) < 0) {
+ Py_XDECREF(type);
+ return NULL;
+ }
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "asanyarray", like, NULL, NULL, args, len_args, kwnames);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(type);
+ return deferred;
+ }
+ }
+ }
+ else {
+ op = args[0];
+ }
+
+ PyObject *res = _array_fromobject_generic(
+ op, type, NPY_FALSE, order, NPY_TRUE, 0);
+ Py_XDECREF(type);
+ return res;
+}
+
+
+static PyObject *
+array_ascontiguousarray(PyObject *NPY_UNUSED(ignored),
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
+ PyObject *op;
+ PyArray_Descr *type = NULL;
+ PyObject *like = NULL;
+ NPY_PREPARE_ARGPARSER;
+
+ if (len_args != 1 || (kwnames != NULL)) {
+ if (npy_parse_arguments("ascontiguousarray", args, len_args, kwnames,
+ "a", NULL, &op,
+ "|dtype", &PyArray_DescrConverter2, &type,
+ "$like", NULL, &like,
+ NULL, NULL, NULL) < 0) {
+ Py_XDECREF(type);
+ return NULL;
+ }
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "ascontiguousarray", like, NULL, NULL, args, len_args, kwnames);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(type);
+ return deferred;
+ }
+ }
+ }
+ else {
+ op = args[0];
+ }
+
+ PyObject *res = _array_fromobject_generic(
+ op, type, NPY_FALSE, NPY_CORDER, NPY_FALSE, 1);
+ Py_XDECREF(type);
+ return res;
+}
+
+static PyObject *
+array_asfortranarray(PyObject *NPY_UNUSED(ignored),
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
+{
+ PyObject *op;
+ PyArray_Descr *type = NULL;
+ PyObject *like = NULL;
+ NPY_PREPARE_ARGPARSER;
+
+ if (len_args != 1 || (kwnames != NULL)) {
+ if (npy_parse_arguments("asfortranarray", args, len_args, kwnames,
+ "a", NULL, &op,
+ "|dtype", &PyArray_DescrConverter2, &type,
+ "$like", NULL, &like,
+ NULL, NULL, NULL) < 0) {
+ Py_XDECREF(type);
+ return NULL;
+ }
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "asfortranarray", like, NULL, NULL, args, len_args, kwnames);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(type);
+ return deferred;
+ }
+ }
+ }
+ else {
+ op = args[0];
+ }
+
+ PyObject *res = _array_fromobject_generic(
+ op, type, NPY_FALSE, NPY_FORTRANORDER, NPY_FALSE, 1);
+ Py_XDECREF(type);
+ return res;
+}
+
+
+static PyObject *
+array_copyto(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kwds)
+{
static char *kwlist[] = {"dst", "src", "casting", "where", NULL};
PyObject *wheremask_in = NULL;
PyArrayObject *dst = NULL, *src = NULL, *wheremask = NULL;
@@ -1827,30 +1891,34 @@ fail:
}
static PyObject *
-array_empty(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kwds)
+array_empty(PyObject *NPY_UNUSED(ignored),
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
-
- static char *kwlist[] = {"shape", "dtype", "order", "like", NULL};
PyArray_Descr *typecode = NULL;
PyArray_Dims shape = {NULL, 0};
NPY_ORDER order = NPY_CORDER;
- PyObject *like = NULL;
npy_bool is_f_order;
- PyObject *array_function_result = NULL;
PyArrayObject *ret = NULL;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|O&O&$O:empty", kwlist,
- PyArray_IntpConverter, &shape,
- PyArray_DescrConverter, &typecode,
- PyArray_OrderConverter, &order,
- &like)) {
+ PyObject *like = NULL;
+ NPY_PREPARE_ARGPARSER;
+
+ if (npy_parse_arguments("empty", args, len_args, kwnames,
+ "shape", &PyArray_IntpConverter, &shape,
+ "|dtype", &PyArray_DescrConverter, &typecode,
+ "|order", &PyArray_OrderConverter, &order,
+ "$like", NULL, &like,
+ NULL, NULL, NULL) < 0) {
goto fail;
}
- array_function_result = array_implement_c_array_function_creation(
- "empty", args, kwds);
- if (array_function_result != Py_NotImplemented) {
- return array_function_result;
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "empty", like, NULL, NULL, args, len_args, kwnames);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(typecode);
+ npy_free_cache_dim_obj(shape);
+ return deferred;
+ }
}
switch (order) {
@@ -2025,29 +2093,35 @@ array_scalar(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kwds)
}
static PyObject *
-array_zeros(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kwds)
+array_zeros(PyObject *NPY_UNUSED(ignored),
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
- static char *kwlist[] = {"shape", "dtype", "order", "like", NULL};
PyArray_Descr *typecode = NULL;
PyArray_Dims shape = {NULL, 0};
NPY_ORDER order = NPY_CORDER;
- PyObject *like = NULL;
npy_bool is_f_order = NPY_FALSE;
- PyObject *array_function_result = NULL;
PyArrayObject *ret = NULL;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O&|O&O&$O:zeros", kwlist,
- PyArray_IntpConverter, &shape,
- PyArray_DescrConverter, &typecode,
- PyArray_OrderConverter, &order,
- &like)) {
+ PyObject *like = NULL;
+ NPY_PREPARE_ARGPARSER;
+
+ if (npy_parse_arguments("zeros", args, len_args, kwnames,
+ "shape", &PyArray_IntpConverter, &shape,
+ "|dtype", &PyArray_DescrConverter, &typecode,
+ "|order", &PyArray_OrderConverter, &order,
+ "$like", NULL, &like,
+ NULL, NULL, NULL) < 0) {
goto fail;
}
- array_function_result = array_implement_c_array_function_creation(
- "zeros", args, kwds);
- if (array_function_result != Py_NotImplemented) {
- return array_function_result;
+
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "zeros", like, NULL, NULL, args, len_args, kwnames);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(typecode);
+ npy_free_cache_dim_obj(shape);
+ return deferred;
+ }
}
switch (order) {
@@ -2105,7 +2179,6 @@ array_fromstring(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *keywds
static char *kwlist[] = {"string", "dtype", "count", "sep", "like", NULL};
PyObject *like = NULL;
PyArray_Descr *descr = NULL;
- PyObject *array_function_result = NULL;
if (!PyArg_ParseTupleAndKeywords(args, keywds,
"s#|O&" NPY_SSIZE_T_PYFMT "s$O:fromstring", kwlist,
@@ -2113,11 +2186,13 @@ array_fromstring(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *keywds
Py_XDECREF(descr);
return NULL;
}
-
- array_function_result = array_implement_c_array_function_creation(
- "fromstring", args, keywds);
- if (array_function_result != Py_NotImplemented) {
- return array_function_result;
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "fromstring", like, args, keywds, NULL, 0, NULL);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(descr);
+ return deferred;
+ }
}
/* binary mode, condition copied from PyArray_FromString */
@@ -2145,7 +2220,6 @@ array_fromfile(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *keywds)
static char *kwlist[] = {"file", "dtype", "count", "sep", "offset", "like", NULL};
PyObject *like = NULL;
PyArray_Descr *type = NULL;
- PyObject *array_function_result = NULL;
int own;
npy_off_t orig_pos = 0, offset = 0;
FILE *fp;
@@ -2157,14 +2231,18 @@ array_fromfile(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *keywds)
return NULL;
}
- array_function_result = array_implement_c_array_function_creation(
- "fromfile", args, keywds);
- if (array_function_result != Py_NotImplemented) {
- return array_function_result;
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "fromfile", like, args, keywds, NULL, 0, NULL);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(type);
+ return deferred;
+ }
}
file = NpyPath_PathlikeToFspath(file);
if (file == NULL) {
+ Py_XDECREF(type);
return NULL;
}
@@ -2232,7 +2310,6 @@ array_fromiter(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *keywds)
static char *kwlist[] = {"iter", "dtype", "count", "like", NULL};
PyObject *like = NULL;
PyArray_Descr *descr = NULL;
- PyObject *array_function_result = NULL;
if (!PyArg_ParseTupleAndKeywords(args, keywds,
"OO&|" NPY_SSIZE_T_PYFMT "$O:fromiter", kwlist,
@@ -2240,12 +2317,13 @@ array_fromiter(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *keywds)
Py_XDECREF(descr);
return NULL;
}
-
- array_function_result = array_implement_c_array_function_creation(
- "fromiter", args, keywds);
- if (array_function_result != Py_NotImplemented) {
- Py_DECREF(descr);
- return array_function_result;
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "fromiter", like, args, keywds, NULL, 0, NULL);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(descr);
+ return deferred;
+ }
}
return PyArray_FromIter(iter, descr, (npy_intp)nin);
@@ -2259,7 +2337,6 @@ array_frombuffer(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *keywds
static char *kwlist[] = {"buffer", "dtype", "count", "offset", "like", NULL};
PyObject *like = NULL;
PyArray_Descr *type = NULL;
- PyObject *array_function_result = NULL;
if (!PyArg_ParseTupleAndKeywords(args, keywds,
"O|O&" NPY_SSIZE_T_PYFMT NPY_SSIZE_T_PYFMT "$O:frombuffer", kwlist,
@@ -2268,10 +2345,13 @@ array_frombuffer(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *keywds
return NULL;
}
- array_function_result = array_implement_c_array_function_creation(
- "frombuffer", args, keywds);
- if (array_function_result != Py_NotImplemented) {
- return array_function_result;
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "frombuffer", like, args, keywds, NULL, 0, NULL);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(type);
+ return deferred;
+ }
}
if (type == NULL) {
@@ -2340,7 +2420,7 @@ array_matrixproduct(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject* kwds)
{
PyObject *v, *a, *o = NULL;
PyArrayObject *ret;
- char* kwlist[] = {"a", "b", "out", NULL };
+ static char* kwlist[] = {"a", "b", "out", NULL};
if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|O:matrixproduct",
kwlist, &a, &v, &o)) {
@@ -2843,56 +2923,80 @@ array_fastCopyAndTranspose(PyObject *NPY_UNUSED(dummy), PyObject *args)
}
static PyObject *
-array_correlate(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *kwds)
+array_correlate(PyObject *NPY_UNUSED(dummy),
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
PyObject *shape, *a0;
int mode = 0;
- static char *kwlist[] = {"a", "v", "mode", NULL};
+ NPY_PREPARE_ARGPARSER;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|i:correlate", kwlist,
- &a0, &shape, &mode)) {
+ if (npy_parse_arguments("correlate", args, len_args, kwnames,
+ "a", NULL, &a0,
+ "v", NULL, &shape,
+ "|mode", &PyArray_CorrelatemodeConverter, &mode,
+ NULL, NULL, NULL) < 0) {
return NULL;
}
return PyArray_Correlate(a0, shape, mode);
}
static PyObject*
-array_correlate2(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *kwds)
+array_correlate2(PyObject *NPY_UNUSED(dummy),
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
PyObject *shape, *a0;
int mode = 0;
- static char *kwlist[] = {"a", "v", "mode", NULL};
+ NPY_PREPARE_ARGPARSER;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|i:correlate2", kwlist,
- &a0, &shape, &mode)) {
+ if (npy_parse_arguments("correlate2", args, len_args, kwnames,
+ "a", NULL, &a0,
+ "v", NULL, &shape,
+ "|mode", &PyArray_CorrelatemodeConverter, &mode,
+ NULL, NULL, NULL) < 0) {
return NULL;
}
return PyArray_Correlate2(a0, shape, mode);
}
static PyObject *
-array_arange(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kws) {
+array_arange(PyObject *NPY_UNUSED(ignored),
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
+{
PyObject *o_start = NULL, *o_stop = NULL, *o_step = NULL, *range=NULL;
- PyObject *like = NULL;
- PyObject *array_function_result = NULL;
- static char *kwd[] = {"start", "stop", "step", "dtype", "like", NULL};
PyArray_Descr *typecode = NULL;
-
- if (!PyArg_ParseTupleAndKeywords(args, kws, "O|OOO&$O:arange", kwd,
- &o_start,
- &o_stop,
- &o_step,
- PyArray_DescrConverter2, &typecode,
- &like)) {
+ PyObject *like = NULL;
+ NPY_PREPARE_ARGPARSER;
+
+ if (npy_parse_arguments("arange", args, len_args, kwnames,
+ "|start", NULL, &o_start,
+ "|stop", NULL, &o_stop,
+ "|step", NULL, &o_step,
+ "|dtype", &PyArray_DescrConverter2, &typecode,
+ "$like", NULL, &like,
+ NULL, NULL, NULL) < 0) {
Py_XDECREF(typecode);
return NULL;
}
+ if (like != NULL) {
+ PyObject *deferred = array_implement_c_array_function_creation(
+ "arange", like, NULL, NULL, args, len_args, kwnames);
+ if (deferred != Py_NotImplemented) {
+ Py_XDECREF(typecode);
+ return deferred;
+ }
+ }
- array_function_result = array_implement_c_array_function_creation(
- "arange", args, kws);
- if (array_function_result != Py_NotImplemented) {
- Py_XDECREF(typecode);
- return array_function_result;
+ if (o_stop == NULL) {
+ if (len_args == 0){
+ PyErr_SetString(PyExc_TypeError,
+ "arange() requires stop to be specified.");
+ Py_XDECREF(typecode);
+ return NULL;
+ }
+ }
+ else if (o_start == NULL) {
+ o_start = o_stop;
+ o_stop = NULL;
}
range = PyArray_ArangeObj(o_start, o_stop, o_step, typecode);
@@ -3252,7 +3356,7 @@ array_can_cast_safely(PyObject *NPY_UNUSED(self), PyObject *args,
PyObject *from_obj = NULL;
PyArray_Descr *d1 = NULL;
PyArray_Descr *d2 = NULL;
- npy_bool ret;
+ int ret;
PyObject *retobj = NULL;
NPY_CASTING casting = NPY_SAFE_CASTING;
static char *kwlist[] = {"from_", "to", "casting", NULL};
@@ -3382,6 +3486,10 @@ array_result_type(PyObject *NPY_UNUSED(dummy), PyObject *args)
if (arr[narr] == NULL) {
goto finish;
}
+ if (PyLong_CheckExact(obj) || PyFloat_CheckExact(obj) ||
+ PyComplex_CheckExact(obj)) {
+ ((PyArrayObject_fields *)arr[narr])->flags |= _NPY_ARRAY_WAS_PYSCALAR;
+ }
++narr;
}
else {
@@ -3427,6 +3535,42 @@ array_datetime_data(PyObject *NPY_UNUSED(dummy), PyObject *args)
return res;
}
+
+static int
+trimmode_converter(PyObject *obj, TrimMode *trim)
+{
+ if (!PyUnicode_Check(obj) || PyUnicode_GetLength(obj) != 1) {
+ goto error;
+ }
+ const char *trimstr = PyUnicode_AsUTF8AndSize(obj, NULL);
+
+ if (trimstr != NULL) {
+ if (trimstr[0] == 'k') {
+ *trim = TrimMode_None;
+ }
+ else if (trimstr[0] == '.') {
+ *trim = TrimMode_Zeros;
+ }
+ else if (trimstr[0] == '0') {
+ *trim = TrimMode_LeaveOneZero;
+ }
+ else if (trimstr[0] == '-') {
+ *trim = TrimMode_DptZeros;
+ }
+ else {
+ goto error;
+ }
+ }
+ return NPY_SUCCEED;
+
+error:
+ PyErr_Format(PyExc_TypeError,
+ "if supplied, trim must be 'k', '.', '0' or '-' found `%100S`",
+ obj);
+ return NPY_FAIL;
+}
+
+
/*
* Prints floating-point scalars using the Dragon4 algorithm, scientific mode.
* See docstring of `np.format_float_scientific` for description of arguments.
@@ -3434,43 +3578,29 @@ array_datetime_data(PyObject *NPY_UNUSED(dummy), PyObject *args)
* precision, which is equivalent to `None`.
*/
static PyObject *
-dragon4_scientific(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *kwds)
+dragon4_scientific(PyObject *NPY_UNUSED(dummy),
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
PyObject *obj;
- static char *kwlist[] = {"x", "precision", "unique", "sign", "trim",
- "pad_left", "exp_digits", NULL};
- int precision=-1, pad_left=-1, exp_digits=-1;
- char *trimstr=NULL;
+ int precision=-1, pad_left=-1, exp_digits=-1, min_digits=-1;
DigitMode digit_mode;
TrimMode trim = TrimMode_None;
int sign=0, unique=1;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|iiisii:dragon4_scientific",
- kwlist, &obj, &precision, &unique, &sign, &trimstr, &pad_left,
- &exp_digits)) {
+ NPY_PREPARE_ARGPARSER;
+
+ if (npy_parse_arguments("dragon4_scientific", args, len_args, kwnames,
+ "x", NULL , &obj,
+ "|precision", &PyArray_PythonPyIntFromInt, &precision,
+ "|unique", &PyArray_PythonPyIntFromInt, &unique,
+ "|sign", &PyArray_PythonPyIntFromInt, &sign,
+ "|trim", &trimmode_converter, &trim,
+ "|pad_left", &PyArray_PythonPyIntFromInt, &pad_left,
+ "|exp_digits", &PyArray_PythonPyIntFromInt, &exp_digits,
+ "|min_digits", &PyArray_PythonPyIntFromInt, &min_digits,
+ NULL, NULL, NULL) < 0) {
return NULL;
}
- if (trimstr != NULL) {
- if (strcmp(trimstr, "k") == 0) {
- trim = TrimMode_None;
- }
- else if (strcmp(trimstr, ".") == 0) {
- trim = TrimMode_Zeros;
- }
- else if (strcmp(trimstr, "0") == 0) {
- trim = TrimMode_LeaveOneZero;
- }
- else if (strcmp(trimstr, "-") == 0) {
- trim = TrimMode_DptZeros;
- }
- else {
- PyErr_SetString(PyExc_TypeError,
- "if supplied, trim must be 'k', '.', '0' or '-'");
- return NULL;
- }
- }
-
digit_mode = unique ? DigitMode_Unique : DigitMode_Exact;
if (unique == 0 && precision < 0) {
@@ -3479,7 +3609,7 @@ dragon4_scientific(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *kwds)
return NULL;
}
- return Dragon4_Scientific(obj, digit_mode, precision, sign, trim,
+ return Dragon4_Scientific(obj, digit_mode, precision, min_digits, sign, trim,
pad_left, exp_digits);
}
@@ -3490,44 +3620,31 @@ dragon4_scientific(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *kwds)
* precision, which is equivalent to `None`.
*/
static PyObject *
-dragon4_positional(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *kwds)
+dragon4_positional(PyObject *NPY_UNUSED(dummy),
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
PyObject *obj;
- static char *kwlist[] = {"x", "precision", "unique", "fractional",
- "sign", "trim", "pad_left", "pad_right", NULL};
- int precision=-1, pad_left=-1, pad_right=-1;
- char *trimstr=NULL;
+ int precision=-1, pad_left=-1, pad_right=-1, min_digits=-1;
CutoffMode cutoff_mode;
DigitMode digit_mode;
TrimMode trim = TrimMode_None;
int sign=0, unique=1, fractional=0;
-
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|iiiisii:dragon4_positional",
- kwlist, &obj, &precision, &unique, &fractional, &sign, &trimstr,
- &pad_left, &pad_right)) {
+ NPY_PREPARE_ARGPARSER;
+
+ if (npy_parse_arguments("dragon4_positional", args, len_args, kwnames,
+ "x", NULL , &obj,
+ "|precision", &PyArray_PythonPyIntFromInt, &precision,
+ "|unique", &PyArray_PythonPyIntFromInt, &unique,
+ "|fractional", &PyArray_PythonPyIntFromInt, &fractional,
+ "|sign", &PyArray_PythonPyIntFromInt, &sign,
+ "|trim", &trimmode_converter, &trim,
+ "|pad_left", &PyArray_PythonPyIntFromInt, &pad_left,
+ "|pad_right", &PyArray_PythonPyIntFromInt, &pad_right,
+ "|min_digits", &PyArray_PythonPyIntFromInt, &min_digits,
+ NULL, NULL, NULL) < 0) {
return NULL;
}
- if (trimstr != NULL) {
- if (strcmp(trimstr, "k") == 0) {
- trim = TrimMode_None;
- }
- else if (strcmp(trimstr, ".") == 0) {
- trim = TrimMode_Zeros;
- }
- else if (strcmp(trimstr, "0") == 0) {
- trim = TrimMode_LeaveOneZero;
- }
- else if (strcmp(trimstr, "-") == 0) {
- trim = TrimMode_DptZeros;
- }
- else {
- PyErr_SetString(PyExc_TypeError,
- "if supplied, trim must be 'k', '.', '0' or '-'");
- return NULL;
- }
- }
-
digit_mode = unique ? DigitMode_Unique : DigitMode_Exact;
cutoff_mode = fractional ? CutoffMode_FractionLength :
CutoffMode_TotalLength;
@@ -3538,8 +3655,8 @@ dragon4_positional(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *kwds)
return NULL;
}
- return Dragon4_Positional(obj, digit_mode, cutoff_mode, precision, sign,
- trim, pad_left, pad_right);
+ return Dragon4_Positional(obj, digit_mode, cutoff_mode, precision,
+ min_digits, sign, trim, pad_left, pad_right);
}
static PyObject *
@@ -3558,7 +3675,7 @@ format_longfloat(PyObject *NPY_UNUSED(dummy), PyObject *args, PyObject *kwds)
"not a longfloat");
return NULL;
}
- return Dragon4_Scientific(obj, DigitMode_Unique, precision, 0,
+ return Dragon4_Scientific(obj, DigitMode_Unique, precision, -1, 0,
TrimMode_LeaveOneZero, -1, -1);
}
@@ -4053,15 +4170,19 @@ array_may_share_memory(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *
}
static PyObject *
-normalize_axis_index(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwds)
+normalize_axis_index(PyObject *NPY_UNUSED(self),
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
- static char *kwlist[] = {"axis", "ndim", "msg_prefix", NULL};
int axis;
int ndim;
PyObject *msg_prefix = Py_None;
+ NPY_PREPARE_ARGPARSER;
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "ii|O:normalize_axis_index",
- kwlist, &axis, &ndim, &msg_prefix)) {
+ if (npy_parse_arguments("normalize_axis_index", args, len_args, kwnames,
+ "axis", &PyArray_PythonPyIntFromInt, &axis,
+ "ndim", &PyArray_PythonPyIntFromInt, &ndim,
+ "|msg_prefix", NULL, &msg_prefix,
+ NULL, NULL, NULL) < 0) {
return NULL;
}
if (check_and_adjust_axis_msg(&axis, ndim, msg_prefix) < 0) {
@@ -4072,6 +4193,42 @@ normalize_axis_index(PyObject *NPY_UNUSED(self), PyObject *args, PyObject *kwds)
}
+static PyObject *
+_reload_guard(PyObject *NPY_UNUSED(self)) {
+ static int initialized = 0;
+
+#if !defined(PYPY_VERSION)
+ if (PyThreadState_Get()->interp != PyInterpreterState_Main()) {
+ if (PyErr_WarnEx(PyExc_UserWarning,
+ "NumPy was imported from a Python sub-interpreter but "
+ "NumPy does not properly support sub-interpreters. "
+ "This will likely work for most users but might cause hard to "
+ "track down issues or subtle bugs. "
+ "A common user of the rare sub-interpreter feature is wsgi "
+ "which also allows single-interpreter mode.\n"
+ "Improvements in the case of bugs are welcome, but is not "
+ "on the NumPy roadmap, and full support may require "
+ "significant effort to achieve.", 2) < 0) {
+ return NULL;
+ }
+ /* No need to give the other warning in a sub-interpreter as well... */
+ initialized = 1;
+ Py_RETURN_NONE;
+ }
+#endif
+ if (initialized) {
+ if (PyErr_WarnEx(PyExc_UserWarning,
+ "The NumPy module was reloaded (imported a second time). "
+ "This can in some cases result in small but subtle issues "
+ "and is discouraged.", 2) < 0) {
+ return NULL;
+ }
+ }
+ initialized = 1;
+ Py_RETURN_NONE;
+}
+
+
static struct PyMethodDef array_module_methods[] = {
{"_get_implementing_args",
(PyCFunction)array__get_implementing_args,
@@ -4095,8 +4252,20 @@ static struct PyMethodDef array_module_methods[] = {
(PyCFunction)array_set_typeDict,
METH_VARARGS, NULL},
{"array",
- (PyCFunction)_array_fromobject,
- METH_VARARGS|METH_KEYWORDS, NULL},
+ (PyCFunction)array_array,
+ METH_FASTCALL | METH_KEYWORDS, NULL},
+ {"asarray",
+ (PyCFunction)array_asarray,
+ METH_FASTCALL | METH_KEYWORDS, NULL},
+ {"asanyarray",
+ (PyCFunction)array_asanyarray,
+ METH_FASTCALL | METH_KEYWORDS, NULL},
+ {"ascontiguousarray",
+ (PyCFunction)array_ascontiguousarray,
+ METH_FASTCALL | METH_KEYWORDS, NULL},
+ {"asfortranarray",
+ (PyCFunction)array_asfortranarray,
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"copyto",
(PyCFunction)array_copyto,
METH_VARARGS|METH_KEYWORDS, NULL},
@@ -4105,16 +4274,16 @@ static struct PyMethodDef array_module_methods[] = {
METH_VARARGS|METH_KEYWORDS, NULL},
{"arange",
(PyCFunction)array_arange,
- METH_VARARGS|METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"zeros",
(PyCFunction)array_zeros,
- METH_VARARGS|METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"count_nonzero",
(PyCFunction)array_count_nonzero,
METH_VARARGS|METH_KEYWORDS, NULL},
{"empty",
(PyCFunction)array_empty,
- METH_VARARGS|METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"empty_like",
(PyCFunction)array_empty_like,
METH_VARARGS|METH_KEYWORDS, NULL},
@@ -4156,10 +4325,10 @@ static struct PyMethodDef array_module_methods[] = {
METH_VARARGS, NULL},
{"correlate",
(PyCFunction)array_correlate,
- METH_VARARGS | METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"correlate2",
(PyCFunction)array_correlate2,
- METH_VARARGS | METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"frombuffer",
(PyCFunction)array_frombuffer,
METH_VARARGS | METH_KEYWORDS, NULL},
@@ -4206,10 +4375,10 @@ static struct PyMethodDef array_module_methods[] = {
METH_VARARGS | METH_KEYWORDS, NULL},
{"dragon4_positional",
(PyCFunction)dragon4_positional,
- METH_VARARGS | METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"dragon4_scientific",
(PyCFunction)dragon4_scientific,
- METH_VARARGS | METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"compare_chararrays",
(PyCFunction)compare_chararrays,
METH_VARARGS | METH_KEYWORDS, NULL},
@@ -4242,7 +4411,7 @@ static struct PyMethodDef array_module_methods[] = {
{"unpackbits", (PyCFunction)io_unpack,
METH_VARARGS | METH_KEYWORDS, NULL},
{"normalize_axis_index", (PyCFunction)normalize_axis_index,
- METH_VARARGS | METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"set_legacy_print_mode", (PyCFunction)set_legacy_print_mode,
METH_VARARGS, NULL},
{"_discover_array_parameters", (PyCFunction)_discover_array_parameters,
@@ -4261,8 +4430,13 @@ static struct PyMethodDef array_module_methods[] = {
METH_VARARGS, NULL},
{"_add_newdoc_ufunc", (PyCFunction)add_newdoc_ufunc,
METH_VARARGS, NULL},
+ {"_get_sfloat_dtype",
+ get_sfloat_dtype, METH_NOARGS, NULL},
{"_set_madvise_hugepage", (PyCFunction)_set_madvise_hugepage,
METH_O, NULL},
+ {"_reload_guard", (PyCFunction)_reload_guard,
+ METH_NOARGS,
+ "Give a warning on reload and big warning in sub-interpreters."},
{NULL, NULL, 0, NULL} /* sentinel */
};
@@ -4434,16 +4608,9 @@ set_flaginfo(PyObject *d)
return;
}
-NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array = NULL;
-NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array_prepare = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array_wrap = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_array_finalize = NULL;
-NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_ufunc = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_implementation = NULL;
-NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_order = NULL;
-NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_copy = NULL;
-NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_dtype = NULL;
-NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_ndmin = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_axis1 = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_axis2 = NULL;
NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_like = NULL;
@@ -4452,27 +4619,35 @@ NPY_VISIBILITY_HIDDEN PyObject * npy_ma_str_numpy = NULL;
static int
intern_strings(void)
{
- npy_ma_str_array = PyUnicode_InternFromString("__array__");
- npy_ma_str_array_prepare = PyUnicode_InternFromString("__array_prepare__");
npy_ma_str_array_wrap = PyUnicode_InternFromString("__array_wrap__");
+ if (npy_ma_str_array_wrap == NULL) {
+ return -1;
+ }
npy_ma_str_array_finalize = PyUnicode_InternFromString("__array_finalize__");
- npy_ma_str_ufunc = PyUnicode_InternFromString("__array_ufunc__");
+ if (npy_ma_str_array_finalize == NULL) {
+ return -1;
+ }
npy_ma_str_implementation = PyUnicode_InternFromString("_implementation");
- npy_ma_str_order = PyUnicode_InternFromString("order");
- npy_ma_str_copy = PyUnicode_InternFromString("copy");
- npy_ma_str_dtype = PyUnicode_InternFromString("dtype");
- npy_ma_str_ndmin = PyUnicode_InternFromString("ndmin");
+ if (npy_ma_str_implementation == NULL) {
+ return -1;
+ }
npy_ma_str_axis1 = PyUnicode_InternFromString("axis1");
+ if (npy_ma_str_axis1 == NULL) {
+ return -1;
+ }
npy_ma_str_axis2 = PyUnicode_InternFromString("axis2");
+ if (npy_ma_str_axis2 == NULL) {
+ return -1;
+ }
npy_ma_str_like = PyUnicode_InternFromString("like");
+ if (npy_ma_str_like == NULL) {
+ return -1;
+ }
npy_ma_str_numpy = PyUnicode_InternFromString("numpy");
-
- return npy_ma_str_array && npy_ma_str_array_prepare &&
- npy_ma_str_array_wrap && npy_ma_str_array_finalize &&
- npy_ma_str_ufunc && npy_ma_str_implementation &&
- npy_ma_str_order && npy_ma_str_copy && npy_ma_str_dtype &&
- npy_ma_str_ndmin && npy_ma_str_axis1 && npy_ma_str_axis2 &&
- npy_ma_str_like && npy_ma_str_numpy;
+ if (npy_ma_str_numpy == NULL) {
+ return -1;
+ }
+ return 0;
}
static struct PyModuleDef moduledef = {
@@ -4525,26 +4700,10 @@ PyMODINIT_FUNC PyInit__multiarray_umath(void) {
goto err;
}
- /*
- * Before calling PyType_Ready, initialize the tp_hash slot in
- * PyArray_Type to work around mingw32 not being able initialize
- * static structure slots with functions from the Python C_API.
- */
- PyArray_Type.tp_hash = PyObject_HashNotImplemented;
-
if (PyType_Ready(&PyUFunc_Type) < 0) {
goto err;
}
- /* Load the ufunc operators into the array module's namespace */
- if (InitOperators(d) < 0) {
- goto err;
- }
-
- if (set_matmul_flags(d) < 0) {
- goto err;
- }
-
PyArrayDTypeMeta_Type.tp_base = &PyType_Type;
if (PyType_Ready(&PyArrayDTypeMeta_Type) < 0) {
goto err;
@@ -4558,6 +4717,7 @@ PyMODINIT_FUNC PyInit__multiarray_umath(void) {
initialize_casting_tables();
initialize_numeric_types();
+
if (initscalarmath(m) < 0) {
goto err;
}
@@ -4568,6 +4728,7 @@ PyMODINIT_FUNC PyInit__multiarray_umath(void) {
if (setup_scalartypes(d) < 0) {
goto err;
}
+
PyArrayIter_Type.tp_iter = PyObject_SelfIter;
NpyIter_Type.tp_iter = PyObject_SelfIter;
PyArrayMultiIter_Type.tp_iter = PyObject_SelfIter;
@@ -4711,7 +4872,7 @@ PyMODINIT_FUNC PyInit__multiarray_umath(void) {
goto err;
}
- if (!intern_strings()) {
+ if (intern_strings() < 0) {
goto err;
}
@@ -4732,6 +4893,15 @@ PyMODINIT_FUNC PyInit__multiarray_umath(void) {
goto err;
}
+ /* Load the ufunc operators into the array module's namespace */
+ if (InitOperators(d) < 0) {
+ goto err;
+ }
+
+ if (set_matmul_flags(d) < 0) {
+ goto err;
+ }
+
if (initumath(m) != 0) {
goto err;
}
diff --git a/numpy/core/src/multiarray/multiarraymodule.h b/numpy/core/src/multiarray/multiarraymodule.h
index d3ee3337c..4cdb6ef72 100644
--- a/numpy/core/src/multiarray/multiarraymodule.h
+++ b/numpy/core/src/multiarray/multiarraymodule.h
@@ -1,16 +1,9 @@
#ifndef _NPY_MULTIARRAY_H_
#define _NPY_MULTIARRAY_H_
-NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_array;
-NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_array_prepare;
NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_array_wrap;
NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_array_finalize;
-NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_ufunc;
NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_implementation;
-NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_order;
-NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_copy;
-NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_dtype;
-NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_ndmin;
NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_axis1;
NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_axis2;
NPY_VISIBILITY_HIDDEN extern PyObject * npy_ma_str_like;
diff --git a/numpy/core/src/multiarray/nditer_api.c b/numpy/core/src/multiarray/nditer_api.c
index 059f2c437..a1ca5bff5 100644
--- a/numpy/core/src/multiarray/nditer_api.c
+++ b/numpy/core/src/multiarray/nditer_api.c
@@ -1557,6 +1557,8 @@ NpyIter_DebugPrint(NpyIter *iter)
if (itflags&NPY_ITFLAG_BUFFER) {
NpyIter_BufferData *bufferdata = NIT_BUFFERDATA(iter);
+ NpyIter_TransferInfo *transferinfo = NBF_TRANSFERINFO(bufferdata);
+
printf("| BufferData:\n");
printf("| BufferSize: %d\n", (int)NBF_BUFFERSIZE(bufferdata));
printf("| Size: %d\n", (int)NBF_SIZE(bufferdata));
@@ -1598,19 +1600,19 @@ NpyIter_DebugPrint(NpyIter *iter)
}
printf("| ReadTransferFn: ");
for (iop = 0; iop < nop; ++iop)
- printf("%p ", (void *)NBF_READTRANSFERFN(bufferdata)[iop]);
+ printf("%p ", (void *)transferinfo[iop].read.func);
printf("\n");
printf("| ReadTransferData: ");
for (iop = 0; iop < nop; ++iop)
- printf("%p ", (void *)NBF_READTRANSFERDATA(bufferdata)[iop]);
+ printf("%p ", (void *)transferinfo[iop].read.auxdata);
printf("\n");
printf("| WriteTransferFn: ");
for (iop = 0; iop < nop; ++iop)
- printf("%p ", (void *)NBF_WRITETRANSFERFN(bufferdata)[iop]);
+ printf("%p ", (void *)transferinfo[iop].write.func);
printf("\n");
printf("| WriteTransferData: ");
for (iop = 0; iop < nop; ++iop)
- printf("%p ", (void *)NBF_WRITETRANSFERDATA(bufferdata)[iop]);
+ printf("%p ", (void *)transferinfo[iop].write.auxdata);
printf("\n");
printf("| Buffers: ");
for (iop = 0; iop < nop; ++iop)
@@ -1758,6 +1760,9 @@ npyiter_allocate_buffers(NpyIter *iter, char **errmsg)
}
goto fail;
}
+ if (PyDataType_FLAGCHK(op_dtype[iop], NPY_NEEDS_INIT)) {
+ memset(buffer, '\0', itemsize*buffersize);
+ }
buffers[iop] = buffer;
}
}
@@ -1889,9 +1894,6 @@ npyiter_copy_from_buffers(NpyIter *iter)
npy_intp reduce_outerdim = 0;
npy_intp *reduce_outerstrides = NULL;
- PyArray_StridedUnaryOp *stransfer = NULL;
- NpyAuxData *transferdata = NULL;
-
npy_intp axisdata_incr = NIT_AXISDATA_SIZEOF(itflags, ndim, nop) /
NPY_SIZEOF_INTP;
@@ -1909,9 +1911,8 @@ npyiter_copy_from_buffers(NpyIter *iter)
transfersize *= NBF_REDUCE_OUTERSIZE(bufferdata);
}
+ NpyIter_TransferInfo *transferinfo = NBF_TRANSFERINFO(bufferdata);
for (iop = 0; iop < nop; ++iop) {
- stransfer = NBF_WRITETRANSFERFN(bufferdata)[iop];
- transferdata = NBF_WRITETRANSFERDATA(bufferdata)[iop];
buffer = buffers[iop];
/*
* Copy the data back to the arrays. If the type has refs,
@@ -1920,7 +1921,7 @@ npyiter_copy_from_buffers(NpyIter *iter)
* The flag USINGBUFFER is set when the buffer was used, so
* only copy back when this flag is on.
*/
- if ((stransfer != NULL) &&
+ if ((transferinfo[iop].write.func != NULL) &&
(op_itflags[iop]&(NPY_OP_ITFLAG_WRITE|NPY_OP_ITFLAG_USINGBUFFER))
== (NPY_OP_ITFLAG_WRITE|NPY_OP_ITFLAG_USINGBUFFER)) {
npy_intp op_transfersize;
@@ -2011,8 +2012,7 @@ npyiter_copy_from_buffers(NpyIter *iter)
dst_coords, axisdata_incr,
dst_shape, axisdata_incr,
op_transfersize, dtypes[iop]->elsize,
- (PyArray_MaskedStridedUnaryOp *)stransfer,
- transferdata) < 0) {
+ &transferinfo[iop].write) < 0) {
return -1;
}
}
@@ -2024,27 +2024,28 @@ npyiter_copy_from_buffers(NpyIter *iter)
dst_coords, axisdata_incr,
dst_shape, axisdata_incr,
op_transfersize, dtypes[iop]->elsize,
- stransfer,
- transferdata) < 0) {
+ &transferinfo[iop].write) < 0) {
return -1;
}
}
}
/* If there's no copy back, we may have to decrement refs. In
- * this case, the transfer function has a 'decsrcref' transfer
- * function, so we can use it to do the decrement.
+ * this case, the transfer is instead a function which clears
+ * (DECREFs) the single input.
*
* The flag USINGBUFFER is set when the buffer was used, so
* only decrement refs when this flag is on.
*/
- else if (stransfer != NULL &&
+ else if (transferinfo[iop].write.func != NULL &&
(op_itflags[iop]&NPY_OP_ITFLAG_USINGBUFFER) != 0) {
NPY_IT_DBG_PRINT1("Iterator: Freeing refs and zeroing buffer "
"of operand %d\n", (int)iop);
/* Decrement refs */
- if (stransfer(NULL, 0, buffer, dtypes[iop]->elsize,
- transfersize, dtypes[iop]->elsize,
- transferdata) < 0) {
+ npy_intp buf_stride = dtypes[iop]->elsize;
+ if (transferinfo[iop].write.func(
+ &transferinfo[iop].write.context,
+ &buffer, &transfersize, &buf_stride,
+ transferinfo[iop].write.auxdata) < 0) {
/* Since this should only decrement, it should never error */
assert(0);
return -1;
@@ -2094,9 +2095,6 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs)
npy_intp *reduce_outerstrides = NULL;
char **reduce_outerptrs = NULL;
- PyArray_StridedUnaryOp *stransfer = NULL;
- NpyAuxData *transferdata = NULL;
-
/*
* Have to get this flag before npyiter_checkreducesize sets
* it for the next iteration.
@@ -2207,13 +2205,9 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs)
is_onestride = 1;
}
+ NpyIter_TransferInfo *transferinfo = NBF_TRANSFERINFO(bufferdata);
for (iop = 0; iop < nop; ++iop) {
- /*
- * If the buffer is write-only, these two are NULL, and the buffer
- * pointers will be set up but the read copy won't be done
- */
- stransfer = NBF_READTRANSFERFN(bufferdata)[iop];
- transferdata = NBF_READTRANSFERDATA(bufferdata)[iop];
+
switch (op_itflags[iop]&
(NPY_OP_ITFLAG_BUFNEVER|
NPY_OP_ITFLAG_CAST|
@@ -2231,8 +2225,8 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs)
* could be zero, but strides[iop] was initialized
* to the first non-trivial stride.
*/
- stransfer = NULL;
/* The flag NPY_OP_ITFLAG_USINGBUFFER can be ignored here */
+ assert(!(op_itflags[iop] & NPY_OP_ITFLAG_USINGBUFFER));
break;
/* Never need to buffer this operand */
case NPY_OP_ITFLAG_BUFNEVER|NPY_OP_ITFLAG_REDUCE:
@@ -2244,8 +2238,8 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs)
* could be zero, but strides[iop] was initialized
* to the first non-trivial stride.
*/
- stransfer = NULL;
/* The flag NPY_OP_ITFLAG_USINGBUFFER can be ignored here */
+ assert(!(op_itflags[iop] & NPY_OP_ITFLAG_USINGBUFFER));
break;
/* Just a copy */
case 0:
@@ -2263,7 +2257,6 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs)
if (is_onestride) {
ptrs[iop] = ad_ptrs[iop];
strides[iop] = ad_strides[iop];
- stransfer = NULL;
/* Signal that the buffer is not being used */
op_itflags[iop] &= (~NPY_OP_ITFLAG_USINGBUFFER);
}
@@ -2278,7 +2271,6 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs)
strides[iop] = ad_strides[iop];
reduce_outerstrides[iop] =
NAD_STRIDES(reduce_outeraxisdata)[iop];
- stransfer = NULL;
/* Signal that the buffer is not being used */
op_itflags[iop] &= (~NPY_OP_ITFLAG_USINGBUFFER);
}
@@ -2309,7 +2301,6 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs)
NPY_IT_DBG_PRINT1("reduce op %d all one stride\n", (int)iop);
ptrs[iop] = ad_ptrs[iop];
reduce_outerstrides[iop] = 0;
- stransfer = NULL;
/* Signal that the buffer is not being used */
op_itflags[iop] &= (~NPY_OP_ITFLAG_USINGBUFFER);
}
@@ -2324,7 +2315,6 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs)
/* Outer reduce loop advances by one item */
reduce_outerstrides[iop] =
NAD_STRIDES(reduce_outeraxisdata)[iop];
- stransfer = NULL;
/* Signal that the buffer is not being used */
op_itflags[iop] &= (~NPY_OP_ITFLAG_USINGBUFFER);
}
@@ -2350,7 +2340,6 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs)
ptrs[iop] = ad_ptrs[iop];
strides[iop] = ad_strides[iop];
reduce_outerstrides[iop] = 0;
- stransfer = NULL;
/* Signal that the buffer is not being used */
op_itflags[iop] &= (~NPY_OP_ITFLAG_USINGBUFFER);
}
@@ -2365,7 +2354,6 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs)
/* Outer reduce loop advances by one item */
reduce_outerstrides[iop] =
NAD_STRIDES(reduce_outeraxisdata)[iop];
- stransfer = NULL;
/* Signal that the buffer is not being used */
op_itflags[iop] &= (~NPY_OP_ITFLAG_USINGBUFFER);
}
@@ -2443,7 +2431,12 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs)
break;
}
- if (stransfer != NULL) {
+ /*
+ * If OP_ITFLAG_USINGBUFFER is enabled and the read func is not NULL,
+ * the buffer needs to be read.
+ */
+ if (op_itflags[iop] & NPY_OP_ITFLAG_USINGBUFFER &&
+ transferinfo[iop].read.func != NULL) {
npy_intp src_itemsize;
npy_intp op_transfersize;
@@ -2454,7 +2447,7 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs)
src_itemsize = PyArray_DTYPE(operands[iop])->elsize;
- /* If stransfer wasn't set to NULL, buffering is required */
+ /* If we reach here, buffering is required */
any_buffered = 1;
/*
@@ -2539,41 +2532,33 @@ npyiter_copy_to_buffers(NpyIter *iter, char **prev_dataptrs)
skip_transfer = 1;
}
- /* If the data type requires zero-inititialization */
- if (PyDataType_FLAGCHK(dtypes[iop], NPY_NEEDS_INIT)) {
- NPY_IT_DBG_PRINT("Iterator: Buffer requires init, "
- "memsetting to 0\n");
- memset(ptrs[iop], 0, dtypes[iop]->elsize*op_transfersize);
- /* Can't skip the transfer in this case */
- skip_transfer = 0;
- }
-
- if (!skip_transfer) {
+ /*
+ * Copy data to the buffers if necessary.
+ *
+ * We always copy if the operand has references. In that case
+ * a "write" function must be in use that either copies or clears
+ * the buffer.
+ * This write from buffer call does not check for skip-transfer
+ * so we have to assume the buffer is cleared. For dtypes that
+ * do not have references, we can assume that the write function
+ * will leave the source (buffer) unmodified.
+ */
+ if (!skip_transfer || PyDataType_REFCHK(dtypes[iop])) {
NPY_IT_DBG_PRINT2("Iterator: Copying operand %d to "
"buffer (%d items)\n",
(int)iop, (int)op_transfersize);
if (PyArray_TransferNDimToStrided(
- ndim_transfer, ptrs[iop], dst_stride,
- ad_ptrs[iop], src_strides, axisdata_incr,
- src_coords, axisdata_incr,
- src_shape, axisdata_incr,
- op_transfersize, src_itemsize,
- stransfer, transferdata) < 0) {
+ ndim_transfer, ptrs[iop], dst_stride,
+ ad_ptrs[iop], src_strides, axisdata_incr,
+ src_coords, axisdata_incr,
+ src_shape, axisdata_incr,
+ op_transfersize, src_itemsize,
+ &transferinfo[iop].read) < 0) {
return -1;
}
}
}
- else if (ptrs[iop] == buffers[iop]) {
- /* If the data type requires zero-inititialization */
- if (PyDataType_FLAGCHK(dtypes[iop], NPY_NEEDS_INIT)) {
- NPY_IT_DBG_PRINT1("Iterator: Write-only buffer for "
- "operand %d requires init, "
- "memsetting to 0\n", (int)iop);
- memset(ptrs[iop], 0, dtypes[iop]->elsize*transfersize);
- }
- }
-
}
/*
@@ -2640,6 +2625,7 @@ npyiter_clear_buffers(NpyIter *iter)
/* Cleanup any buffers with references */
char **buffers = NBF_BUFFERS(bufferdata);
PyArray_Descr **dtypes = NIT_DTYPES(iter);
+ npyiter_opitflags *op_itflags = NIT_OPITFLAGS(iter);
for (int iop = 0; iop < nop; ++iop, ++buffers) {
/*
* We may want to find a better way to do this, on the other hand,
@@ -2648,7 +2634,8 @@ npyiter_clear_buffers(NpyIter *iter)
* a well defined state (either NULL or owning the reference).
* Only we implement cleanup
*/
- if (!PyDataType_REFCHK(dtypes[iop])) {
+ if (!PyDataType_REFCHK(dtypes[iop]) ||
+ !(op_itflags[iop]&NPY_OP_ITFLAG_USINGBUFFER)) {
continue;
}
if (*buffers == 0) {
diff --git a/numpy/core/src/multiarray/nditer_constr.c b/numpy/core/src/multiarray/nditer_constr.c
index b379a28ac..98d4f5a75 100644
--- a/numpy/core/src/multiarray/nditer_constr.c
+++ b/numpy/core/src/multiarray/nditer_constr.c
@@ -235,8 +235,8 @@ NpyIter_AdvancedNew(int nop, PyArrayObject **op_in, npy_uint32 flags,
NBF_SIZE(bufferdata) = 0;
memset(NBF_BUFFERS(bufferdata), 0, nop*NPY_SIZEOF_INTP);
memset(NBF_PTRS(bufferdata), 0, nop*NPY_SIZEOF_INTP);
- memset(NBF_READTRANSFERDATA(bufferdata), 0, nop*NPY_SIZEOF_INTP);
- memset(NBF_WRITETRANSFERDATA(bufferdata), 0, nop*NPY_SIZEOF_INTP);
+ /* Ensure that the transferdata/auxdata is NULLed */
+ memset(NBF_TRANSFERINFO(bufferdata), 0, nop * sizeof(NpyIter_TransferInfo));
}
/* Fill in the AXISDATA arrays and set the ITERSIZE field */
@@ -449,6 +449,11 @@ NpyIter_AdvancedNew(int nop, PyArrayObject **op_in, npy_uint32 flags,
/*
* If REFS_OK was specified, check whether there are any
* reference arrays and flag it if so.
+ *
+ * NOTE: This really should be unnecessary, but chances are someone relies
+ * on it. The iterator itself does not require the API here
+ * as it only does so for casting/buffering. But in almost all
+ * use-cases the API will be required for whatever operation is done.
*/
if (flags & NPY_ITER_REFS_OK) {
for (iop = 0; iop < nop; ++iop) {
@@ -577,13 +582,11 @@ NpyIter_Copy(NpyIter *iter)
NpyIter_BufferData *bufferdata;
npy_intp buffersize, itemsize;
char **buffers;
- NpyAuxData **readtransferdata, **writetransferdata;
bufferdata = NIT_BUFFERDATA(newiter);
buffers = NBF_BUFFERS(bufferdata);
- readtransferdata = NBF_READTRANSFERDATA(bufferdata);
- writetransferdata = NBF_WRITETRANSFERDATA(bufferdata);
buffersize = NBF_BUFFERSIZE(bufferdata);
+ NpyIter_TransferInfo *transferinfo = NBF_TRANSFERINFO(bufferdata);
for (iop = 0; iop < nop; ++iop) {
if (buffers[iop] != NULL) {
@@ -596,30 +599,33 @@ NpyIter_Copy(NpyIter *iter)
if (buffers[iop] == NULL) {
out_of_memory = 1;
}
+ else {
+ if (PyDataType_FLAGCHK(dtypes[iop], NPY_NEEDS_INIT)) {
+ memset(buffers[iop], '\0', itemsize*buffersize);
+ }
+ }
}
}
- if (readtransferdata[iop] != NULL) {
+ if (transferinfo[iop].read.func != NULL) {
if (out_of_memory) {
- readtransferdata[iop] = NULL;
+ transferinfo[iop].read.func = NULL; /* No cleanup */
}
else {
- readtransferdata[iop] =
- NPY_AUXDATA_CLONE(readtransferdata[iop]);
- if (readtransferdata[iop] == NULL) {
+ if (NPY_cast_info_copy(&transferinfo[iop].read,
+ &transferinfo[iop].read) < 0) {
out_of_memory = 1;
}
}
}
- if (writetransferdata[iop] != NULL) {
+ if (transferinfo[iop].write.func != NULL) {
if (out_of_memory) {
- writetransferdata[iop] = NULL;
+ transferinfo[iop].write.func = NULL; /* No cleanup */
}
else {
- writetransferdata[iop] =
- NPY_AUXDATA_CLONE(writetransferdata[iop]);
- if (writetransferdata[iop] == NULL) {
+ if (NPY_cast_info_copy(&transferinfo[iop].write,
+ &transferinfo[iop].write) < 0) {
out_of_memory = 1;
}
}
@@ -688,26 +694,18 @@ NpyIter_Deallocate(NpyIter *iter)
NpyIter_BufferData *bufferdata = NIT_BUFFERDATA(iter);
char **buffers;
- NpyAuxData **transferdata;
/* buffers */
buffers = NBF_BUFFERS(bufferdata);
for (iop = 0; iop < nop; ++iop, ++buffers) {
PyArray_free(*buffers);
}
+
+ NpyIter_TransferInfo *transferinfo = NBF_TRANSFERINFO(bufferdata);
/* read bufferdata */
- transferdata = NBF_READTRANSFERDATA(bufferdata);
- for(iop = 0; iop < nop; ++iop, ++transferdata) {
- if (*transferdata) {
- NPY_AUXDATA_FREE(*transferdata);
- }
- }
- /* write bufferdata */
- transferdata = NBF_WRITETRANSFERDATA(bufferdata);
- for(iop = 0; iop < nop; ++iop, ++transferdata) {
- if (*transferdata) {
- NPY_AUXDATA_FREE(*transferdata);
- }
+ for (iop = 0; iop < nop; ++iop, ++transferinfo) {
+ NPY_cast_info_xfree(&transferinfo->read);
+ NPY_cast_info_xfree(&transferinfo->write);
}
}
@@ -3142,13 +3140,8 @@ npyiter_allocate_transfer_functions(NpyIter *iter)
PyArrayObject **op = NIT_OPERANDS(iter);
PyArray_Descr **op_dtype = NIT_DTYPES(iter);
npy_intp *strides = NAD_STRIDES(axisdata), op_stride;
- PyArray_StridedUnaryOp **readtransferfn = NBF_READTRANSFERFN(bufferdata),
- **writetransferfn = NBF_WRITETRANSFERFN(bufferdata);
- NpyAuxData **readtransferdata = NBF_READTRANSFERDATA(bufferdata),
- **writetransferdata = NBF_WRITETRANSFERDATA(bufferdata);
+ NpyIter_TransferInfo *transferinfo = NBF_TRANSFERINFO(bufferdata);
- PyArray_StridedUnaryOp *stransfer = NULL;
- NpyAuxData *transferdata = NULL;
int needs_api = 0;
for (iop = 0; iop < nop; ++iop) {
@@ -3174,17 +3167,14 @@ npyiter_allocate_transfer_functions(NpyIter *iter)
PyArray_DESCR(op[iop]),
op_dtype[iop],
move_references,
- &stransfer,
- &transferdata,
+ &transferinfo[iop].read,
&needs_api) != NPY_SUCCEED) {
iop -= 1; /* This one cannot be cleaned up yet. */
goto fail;
}
- readtransferfn[iop] = stransfer;
- readtransferdata[iop] = transferdata;
}
else {
- readtransferfn[iop] = NULL;
+ transferinfo[iop].read.func = NULL;
}
if (flags & NPY_OP_ITFLAG_WRITE) {
int move_references = 1;
@@ -3200,38 +3190,33 @@ npyiter_allocate_transfer_functions(NpyIter *iter)
* could be inconsistent.
*/
if (PyArray_GetMaskedDTypeTransferFunction(
- (flags & NPY_OP_ITFLAG_ALIGNED) != 0,
- op_dtype[iop]->elsize,
- op_stride,
- (strides[maskop] == mask_dtype->elsize) ?
- mask_dtype->elsize :
- NPY_MAX_INTP,
- op_dtype[iop],
- PyArray_DESCR(op[iop]),
- mask_dtype,
- move_references,
- (PyArray_MaskedStridedUnaryOp **)&stransfer,
- &transferdata,
- &needs_api) != NPY_SUCCEED) {
+ (flags & NPY_OP_ITFLAG_ALIGNED) != 0,
+ op_dtype[iop]->elsize,
+ op_stride,
+ (strides[maskop] == mask_dtype->elsize) ?
+ mask_dtype->elsize : NPY_MAX_INTP,
+ op_dtype[iop],
+ PyArray_DESCR(op[iop]),
+ mask_dtype,
+ move_references,
+ &transferinfo[iop].write,
+ &needs_api) != NPY_SUCCEED) {
goto fail;
}
}
else {
if (PyArray_GetDTypeTransferFunction(
- (flags & NPY_OP_ITFLAG_ALIGNED) != 0,
- op_dtype[iop]->elsize,
- op_stride,
- op_dtype[iop],
- PyArray_DESCR(op[iop]),
- move_references,
- &stransfer,
- &transferdata,
- &needs_api) != NPY_SUCCEED) {
+ (flags & NPY_OP_ITFLAG_ALIGNED) != 0,
+ op_dtype[iop]->elsize,
+ op_stride,
+ op_dtype[iop],
+ PyArray_DESCR(op[iop]),
+ move_references,
+ &transferinfo[iop].write,
+ &needs_api) != NPY_SUCCEED) {
goto fail;
}
}
- writetransferfn[iop] = stransfer;
- writetransferdata[iop] = transferdata;
}
/* If no write back but there are references make a decref fn */
else if (PyDataType_REFCHK(op_dtype[iop])) {
@@ -3241,25 +3226,22 @@ npyiter_allocate_transfer_functions(NpyIter *iter)
* src references.
*/
if (PyArray_GetDTypeTransferFunction(
- (flags & NPY_OP_ITFLAG_ALIGNED) != 0,
- op_dtype[iop]->elsize, 0,
- op_dtype[iop], NULL,
- 1,
- &stransfer,
- &transferdata,
- &needs_api) != NPY_SUCCEED) {
+ (flags & NPY_OP_ITFLAG_ALIGNED) != 0,
+ op_dtype[iop]->elsize, 0,
+ op_dtype[iop], NULL,
+ 1,
+ &transferinfo[iop].write,
+ &needs_api) != NPY_SUCCEED) {
goto fail;
}
- writetransferfn[iop] = stransfer;
- writetransferdata[iop] = transferdata;
}
else {
- writetransferfn[iop] = NULL;
+ transferinfo[iop].write.func = NULL;
}
}
else {
- readtransferfn[iop] = NULL;
- writetransferfn[iop] = NULL;
+ transferinfo[iop].read.func = NULL;
+ transferinfo[iop].write.func = NULL;
}
}
@@ -3272,14 +3254,8 @@ npyiter_allocate_transfer_functions(NpyIter *iter)
fail:
for (i = 0; i < iop+1; ++i) {
- if (readtransferdata[iop] != NULL) {
- NPY_AUXDATA_FREE(readtransferdata[iop]);
- readtransferdata[iop] = NULL;
- }
- if (writetransferdata[iop] != NULL) {
- NPY_AUXDATA_FREE(writetransferdata[iop]);
- writetransferdata[iop] = NULL;
- }
+ NPY_cast_info_xfree(&transferinfo[iop].read);
+ NPY_cast_info_xfree(&transferinfo[iop].write);
}
return 0;
}
diff --git a/numpy/core/src/multiarray/nditer_impl.h b/numpy/core/src/multiarray/nditer_impl.h
index 378d6f711..a5a9177e5 100644
--- a/numpy/core/src/multiarray/nditer_impl.h
+++ b/numpy/core/src/multiarray/nditer_impl.h
@@ -21,6 +21,7 @@
#include "convert_datatype.h"
#include "lowlevel_strided_loops.h"
+#include "dtype_transfer.h"
/********** ITERATOR CONSTRUCTION TIMING **************/
#define NPY_IT_CONSTRUCTION_TIMING 0
@@ -148,8 +149,9 @@ struct NpyIter_InternalOnly {
char iter_flexdata;
};
-typedef struct NpyIter_AD NpyIter_AxisData;
-typedef struct NpyIter_BD NpyIter_BufferData;
+typedef struct NpyIter_AxisData_tag NpyIter_AxisData;
+typedef struct NpyIter_TransferInfo_tag NpyIter_TransferInfo;
+typedef struct NpyIter_BufferData_tag NpyIter_BufferData;
typedef npy_int16 npyiter_opitflags;
@@ -167,7 +169,8 @@ typedef npy_int16 npyiter_opitflags;
#define NIT_OPITFLAGS_SIZEOF(itflags, ndim, nop) \
(NPY_INTP_ALIGNED(sizeof(npyiter_opitflags) * nop))
#define NIT_BUFFERDATA_SIZEOF(itflags, ndim, nop) \
- ((itflags&NPY_ITFLAG_BUFFER) ? ((NPY_SIZEOF_INTP)*(6 + 9*nop)) : 0)
+ ((itflags&NPY_ITFLAG_BUFFER) ? ( \
+ (NPY_SIZEOF_INTP)*(6 + 5*nop) + sizeof(NpyIter_TransferInfo) * nop) : 0)
/* Byte offsets of the iterator members starting from iter->iter_flexdata */
#define NIT_PERM_OFFSET() \
@@ -229,11 +232,20 @@ typedef npy_int16 npyiter_opitflags;
&(iter)->iter_flexdata + NIT_AXISDATA_OFFSET(itflags, ndim, nop)))
/* Internal-only BUFFERDATA MEMBER ACCESS */
-struct NpyIter_BD {
+
+struct NpyIter_TransferInfo_tag {
+ NPY_cast_info read;
+ NPY_cast_info write;
+ /* Probably unnecessary, but make sure what follows is intp aligned: */
+ npy_intp _unused_ensure_alignment[];
+};
+
+struct NpyIter_BufferData_tag {
npy_intp buffersize, size, bufiterend,
reduce_pos, reduce_outersize, reduce_outerdim;
npy_intp bd_flexdata;
};
+
#define NBF_BUFFERSIZE(bufferdata) ((bufferdata)->buffersize)
#define NBF_SIZE(bufferdata) ((bufferdata)->size)
#define NBF_BUFITEREND(bufferdata) ((bufferdata)->bufiterend)
@@ -248,19 +260,13 @@ struct NpyIter_BD {
(&(bufferdata)->bd_flexdata + 2*(nop)))
#define NBF_REDUCE_OUTERPTRS(bufferdata) ((char **) \
(&(bufferdata)->bd_flexdata + 3*(nop)))
-#define NBF_READTRANSFERFN(bufferdata) ((PyArray_StridedUnaryOp **) \
+#define NBF_BUFFERS(bufferdata) ((char **) \
(&(bufferdata)->bd_flexdata + 4*(nop)))
-#define NBF_READTRANSFERDATA(bufferdata) ((NpyAuxData **) \
+#define NBF_TRANSFERINFO(bufferdata) ((NpyIter_TransferInfo *) \
(&(bufferdata)->bd_flexdata + 5*(nop)))
-#define NBF_WRITETRANSFERFN(bufferdata) ((PyArray_StridedUnaryOp **) \
- (&(bufferdata)->bd_flexdata + 6*(nop)))
-#define NBF_WRITETRANSFERDATA(bufferdata) ((NpyAuxData **) \
- (&(bufferdata)->bd_flexdata + 7*(nop)))
-#define NBF_BUFFERS(bufferdata) ((char **) \
- (&(bufferdata)->bd_flexdata + 8*(nop)))
/* Internal-only AXISDATA MEMBER ACCESS. */
-struct NpyIter_AD {
+struct NpyIter_AxisData_tag {
npy_intp shape, index;
npy_intp ad_flexdata;
};
diff --git a/numpy/core/src/multiarray/nditer_pywrap.c b/numpy/core/src/multiarray/nditer_pywrap.c
index 8839d1be7..8acc7f87f 100644
--- a/numpy/core/src/multiarray/nditer_pywrap.c
+++ b/numpy/core/src/multiarray/nditer_pywrap.c
@@ -1134,6 +1134,9 @@ static void
npyiter_dealloc(NewNpyArrayIterObject *self)
{
if (self->iter) {
+ /* Store error, so that WriteUnraisable cannot clear an existing one */
+ PyObject *exc, *val, *tb;
+ PyErr_Fetch(&exc, &val, &tb);
if (npyiter_has_writeback(self->iter)) {
if (PyErr_WarnEx(PyExc_RuntimeWarning,
"Temporary data has not been written back to one of the "
@@ -1152,10 +1155,13 @@ npyiter_dealloc(NewNpyArrayIterObject *self)
}
}
}
- NpyIter_Deallocate(self->iter);
+ if (!NpyIter_Deallocate(self->iter)) {
+ PyErr_WriteUnraisable(Py_None);
+ }
self->iter = NULL;
Py_XDECREF(self->nested_child);
self->nested_child = NULL;
+ PyErr_Restore(exc, val, tb);
}
Py_TYPE(self)->tp_free((PyObject*)self);
}
@@ -1378,7 +1384,8 @@ npyiter_debug_print(NewNpyArrayIterObject *self)
NPY_NO_EXPORT PyObject *
npyiter_seq_item(NewNpyArrayIterObject *self, Py_ssize_t i);
-static PyObject *npyiter_value_get(NewNpyArrayIterObject *self)
+static PyObject *
+npyiter_value_get(NewNpyArrayIterObject *self, void *NPY_UNUSED(ignored))
{
PyObject *ret;
@@ -1414,7 +1421,8 @@ static PyObject *npyiter_value_get(NewNpyArrayIterObject *self)
return ret;
}
-static PyObject *npyiter_operands_get(NewNpyArrayIterObject *self)
+static PyObject *
+npyiter_operands_get(NewNpyArrayIterObject *self, void *NPY_UNUSED(ignored))
{
PyObject *ret;
@@ -1443,7 +1451,8 @@ static PyObject *npyiter_operands_get(NewNpyArrayIterObject *self)
return ret;
}
-static PyObject *npyiter_itviews_get(NewNpyArrayIterObject *self)
+static PyObject *
+npyiter_itviews_get(NewNpyArrayIterObject *self, void *NPY_UNUSED(ignored))
{
PyObject *ret;
@@ -1502,13 +1511,13 @@ npyiter_next(NewNpyArrayIterObject *self)
}
self->started = 1;
- return npyiter_value_get(self);
+ return npyiter_value_get(self, NULL);
};
-static PyObject *npyiter_shape_get(NewNpyArrayIterObject *self)
+static PyObject *
+npyiter_shape_get(NewNpyArrayIterObject *self, void *NPY_UNUSED(ignored))
{
- PyObject *ret;
- npy_intp idim, ndim, shape[NPY_MAXDIMS];
+ npy_intp ndim, shape[NPY_MAXDIMS];
if (self->iter == NULL || self->finished) {
PyErr_SetString(PyExc_ValueError,
@@ -1518,23 +1527,16 @@ static PyObject *npyiter_shape_get(NewNpyArrayIterObject *self)
if (NpyIter_GetShape(self->iter, shape) == NPY_SUCCEED) {
ndim = NpyIter_GetNDim(self->iter);
- ret = PyTuple_New(ndim);
- if (ret != NULL) {
- for (idim = 0; idim < ndim; ++idim) {
- PyTuple_SET_ITEM(ret, idim,
- PyLong_FromLong(shape[idim]));
- }
- return ret;
- }
+ return PyArray_IntTupleFromIntp(ndim, shape);
}
return NULL;
}
-static PyObject *npyiter_multi_index_get(NewNpyArrayIterObject *self)
+static PyObject *
+npyiter_multi_index_get(NewNpyArrayIterObject *self, void *NPY_UNUSED(ignored))
{
- PyObject *ret;
- npy_intp idim, ndim, multi_index[NPY_MAXDIMS];
+ npy_intp ndim, multi_index[NPY_MAXDIMS];
if (self->iter == NULL || self->finished) {
PyErr_SetString(PyExc_ValueError,
@@ -1545,15 +1547,7 @@ static PyObject *npyiter_multi_index_get(NewNpyArrayIterObject *self)
if (self->get_multi_index != NULL) {
ndim = NpyIter_GetNDim(self->iter);
self->get_multi_index(self->iter, multi_index);
- ret = PyTuple_New(ndim);
- if (ret == NULL) {
- return NULL;
- }
- for (idim = 0; idim < ndim; ++idim) {
- PyTuple_SET_ITEM(ret, idim,
- PyLong_FromLong(multi_index[idim]));
- }
- return ret;
+ return PyArray_IntTupleFromIntp(ndim, multi_index);
}
else {
if (!NpyIter_HasMultiIndex(self->iter)) {
@@ -1576,7 +1570,8 @@ static PyObject *npyiter_multi_index_get(NewNpyArrayIterObject *self)
}
static int
-npyiter_multi_index_set(NewNpyArrayIterObject *self, PyObject *value)
+npyiter_multi_index_set(
+ NewNpyArrayIterObject *self, PyObject *value, void *NPY_UNUSED(ignored))
{
npy_intp idim, ndim, multi_index[NPY_MAXDIMS];
@@ -1606,8 +1601,8 @@ npyiter_multi_index_set(NewNpyArrayIterObject *self, PyObject *value)
for (idim = 0; idim < ndim; ++idim) {
PyObject *v = PySequence_GetItem(value, idim);
multi_index[idim] = PyLong_AsLong(v);
+ Py_DECREF(v);
if (error_converting(multi_index[idim])) {
- Py_XDECREF(v);
return -1;
}
}
@@ -1631,7 +1626,8 @@ npyiter_multi_index_set(NewNpyArrayIterObject *self, PyObject *value)
}
}
-static PyObject *npyiter_index_get(NewNpyArrayIterObject *self)
+static PyObject *
+npyiter_index_get(NewNpyArrayIterObject *self, void *NPY_UNUSED(ignored))
{
if (self->iter == NULL || self->finished) {
PyErr_SetString(PyExc_ValueError,
@@ -1650,7 +1646,9 @@ static PyObject *npyiter_index_get(NewNpyArrayIterObject *self)
}
}
-static int npyiter_index_set(NewNpyArrayIterObject *self, PyObject *value)
+static int
+npyiter_index_set(
+ NewNpyArrayIterObject *self, PyObject *value, void *NPY_UNUSED(ignored))
{
if (value == NULL) {
PyErr_SetString(PyExc_AttributeError,
@@ -1689,7 +1687,8 @@ static int npyiter_index_set(NewNpyArrayIterObject *self, PyObject *value)
}
}
-static PyObject *npyiter_iterindex_get(NewNpyArrayIterObject *self)
+static PyObject *
+npyiter_iterindex_get(NewNpyArrayIterObject *self, void *NPY_UNUSED(ignored))
{
if (self->iter == NULL || self->finished) {
PyErr_SetString(PyExc_ValueError,
@@ -1700,7 +1699,9 @@ static PyObject *npyiter_iterindex_get(NewNpyArrayIterObject *self)
return PyLong_FromLong(NpyIter_GetIterIndex(self->iter));
}
-static int npyiter_iterindex_set(NewNpyArrayIterObject *self, PyObject *value)
+static int
+npyiter_iterindex_set(
+ NewNpyArrayIterObject *self, PyObject *value, void *NPY_UNUSED(ignored))
{
npy_intp iterindex;
@@ -1733,7 +1734,8 @@ static int npyiter_iterindex_set(NewNpyArrayIterObject *self, PyObject *value)
return 0;
}
-static PyObject *npyiter_iterrange_get(NewNpyArrayIterObject *self)
+static PyObject *
+npyiter_iterrange_get(NewNpyArrayIterObject *self, void *NPY_UNUSED(ignored))
{
npy_intp istart = 0, iend = 0;
PyObject *ret;
@@ -1757,7 +1759,9 @@ static PyObject *npyiter_iterrange_get(NewNpyArrayIterObject *self)
return ret;
}
-static int npyiter_iterrange_set(NewNpyArrayIterObject *self, PyObject *value)
+static int
+npyiter_iterrange_set(
+ NewNpyArrayIterObject *self, PyObject *value, void *NPY_UNUSED(ignored))
{
npy_intp istart = 0, iend = 0;
@@ -1799,7 +1803,9 @@ static int npyiter_iterrange_set(NewNpyArrayIterObject *self, PyObject *value)
return 0;
}
-static PyObject *npyiter_has_delayed_bufalloc_get(NewNpyArrayIterObject *self)
+static PyObject *
+npyiter_has_delayed_bufalloc_get(
+ NewNpyArrayIterObject *self, void *NPY_UNUSED(ignored))
{
if (self->iter == NULL) {
PyErr_SetString(PyExc_ValueError,
@@ -1815,7 +1821,9 @@ static PyObject *npyiter_has_delayed_bufalloc_get(NewNpyArrayIterObject *self)
}
}
-static PyObject *npyiter_iterationneedsapi_get(NewNpyArrayIterObject *self)
+static PyObject *
+npyiter_iterationneedsapi_get(
+ NewNpyArrayIterObject *self, void *NPY_UNUSED(ignored))
{
if (self->iter == NULL) {
PyErr_SetString(PyExc_ValueError,
@@ -1831,7 +1839,9 @@ static PyObject *npyiter_iterationneedsapi_get(NewNpyArrayIterObject *self)
}
}
-static PyObject *npyiter_has_multi_index_get(NewNpyArrayIterObject *self)
+static PyObject *
+npyiter_has_multi_index_get(
+ NewNpyArrayIterObject *self, void *NPY_UNUSED(ignored))
{
if (self->iter == NULL) {
PyErr_SetString(PyExc_ValueError,
@@ -1847,7 +1857,8 @@ static PyObject *npyiter_has_multi_index_get(NewNpyArrayIterObject *self)
}
}
-static PyObject *npyiter_has_index_get(NewNpyArrayIterObject *self)
+static PyObject *
+npyiter_has_index_get(NewNpyArrayIterObject *self, void *NPY_UNUSED(ignored))
{
if (self->iter == NULL) {
PyErr_SetString(PyExc_ValueError,
@@ -1863,7 +1874,8 @@ static PyObject *npyiter_has_index_get(NewNpyArrayIterObject *self)
}
}
-static PyObject *npyiter_dtypes_get(NewNpyArrayIterObject *self)
+static PyObject *
+npyiter_dtypes_get(NewNpyArrayIterObject *self, void *NPY_UNUSED(ignored))
{
PyObject *ret;
@@ -1892,7 +1904,8 @@ static PyObject *npyiter_dtypes_get(NewNpyArrayIterObject *self)
return ret;
}
-static PyObject *npyiter_ndim_get(NewNpyArrayIterObject *self)
+static PyObject *
+npyiter_ndim_get(NewNpyArrayIterObject *self, void *NPY_UNUSED(ignored))
{
if (self->iter == NULL) {
PyErr_SetString(PyExc_ValueError,
@@ -1903,7 +1916,8 @@ static PyObject *npyiter_ndim_get(NewNpyArrayIterObject *self)
return PyLong_FromLong(NpyIter_GetNDim(self->iter));
}
-static PyObject *npyiter_nop_get(NewNpyArrayIterObject *self)
+static PyObject *
+npyiter_nop_get(NewNpyArrayIterObject *self, void *NPY_UNUSED(ignored))
{
if (self->iter == NULL) {
PyErr_SetString(PyExc_ValueError,
@@ -1914,7 +1928,8 @@ static PyObject *npyiter_nop_get(NewNpyArrayIterObject *self)
return PyLong_FromLong(NpyIter_GetNOp(self->iter));
}
-static PyObject *npyiter_itersize_get(NewNpyArrayIterObject *self)
+static PyObject *
+npyiter_itersize_get(NewNpyArrayIterObject *self, void *NPY_UNUSED(ignored))
{
if (self->iter == NULL) {
PyErr_SetString(PyExc_ValueError,
@@ -1925,7 +1940,8 @@ static PyObject *npyiter_itersize_get(NewNpyArrayIterObject *self)
return PyLong_FromLong(NpyIter_GetIterSize(self->iter));
}
-static PyObject *npyiter_finished_get(NewNpyArrayIterObject *self)
+static PyObject *
+npyiter_finished_get(NewNpyArrayIterObject *self, void *NPY_UNUSED(ignored))
{
if (self->iter == NULL || !self->finished) {
Py_RETURN_FALSE;
@@ -2320,7 +2336,7 @@ npyiter_close(NewNpyArrayIterObject *self)
self->iter = NULL;
Py_XDECREF(self->nested_child);
self->nested_child = NULL;
- if (ret < 0) {
+ if (ret != NPY_SUCCEED) {
return NULL;
}
Py_RETURN_NONE;
@@ -2363,7 +2379,7 @@ static PyMethodDef npyiter_methods[] = {
{"__exit__", (PyCFunction)npyiter_exit,
METH_VARARGS, NULL},
{"close", (PyCFunction)npyiter_close,
- METH_VARARGS, NULL},
+ METH_NOARGS, NULL},
{NULL, NULL, 0, NULL},
};
diff --git a/numpy/core/src/multiarray/number.c b/numpy/core/src/multiarray/number.c
index a629dfe97..9ed7cde47 100644
--- a/numpy/core/src/multiarray/number.c
+++ b/numpy/core/src/multiarray/number.c
@@ -16,6 +16,9 @@
#include "binop_override.h"
#include "ufunc_override.h"
+#include "abstractdtypes.h"
+#include "common_dtype.h"
+#include "convert_datatype.h"
/*************************************************************************
**************** Implement Number Protocol ****************************
@@ -227,10 +230,7 @@ PyArray_GenericReduceFunction(PyArrayObject *m1, PyObject *op, int axis,
{
PyObject *args, *ret = NULL, *meth;
PyObject *kwds;
- if (op == NULL) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
+
args = Py_BuildValue("(Oi)", m1, axis);
kwds = _get_keywords(rtype, out);
meth = PyObject_GetAttrString(op, "reduce");
@@ -250,10 +250,7 @@ PyArray_GenericAccumulateFunction(PyArrayObject *m1, PyObject *op, int axis,
{
PyObject *args, *ret = NULL, *meth;
PyObject *kwds;
- if (op == NULL) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
+
args = Py_BuildValue("(Oi)", m1, axis);
kwds = _get_keywords(rtype, out);
meth = PyObject_GetAttrString(op, "accumulate");
@@ -268,30 +265,14 @@ PyArray_GenericAccumulateFunction(PyArrayObject *m1, PyObject *op, int axis,
NPY_NO_EXPORT PyObject *
-PyArray_GenericBinaryFunction(PyArrayObject *m1, PyObject *m2, PyObject *op)
+PyArray_GenericBinaryFunction(PyObject *m1, PyObject *m2, PyObject *op)
{
- /*
- * I suspect that the next few lines are buggy and cause NotImplemented to
- * be returned at weird times... but if we raise an error here, then
- * *everything* breaks. (Like, 'arange(10) + 1' and just
- * 'repr(arange(10))' both blow up with an error here.) Not sure what's
- * going on with that, but I'll leave it alone for now. - njs, 2015-06-21
- */
- if (op == NULL) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
-
return PyObject_CallFunctionObjArgs(op, m1, m2, NULL);
}
NPY_NO_EXPORT PyObject *
PyArray_GenericUnaryFunction(PyArrayObject *m1, PyObject *op)
{
- if (op == NULL) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
return PyObject_CallFunctionObjArgs(op, m1, NULL);
}
@@ -299,25 +280,17 @@ static PyObject *
PyArray_GenericInplaceBinaryFunction(PyArrayObject *m1,
PyObject *m2, PyObject *op)
{
- if (op == NULL) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
return PyObject_CallFunctionObjArgs(op, m1, m2, m1, NULL);
}
static PyObject *
PyArray_GenericInplaceUnaryFunction(PyArrayObject *m1, PyObject *op)
{
- if (op == NULL) {
- Py_INCREF(Py_NotImplemented);
- return Py_NotImplemented;
- }
return PyObject_CallFunctionObjArgs(op, m1, m1, NULL);
}
static PyObject *
-array_add(PyArrayObject *m1, PyObject *m2)
+array_add(PyObject *m1, PyObject *m2)
{
PyObject *res;
@@ -329,7 +302,7 @@ array_add(PyArrayObject *m1, PyObject *m2)
}
static PyObject *
-array_subtract(PyArrayObject *m1, PyObject *m2)
+array_subtract(PyObject *m1, PyObject *m2)
{
PyObject *res;
@@ -341,7 +314,7 @@ array_subtract(PyArrayObject *m1, PyObject *m2)
}
static PyObject *
-array_multiply(PyArrayObject *m1, PyObject *m2)
+array_multiply(PyObject *m1, PyObject *m2)
{
PyObject *res;
@@ -353,14 +326,14 @@ array_multiply(PyArrayObject *m1, PyObject *m2)
}
static PyObject *
-array_remainder(PyArrayObject *m1, PyObject *m2)
+array_remainder(PyObject *m1, PyObject *m2)
{
BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_remainder, array_remainder);
return PyArray_GenericBinaryFunction(m1, m2, n_ops.remainder);
}
static PyObject *
-array_divmod(PyArrayObject *m1, PyObject *m2)
+array_divmod(PyObject *m1, PyObject *m2)
{
BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_divmod, array_divmod);
return PyArray_GenericBinaryFunction(m1, m2, n_ops.divmod);
@@ -368,7 +341,7 @@ array_divmod(PyArrayObject *m1, PyObject *m2)
/* Need this to be version dependent on account of the slot check */
static PyObject *
-array_matrix_multiply(PyArrayObject *m1, PyObject *m2)
+array_matrix_multiply(PyObject *m1, PyObject *m2)
{
BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_matrix_multiply, array_matrix_multiply);
return PyArray_GenericBinaryFunction(m1, m2, n_ops.matmul);
@@ -456,6 +429,7 @@ is_scalar_with_conversion(PyObject *o2, double* out_exponent)
return NPY_NOSCALAR;
}
val = PyLong_AsSsize_t(value);
+ Py_DECREF(value);
if (error_converting(val)) {
PyErr_Clear();
return NPY_NOSCALAR;
@@ -472,15 +446,16 @@ is_scalar_with_conversion(PyObject *o2, double* out_exponent)
* the result is in value (can be NULL if an error occurred)
*/
static int
-fast_scalar_power(PyArrayObject *a1, PyObject *o2, int inplace,
+fast_scalar_power(PyObject *o1, PyObject *o2, int inplace,
PyObject **value)
{
double exponent;
NPY_SCALARKIND kind; /* NPY_NOSCALAR is not scalar */
- if (PyArray_Check(a1) &&
- !PyArray_ISOBJECT(a1) &&
+ if (PyArray_Check(o1) &&
+ !PyArray_ISOBJECT((PyArrayObject *)o1) &&
((kind=is_scalar_with_conversion(o2, &exponent))>0)) {
+ PyArrayObject *a1 = (PyArrayObject *)o1;
PyObject *fastop = NULL;
if (PyArray_ISFLOAT(a1) || PyArray_ISCOMPLEX(a1)) {
if (exponent == 1.0) {
@@ -544,7 +519,7 @@ fast_scalar_power(PyArrayObject *a1, PyObject *o2, int inplace,
}
static PyObject *
-array_power(PyArrayObject *a1, PyObject *o2, PyObject *modulo)
+array_power(PyObject *a1, PyObject *o2, PyObject *modulo)
{
PyObject *value = NULL;
@@ -635,7 +610,7 @@ array_invert(PyArrayObject *m1)
}
static PyObject *
-array_left_shift(PyArrayObject *m1, PyObject *m2)
+array_left_shift(PyObject *m1, PyObject *m2)
{
PyObject *res;
@@ -647,7 +622,7 @@ array_left_shift(PyArrayObject *m1, PyObject *m2)
}
static PyObject *
-array_right_shift(PyArrayObject *m1, PyObject *m2)
+array_right_shift(PyObject *m1, PyObject *m2)
{
PyObject *res;
@@ -659,7 +634,7 @@ array_right_shift(PyArrayObject *m1, PyObject *m2)
}
static PyObject *
-array_bitwise_and(PyArrayObject *m1, PyObject *m2)
+array_bitwise_and(PyObject *m1, PyObject *m2)
{
PyObject *res;
@@ -671,7 +646,7 @@ array_bitwise_and(PyArrayObject *m1, PyObject *m2)
}
static PyObject *
-array_bitwise_or(PyArrayObject *m1, PyObject *m2)
+array_bitwise_or(PyObject *m1, PyObject *m2)
{
PyObject *res;
@@ -683,7 +658,7 @@ array_bitwise_or(PyArrayObject *m1, PyObject *m2)
}
static PyObject *
-array_bitwise_xor(PyArrayObject *m1, PyObject *m2)
+array_bitwise_xor(PyObject *m1, PyObject *m2)
{
PyObject *res;
@@ -734,7 +709,7 @@ array_inplace_power(PyArrayObject *a1, PyObject *o2, PyObject *NPY_UNUSED(modulo
INPLACE_GIVE_UP_IF_NEEDED(
a1, o2, nb_inplace_power, array_inplace_power);
- if (fast_scalar_power(a1, o2, 1, &value) != 0) {
+ if (fast_scalar_power((PyObject *)a1, o2, 1, &value) != 0) {
value = PyArray_GenericInplaceBinaryFunction(a1, o2, n_ops.power);
}
return value;
@@ -781,7 +756,7 @@ array_inplace_bitwise_xor(PyArrayObject *m1, PyObject *m2)
}
static PyObject *
-array_floor_divide(PyArrayObject *m1, PyObject *m2)
+array_floor_divide(PyObject *m1, PyObject *m2)
{
PyObject *res;
@@ -793,13 +768,14 @@ array_floor_divide(PyArrayObject *m1, PyObject *m2)
}
static PyObject *
-array_true_divide(PyArrayObject *m1, PyObject *m2)
+array_true_divide(PyObject *m1, PyObject *m2)
{
PyObject *res;
+ PyArrayObject *a1 = (PyArrayObject *)m1;
BINOP_GIVE_UP_IF_NEEDED(m1, m2, nb_true_divide, array_true_divide);
if (PyArray_CheckExact(m1) &&
- (PyArray_ISFLOAT(m1) || PyArray_ISCOMPLEX(m1)) &&
+ (PyArray_ISFLOAT(a1) || PyArray_ISCOMPLEX(a1)) &&
try_binary_elide(m1, m2, &array_inplace_true_divide, &res, 0)) {
return res;
}
@@ -930,22 +906,22 @@ array_index(PyArrayObject *v)
NPY_NO_EXPORT PyNumberMethods array_as_number = {
- .nb_add = (binaryfunc)array_add,
- .nb_subtract = (binaryfunc)array_subtract,
- .nb_multiply = (binaryfunc)array_multiply,
- .nb_remainder = (binaryfunc)array_remainder,
- .nb_divmod = (binaryfunc)array_divmod,
+ .nb_add = array_add,
+ .nb_subtract = array_subtract,
+ .nb_multiply = array_multiply,
+ .nb_remainder = array_remainder,
+ .nb_divmod = array_divmod,
.nb_power = (ternaryfunc)array_power,
.nb_negative = (unaryfunc)array_negative,
.nb_positive = (unaryfunc)array_positive,
.nb_absolute = (unaryfunc)array_absolute,
.nb_bool = (inquiry)_array_nonzero,
.nb_invert = (unaryfunc)array_invert,
- .nb_lshift = (binaryfunc)array_left_shift,
- .nb_rshift = (binaryfunc)array_right_shift,
- .nb_and = (binaryfunc)array_bitwise_and,
- .nb_xor = (binaryfunc)array_bitwise_xor,
- .nb_or = (binaryfunc)array_bitwise_or,
+ .nb_lshift = array_left_shift,
+ .nb_rshift = array_right_shift,
+ .nb_and = array_bitwise_and,
+ .nb_xor = array_bitwise_xor,
+ .nb_or = array_bitwise_or,
.nb_int = (unaryfunc)array_int,
.nb_float = (unaryfunc)array_float,
@@ -962,11 +938,11 @@ NPY_NO_EXPORT PyNumberMethods array_as_number = {
.nb_inplace_xor = (binaryfunc)array_inplace_bitwise_xor,
.nb_inplace_or = (binaryfunc)array_inplace_bitwise_or,
- .nb_floor_divide = (binaryfunc)array_floor_divide,
- .nb_true_divide = (binaryfunc)array_true_divide,
+ .nb_floor_divide = array_floor_divide,
+ .nb_true_divide = array_true_divide,
.nb_inplace_floor_divide = (binaryfunc)array_inplace_floor_divide,
.nb_inplace_true_divide = (binaryfunc)array_inplace_true_divide,
- .nb_matrix_multiply = (binaryfunc)array_matrix_multiply,
+ .nb_matrix_multiply = array_matrix_multiply,
.nb_inplace_matrix_multiply = (binaryfunc)array_inplace_matrix_multiply,
};
diff --git a/numpy/core/src/multiarray/number.h b/numpy/core/src/multiarray/number.h
index 643241b3d..4f426f964 100644
--- a/numpy/core/src/multiarray/number.h
+++ b/numpy/core/src/multiarray/number.h
@@ -56,7 +56,7 @@ NPY_NO_EXPORT PyObject *
_PyArray_GetNumericOps(void);
NPY_NO_EXPORT PyObject *
-PyArray_GenericBinaryFunction(PyArrayObject *m1, PyObject *m2, PyObject *op);
+PyArray_GenericBinaryFunction(PyObject *m1, PyObject *m2, PyObject *op);
NPY_NO_EXPORT PyObject *
PyArray_GenericUnaryFunction(PyArrayObject *m1, PyObject *op);
diff --git a/numpy/core/src/multiarray/scalartypes.c.src b/numpy/core/src/multiarray/scalartypes.c.src
index e480628e7..40f736125 100644
--- a/numpy/core/src/multiarray/scalartypes.c.src
+++ b/numpy/core/src/multiarray/scalartypes.c.src
@@ -331,13 +331,13 @@ format_@name@(@type@ val, npy_bool scientific,
{
if (scientific) {
return Dragon4_Scientific_@Name@(&val,
- DigitMode_Unique, precision,
+ DigitMode_Unique, precision, -1,
sign, trim, pad_left, exp_digits);
}
else {
return Dragon4_Positional_@Name@(&val,
DigitMode_Unique, CutoffMode_TotalLength, precision,
- sign, trim, pad_left, pad_right);
+ -1, sign, trim, pad_left, pad_right);
}
}
@@ -1054,19 +1054,19 @@ gentype_richcompare(PyObject *self, PyObject *other, int cmp_op)
}
static PyObject *
-gentype_ndim_get(PyObject *NPY_UNUSED(self))
+gentype_ndim_get(PyObject *NPY_UNUSED(self), void *NPY_UNUSED(ignored))
{
return PyLong_FromLong(0);
}
static PyObject *
-gentype_flags_get(PyObject *NPY_UNUSED(self))
+gentype_flags_get(PyObject *NPY_UNUSED(self), void *NPY_UNUSED(ignored))
{
return PyArray_NewFlagsObject(NULL);
}
static PyObject *
-voidtype_flags_get(PyVoidScalarObject *self)
+voidtype_flags_get(PyVoidScalarObject *self, void *NPY_UNUSED(ignored))
{
PyObject *flagobj;
flagobj = PyArrayFlags_Type.tp_alloc(&PyArrayFlags_Type, 0);
@@ -1079,7 +1079,7 @@ voidtype_flags_get(PyVoidScalarObject *self)
}
static PyObject *
-voidtype_dtypedescr_get(PyVoidScalarObject *self)
+voidtype_dtypedescr_get(PyVoidScalarObject *self, void *NPY_UNUSED(ignored))
{
Py_INCREF(self->descr);
return (PyObject *)self->descr;
@@ -1087,7 +1087,7 @@ voidtype_dtypedescr_get(PyVoidScalarObject *self)
static PyObject *
-inttype_numerator_get(PyObject *self)
+inttype_numerator_get(PyObject *self, void *NPY_UNUSED(ignored))
{
Py_INCREF(self);
return self;
@@ -1095,21 +1095,21 @@ inttype_numerator_get(PyObject *self)
static PyObject *
-inttype_denominator_get(PyObject *self)
+inttype_denominator_get(PyObject *self, void *NPY_UNUSED(ignored))
{
return PyLong_FromLong(1);
}
static PyObject *
-gentype_data_get(PyObject *self)
+gentype_data_get(PyObject *self, void *NPY_UNUSED(ignored))
{
return PyMemoryView_FromObject(self);
}
static PyObject *
-gentype_itemsize_get(PyObject *self)
+gentype_itemsize_get(PyObject *self, void *NPY_UNUSED(ignored))
{
PyArray_Descr *typecode;
PyObject *ret;
@@ -1123,7 +1123,7 @@ gentype_itemsize_get(PyObject *self)
}
static PyObject *
-gentype_size_get(PyObject *NPY_UNUSED(self))
+gentype_size_get(PyObject *NPY_UNUSED(self), void *NPY_UNUSED(ignored))
{
return PyLong_FromLong(1);
}
@@ -1132,7 +1132,7 @@ static PyObject *
gentype_sizeof(PyObject *self)
{
Py_ssize_t nbytes;
- PyObject * isz = gentype_itemsize_get(self);
+ PyObject * isz = gentype_itemsize_get(self, NULL);
if (isz == NULL) {
return NULL;
}
@@ -1161,7 +1161,7 @@ gentype_struct_free(PyObject *ptr)
}
static PyObject *
-gentype_struct_get(PyObject *self)
+gentype_struct_get(PyObject *self, void *NPY_UNUSED(ignored))
{
PyArrayObject *arr;
PyArrayInterface *inter;
@@ -1187,20 +1187,20 @@ gentype_struct_get(PyObject *self)
}
static PyObject *
-gentype_priority_get(PyObject *NPY_UNUSED(self))
+gentype_priority_get(PyObject *NPY_UNUSED(self), void *NPY_UNUSED(ignored))
{
return PyFloat_FromDouble(NPY_SCALAR_PRIORITY);
}
static PyObject *
-gentype_shape_get(PyObject *NPY_UNUSED(self))
+gentype_shape_get(PyObject *NPY_UNUSED(self), void *NPY_UNUSED(ignored))
{
return PyTuple_New(0);
}
static PyObject *
-gentype_interface_get(PyObject *self)
+gentype_interface_get(PyObject *self, void *NPY_UNUSED(ignored))
{
PyArrayObject *arr;
PyObject *inter;
@@ -1220,20 +1220,20 @@ gentype_interface_get(PyObject *self)
static PyObject *
-gentype_typedescr_get(PyObject *self)
+gentype_typedescr_get(PyObject *self, void *NPY_UNUSED(ignored))
{
return (PyObject *)PyArray_DescrFromScalar(self);
}
static PyObject *
-gentype_base_get(PyObject *NPY_UNUSED(self))
+gentype_base_get(PyObject *NPY_UNUSED(self), void *NPY_UNUSED(ignored))
{
Py_RETURN_NONE;
}
static PyObject *
-voidtype_base_get(PyVoidScalarObject *self)
+voidtype_base_get(PyVoidScalarObject *self, void *NPY_UNUSED(ignored))
{
if (self->base == NULL) {
Py_RETURN_NONE;
@@ -1264,7 +1264,7 @@ _realdescr_fromcomplexscalar(PyObject *self, int *typenum)
}
static PyObject *
-gentype_real_get(PyObject *self)
+gentype_real_get(PyObject *self, void *NPY_UNUSED(ignored))
{
PyArray_Descr *typecode;
PyObject *ret;
@@ -1291,7 +1291,7 @@ gentype_real_get(PyObject *self)
}
static PyObject *
-gentype_imag_get(PyObject *self)
+gentype_imag_get(PyObject *self, void *NPY_UNUSED(ignored))
{
PyArray_Descr *typecode=NULL;
PyObject *ret;
@@ -1331,7 +1331,7 @@ gentype_imag_get(PyObject *self)
}
static PyObject *
-gentype_flat_get(PyObject *self)
+gentype_flat_get(PyObject *self, void *NPY_UNUSED(ignored))
{
PyObject *ret, *arr;
@@ -1346,7 +1346,7 @@ gentype_flat_get(PyObject *self)
static PyObject *
-gentype_transpose_get(PyObject *self)
+gentype_transpose_get(PyObject *self, void *NPY_UNUSED(ignored))
{
Py_INCREF(self);
return self;
@@ -2711,7 +2711,7 @@ static PyObject *
/* TODO: include type name in error message, which is not @name@ */
PyObject *obj = NULL;
- char *kwnames[] = {"", NULL}; /* positional-only */
+ static char *kwnames[] = {"", NULL}; /* positional-only */
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O", kwnames, &obj)) {
return NULL;
}
@@ -2799,7 +2799,7 @@ static PyObject *
object_arrtype_new(PyTypeObject *NPY_UNUSED(type), PyObject *args, PyObject *kwds)
{
PyObject *obj = Py_None;
- char *kwnames[] = {"", NULL}; /* positional-only */
+ static char *kwnames[] = {"", NULL}; /* positional-only */
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:object_", kwnames, &obj)) {
return NULL;
}
@@ -2825,7 +2825,7 @@ static PyObject *
PyObject *obj = NULL, *meta_obj = NULL;
Py@Name@ScalarObject *ret;
- char *kwnames[] = {"", "", NULL}; /* positional-only */
+ static char *kwnames[] = {"", "", NULL}; /* positional-only */
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OO", kwnames, &obj, &meta_obj)) {
return NULL;
}
@@ -2884,7 +2884,7 @@ bool_arrtype_new(PyTypeObject *NPY_UNUSED(type), PyObject *args, PyObject *kwds)
PyObject *obj = NULL;
PyArrayObject *arr;
- char *kwnames[] = {"", NULL}; /* positional-only */
+ static char *kwnames[] = {"", NULL}; /* positional-only */
if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O:bool_", kwnames, &obj)) {
return NULL;
}
@@ -2995,7 +2995,7 @@ void_arrtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
PyObject *obj, *arr;
PyObject *new = NULL;
- char *kwnames[] = {"", NULL}; /* positional-only */
+ static char *kwnames[] = {"", NULL}; /* positional-only */
if (!PyArg_ParseTupleAndKeywords(args, kwds, "O:void", kwnames, &obj)) {
return NULL;
}
@@ -3172,7 +3172,7 @@ static npy_hash_t
static npy_hash_t
@lname@_arrtype_hash(PyObject *obj)
{
- return _Py_HashDouble((double) PyArrayScalar_VAL(obj, @name@));
+ return Npy_HashDouble(obj, (double)PyArrayScalar_VAL(obj, @name@));
}
/* borrowed from complex_hash */
@@ -3180,14 +3180,14 @@ static npy_hash_t
c@lname@_arrtype_hash(PyObject *obj)
{
npy_hash_t hashreal, hashimag, combined;
- hashreal = _Py_HashDouble((double)
- PyArrayScalar_VAL(obj, C@name@).real);
+ hashreal = Npy_HashDouble(
+ obj, (double)PyArrayScalar_VAL(obj, C@name@).real);
if (hashreal == -1) {
return -1;
}
- hashimag = _Py_HashDouble((double)
- PyArrayScalar_VAL(obj, C@name@).imag);
+ hashimag = Npy_HashDouble(
+ obj, (double)PyArrayScalar_VAL(obj, C@name@).imag);
if (hashimag == -1) {
return -1;
}
@@ -3202,7 +3202,8 @@ c@lname@_arrtype_hash(PyObject *obj)
static npy_hash_t
half_arrtype_hash(PyObject *obj)
{
- return _Py_HashDouble(npy_half_to_double(PyArrayScalar_VAL(obj, Half)));
+ return Npy_HashDouble(
+ obj, npy_half_to_double(PyArrayScalar_VAL(obj, Half)));
}
static npy_hash_t
diff --git a/numpy/core/src/multiarray/temp_elide.c b/numpy/core/src/multiarray/temp_elide.c
index b19dee418..2b4621744 100644
--- a/numpy/core/src/multiarray/temp_elide.c
+++ b/numpy/core/src/multiarray/temp_elide.c
@@ -274,13 +274,14 @@ check_callers(int * cannot)
* "cannot" is set to true if it cannot be done even with swapped arguments
*/
static int
-can_elide_temp(PyArrayObject * alhs, PyObject * orhs, int * cannot)
+can_elide_temp(PyObject *olhs, PyObject *orhs, int *cannot)
{
/*
* to be a candidate the array needs to have reference count 1, be an exact
* array of a basic type, own its data and size larger than threshold
*/
- if (Py_REFCNT(alhs) != 1 || !PyArray_CheckExact(alhs) ||
+ PyArrayObject *alhs = (PyArrayObject *)olhs;
+ if (Py_REFCNT(olhs) != 1 || !PyArray_CheckExact(olhs) ||
!PyArray_ISNUMBER(alhs) ||
!PyArray_CHKFLAGS(alhs, NPY_ARRAY_OWNDATA) ||
!PyArray_ISWRITEABLE(alhs) ||
@@ -328,22 +329,22 @@ can_elide_temp(PyArrayObject * alhs, PyObject * orhs, int * cannot)
* try eliding a binary op, if commutative is true also try swapped arguments
*/
NPY_NO_EXPORT int
-try_binary_elide(PyArrayObject * m1, PyObject * m2,
+try_binary_elide(PyObject * m1, PyObject * m2,
PyObject * (inplace_op)(PyArrayObject * m1, PyObject * m2),
PyObject ** res, int commutative)
{
/* set when no elision can be done independent of argument order */
int cannot = 0;
if (can_elide_temp(m1, m2, &cannot)) {
- *res = inplace_op(m1, m2);
+ *res = inplace_op((PyArrayObject *)m1, m2);
#if NPY_ELIDE_DEBUG != 0
puts("elided temporary in binary op");
#endif
return 1;
}
else if (commutative && !cannot) {
- if (can_elide_temp((PyArrayObject *)m2, (PyObject *)m1, &cannot)) {
- *res = inplace_op((PyArrayObject *)m2, (PyObject *)m1);
+ if (can_elide_temp(m2, m1, &cannot)) {
+ *res = inplace_op((PyArrayObject *)m2, m1);
#if NPY_ELIDE_DEBUG != 0
puts("elided temporary in commutative binary op");
#endif
diff --git a/numpy/core/src/multiarray/temp_elide.h b/numpy/core/src/multiarray/temp_elide.h
index d073adf28..206bb0253 100644
--- a/numpy/core/src/multiarray/temp_elide.h
+++ b/numpy/core/src/multiarray/temp_elide.h
@@ -8,7 +8,7 @@ NPY_NO_EXPORT int
can_elide_temp_unary(PyArrayObject * m1);
NPY_NO_EXPORT int
-try_binary_elide(PyArrayObject * m1, PyObject * m2,
+try_binary_elide(PyObject * m1, PyObject * m2,
PyObject * (inplace_op)(PyArrayObject * m1, PyObject * m2),
PyObject ** res, int commutative);
diff --git a/numpy/core/src/multiarray/usertypes.c b/numpy/core/src/multiarray/usertypes.c
index 3eaf99196..5602304e9 100644
--- a/numpy/core/src/multiarray/usertypes.c
+++ b/numpy/core/src/multiarray/usertypes.c
@@ -235,7 +235,7 @@ PyArray_RegisterDataType(PyArray_Descr *descr)
!PyDict_CheckExact(descr->fields)) {
PyErr_Format(PyExc_ValueError,
"Failed to register dtype for %S: Legacy user dtypes "
- "using `NPY_ITEM_IS_POINTER` or `NPY_ITEM_REFCOUNT` are"
+ "using `NPY_ITEM_IS_POINTER` or `NPY_ITEM_REFCOUNT` are "
"unsupported. It is possible to create such a dtype only "
"if it is a structured dtype with names and fields "
"hardcoded at registration time.\n"
@@ -388,7 +388,7 @@ legacy_userdtype_common_dtype_function(
{
int skind1 = NPY_NOSCALAR, skind2 = NPY_NOSCALAR, skind;
- if (!other->legacy) {
+ if (!NPY_DT_is_legacy(other)) {
/* legacy DTypes can always defer to new style ones */
Py_INCREF(Py_NotImplemented);
return (PyArray_DTypeMeta *)Py_NotImplemented;
@@ -422,7 +422,7 @@ legacy_userdtype_common_dtype_function(
*/
/* Convert the 'kind' char into a scalar kind */
- switch (cls->kind) {
+ switch (cls->singleton->kind) {
case 'b':
skind1 = NPY_BOOL_SCALAR;
break;
@@ -439,7 +439,7 @@ legacy_userdtype_common_dtype_function(
skind1 = NPY_COMPLEX_SCALAR;
break;
}
- switch (other->kind) {
+ switch (other->singleton->kind) {
case 'b':
skind2 = NPY_BOOL_SCALAR;
break;
@@ -538,7 +538,7 @@ PyArray_AddLegacyWrapping_CastingImpl(
if (from == to) {
spec.flags = NPY_METH_REQUIRES_PYAPI | NPY_METH_SUPPORTS_UNALIGNED;
PyType_Slot slots[] = {
- {NPY_METH_get_loop, NULL},
+ {NPY_METH_get_loop, &legacy_cast_get_strided_loop},
{NPY_METH_resolve_descriptors, &legacy_same_dtype_resolve_descriptors},
{0, NULL}};
spec.slots = slots;
@@ -547,7 +547,7 @@ PyArray_AddLegacyWrapping_CastingImpl(
else {
spec.flags = NPY_METH_REQUIRES_PYAPI;
PyType_Slot slots[] = {
- {NPY_METH_get_loop, NULL},
+ {NPY_METH_get_loop, &legacy_cast_get_strided_loop},
{NPY_METH_resolve_descriptors, &simple_cast_resolve_descriptors},
{0, NULL}};
spec.slots = slots;
diff --git a/numpy/core/src/npymath/npy_math_internal.h.src b/numpy/core/src/npymath/npy_math_internal.h.src
index ff4663dc3..1e46a2303 100644
--- a/numpy/core/src/npymath/npy_math_internal.h.src
+++ b/numpy/core/src/npymath/npy_math_internal.h.src
@@ -398,8 +398,8 @@ NPY_INPLACE @type@ npy_@kind@@c@(@type@ x)
/**end repeat1**/
/**begin repeat1
- * #kind = atan2,hypot,pow,copysign#
- * #KIND = ATAN2,HYPOT,POW,COPYSIGN#
+ * #kind = atan2,hypot,pow,fmod,copysign#
+ * #KIND = ATAN2,HYPOT,POW,FMOD,COPYSIGN#
*/
#ifdef @kind@@c@
#undef @kind@@c@
@@ -412,32 +412,6 @@ NPY_INPLACE @type@ npy_@kind@@c@(@type@ x, @type@ y)
#endif
/**end repeat1**/
-/**begin repeat1
- * #kind = fmod#
- * #KIND = FMOD#
- */
-#ifdef @kind@@c@
-#undef @kind@@c@
-#endif
-#ifndef HAVE_MODF@C@
-NPY_INPLACE @type@
-npy_@kind@@c@(@type@ x, @type@ y)
-{
- int are_inputs_inf = (npy_isinf(x) && npy_isinf(y));
- /* force set invalid flag, doesnt raise by default on gcc < 8 */
- if (npy_isnan(x) || npy_isnan(y)) {
- npy_set_floatstatus_invalid();
- }
- if (are_inputs_inf || !y) {
- if (!npy_isnan(x)) {
- npy_set_floatstatus_invalid();
- }
- }
- return (@type@) npy_@kind@((double)x, (double) y);
-}
-#endif
-/**end repeat1**/
-
#ifdef modf@c@
#undef modf@c@
#endif
@@ -499,8 +473,8 @@ NPY_INPLACE @type@ npy_@kind@@c@(@type@ x)
/**end repeat1**/
/**begin repeat1
- * #kind = atan2,hypot,pow,copysign#
- * #KIND = ATAN2,HYPOT,POW,COPYSIGN#
+ * #kind = atan2,hypot,pow,fmod,copysign#
+ * #KIND = ATAN2,HYPOT,POW,FMOD,COPYSIGN#
*/
#ifdef HAVE_@KIND@@C@
NPY_INPLACE @type@ npy_@kind@@c@(@type@ x, @type@ y)
@@ -510,29 +484,6 @@ NPY_INPLACE @type@ npy_@kind@@c@(@type@ x, @type@ y)
#endif
/**end repeat1**/
-/**begin repeat1
- * #kind = fmod#
- * #KIND = FMOD#
- */
-#ifdef HAVE_FMOD@C@
-NPY_INPLACE @type@
-npy_@kind@@c@(@type@ x, @type@ y)
-{
- int are_inputs_inf = (npy_isinf(x) && npy_isinf(y));
- /* force set invalid flag, doesnt raise by default on gcc < 8 */
- if (npy_isnan(x) || npy_isnan(y)) {
- npy_set_floatstatus_invalid();
- }
- if (are_inputs_inf || !y) {
- if (!npy_isnan(x)) {
- npy_set_floatstatus_invalid();
- }
- }
- return @kind@@c@(x, y);
-}
-#endif
-/**end repeat1**/
-
#ifdef HAVE_MODF@C@
NPY_INPLACE @type@ npy_modf@c@(@type@ x, @type@ *iptr)
{
@@ -682,8 +633,14 @@ npy_remainder@c@(@type@ a, @type@ b)
{
@type@ mod;
if (NPY_UNLIKELY(!b)) {
+ /*
+ * in2 == 0 (and not NaN): normal fmod will give the correct
+ * result (always NaN). `divmod` may set additional FPE for the
+ * division by zero creating an inf.
+ */
mod = npy_fmod@c@(a, b);
- } else {
+ }
+ else {
npy_divmod@c@(a, b, &mod);
}
return mod;
@@ -693,13 +650,14 @@ NPY_INPLACE @type@
npy_floor_divide@c@(@type@ a, @type@ b) {
@type@ div, mod;
if (NPY_UNLIKELY(!b)) {
+ /*
+ * in2 == 0 (and not NaN): normal division will give the correct
+ * result (Inf or NaN). `divmod` may set additional FPE for the modulo
+ * evaluating to NaN.
+ */
div = a / b;
- if (!a || npy_isnan(a)) {
- npy_set_floatstatus_invalid();
- } else {
- npy_set_floatstatus_divbyzero();
- }
- } else {
+ }
+ else {
div = npy_divmod@c@(a, b, &mod);
}
return div;
@@ -715,19 +673,11 @@ npy_divmod@c@(@type@ a, @type@ b, @type@ *modulus)
{
@type@ div, mod, floordiv;
- /* force set invalid flag, doesnt raise by default on gcc < 8 */
- if (npy_isnan(a) || npy_isnan(b)) {
- npy_set_floatstatus_invalid();
- }
mod = npy_fmod@c@(a, b);
if (NPY_UNLIKELY(!b)) {
- div = a / b;
- if (a && !npy_isnan(a)) {
- npy_set_floatstatus_divbyzero();
- }
- /* If b == 0, return result of fmod. For IEEE is nan */
+ /* b == 0 (not NaN): return result of fmod. For IEEE is nan */
*modulus = mod;
- return div;
+ return a / b;
}
/* a - mod should be very nearly an integer multiple of b */
@@ -735,7 +685,7 @@ npy_divmod@c@(@type@ a, @type@ b, @type@ *modulus)
/* adjust fmod result to conform to Python convention of remainder */
if (mod) {
- if ((b < 0) != (mod < 0)) {
+ if (isless(b, 0) != isless(mod, 0)) {
mod += b;
div -= 1.0@c@;
}
@@ -748,7 +698,7 @@ npy_divmod@c@(@type@ a, @type@ b, @type@ *modulus)
/* snap quotient to nearest integral value */
if (div) {
floordiv = npy_floor@c@(div);
- if (div - floordiv > 0.5@c@)
+ if (isgreater(div - floordiv, 0.5@c@))
floordiv += 1.0@c@;
}
else {
diff --git a/numpy/core/src/npysort/timsort.c.src b/numpy/core/src/npysort/timsort.c.src
index 3fdd46f61..5298f5a1d 100644
--- a/numpy/core/src/npysort/timsort.c.src
+++ b/numpy/core/src/npysort/timsort.c.src
@@ -507,9 +507,7 @@ timsort_@suff@(void *start, npy_intp num, void *NPY_UNUSED(varr))
ret = 0;
cleanup:
- if (buffer.pw != NULL) {
- free(buffer.pw);
- }
+ free(buffer.pw);
return ret;
}
diff --git a/numpy/core/src/umath/_scaled_float_dtype.c b/numpy/core/src/umath/_scaled_float_dtype.c
new file mode 100644
index 000000000..599774cce
--- /dev/null
+++ b/numpy/core/src/umath/_scaled_float_dtype.c
@@ -0,0 +1,720 @@
+/*
+ * This file implements a basic scaled float64 DType. The reason is to have
+ * a simple parametric DType for testing. It is not meant to be a useful
+ * DType by itself, but due to the scaling factor has similar properties as
+ * a Unit DType.
+ *
+ * The code here should be seen as a work in progress. Some choices are made
+ * to test certain code paths, but that does not mean that they must not
+ * be modified.
+ *
+ * NOTE: The tests were initially written using private API and ABI, ideally
+ * they should be replaced/modified with versions using public API.
+ */
+
+#define _UMATHMODULE
+#define _MULTIARRAYMODULE
+#define NPY_NO_DEPRECATED_API NPY_API_VERSION
+#include "numpy/ndarrayobject.h"
+#include "numpy/ufuncobject.h"
+
+#include "array_method.h"
+#include "common.h"
+#include "numpy/npy_math.h"
+#include "convert_datatype.h"
+#include "dtypemeta.h"
+#include "dispatching.h"
+
+
+typedef struct {
+ PyArray_Descr base;
+ double scaling;
+} PyArray_SFloatDescr;
+
+static PyArray_DTypeMeta PyArray_SFloatDType;
+static PyArray_SFloatDescr SFloatSingleton;
+
+
+static int
+sfloat_is_known_scalar_type(PyArray_DTypeMeta *NPY_UNUSED(cls), PyTypeObject *type)
+{
+ /* Accept only floats (some others may work due to normal casting) */
+ if (type == &PyFloat_Type) {
+ return 1;
+ }
+ return 0;
+}
+
+
+static PyArray_Descr *
+sfloat_default_descr(PyArray_DTypeMeta *NPY_UNUSED(cls))
+{
+ Py_INCREF(&SFloatSingleton);
+ return (PyArray_Descr *)&SFloatSingleton;
+}
+
+
+static PyArray_Descr *
+sfloat_discover_from_pyobject(PyArray_DTypeMeta *cls, PyObject *NPY_UNUSED(obj))
+{
+ return sfloat_default_descr(cls);
+}
+
+
+static PyArray_DTypeMeta *
+sfloat_common_dtype(PyArray_DTypeMeta *cls, PyArray_DTypeMeta *other)
+{
+ if (NPY_DT_is_legacy(other) && other->type_num == NPY_DOUBLE) {
+ Py_INCREF(cls);
+ return cls;
+ }
+ Py_INCREF(Py_NotImplemented);
+ return (PyArray_DTypeMeta *)Py_NotImplemented;
+}
+
+
+static PyArray_Descr *
+sfloat_common_instance(PyArray_Descr *descr1, PyArray_Descr *descr2)
+{
+ PyArray_SFloatDescr *sf1 = (PyArray_SFloatDescr *)descr1;
+ PyArray_SFloatDescr *sf2 = (PyArray_SFloatDescr *)descr2;
+ /* We make the choice of using the larger scaling */
+ if (sf1->scaling >= sf2->scaling) {
+ Py_INCREF(descr1);
+ return descr1;
+ }
+ Py_INCREF(descr2);
+ return descr2;
+}
+
+
+/*
+ * Implement minimal getitem and setitem to make this DType mostly(?) safe to
+ * expose in Python.
+ * TODO: This should not use the old-style API, but the new-style is missing!
+*/
+
+static PyObject *
+sfloat_getitem(char *data, PyArrayObject *arr)
+{
+ PyArray_SFloatDescr *descr = (PyArray_SFloatDescr *)PyArray_DESCR(arr);
+ double value;
+
+ memcpy(&value, data, sizeof(double));
+ return PyFloat_FromDouble(value * descr->scaling);
+}
+
+
+static int
+sfloat_setitem(PyObject *obj, char *data, PyArrayObject *arr)
+{
+ if (!PyFloat_CheckExact(obj)) {
+ PyErr_SetString(PyExc_NotImplementedError,
+ "Currently only accepts floats");
+ return -1;
+ }
+
+ PyArray_SFloatDescr *descr = (PyArray_SFloatDescr *)PyArray_DESCR(arr);
+ double value = PyFloat_AsDouble(obj);
+ value /= descr->scaling;
+
+ memcpy(data, &value, sizeof(double));
+ return 0;
+}
+
+
+/* Special DType methods and the descr->f slot storage */
+NPY_DType_Slots sfloat_slots = {
+ .default_descr = &sfloat_default_descr,
+ .discover_descr_from_pyobject = &sfloat_discover_from_pyobject,
+ .is_known_scalar_type = &sfloat_is_known_scalar_type,
+ .common_dtype = &sfloat_common_dtype,
+ .common_instance = &sfloat_common_instance,
+ .f = {
+ .getitem = (PyArray_GetItemFunc *)&sfloat_getitem,
+ .setitem = (PyArray_SetItemFunc *)&sfloat_setitem,
+ }
+};
+
+
+static PyArray_SFloatDescr SFloatSingleton = {{
+ .elsize = sizeof(double),
+ .alignment = _ALIGN(double),
+ .flags = NPY_USE_GETITEM|NPY_USE_SETITEM,
+ .type_num = -1,
+ .f = &sfloat_slots.f,
+ .byteorder = '|', /* do not bother with byte-swapping... */
+ },
+ .scaling = 1,
+};
+
+
+static PyArray_Descr *
+sfloat_scaled_copy(PyArray_SFloatDescr *self, double factor) {
+ PyArray_SFloatDescr *new = PyObject_New(
+ PyArray_SFloatDescr, (PyTypeObject *)&PyArray_SFloatDType);
+ if (new == NULL) {
+ return NULL;
+ }
+ /* Don't copy PyObject_HEAD part */
+ memcpy((char *)new + sizeof(PyObject),
+ (char *)self + sizeof(PyObject),
+ sizeof(PyArray_SFloatDescr) - sizeof(PyObject));
+
+ new->scaling = new->scaling * factor;
+ return (PyArray_Descr *)new;
+}
+
+
+PyObject *
+python_sfloat_scaled_copy(PyArray_SFloatDescr *self, PyObject *arg)
+{
+ if (!PyFloat_Check(arg)) {
+ PyErr_SetString(PyExc_TypeError,
+ "Scaling factor must be a python float.");
+ return NULL;
+ }
+ double factor = PyFloat_AsDouble(arg);
+
+ return (PyObject *)sfloat_scaled_copy(self, factor);
+}
+
+
+static PyObject *
+sfloat_get_scaling(PyArray_SFloatDescr *self, PyObject *NPY_UNUSED(args))
+{
+ return PyFloat_FromDouble(self->scaling);
+}
+
+
+PyMethodDef sfloat_methods[] = {
+ {"scaled_by",
+ (PyCFunction)python_sfloat_scaled_copy, METH_O,
+ "Method to get a dtype copy with different scaling, mainly to "
+ "avoid having to implement many ways to create new instances."},
+ {"get_scaling",
+ (PyCFunction)sfloat_get_scaling, METH_NOARGS, NULL},
+ {NULL, NULL, 0, NULL}
+};
+
+
+static PyObject *
+sfloat_new(PyTypeObject *NPY_UNUSED(cls), PyObject *args, PyObject *kwds)
+{
+ double scaling = 1.;
+ static char *kwargs_strs[] = {"scaling", NULL};
+
+ if (!PyArg_ParseTupleAndKeywords(
+ args, kwds, "|d:_ScaledFloatTestDType", kwargs_strs, &scaling)) {
+ return NULL;
+ }
+ if (scaling == 1.) {
+ Py_INCREF(&SFloatSingleton);
+ return (PyObject *)&SFloatSingleton;
+ }
+ return (PyObject *)sfloat_scaled_copy(&SFloatSingleton, scaling);
+}
+
+
+static PyObject *
+sfloat_repr(PyArray_SFloatDescr *self)
+{
+ PyObject *scaling = PyFloat_FromDouble(self->scaling);
+ if (scaling == NULL) {
+ return NULL;
+ }
+ PyObject *res = PyUnicode_FromFormat(
+ "_ScaledFloatTestDType(scaling=%R)", scaling);
+ Py_DECREF(scaling);
+ return res;
+}
+
+
+static PyArray_DTypeMeta PyArray_SFloatDType = {{{
+ PyVarObject_HEAD_INIT(NULL, 0)
+ .tp_name = "numpy._ScaledFloatTestDType",
+ .tp_methods = sfloat_methods,
+ .tp_new = sfloat_new,
+ .tp_repr = (reprfunc)sfloat_repr,
+ .tp_str = (reprfunc)sfloat_repr,
+ .tp_basicsize = sizeof(PyArray_SFloatDescr),
+ }},
+ .type_num = -1,
+ .scalar_type = NULL,
+ .flags = NPY_DT_PARAMETRIC,
+ .dt_slots = &sfloat_slots,
+};
+
+
+/*
+ * Implement some casts.
+ */
+
+/*
+ * It would make more sense to test this early on, but this allows testing
+ * error returns.
+ */
+static int
+check_factor(double factor) {
+ if (npy_isfinite(factor) && factor != 0.) {
+ return 0;
+ }
+ NPY_ALLOW_C_API_DEF;
+ NPY_ALLOW_C_API;
+ PyErr_SetString(PyExc_TypeError,
+ "error raised inside the core-loop: non-finite factor!");
+ NPY_DISABLE_C_API;
+ return -1;
+}
+
+
+static int
+cast_sfloat_to_sfloat_unaligned(PyArrayMethod_Context *context,
+ char *const data[], npy_intp const dimensions[],
+ npy_intp const strides[], NpyAuxData *NPY_UNUSED(auxdata))
+{
+ /* could also be moved into auxdata: */
+ double factor = ((PyArray_SFloatDescr *)context->descriptors[0])->scaling;
+ factor /= ((PyArray_SFloatDescr *)context->descriptors[1])->scaling;
+ if (check_factor(factor) < 0) {
+ return -1;
+ }
+
+ npy_intp N = dimensions[0];
+ char *in = data[0];
+ char *out = data[1];
+ for (npy_intp i = 0; i < N; i++) {
+ double tmp;
+ memcpy(&tmp, in, sizeof(double));
+ tmp *= factor;
+ memcpy(out, &tmp, sizeof(double));
+
+ in += strides[0];
+ out += strides[1];
+ }
+ return 0;
+}
+
+
+static int
+cast_sfloat_to_sfloat_aligned(PyArrayMethod_Context *context,
+ char *const data[], npy_intp const dimensions[],
+ npy_intp const strides[], NpyAuxData *NPY_UNUSED(auxdata))
+{
+ /* could also be moved into auxdata: */
+ double factor = ((PyArray_SFloatDescr *)context->descriptors[0])->scaling;
+ factor /= ((PyArray_SFloatDescr *)context->descriptors[1])->scaling;
+ if (check_factor(factor) < 0) {
+ return -1;
+ }
+
+ npy_intp N = dimensions[0];
+ char *in = data[0];
+ char *out = data[1];
+ for (npy_intp i = 0; i < N; i++) {
+ *(double *)out = *(double *)in * factor;
+ in += strides[0];
+ out += strides[1];
+ }
+ return 0;
+}
+
+
+static NPY_CASTING
+sfloat_to_sfloat_resolve_descriptors(
+ PyArrayMethodObject *NPY_UNUSED(self),
+ PyArray_DTypeMeta *NPY_UNUSED(dtypes[2]),
+ PyArray_Descr *given_descrs[2],
+ PyArray_Descr *loop_descrs[2])
+{
+ loop_descrs[0] = given_descrs[0];
+ Py_INCREF(loop_descrs[0]);
+
+ if (given_descrs[1] == NULL) {
+ loop_descrs[1] = given_descrs[0];
+ }
+ else {
+ loop_descrs[1] = given_descrs[1];
+ }
+ Py_INCREF(loop_descrs[1]);
+
+ if (((PyArray_SFloatDescr *)loop_descrs[0])->scaling
+ == ((PyArray_SFloatDescr *)loop_descrs[1])->scaling) {
+ /* same scaling is just a view */
+ return NPY_NO_CASTING | _NPY_CAST_IS_VIEW;
+ }
+ else if (-((PyArray_SFloatDescr *)loop_descrs[0])->scaling
+ == ((PyArray_SFloatDescr *)loop_descrs[1])->scaling) {
+ /* changing the sign does not lose precision */
+ return NPY_EQUIV_CASTING;
+ }
+ /* Technically, this is not a safe cast, since over/underflows can occur */
+ return NPY_SAME_KIND_CASTING;
+}
+
+
+/*
+ * Casting to and from doubles.
+ *
+ * To keep things interesting, we ONLY define the trivial cast with a factor
+ * of 1. All other casts have to be handled by the sfloat to sfloat cast.
+ *
+ * The casting machinery should optimize this step away normally, since we
+ * flag the this is a view.
+ */
+static int
+cast_float_to_from_sfloat(PyArrayMethod_Context *NPY_UNUSED(context),
+ char *const data[], npy_intp const dimensions[],
+ npy_intp const strides[], NpyAuxData *NPY_UNUSED(auxdata))
+{
+ npy_intp N = dimensions[0];
+ char *in = data[0];
+ char *out = data[1];
+ for (npy_intp i = 0; i < N; i++) {
+ *(double *)out = *(double *)in;
+ in += strides[0];
+ out += strides[1];
+ }
+ return 0;
+}
+
+
+static NPY_CASTING
+float_to_from_sfloat_resolve_descriptors(
+ PyArrayMethodObject *NPY_UNUSED(self),
+ PyArray_DTypeMeta *dtypes[2],
+ PyArray_Descr *NPY_UNUSED(given_descrs[2]),
+ PyArray_Descr *loop_descrs[2])
+{
+ loop_descrs[0] = NPY_DT_CALL_default_descr(dtypes[0]);
+ if (loop_descrs[0] == NULL) {
+ return -1;
+ }
+ loop_descrs[1] = NPY_DT_CALL_default_descr(dtypes[1]);
+ if (loop_descrs[1] == NULL) {
+ return -1;
+ }
+ return NPY_NO_CASTING | _NPY_CAST_IS_VIEW;
+}
+
+
+static int
+init_casts(void)
+{
+ PyArray_DTypeMeta *dtypes[2] = {&PyArray_SFloatDType, &PyArray_SFloatDType};
+ PyType_Slot slots[4] = {{0, NULL}};
+ PyArrayMethod_Spec spec = {
+ .name = "sfloat_to_sfloat_cast",
+ .nin = 1,
+ .nout = 1,
+ .flags = NPY_METH_SUPPORTS_UNALIGNED,
+ .dtypes = dtypes,
+ .slots = slots,
+ /* minimal guaranteed casting */
+ .casting = NPY_SAME_KIND_CASTING,
+ };
+
+ slots[0].slot = NPY_METH_resolve_descriptors;
+ slots[0].pfunc = &sfloat_to_sfloat_resolve_descriptors;
+
+ slots[1].slot = NPY_METH_strided_loop;
+ slots[1].pfunc = &cast_sfloat_to_sfloat_aligned;
+
+ slots[2].slot = NPY_METH_unaligned_strided_loop;
+ slots[2].pfunc = &cast_sfloat_to_sfloat_unaligned;
+
+ if (PyArray_AddCastingImplementation_FromSpec(&spec, 0)) {
+ return -1;
+ }
+
+ spec.name = "float_to_sfloat_cast";
+ /* Technically, it is just a copy currently so this is fine: */
+ spec.flags = NPY_METH_NO_FLOATINGPOINT_ERRORS;
+ PyArray_DTypeMeta *double_DType = PyArray_DTypeFromTypeNum(NPY_DOUBLE);
+ Py_DECREF(double_DType); /* immortal anyway */
+ dtypes[0] = double_DType;
+
+ slots[0].slot = NPY_METH_resolve_descriptors;
+ slots[0].pfunc = &float_to_from_sfloat_resolve_descriptors;
+ slots[1].slot = NPY_METH_strided_loop;
+ slots[1].pfunc = &cast_float_to_from_sfloat;
+ slots[2].slot = 0;
+ slots[2].pfunc = NULL;
+
+ if (PyArray_AddCastingImplementation_FromSpec(&spec, 0)) {
+ return -1;
+ }
+
+ spec.name = "sfloat_to_float_cast";
+ dtypes[0] = &PyArray_SFloatDType;
+ dtypes[1] = double_DType;
+
+ if (PyArray_AddCastingImplementation_FromSpec(&spec, 0)) {
+ return -1;
+ }
+
+ return 0;
+}
+
+
+/*
+ * We also wish to test very simple ufunc functionality. So create two
+ * ufunc loops:
+ * 1. Multiplication, which can multiply the factors and work with that.
+ * 2. Addition, which needs to use the common instance, and runs into
+ * cast safety subtleties since we will implement it without an additional
+ * cast.
+ *
+ * NOTE: When first writing this, promotion did not exist for new-style loops,
+ * if it exists, we could use promotion to implement double * sfloat.
+ */
+static int
+multiply_sfloats(PyArrayMethod_Context *NPY_UNUSED(context),
+ char *const data[], npy_intp const dimensions[],
+ npy_intp const strides[], NpyAuxData *NPY_UNUSED(auxdata))
+{
+ npy_intp N = dimensions[0];
+ char *in1 = data[0];
+ char *in2 = data[1];
+ char *out = data[2];
+ for (npy_intp i = 0; i < N; i++) {
+ *(double *)out = *(double *)in1 * *(double *)in2;
+ in1 += strides[0];
+ in2 += strides[1];
+ out += strides[2];
+ }
+ return 0;
+}
+
+
+static NPY_CASTING
+multiply_sfloats_resolve_descriptors(
+ PyArrayMethodObject *NPY_UNUSED(self),
+ PyArray_DTypeMeta *NPY_UNUSED(dtypes[3]),
+ PyArray_Descr *given_descrs[3],
+ PyArray_Descr *loop_descrs[3])
+{
+ /*
+ * Multiply the scaling for the result. If the result was passed in we
+ * simply ignore it and let the casting machinery fix it up here.
+ */
+ double factor = ((PyArray_SFloatDescr *)given_descrs[1])->scaling;
+ loop_descrs[2] = sfloat_scaled_copy(
+ (PyArray_SFloatDescr *)given_descrs[0], factor);
+ if (loop_descrs[2] == 0) {
+ return -1;
+ }
+ Py_INCREF(given_descrs[0]);
+ loop_descrs[0] = given_descrs[0];
+ Py_INCREF(given_descrs[1]);
+ loop_descrs[1] = given_descrs[1];
+ return NPY_NO_CASTING;
+}
+
+
+/*
+ * Unlike the multiplication implementation above, this loops deals with
+ * scaling (casting) internally. This allows to test some different paths.
+ */
+static int
+add_sfloats(PyArrayMethod_Context *context,
+ char *const data[], npy_intp const dimensions[],
+ npy_intp const strides[], NpyAuxData *NPY_UNUSED(auxdata))
+{
+ double fin1 = ((PyArray_SFloatDescr *)context->descriptors[0])->scaling;
+ double fin2 = ((PyArray_SFloatDescr *)context->descriptors[1])->scaling;
+ double fout = ((PyArray_SFloatDescr *)context->descriptors[2])->scaling;
+
+ double fact1 = fin1 / fout;
+ double fact2 = fin2 / fout;
+ if (check_factor(fact1) < 0) {
+ return -1;
+ }
+ if (check_factor(fact2) < 0) {
+ return -1;
+ }
+
+ npy_intp N = dimensions[0];
+ char *in1 = data[0];
+ char *in2 = data[1];
+ char *out = data[2];
+ for (npy_intp i = 0; i < N; i++) {
+ *(double *)out = (*(double *)in1 * fact1) + (*(double *)in2 * fact2);
+ in1 += strides[0];
+ in2 += strides[1];
+ out += strides[2];
+ }
+ return 0;
+}
+
+
+static NPY_CASTING
+add_sfloats_resolve_descriptors(
+ PyArrayMethodObject *NPY_UNUSED(self),
+ PyArray_DTypeMeta *NPY_UNUSED(dtypes[3]),
+ PyArray_Descr *given_descrs[3],
+ PyArray_Descr *loop_descrs[3])
+{
+ /*
+ * Here we accept an output descriptor (the inner loop can deal with it),
+ * if none is given, we use the "common instance":
+ */
+ if (given_descrs[2] == NULL) {
+ loop_descrs[2] = sfloat_common_instance(
+ given_descrs[0], given_descrs[1]);
+ if (loop_descrs[2] == 0) {
+ return -1;
+ }
+ }
+ else {
+ Py_INCREF(given_descrs[2]);
+ loop_descrs[2] = given_descrs[2];
+ }
+ Py_INCREF(given_descrs[0]);
+ loop_descrs[0] = given_descrs[0];
+ Py_INCREF(given_descrs[1]);
+ loop_descrs[1] = given_descrs[1];
+
+ /* If the factors mismatch, we do implicit casting inside the ufunc! */
+ double fin1 = ((PyArray_SFloatDescr *)loop_descrs[0])->scaling;
+ double fin2 = ((PyArray_SFloatDescr *)loop_descrs[1])->scaling;
+ double fout = ((PyArray_SFloatDescr *)loop_descrs[2])->scaling;
+
+ if (fin1 == fout && fin2 == fout) {
+ return NPY_NO_CASTING;
+ }
+ if (npy_fabs(fin1) == npy_fabs(fout) && npy_fabs(fin2) == npy_fabs(fout)) {
+ return NPY_EQUIV_CASTING;
+ }
+ return NPY_SAME_KIND_CASTING;
+}
+
+
+static int
+add_loop(const char *ufunc_name, PyBoundArrayMethodObject *bmeth)
+{
+ PyObject *mod = PyImport_ImportModule("numpy");
+ if (mod == NULL) {
+ return -1;
+ }
+ PyObject *ufunc = PyObject_GetAttrString(mod, ufunc_name);
+ Py_DECREF(mod);
+ if (!PyObject_TypeCheck(ufunc, &PyUFunc_Type)) {
+ Py_DECREF(ufunc);
+ PyErr_Format(PyExc_TypeError,
+ "numpy.%s was not a ufunc!", ufunc_name);
+ return -1;
+ }
+ PyObject *dtype_tup = PyArray_TupleFromItems(
+ 3, (PyObject **)bmeth->dtypes, 0);
+ if (dtype_tup == NULL) {
+ Py_DECREF(ufunc);
+ return -1;
+ }
+ PyObject *info = PyTuple_Pack(2, dtype_tup, bmeth->method);
+ Py_DECREF(dtype_tup);
+ if (info == NULL) {
+ Py_DECREF(ufunc);
+ return -1;
+ }
+ int res = PyUFunc_AddLoop((PyUFuncObject *)ufunc, info, 0);
+ Py_DECREF(ufunc);
+ Py_DECREF(info);
+ return res;
+}
+
+
+/*
+ * Add new ufunc loops (this is somewhat clumsy as of writing it, but should
+ * get less so with the introduction of public API).
+ */
+static int
+init_ufuncs(void) {
+ PyArray_DTypeMeta *dtypes[3] = {
+ &PyArray_SFloatDType, &PyArray_SFloatDType, &PyArray_SFloatDType};
+ PyType_Slot slots[3] = {{0, NULL}};
+ PyArrayMethod_Spec spec = {
+ .nin = 2,
+ .nout =1,
+ .dtypes = dtypes,
+ .slots = slots,
+ };
+ spec.name = "sfloat_multiply";
+ spec.casting = NPY_NO_CASTING;
+
+ slots[0].slot = NPY_METH_resolve_descriptors;
+ slots[0].pfunc = &multiply_sfloats_resolve_descriptors;
+ slots[1].slot = NPY_METH_strided_loop;
+ slots[1].pfunc = &multiply_sfloats;
+ PyBoundArrayMethodObject *bmeth = PyArrayMethod_FromSpec_int(&spec, 0);
+ if (bmeth == NULL) {
+ return -1;
+ }
+ int res = add_loop("multiply", bmeth);
+ Py_DECREF(bmeth);
+ if (res < 0) {
+ return -1;
+ }
+
+ spec.name = "sfloat_add";
+ spec.casting = NPY_SAME_KIND_CASTING;
+
+ slots[0].slot = NPY_METH_resolve_descriptors;
+ slots[0].pfunc = &add_sfloats_resolve_descriptors;
+ slots[1].slot = NPY_METH_strided_loop;
+ slots[1].pfunc = &add_sfloats;
+ bmeth = PyArrayMethod_FromSpec_int(&spec, 0);
+ if (bmeth == NULL) {
+ return -1;
+ }
+ res = add_loop("add", bmeth);
+ Py_DECREF(bmeth);
+ if (res < 0) {
+ return -1;
+ }
+ return 0;
+}
+
+
+/*
+ * Python entry point, exported via `umathmodule.h` and `multiarraymodule.c`.
+ * TODO: Should be moved when the necessary API is not internal anymore.
+ */
+NPY_NO_EXPORT PyObject *
+get_sfloat_dtype(PyObject *NPY_UNUSED(mod), PyObject *NPY_UNUSED(args))
+{
+ /* Allow calling the function multiple times. */
+ static npy_bool initalized = NPY_FALSE;
+
+ if (initalized) {
+ Py_INCREF(&PyArray_SFloatDType);
+ return (PyObject *)&PyArray_SFloatDType;
+ }
+
+ PyArray_SFloatDType.super.ht_type.tp_base = &PyArrayDescr_Type;
+
+ if (PyType_Ready((PyTypeObject *)&PyArray_SFloatDType) < 0) {
+ return NULL;
+ }
+ NPY_DT_SLOTS(&PyArray_SFloatDType)->castingimpls = PyDict_New();
+ if (NPY_DT_SLOTS(&PyArray_SFloatDType)->castingimpls == NULL) {
+ return NULL;
+ }
+
+ PyObject *o = PyObject_Init(
+ (PyObject *)&SFloatSingleton, (PyTypeObject *)&PyArray_SFloatDType);
+ if (o == NULL) {
+ return NULL;
+ }
+
+ if (init_casts() < 0) {
+ return NULL;
+ }
+
+ if (init_ufuncs() < 0) {
+ return NULL;
+ }
+
+ initalized = NPY_TRUE;
+ return (PyObject *)&PyArray_SFloatDType;
+}
diff --git a/numpy/core/src/umath/_umath_tests.c.src b/numpy/core/src/umath/_umath_tests.c.src
index 750fbeb92..2e79d377e 100644
--- a/numpy/core/src/umath/_umath_tests.c.src
+++ b/numpy/core/src/umath/_umath_tests.c.src
@@ -532,7 +532,7 @@ UMath_Tests_test_signature(PyObject *NPY_UNUSED(dummy), PyObject *args)
}
if (f->core_dim_ixs != NULL) {
core_dim_ixs = PyTuple_New(core_num_ixs);
- if (core_num_dims == NULL) {
+ if (core_dim_ixs == NULL) {
goto fail;
}
for (i = 0; i < core_num_ixs; i++) {
@@ -614,12 +614,14 @@ UMath_Tests_test_dispatch(PyObject *NPY_UNUSED(dummy), PyObject *NPY_UNUSED(dumm
if (item == NULL || PyDict_SetItemString(dict, "@str@", item) < 0) {
goto err;
}
+ Py_DECREF(item);
/**end repeat**/
item = PyList_New(0);
if (item == NULL || PyDict_SetItemString(dict, "all", item) < 0) {
goto err;
}
NPY_CPU_DISPATCH_CALL_ALL(_umath_tests_dispatch_attach, (item));
+ Py_SETREF(item, NULL);
if (PyErr_Occurred()) {
goto err;
}
diff --git a/numpy/core/src/umath/_umath_tests.dispatch.c b/numpy/core/src/umath/_umath_tests.dispatch.c
index d86a54411..85f365010 100644
--- a/numpy/core/src/umath/_umath_tests.dispatch.c
+++ b/numpy/core/src/umath/_umath_tests.dispatch.c
@@ -29,5 +29,6 @@ void NPY_CPU_DISPATCH_CURFX(_umath_tests_dispatch_attach)(PyObject *list)
PyObject *item = PyUnicode_FromString(NPY_TOSTRING(NPY_CPU_DISPATCH_CURFX(func)));
if (item) {
PyList_Append(list, item);
+ Py_DECREF(item);
}
}
diff --git a/numpy/core/src/umath/dispatching.c b/numpy/core/src/umath/dispatching.c
new file mode 100644
index 000000000..b1c5ccb6b
--- /dev/null
+++ b/numpy/core/src/umath/dispatching.c
@@ -0,0 +1,690 @@
+/*
+ * This file implements universal function dispatching and promotion (which
+ * is necessary to happen before dispatching).
+ * This is part of the UFunc object. Promotion and dispatching uses the
+ * following things:
+ *
+ * - operand_DTypes: The datatypes as passed in by the user.
+ * - signature: The DTypes fixed by the user with `dtype=` or `signature=`.
+ * - ufunc._loops: A list of all ArrayMethods and promoters, it contains
+ * tuples `(dtypes, ArrayMethod)` or `(dtypes, promoter)`.
+ * - ufunc._dispatch_cache: A cache to store previous promotion and/or
+ * dispatching results.
+ * - The actual arrays are used to support the old code paths where necessary.
+ * (this includes any value-based casting/promotion logic)
+ *
+ * In general, `operand_Dtypes` is always overridden by `signature`. If a
+ * DType is included in the `signature` it must match precisely.
+ *
+ * The process of dispatching and promotion can be summarized in the following
+ * steps:
+ *
+ * 1. Override any `operand_DTypes` from `signature`.
+ * 2. Check if the new `operand_Dtypes` is cached (if it is, got to 4.)
+ * 3. Find the best matching "loop". This is done using multiple dispatching
+ * on all `operand_DTypes` and loop `dtypes`. A matching loop must be
+ * one whose DTypes are superclasses of the `operand_DTypes` (that are
+ * defined). The best matching loop must be better than any other matching
+ * loop. This result is cached.
+ * 4. If the found loop is a promoter: We call the promoter. It can modify
+ * the `operand_DTypes` currently. Then go back to step 2.
+ * (The promoter can call arbitrary code, so it could even add the matching
+ * loop first.)
+ * 5. The final `ArrayMethod` is found, its registered `dtypes` is copied
+ * into the `signature` so that it is available to the ufunc loop.
+ *
+ */
+#include <Python.h>
+
+#define _UMATHMODULE
+#define _MULTIARRAYMODULE
+#define NPY_NO_DEPRECATED_API NPY_API_VERSION
+
+#include "numpy/ndarraytypes.h"
+#include "common.h"
+
+#include "dispatching.h"
+#include "dtypemeta.h"
+#include "npy_hashtable.h"
+#include "legacy_array_method.h"
+#include "ufunc_object.h"
+#include "ufunc_type_resolution.h"
+
+
+/* forward declaration */
+static NPY_INLINE PyObject *
+promote_and_get_info_and_ufuncimpl(PyUFuncObject *ufunc,
+ PyArrayObject *const ops[],
+ PyArray_DTypeMeta *signature[],
+ PyArray_DTypeMeta *op_dtypes[],
+ npy_bool allow_legacy_promotion, npy_bool cache);
+
+
+/**
+ * Function to add a new loop to the ufunc. This mainly appends it to the
+ * list (as it currently is just a list).
+ *
+ * @param ufunc The universal function to add the loop to.
+ * @param info The tuple (dtype_tuple, ArrayMethod/promoter).
+ * @param ignore_duplicate If 1 and a loop with the same `dtype_tuple` is
+ * found, the function does nothing.
+ */
+NPY_NO_EXPORT int
+PyUFunc_AddLoop(PyUFuncObject *ufunc, PyObject *info, int ignore_duplicate)
+{
+ /*
+ * Validate the info object, this should likely move to to a different
+ * entry-point in the future (and is mostly unnecessary currently).
+ */
+ if (!PyTuple_CheckExact(info) || PyTuple_GET_SIZE(info) != 2) {
+ PyErr_SetString(PyExc_TypeError,
+ "Info must be a tuple: "
+ "(tuple of DTypes or None, ArrayMethod or promoter)");
+ return -1;
+ }
+ PyObject *DType_tuple = PyTuple_GetItem(info, 0);
+ if (PyTuple_GET_SIZE(DType_tuple) != ufunc->nargs) {
+ PyErr_SetString(PyExc_TypeError,
+ "DType tuple length does not match ufunc number of operands");
+ return -1;
+ }
+ for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(DType_tuple); i++) {
+ PyObject *item = PyTuple_GET_ITEM(DType_tuple, i);
+ if (item != Py_None
+ && !PyObject_TypeCheck(item, &PyArrayDTypeMeta_Type)) {
+ PyErr_SetString(PyExc_TypeError,
+ "DType tuple may only contain None and DType classes");
+ return -1;
+ }
+ }
+ if (!PyObject_TypeCheck(PyTuple_GET_ITEM(info, 1), &PyArrayMethod_Type)) {
+ /* Must also accept promoters in the future. */
+ PyErr_SetString(PyExc_TypeError,
+ "Second argument to info must be an ArrayMethod or promoter");
+ return -1;
+ }
+
+ if (ufunc->_loops == NULL) {
+ ufunc->_loops = PyList_New(0);
+ if (ufunc->_loops == NULL) {
+ return -1;
+ }
+ }
+
+ PyObject *loops = ufunc->_loops;
+ Py_ssize_t length = PyList_Size(loops);
+ for (Py_ssize_t i = 0; i < length; i++) {
+ PyObject *item = PyList_GetItem(loops, i);
+ PyObject *cur_DType_tuple = PyTuple_GetItem(item, 0);
+ int cmp = PyObject_RichCompareBool(cur_DType_tuple, DType_tuple, Py_EQ);
+ if (cmp < 0) {
+ return -1;
+ }
+ if (cmp == 0) {
+ continue;
+ }
+ if (ignore_duplicate) {
+ return 0;
+ }
+ PyErr_Format(PyExc_TypeError,
+ "A loop/promoter has already been registered with '%s' for %R",
+ ufunc_get_name_cstr(ufunc), DType_tuple);
+ return -1;
+ }
+
+ if (PyList_Append(loops, info) < 0) {
+ return -1;
+ }
+ return 0;
+}
+
+
+/**
+ * Resolves the implementation to use, this uses typical multiple dispatching
+ * methods of finding the best matching implementation or resolver.
+ * (Based on `isinstance()`, the knowledge that non-abstract DTypes cannot
+ * be subclassed is used, however.)
+ *
+ * @param ufunc
+ * @param op_dtypes The DTypes that are either passed in (defined by an
+ * operand) or defined by the `signature` as also passed in as
+ * `fixed_DTypes`.
+ * @param out_info Returns the tuple describing the best implementation
+ * (consisting of dtypes and ArrayMethod or promoter).
+ * WARNING: Returns a borrowed reference!
+ * @returns -1 on error 0 on success. Note that the output can be NULL on
+ * success if nothing is found.
+ */
+static int
+resolve_implementation_info(PyUFuncObject *ufunc,
+ PyArray_DTypeMeta *op_dtypes[], PyObject **out_info)
+{
+ int nin = ufunc->nin, nargs = ufunc->nargs;
+ Py_ssize_t size = PySequence_Length(ufunc->_loops);
+ PyObject *best_dtypes = NULL;
+ PyObject *best_resolver_info = NULL;
+
+ for (Py_ssize_t res_idx = 0; res_idx < size; res_idx++) {
+ /* Test all resolvers */
+ PyObject *resolver_info = PySequence_Fast_GET_ITEM(
+ ufunc->_loops, res_idx);
+ PyObject *curr_dtypes = PyTuple_GET_ITEM(resolver_info, 0);
+ /*
+ * Test if the current resolver matches, it could make sense to
+ * reorder these checks to avoid the IsSubclass check as much as
+ * possible.
+ */
+
+ npy_bool matches = NPY_TRUE;
+ /*
+ * NOTE: We check also the output DType. In principle we do not
+ * have to strictly match it (unless it is provided by the
+ * `signature`). This assumes that a (fallback) promoter will
+ * unset the output DType if no exact match is found.
+ */
+ for (Py_ssize_t i = 0; i < nargs; i++) {
+ PyArray_DTypeMeta *given_dtype = op_dtypes[i];
+ PyArray_DTypeMeta *resolver_dtype = (
+ (PyArray_DTypeMeta *)PyTuple_GET_ITEM(curr_dtypes, i));
+ assert((PyObject *)given_dtype != Py_None);
+ if (given_dtype == NULL && i >= nin) {
+ /* Unspecified out always matches (see below for inputs) */
+ continue;
+ }
+ if (given_dtype == resolver_dtype) {
+ continue;
+ }
+ if (!NPY_DT_is_abstract(resolver_dtype)) {
+ matches = NPY_FALSE;
+ break;
+ }
+ if (given_dtype == NULL) {
+ /*
+ * If an input was not specified, this is a reduce-like
+ * operation: reductions use `(operand_DType, NULL, out_DType)`
+ * as they only have a single operand. This allows special
+ * reduce promotion rules useful for example for sum/product.
+ * E.g. `np.add.reduce([True, True])` promotes to integer.
+ *
+ * Continuing here allows a promoter to handle reduce-like
+ * promotions explicitly if necessary.
+ * TODO: The `!NPY_DT_is_abstract(resolver_dtype)` currently
+ * ensures that this is a promoter. If we allow
+ * `ArrayMethods` to use abstract DTypes, we may have to
+ * reject it here or the `ArrayMethod` has to implement
+ * the reduce promotion.
+ */
+ continue;
+ }
+ int subclass = PyObject_IsSubclass(
+ (PyObject *)given_dtype, (PyObject *)resolver_dtype);
+ if (subclass < 0) {
+ return -1;
+ }
+ if (!subclass) {
+ matches = NPY_FALSE;
+ break;
+ }
+ /*
+ * TODO: Could consider allowing reverse subclass relation, i.e.
+ * the operation DType passed in to be abstract. That
+ * definitely is OK for outputs (and potentially useful,
+ * you could enforce e.g. an inexact result).
+ * It might also be useful for some stranger promoters.
+ */
+ }
+ if (!matches) {
+ continue;
+ }
+
+ /* The resolver matches, but we have to check if it is better */
+ if (best_dtypes != NULL) {
+ int current_best = -1; /* -1 neither, 0 current best, 1 new */
+ /*
+ * If both have concrete and None in the same position and
+ * they are identical, we will continue searching using the
+ * first best for comparison, in an attempt to find a better
+ * one.
+ * In all cases, we give up resolution, since it would be
+ * necessary to compare to two "best" cases.
+ */
+ int unambiguously_equally_good = 1;
+ for (Py_ssize_t i = 0; i < nargs; i++) {
+ int best;
+
+ PyObject *prev_dtype = PyTuple_GET_ITEM(best_dtypes, i);
+ PyObject *new_dtype = PyTuple_GET_ITEM(curr_dtypes, i);
+
+ if (prev_dtype == new_dtype) {
+ /* equivalent, so this entry does not matter */
+ continue;
+ }
+ /*
+ * TODO: Even if the input is not specified, if we have
+ * abstract DTypes and one is a subclass of the other,
+ * the subclass should be considered a better match
+ * (subclasses are always more specific).
+ */
+ /* If either is None, the other is strictly more specific */
+ if (prev_dtype == Py_None) {
+ unambiguously_equally_good = 0;
+ best = 1;
+ }
+ else if (new_dtype == Py_None) {
+ unambiguously_equally_good = 0;
+ best = 0;
+ }
+ /*
+ * If both are concrete and not identical, this is
+ * ambiguous.
+ */
+ else if (!NPY_DT_is_abstract((PyArray_DTypeMeta *)prev_dtype) &&
+ !NPY_DT_is_abstract((PyArray_DTypeMeta *)new_dtype)) {
+ /*
+ * Ambiguous unless the are identical (checked above),
+ * but since they are concrete it does not matter which
+ * best to compare.
+ */
+ best = -1;
+ }
+ /*
+ * TODO: Unreachable, but we will need logic for abstract
+ * DTypes to decide if one is a subclass of the other
+ * (And their subclass relation is well defined.)
+ */
+ else {
+ assert(0);
+ }
+
+ if ((current_best != -1) && (current_best != best)) {
+ /*
+ * We need a clear best, this could be tricky, unless
+ * the signature is identical, we would have to compare
+ * against both of the found ones until we find a
+ * better one.
+ * Instead, only support the case where they are
+ * identical.
+ */
+ /* TODO: Document the above comment, may need relaxing? */
+ current_best = -1;
+ break;
+ }
+ current_best = best;
+ }
+
+ if (current_best == -1) {
+ /*
+ * TODO: It would be nice to have a "diagnostic mode" that
+ * informs if this happens! (An immediate error currently
+ * blocks later legacy resolution, but may work in the
+ * future.)
+ */
+ if (unambiguously_equally_good) {
+ /* unset the best resolver to indicate this */
+ best_resolver_info = NULL;
+ continue;
+ }
+ *out_info = NULL;
+ return 0;
+ }
+ else if (current_best == 0) {
+ /* The new match is not better, continue looking. */
+ continue;
+ }
+ }
+ /* The new match is better (or there was no previous match) */
+ best_dtypes = curr_dtypes;
+ best_resolver_info = resolver_info;
+ }
+ if (best_dtypes == NULL) {
+ /* The non-legacy lookup failed */
+ *out_info = NULL;
+ return 0;
+ }
+
+ *out_info = best_resolver_info;
+ return 0;
+}
+
+
+/*
+ * A promoter can currently be either a C-Capsule containing a promoter
+ * function pointer, or a Python function. Both of these can at this time
+ * only return new operation DTypes (i.e. mutate the input while leaving
+ * those defined by the `signature` unmodified).
+ */
+static PyObject *
+call_promoter_and_recurse(
+ PyUFuncObject *NPY_UNUSED(ufunc), PyObject *NPY_UNUSED(promoter),
+ PyArray_DTypeMeta *NPY_UNUSED(op_dtypes[]),
+ PyArray_DTypeMeta *NPY_UNUSED(signature[]),
+ PyArrayObject *const NPY_UNUSED(operands[]))
+{
+ PyErr_SetString(PyExc_NotImplementedError,
+ "Internal NumPy error, promoters are not used/implemented yet.");
+ return NULL;
+}
+
+
+/*
+ * Convert the DType `signature` into the tuple of descriptors that is used
+ * by the old ufunc type resolvers in `ufunc_type_resolution.c`.
+ *
+ * Note that we do not need to pass the type tuple when we use the legacy path
+ * for type resolution rather than promotion, since the signature is always
+ * correct in that case.
+ */
+static int
+_make_new_typetup(
+ int nop, PyArray_DTypeMeta *signature[], PyObject **out_typetup) {
+ *out_typetup = PyTuple_New(nop);
+ if (*out_typetup == NULL) {
+ return -1;
+ }
+
+ int none_count = 0;
+ for (int i = 0; i < nop; i++) {
+ PyObject *item;
+ if (signature[i] == NULL) {
+ item = Py_None;
+ none_count++;
+ }
+ else {
+ if (!NPY_DT_is_legacy(signature[i])
+ || NPY_DT_is_abstract(signature[i])) {
+ /*
+ * The legacy type resolution can't deal with these.
+ * This path will return `None` or so in the future to
+ * set an error later if the legacy type resolution is used.
+ */
+ PyErr_SetString(PyExc_RuntimeError,
+ "Internal NumPy error: new DType in signature not yet "
+ "supported. (This should be unreachable code!)");
+ Py_SETREF(*out_typetup, NULL);
+ return -1;
+ }
+ item = (PyObject *)signature[i]->singleton;
+ }
+ Py_INCREF(item);
+ PyTuple_SET_ITEM(*out_typetup, i, item);
+ }
+ if (none_count == nop) {
+ /* The whole signature was None, simply ignore type tuple */
+ Py_DECREF(*out_typetup);
+ *out_typetup = NULL;
+ }
+ return 0;
+}
+
+
+/*
+ * Fills in the operation_DTypes with borrowed references. This may change
+ * the content, since it will use the legacy type resolution, which can special
+ * case 0-D arrays (using value-based logic).
+ */
+static int
+legacy_promote_using_legacy_type_resolver(PyUFuncObject *ufunc,
+ PyArrayObject *const *ops, PyArray_DTypeMeta *signature[],
+ PyArray_DTypeMeta *operation_DTypes[], int *out_cacheable)
+{
+ int nargs = ufunc->nargs;
+ PyArray_Descr *out_descrs[NPY_MAXARGS] = {NULL};
+
+ PyObject *type_tuple = NULL;
+ if (_make_new_typetup(nargs, signature, &type_tuple) < 0) {
+ return -1;
+ }
+
+ /*
+ * We use unsafe casting. This is of course not accurate, but that is OK
+ * here, because for promotion/dispatching the casting safety makes no
+ * difference. Whether the actual operands can be casts must be checked
+ * during the type resolution step (which may _also_ calls this!).
+ */
+ if (ufunc->type_resolver(ufunc,
+ NPY_UNSAFE_CASTING, (PyArrayObject **)ops, type_tuple,
+ out_descrs) < 0) {
+ Py_XDECREF(type_tuple);
+ return -1;
+ }
+ Py_XDECREF(type_tuple);
+
+ for (int i = 0; i < nargs; i++) {
+ Py_XSETREF(operation_DTypes[i], NPY_DTYPE(out_descrs[i]));
+ Py_INCREF(operation_DTypes[i]);
+ Py_DECREF(out_descrs[i]);
+ }
+ if (ufunc->type_resolver == &PyUFunc_SimpleBinaryComparisonTypeResolver) {
+ /*
+ * In this one case, the deprecation means that we actually override
+ * the signature.
+ */
+ for (int i = 0; i < nargs; i++) {
+ if (signature[i] != NULL && signature[i] != operation_DTypes[i]) {
+ Py_INCREF(operation_DTypes[i]);
+ Py_SETREF(signature[i], operation_DTypes[i]);
+ *out_cacheable = 0;
+ }
+ }
+ }
+ return 0;
+}
+
+
+/*
+ * Note, this function returns a BORROWED references to info since it adds
+ * it to the loops.
+ */
+NPY_NO_EXPORT PyObject *
+add_and_return_legacy_wrapping_ufunc_loop(PyUFuncObject *ufunc,
+ PyArray_DTypeMeta *operation_dtypes[], int ignore_duplicate)
+{
+ PyObject *DType_tuple = PyArray_TupleFromItems(ufunc->nargs,
+ (PyObject **)operation_dtypes, 0);
+ if (DType_tuple == NULL) {
+ return NULL;
+ }
+
+ PyArrayMethodObject *method = PyArray_NewLegacyWrappingArrayMethod(
+ ufunc, operation_dtypes);
+ if (method == NULL) {
+ Py_DECREF(DType_tuple);
+ return NULL;
+ }
+ PyObject *info = PyTuple_Pack(2, DType_tuple, method);
+ Py_DECREF(DType_tuple);
+ Py_DECREF(method);
+ if (info == NULL) {
+ return NULL;
+ }
+ if (PyUFunc_AddLoop(ufunc, info, ignore_duplicate) < 0) {
+ Py_DECREF(info);
+ return NULL;
+ }
+
+ return info;
+}
+
+
+/*
+ * The main implementation to find the correct DType signature and ArrayMethod
+ * to use for a ufunc. This function may recurse with `do_legacy_fallback`
+ * set to False.
+ *
+ * If value-based promotion is necessary, this is handled ahead of time by
+ * `promote_and_get_ufuncimpl`.
+ */
+static NPY_INLINE PyObject *
+promote_and_get_info_and_ufuncimpl(PyUFuncObject *ufunc,
+ PyArrayObject *const ops[],
+ PyArray_DTypeMeta *signature[],
+ PyArray_DTypeMeta *op_dtypes[],
+ npy_bool allow_legacy_promotion, npy_bool cache)
+{
+ /*
+ * Fetch the dispatching info which consists of the implementation and
+ * the DType signature tuple. There are three steps:
+ *
+ * 1. Check the cache.
+ * 2. Check all registered loops/promoters to find the best match.
+ * 3. Fall back to the legacy implementation if no match was found.
+ */
+ PyObject *info = PyArrayIdentityHash_GetItem(ufunc->_dispatch_cache,
+ (PyObject **)op_dtypes);
+ if (info != NULL && PyObject_TypeCheck(
+ PyTuple_GET_ITEM(info, 1), &PyArrayMethod_Type)) {
+ /* Found the ArrayMethod and NOT a promoter: return it */
+ return info;
+ }
+
+ /*
+ * If `info == NULL`, the caching failed, repeat using the full resolution
+ * in `resolve_implementation_info`.
+ */
+ if (info == NULL) {
+ if (resolve_implementation_info(ufunc, op_dtypes, &info) < 0) {
+ return NULL;
+ }
+ if (info != NULL && PyObject_TypeCheck(
+ PyTuple_GET_ITEM(info, 1), &PyArrayMethod_Type)) {
+ /*
+ * Found the ArrayMethod and NOT promoter. Before returning it
+ * add it to the cache for faster lookup in the future.
+ */
+ if (cache && PyArrayIdentityHash_SetItem(ufunc->_dispatch_cache,
+ (PyObject **)op_dtypes, info, 0) < 0) {
+ return NULL;
+ }
+ return info;
+ }
+ }
+
+ /*
+ * At this point `info` is NULL if there is no matching loop, or it is
+ * a promoter that needs to be used/called:
+ */
+ if (info != NULL) {
+ PyObject *promoter = PyTuple_GET_ITEM(info, 1);
+
+ info = call_promoter_and_recurse(ufunc,
+ promoter, op_dtypes, signature, ops);
+ if (info == NULL && PyErr_Occurred()) {
+ return NULL;
+ }
+ else if (info != NULL) {
+ return info;
+ }
+ }
+
+ /*
+ * Even using promotion no loop was found.
+ * Using promotion failed, this should normally be an error.
+ * However, we need to give the legacy implementation a chance here.
+ * (it will modify `op_dtypes`).
+ */
+ if (!allow_legacy_promotion || ufunc->type_resolver == NULL ||
+ (ufunc->ntypes == 0 && ufunc->userloops == NULL)) {
+ /* Already tried or not a "legacy" ufunc (no loop found, return) */
+ return NULL;
+ }
+
+ PyArray_DTypeMeta *new_op_dtypes[NPY_MAXARGS] = {NULL};
+ int cacheable = 1; /* TODO: only the comparison deprecation needs this */
+ if (legacy_promote_using_legacy_type_resolver(ufunc,
+ ops, signature, new_op_dtypes, &cacheable) < 0) {
+ return NULL;
+ }
+ info = promote_and_get_info_and_ufuncimpl(ufunc,
+ ops, signature, new_op_dtypes, NPY_FALSE, cacheable);
+ for (int i = 0; i < ufunc->nargs; i++) {
+ Py_XDECREF(new_op_dtypes);
+ }
+ return info;
+}
+
+
+/**
+ * The central entry-point for the promotion and dispatching machinery.
+ *
+ * It currently may work with the operands (although it would be possible to
+ * only work with DType (classes/types). This is because it has to ensure
+ * that legacy (value-based promotion) is used when necessary.
+ *
+ * @param ufunc The ufunc object, used mainly for the fallback.
+ * @param ops The array operands (used only for the fallback).
+ * @param signature As input, the DType signature fixed explicitly by the user.
+ * The signature is *filled* in with the operation signature we end up
+ * using.
+ * @param op_dtypes The operand DTypes (without casting) which are specified
+ * either by the `signature` or by an `operand`.
+ * (outputs and the second input can be NULL for reductions).
+ * NOTE: In some cases, the promotion machinery may currently modify
+ * these.
+ * @param force_legacy_promotion If set, we have to use the old type resolution
+ * to implement value-based promotion/casting.
+ */
+NPY_NO_EXPORT PyArrayMethodObject *
+promote_and_get_ufuncimpl(PyUFuncObject *ufunc,
+ PyArrayObject *const ops[],
+ PyArray_DTypeMeta *signature[],
+ PyArray_DTypeMeta *op_dtypes[],
+ npy_bool force_legacy_promotion,
+ npy_bool allow_legacy_promotion)
+{
+ int nargs = ufunc->nargs;
+
+ /*
+ * Get the actual DTypes we operate with by mixing the operand array
+ * ones with the passed signature.
+ */
+ for (int i = 0; i < nargs; i++) {
+ if (signature[i] != NULL) {
+ /*
+ * ignore the operand input, we cannot overwrite signature yet
+ * since it is fixed (cannot be promoted!)
+ */
+ Py_INCREF(signature[i]);
+ Py_XSETREF(op_dtypes[i], signature[i]);
+ assert(i >= ufunc->nin || !NPY_DT_is_abstract(signature[i]));
+ }
+ }
+
+ if (force_legacy_promotion) {
+ /*
+ * We must use legacy promotion for value-based logic. Call the old
+ * resolver once up-front to get the "actual" loop dtypes.
+ * After this (additional) promotion, we can even use normal caching.
+ */
+ int cacheable = 1; /* unused, as we modify the original `op_dtypes` */
+ if (legacy_promote_using_legacy_type_resolver(ufunc,
+ ops, signature, op_dtypes, &cacheable) < 0) {
+ return NULL;
+ }
+ }
+
+ PyObject *info = promote_and_get_info_and_ufuncimpl(ufunc,
+ ops, signature, op_dtypes, allow_legacy_promotion, NPY_TRUE);
+
+ if (info == NULL) {
+ if (!PyErr_Occurred()) {
+ raise_no_loop_found_error(ufunc, (PyObject **)op_dtypes);
+ }
+ return NULL;
+ }
+
+ PyArrayMethodObject *method = (PyArrayMethodObject *)PyTuple_GET_ITEM(info, 1);
+
+ /* Fill `signature` with final DTypes used by the ArrayMethod/inner-loop */
+ PyObject *all_dtypes = PyTuple_GET_ITEM(info, 0);
+ for (int i = 0; i < nargs; i++) {
+ if (signature[i] == NULL) {
+ signature[i] = (PyArray_DTypeMeta *)PyTuple_GET_ITEM(all_dtypes, i);
+ Py_INCREF(signature[i]);
+ }
+ else {
+ assert((PyObject *)signature[i] == PyTuple_GET_ITEM(all_dtypes, i));
+ }
+ }
+
+ return method;
+}
diff --git a/numpy/core/src/umath/dispatching.h b/numpy/core/src/umath/dispatching.h
new file mode 100644
index 000000000..b01bc79fa
--- /dev/null
+++ b/numpy/core/src/umath/dispatching.h
@@ -0,0 +1,25 @@
+#ifndef _NPY_DISPATCHING_H
+#define _NPY_DISPATCHING_H
+
+#define _UMATHMODULE
+
+#include <numpy/ufuncobject.h>
+#include "array_method.h"
+
+
+NPY_NO_EXPORT int
+PyUFunc_AddLoop(PyUFuncObject *ufunc, PyObject *info, int ignore_duplicate);
+
+NPY_NO_EXPORT PyArrayMethodObject *
+promote_and_get_ufuncimpl(PyUFuncObject *ufunc,
+ PyArrayObject *const ops[],
+ PyArray_DTypeMeta *signature[],
+ PyArray_DTypeMeta *op_dtypes[],
+ npy_bool force_legacy_promotion,
+ npy_bool allow_legacy_promotion);
+
+NPY_NO_EXPORT PyObject *
+add_and_return_legacy_wrapping_ufunc_loop(PyUFuncObject *ufunc,
+ PyArray_DTypeMeta *operation_dtypes[], int ignore_duplicate);
+
+#endif /*_NPY_DISPATCHING_H */
diff --git a/numpy/core/src/umath/fast_loop_macros.h b/numpy/core/src/umath/fast_loop_macros.h
index 74bf01643..4a36c9721 100644
--- a/numpy/core/src/umath/fast_loop_macros.h
+++ b/numpy/core/src/umath/fast_loop_macros.h
@@ -10,6 +10,21 @@
#ifndef _NPY_UMATH_FAST_LOOP_MACROS_H_
#define _NPY_UMATH_FAST_LOOP_MACROS_H_
+/*
+ * MAX_STEP_SIZE is used to determine if we need to use SIMD version of the ufunc.
+ * Very large step size can be as slow as processing it using scalar. The
+ * value of 2097152 ( = 2MB) was chosen using 2 considerations:
+ * 1) Typical linux kernel page size is 4Kb, but sometimes it could also be 2MB
+ * which is == 2097152 Bytes. For a step size as large as this, surely all
+ * the loads/stores of gather/scatter instructions falls on 16 different pages
+ * which one would think would slow down gather/scatter instructions.
+ * 2) It additionally satisfies MAX_STEP_SIZE*16/esize < NPY_MAX_INT32 which
+ * allows us to use i32 version of gather/scatter (as opposed to the i64 version)
+ * without problems (step larger than NPY_MAX_INT32*esize/16 would require use of
+ * i64gather/scatter). esize = element size = 4/8 bytes for float/double.
+ */
+#define MAX_STEP_SIZE 2097152
+
static NPY_INLINE npy_uintp
abs_ptrdiff(char *a, char *b)
{
@@ -46,14 +61,20 @@ abs_ptrdiff(char *a, char *b)
npy_intp i;\
for(i = 0; i < n; i++, ip1 += is1, op1 += os1, op2 += os2)
-/** (ip1, ip2) -> (op1) */
-#define BINARY_LOOP\
+#define BINARY_DEFS\
char *ip1 = args[0], *ip2 = args[1], *op1 = args[2];\
npy_intp is1 = steps[0], is2 = steps[1], os1 = steps[2];\
npy_intp n = dimensions[0];\
npy_intp i;\
+
+#define BINARY_LOOP_SLIDING\
for(i = 0; i < n; i++, ip1 += is1, ip2 += is2, op1 += os1)
+/** (ip1, ip2) -> (op1) */
+#define BINARY_LOOP\
+ BINARY_DEFS\
+ BINARY_LOOP_SLIDING
+
/** (ip1, ip2) -> (op1, op2) */
#define BINARY_LOOP_TWO_OUT\
char *ip1 = args[0], *ip2 = args[1], *op1 = args[2], *op2 = args[3];\
@@ -155,10 +176,7 @@ abs_ptrdiff(char *a, char *b)
#define IVDEP_LOOP
#endif
#define BASE_BINARY_LOOP_INP(tin, tout, op) \
- char *ip1 = args[0], *ip2 = args[1], *op1 = args[2];\
- npy_intp is1 = steps[0], is2 = steps[1], os1 = steps[2];\
- npy_intp n = dimensions[0];\
- npy_intp i;\
+ BINARY_DEFS\
IVDEP_LOOP \
for(i = 0; i < n; i++, ip1 += is1, ip2 += is2, op1 += os1) { \
const tin in1 = *(tin *)ip1; \
@@ -234,5 +252,117 @@ abs_ptrdiff(char *a, char *b)
TYPE io1 = *(TYPE *)iop1; \
BINARY_REDUCE_LOOP_INNER
+#define IS_BINARY_STRIDE_ONE(esize, vsize) \
+ ((steps[0] == esize) && \
+ (steps[1] == esize) && \
+ (steps[2] == esize) && \
+ (abs_ptrdiff(args[2], args[0]) >= vsize) && \
+ (abs_ptrdiff(args[2], args[1]) >= vsize))
+
+/*
+ * stride is equal to element size and input and destination are equal or
+ * don't overlap within one register. The check of the steps against
+ * esize also quarantees that steps are >= 0.
+ */
+#define IS_BLOCKABLE_UNARY(esize, vsize) \
+ (steps[0] == (esize) && steps[0] == steps[1] && \
+ (npy_is_aligned(args[0], esize) && npy_is_aligned(args[1], esize)) && \
+ ((abs_ptrdiff(args[1], args[0]) >= (vsize)) || \
+ ((abs_ptrdiff(args[1], args[0]) == 0))))
+
+/*
+ * Avoid using SIMD for very large step sizes for several reasons:
+ * 1) Supporting large step sizes requires use of i64gather/scatter_ps instructions,
+ * in which case we need two i64gather instructions and an additional vinsertf32x8
+ * instruction to load a single zmm register (since one i64gather instruction
+ * loads into a ymm register). This is not ideal for performance.
+ * 2) Gather and scatter instructions can be slow when the loads/stores
+ * cross page boundaries.
+ *
+ * We instead rely on i32gather/scatter_ps instructions which use a 32-bit index
+ * element. The index needs to be < INT_MAX to avoid overflow. MAX_STEP_SIZE
+ * ensures this. The condition also requires that the input and output arrays
+ * should have no overlap in memory.
+ */
+#define IS_BINARY_SMALL_STEPS_AND_NOMEMOVERLAP \
+ ((labs(steps[0]) < MAX_STEP_SIZE) && \
+ (labs(steps[1]) < MAX_STEP_SIZE) && \
+ (labs(steps[2]) < MAX_STEP_SIZE) && \
+ (nomemoverlap(args[0], steps[0] * dimensions[0], args[2], steps[2] * dimensions[0])) && \
+ (nomemoverlap(args[1], steps[1] * dimensions[0], args[2], steps[2] * dimensions[0])))
+
+#define IS_UNARY_TWO_OUT_SMALL_STEPS_AND_NOMEMOVERLAP \
+ ((labs(steps[0]) < MAX_STEP_SIZE) && \
+ (labs(steps[1]) < MAX_STEP_SIZE) && \
+ (labs(steps[2]) < MAX_STEP_SIZE) && \
+ (nomemoverlap(args[0], steps[0] * dimensions[0], args[2], steps[2] * dimensions[0])) && \
+ (nomemoverlap(args[0], steps[0] * dimensions[0], args[1], steps[1] * dimensions[0])))
+
+/*
+ * 1) Output should be contiguous, can handle strided input data
+ * 2) Input step should be smaller than MAX_STEP_SIZE for performance
+ * 3) Input and output arrays should have no overlap in memory
+ */
+#define IS_OUTPUT_BLOCKABLE_UNARY(esizein, esizeout, vsize) \
+ ((steps[0] & (esizein-1)) == 0 && \
+ steps[1] == (esizeout) && llabs(steps[0]) < MAX_STEP_SIZE && \
+ (nomemoverlap(args[1], steps[1] * dimensions[0], args[0], steps[0] * dimensions[0])))
+
+#define IS_BLOCKABLE_REDUCE(esize, vsize) \
+ (steps[1] == (esize) && abs_ptrdiff(args[1], args[0]) >= (vsize) && \
+ npy_is_aligned(args[1], (esize)) && \
+ npy_is_aligned(args[0], (esize)))
+
+#define IS_BLOCKABLE_BINARY(esize, vsize) \
+ (steps[0] == steps[1] && steps[1] == steps[2] && steps[2] == (esize) && \
+ npy_is_aligned(args[2], (esize)) && npy_is_aligned(args[1], (esize)) && \
+ npy_is_aligned(args[0], (esize)) && \
+ (abs_ptrdiff(args[2], args[0]) >= (vsize) || \
+ abs_ptrdiff(args[2], args[0]) == 0) && \
+ (abs_ptrdiff(args[2], args[1]) >= (vsize) || \
+ abs_ptrdiff(args[2], args[1]) >= 0))
+
+#define IS_BLOCKABLE_BINARY_SCALAR1(esize, vsize) \
+ (steps[0] == 0 && steps[1] == steps[2] && steps[2] == (esize) && \
+ npy_is_aligned(args[2], (esize)) && npy_is_aligned(args[1], (esize)) && \
+ ((abs_ptrdiff(args[2], args[1]) >= (vsize)) || \
+ (abs_ptrdiff(args[2], args[1]) == 0)) && \
+ abs_ptrdiff(args[2], args[0]) >= (esize))
+
+#define IS_BLOCKABLE_BINARY_SCALAR2(esize, vsize) \
+ (steps[1] == 0 && steps[0] == steps[2] && steps[2] == (esize) && \
+ npy_is_aligned(args[2], (esize)) && npy_is_aligned(args[0], (esize)) && \
+ ((abs_ptrdiff(args[2], args[0]) >= (vsize)) || \
+ (abs_ptrdiff(args[2], args[0]) == 0)) && \
+ abs_ptrdiff(args[2], args[1]) >= (esize))
+
+#undef abs_ptrdiff
+
+#define IS_BLOCKABLE_BINARY_BOOL(esize, vsize) \
+ (steps[0] == (esize) && steps[0] == steps[1] && steps[2] == (1) && \
+ npy_is_aligned(args[1], (esize)) && \
+ npy_is_aligned(args[0], (esize)))
+
+#define IS_BLOCKABLE_BINARY_SCALAR1_BOOL(esize, vsize) \
+ (steps[0] == 0 && steps[1] == (esize) && steps[2] == (1) && \
+ npy_is_aligned(args[1], (esize)))
+
+#define IS_BLOCKABLE_BINARY_SCALAR2_BOOL(esize, vsize) \
+ (steps[0] == (esize) && steps[1] == 0 && steps[2] == (1) && \
+ npy_is_aligned(args[0], (esize)))
+
+/* align var to alignment */
+#define LOOP_BLOCK_ALIGN_VAR(var, type, alignment)\
+ npy_intp i, peel = npy_aligned_block_offset(var, sizeof(type),\
+ alignment, n);\
+ for(i = 0; i < peel; i++)
+
+#define LOOP_BLOCKED(type, vsize)\
+ for(; i < npy_blocked_end(peel, sizeof(type), vsize, n);\
+ i += (vsize / sizeof(type)))
+
+#define LOOP_BLOCKED_END\
+ for (; i < n; i++)
+
#endif /* _NPY_UMATH_FAST_LOOP_MACROS_H_ */
diff --git a/numpy/core/src/umath/legacy_array_method.c b/numpy/core/src/umath/legacy_array_method.c
new file mode 100644
index 000000000..a5e123baa
--- /dev/null
+++ b/numpy/core/src/umath/legacy_array_method.c
@@ -0,0 +1,258 @@
+/*
+ * This file defines most of the machinery in order to wrap legacy style
+ * ufunc loops into new style arraymethods.
+ */
+
+#include <Python.h>
+
+#define _UMATHMODULE
+#define _MULTIARRAYMODULE
+#define NPY_NO_DEPRECATED_API NPY_API_VERSION
+#include "numpy/ndarraytypes.h"
+
+#include "convert_datatype.h"
+#include "array_method.h"
+#include "dtype_transfer.h"
+#include "legacy_array_method.h"
+#include "dtypemeta.h"
+
+
+typedef struct {
+ NpyAuxData base;
+ /* The legacy loop and additional user data: */
+ PyUFuncGenericFunction loop;
+ void *user_data;
+ /* Whether to check for PyErr_Occurred(), must require GIL if used */
+ int pyerr_check;
+} legacy_array_method_auxdata;
+
+
+/* Use a free list, since we should normally only need one at a time */
+#define NPY_LOOP_DATA_CACHE_SIZE 5
+static int loop_data_num_cached = 0;
+static legacy_array_method_auxdata *loop_data_cache[NPY_LOOP_DATA_CACHE_SIZE];
+
+
+static void
+legacy_array_method_auxdata_free(NpyAuxData *data)
+{
+ if (loop_data_num_cached < NPY_LOOP_DATA_CACHE_SIZE) {
+ loop_data_cache[loop_data_num_cached] = (
+ (legacy_array_method_auxdata *)data);
+ loop_data_num_cached++;
+ }
+ else {
+ PyMem_Free(data);
+ }
+}
+
+#undef NPY_LOOP_DATA_CACHE_SIZE
+
+
+NpyAuxData *
+get_new_loop_data(
+ PyUFuncGenericFunction loop, void *user_data, int pyerr_check)
+{
+ legacy_array_method_auxdata *data;
+ if (NPY_LIKELY(loop_data_num_cached > 0)) {
+ loop_data_num_cached--;
+ data = loop_data_cache[loop_data_num_cached];
+ }
+ else {
+ data = PyMem_Malloc(sizeof(legacy_array_method_auxdata));
+ if (data == NULL) {
+ return NULL;
+ }
+ data->base.free = legacy_array_method_auxdata_free;
+ data->base.clone = NULL; /* no need for cloning (at least for now) */
+ }
+ data->loop = loop;
+ data->user_data = user_data;
+ data->pyerr_check = pyerr_check;
+ return (NpyAuxData *)data;
+}
+
+
+/*
+ * This is a thin wrapper around the legacy loop signature.
+ */
+static int
+generic_wrapped_legacy_loop(PyArrayMethod_Context *NPY_UNUSED(context),
+ char *const *data, const npy_intp *dimensions, const npy_intp *strides,
+ NpyAuxData *auxdata)
+{
+ legacy_array_method_auxdata *ldata = (legacy_array_method_auxdata *)auxdata;
+
+ ldata->loop((char **)data, dimensions, strides, ldata->user_data);
+ if (ldata->pyerr_check && PyErr_Occurred()) {
+ return -1;
+ }
+ return 0;
+}
+
+
+/*
+ * Signal that the old type-resolution function must be used to resolve
+ * the descriptors (mainly/only used for datetimes due to the unit).
+ *
+ * ArrayMethod's are expected to implement this, but it is too tricky
+ * to support properly. So we simply set an error that should never be seen.
+ */
+NPY_NO_EXPORT NPY_CASTING
+wrapped_legacy_resolve_descriptors(PyArrayMethodObject *NPY_UNUSED(self),
+ PyArray_DTypeMeta *NPY_UNUSED(dtypes[]),
+ PyArray_Descr *NPY_UNUSED(given_descrs[]),
+ PyArray_Descr *NPY_UNUSED(loop_descrs[]))
+{
+ PyErr_SetString(PyExc_RuntimeError,
+ "cannot use legacy wrapping ArrayMethod without calling the ufunc "
+ "itself. If this error is hit, the solution will be to port the "
+ "legacy ufunc loop implementation to the new API.");
+ return -1;
+}
+
+/*
+ * Much the same as the default type resolver, but tries a bit harder to
+ * preserve metadata.
+ */
+static NPY_CASTING
+simple_legacy_resolve_descriptors(
+ PyArrayMethodObject *method,
+ PyArray_DTypeMeta **dtypes,
+ PyArray_Descr **given_descrs,
+ PyArray_Descr **output_descrs)
+{
+ int nin = method->nin;
+ int nout = method->nout;
+
+ for (int i = 0; i < nin + nout; i++) {
+ if (given_descrs[i] != NULL) {
+ output_descrs[i] = ensure_dtype_nbo(given_descrs[i]);
+ }
+ else if (dtypes[i] == dtypes[0] && i > 0) {
+ /* Preserve metadata from the first operand if same dtype */
+ Py_INCREF(output_descrs[0]);
+ output_descrs[i] = output_descrs[0];
+ }
+ else {
+ output_descrs[i] = NPY_DT_CALL_default_descr(dtypes[i]);
+ }
+ if (output_descrs[i] == NULL) {
+ goto fail;
+ }
+ }
+
+ return NPY_SAFE_CASTING;
+
+ fail:
+ for (int i = 0; i < nin + nout; i++) {
+ Py_CLEAR(output_descrs[i]);
+ }
+ return -1;
+}
+
+
+/*
+ * This function grabs the legacy inner-loop. If this turns out to be slow
+ * we could probably cache it (with some care).
+ */
+NPY_NO_EXPORT int
+get_wrapped_legacy_ufunc_loop(PyArrayMethod_Context *context,
+ int aligned, int move_references,
+ npy_intp *NPY_UNUSED(strides),
+ PyArrayMethod_StridedLoop **out_loop,
+ NpyAuxData **out_transferdata,
+ NPY_ARRAYMETHOD_FLAGS *flags)
+{
+ assert(aligned);
+ assert(!move_references);
+
+ if (context->caller == NULL ||
+ !PyObject_TypeCheck(context->caller, &PyUFunc_Type)) {
+ PyErr_Format(PyExc_RuntimeError,
+ "cannot call %s without its ufunc as caller context.",
+ context->method->name);
+ return -1;
+ }
+
+ PyUFuncObject *ufunc = (PyUFuncObject *)context->caller;
+ void *user_data;
+ int needs_api = 0;
+
+ PyUFuncGenericFunction loop = NULL;
+ /* Note that `needs_api` is not reliable (it was in fact unused normally) */
+ if (ufunc->legacy_inner_loop_selector(ufunc,
+ context->descriptors, &loop, &user_data, &needs_api) < 0) {
+ return -1;
+ }
+ *flags = context->method->flags & NPY_METH_RUNTIME_FLAGS;
+ if (needs_api) {
+ *flags |= NPY_METH_REQUIRES_PYAPI;
+ }
+
+ *out_loop = &generic_wrapped_legacy_loop;
+ *out_transferdata = get_new_loop_data(
+ loop, user_data, (*flags & NPY_METH_REQUIRES_PYAPI) != 0);
+ return 0;
+}
+
+
+/*
+ * Get the unbound ArrayMethod which wraps the instances of the ufunc.
+ * Note that this function stores the result on the ufunc and then only
+ * returns the same one.
+ */
+NPY_NO_EXPORT PyArrayMethodObject *
+PyArray_NewLegacyWrappingArrayMethod(PyUFuncObject *ufunc,
+ PyArray_DTypeMeta *signature[])
+{
+ char method_name[101];
+ const char *name = ufunc->name ? ufunc->name : "<unknown>";
+ snprintf(method_name, 100, "legacy_ufunc_wrapper_for_%s", name);
+
+ /*
+ * Assume that we require the Python API when any of the (legacy) dtypes
+ * flags it.
+ */
+ int any_output_flexible = 0;
+ NPY_ARRAYMETHOD_FLAGS flags = 0;
+
+ for (int i = 0; i < ufunc->nin+ufunc->nout; i++) {
+ if (signature[i]->singleton->flags & (
+ NPY_ITEM_REFCOUNT | NPY_ITEM_IS_POINTER | NPY_NEEDS_PYAPI)) {
+ flags |= NPY_METH_REQUIRES_PYAPI;
+ }
+ if (NPY_DT_is_parametric(signature[i])) {
+ any_output_flexible = 1;
+ }
+ }
+
+ PyType_Slot slots[3] = {
+ {NPY_METH_get_loop, &get_wrapped_legacy_ufunc_loop},
+ {NPY_METH_resolve_descriptors, &simple_legacy_resolve_descriptors},
+ {0, NULL},
+ };
+ if (any_output_flexible) {
+ /* We cannot use the default descriptor resolver. */
+ slots[1].pfunc = &wrapped_legacy_resolve_descriptors;
+ }
+
+ PyArrayMethod_Spec spec = {
+ .name = method_name,
+ .nin = ufunc->nin,
+ .nout = ufunc->nout,
+ .dtypes = signature,
+ .flags = flags,
+ .slots = slots,
+ .casting = NPY_EQUIV_CASTING,
+ };
+
+ PyBoundArrayMethodObject *bound_res = PyArrayMethod_FromSpec_int(&spec, 1);
+ if (bound_res == NULL) {
+ return NULL;
+ }
+ PyArrayMethodObject *res = bound_res->method;
+ Py_INCREF(res);
+ Py_DECREF(bound_res);
+ return res;
+}
diff --git a/numpy/core/src/umath/legacy_array_method.h b/numpy/core/src/umath/legacy_array_method.h
new file mode 100644
index 000000000..0dec1fb3a
--- /dev/null
+++ b/numpy/core/src/umath/legacy_array_method.h
@@ -0,0 +1,33 @@
+#ifndef _NPY_LEGACY_ARRAY_METHOD_H
+#define _NPY_LEGACY_ARRAY_METHOD_H
+
+#include "numpy/ndarraytypes.h"
+#include "numpy/ufuncobject.h"
+#include "array_method.h"
+
+
+NPY_NO_EXPORT PyArrayMethodObject *
+PyArray_NewLegacyWrappingArrayMethod(PyUFuncObject *ufunc,
+ PyArray_DTypeMeta *signature[]);
+
+
+
+/*
+ * The following two symbols are in the header so that other places can use
+ * them to probe for special cases (or whether an ArrayMethod is a "legacy"
+ * one).
+ */
+NPY_NO_EXPORT int
+get_wrapped_legacy_ufunc_loop(PyArrayMethod_Context *context,
+ int aligned, int move_references,
+ npy_intp *NPY_UNUSED(strides),
+ PyArrayMethod_StridedLoop **out_loop,
+ NpyAuxData **out_transferdata,
+ NPY_ARRAYMETHOD_FLAGS *flags);
+
+NPY_NO_EXPORT NPY_CASTING
+wrapped_legacy_resolve_descriptors(PyArrayMethodObject *,
+ PyArray_DTypeMeta **, PyArray_Descr **, PyArray_Descr **);
+
+
+#endif /*_NPY_LEGACY_ARRAY_METHOD_H */
diff --git a/numpy/core/src/umath/loops.c.src b/numpy/core/src/umath/loops.c.src
index c2e06a4fd..b1afa69a7 100644
--- a/numpy/core/src/umath/loops.c.src
+++ b/numpy/core/src/umath/loops.c.src
@@ -20,6 +20,9 @@
#include <string.h> /* for memchr */
+/* Use Libdivide for faster division */
+#include "numpy/libdivide/libdivide.h"
+
/*
* cutoff blocksize for pairwise summation
* decreasing it decreases errors slightly as more pairs are summed but
@@ -570,7 +573,7 @@ NPY_NO_EXPORT void
/**begin repeat1
* #isa = , _avx2#
* #ISA = , AVX2#
- * #CHK = 1, HAVE_ATTRIBUTE_TARGET_AVX2#
+ * #CHK = 1, defined(HAVE_ATTRIBUTE_TARGET_AVX2)#
* #ATTR = , NPY_GCC_TARGET_AVX2#
*/
@@ -841,32 +844,6 @@ NPY_NO_EXPORT NPY_GCC_OPT_3 void
}
NPY_NO_EXPORT void
-@TYPE@_divide(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
-{
- BINARY_LOOP {
- const @type@ in1 = *(@type@ *)ip1;
- const @type@ in2 = *(@type@ *)ip2;
- /*
- * FIXME: On x86 at least, dividing the smallest representable integer
- * by -1 causes a SIFGPE (division overflow). We treat this case here
- * (to avoid a SIGFPE crash at python level), but a good solution would
- * be to treat integer division problems separately from FPU exceptions
- * (i.e. a different approach than npy_set_floatstatus_divbyzero()).
- */
- if (in2 == 0 || (in1 == NPY_MIN_@TYPE@ && in2 == -1)) {
- npy_set_floatstatus_divbyzero();
- *((@type@ *)op1) = 0;
- }
- else if (((in1 > 0) != (in2 > 0)) && (in1 % in2 != 0)) {
- *((@type@ *)op1) = in1/in2 - 1;
- }
- else {
- *((@type@ *)op1) = in1/in2;
- }
- }
-}
-
-NPY_NO_EXPORT void
@TYPE@_remainder(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
{
BINARY_LOOP {
@@ -952,22 +929,6 @@ NPY_NO_EXPORT NPY_GCC_OPT_3 void
}
NPY_NO_EXPORT void
-@TYPE@_divide(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
-{
- BINARY_LOOP {
- const @type@ in1 = *(@type@ *)ip1;
- const @type@ in2 = *(@type@ *)ip2;
- if (in2 == 0) {
- npy_set_floatstatus_divbyzero();
- *((@type@ *)op1) = 0;
- }
- else {
- *((@type@ *)op1)= in1/in2;
- }
- }
-}
-
-NPY_NO_EXPORT void
@TYPE@_remainder(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
{
BINARY_LOOP {
@@ -1352,14 +1313,48 @@ TIMEDELTA_dm_m_multiply(char **args, npy_intp const *dimensions, npy_intp const
NPY_NO_EXPORT void
TIMEDELTA_mq_m_divide(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
{
- BINARY_LOOP {
- const npy_timedelta in1 = *(npy_timedelta *)ip1;
+ /* NOTE: This code is similar to array floor divide */
+ BINARY_DEFS
+
+ /* When the divisor is a constant, use libdivide for faster division */
+ if (steps[1] == 0) {
+ /* In case of empty array, just return */
+ if (n == 0) {
+ return;
+ }
+
const npy_int64 in2 = *(npy_int64 *)ip2;
- if (in1 == NPY_DATETIME_NAT || in2 == 0) {
- *((npy_timedelta *)op1) = NPY_DATETIME_NAT;
+
+ /* If divisor is 0, we need not compute anything */
+ if (in2 == 0) {
+ npy_set_floatstatus_divbyzero();
+ BINARY_LOOP_SLIDING {
+ *((npy_timedelta *)op1) = NPY_DATETIME_NAT;
+ }
}
else {
- *((npy_timedelta *)op1) = in1 / in2;
+ struct libdivide_s64_t fast_d = libdivide_s64_gen(in2);
+ BINARY_LOOP_SLIDING {
+ const npy_timedelta in1 = *(npy_timedelta *)ip1;
+ if (in1 == NPY_DATETIME_NAT) {
+ *((npy_timedelta *)op1) = NPY_DATETIME_NAT;
+ }
+ else {
+ *((npy_timedelta *)op1) = libdivide_s64_do(in1, &fast_d);;
+ }
+ }
+ }
+ }
+ else {
+ BINARY_LOOP_SLIDING {
+ const npy_timedelta in1 = *(npy_timedelta *)ip1;
+ const npy_int64 in2 = *(npy_int64 *)ip2;
+ if (in1 == NPY_DATETIME_NAT || in2 == 0) {
+ *((npy_timedelta *)op1) = NPY_DATETIME_NAT;
+ }
+ else {
+ *((npy_timedelta *)op1) = in1 / in2;
+ }
}
}
}
@@ -1431,23 +1426,69 @@ TIMEDELTA_mm_m_remainder(char **args, npy_intp const *dimensions, npy_intp const
NPY_NO_EXPORT void
TIMEDELTA_mm_q_floor_divide(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
{
- BINARY_LOOP {
- const npy_timedelta in1 = *(npy_timedelta *)ip1;
- const npy_timedelta in2 = *(npy_timedelta *)ip2;
- if (in1 == NPY_DATETIME_NAT || in2 == NPY_DATETIME_NAT) {
- npy_set_floatstatus_invalid();
- *((npy_int64 *)op1) = 0;
+ /* NOTE: This code is similar to array floor divide */
+ BINARY_DEFS
+
+ /* When the divisor is a constant, use libdivide for faster division */
+ if (steps[1] == 0) {
+ /* In case of empty array, just return */
+ if (n == 0) {
+ return;
}
- else if (in2 == 0) {
+
+ const npy_timedelta in2 = *(npy_timedelta *)ip2;
+
+ /* If divisor is 0 or NAT, we need not compute anything */
+ if (in2 == 0) {
npy_set_floatstatus_divbyzero();
- *((npy_int64 *)op1) = 0;
+ BINARY_LOOP_SLIDING {
+ *((npy_int64 *)op1) = 0;
+ }
+ }
+ else if (in2 == NPY_DATETIME_NAT) {
+ npy_set_floatstatus_invalid();
+ BINARY_LOOP_SLIDING {
+ *((npy_int64 *)op1) = 0;
+ }
}
else {
- if (((in1 > 0) != (in2 > 0)) && (in1 % in2 != 0)) {
- *((npy_int64 *)op1) = in1/in2 - 1;
+ struct libdivide_s64_t fast_d = libdivide_s64_gen(in2);
+ BINARY_LOOP_SLIDING {
+ const npy_timedelta in1 = *(npy_timedelta *)ip1;
+ if (in1 == NPY_DATETIME_NAT) {
+ npy_set_floatstatus_invalid();
+ *((npy_int64 *)op1) = 0;
+ }
+ else {
+ *((npy_int64 *)op1) = libdivide_s64_do(in1, &fast_d);
+
+ /* Negative quotients needs to be rounded down */
+ if (((in1 > 0) != (in2 > 0)) && (*((npy_int64 *)op1) * in2 != in1)) {
+ *((npy_int64 *)op1) = *((npy_int64 *)op1) - 1;
+ }
+ }
+ }
+ }
+ }
+ else {
+ BINARY_LOOP_SLIDING {
+ const npy_timedelta in1 = *(npy_timedelta *)ip1;
+ const npy_timedelta in2 = *(npy_timedelta *)ip2;
+ if (in1 == NPY_DATETIME_NAT || in2 == NPY_DATETIME_NAT) {
+ npy_set_floatstatus_invalid();
+ *((npy_int64 *)op1) = 0;
+ }
+ else if (in2 == 0) {
+ npy_set_floatstatus_divbyzero();
+ *((npy_int64 *)op1) = 0;
}
else {
*((npy_int64 *)op1) = in1/in2;
+
+ /* Negative quotients needs to be rounded down */
+ if (((in1 > 0) != (in2 > 0)) && (*((npy_int64 *)op1) * in2 != in1)) {
+ *((npy_int64 *)op1) = *((npy_int64 *)op1) - 1;
+ }
}
}
}
@@ -1515,39 +1556,6 @@ NPY_NO_EXPORT NPY_GCC_OPT_3 void
/**end repeat**/
/**begin repeat
- * #func = sin, cos, exp, log#
- * #scalarf = npy_sinf, npy_cosf, npy_expf, npy_logf#
- */
-
-NPY_NO_EXPORT NPY_GCC_OPT_3 void
-FLOAT_@func@(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(data))
-{
- UNARY_LOOP {
- const npy_float in1 = *(npy_float *)ip1;
- *(npy_float *)op1 = @scalarf@(in1);
- }
-}
-
-/**end repeat**/
-
-NPY_NO_EXPORT NPY_GCC_OPT_3 void
-DOUBLE_exp(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(data))
-{
- UNARY_LOOP {
- const npy_double in1 = *(npy_double *)ip1;
- *(npy_double *)op1 = npy_exp(in1);
- }
-}
-NPY_NO_EXPORT NPY_GCC_OPT_3 void
-DOUBLE_log(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(data))
-{
- UNARY_LOOP {
- const npy_double in1 = *(npy_double *)ip1;
- *(npy_double *)op1 = npy_log(in1);
- }
-}
-
-/**begin repeat
* #isa = avx512f, fma#
* #ISA = AVX512F, FMA#
* #CHK = HAVE_ATTRIBUTE_TARGET_AVX512F_WITH_INTRINSICS, HAVE_ATTRIBUTE_TARGET_AVX2_WITH_INTRINSICS#
@@ -1577,159 +1585,6 @@ NPY_NO_EXPORT NPY_GCC_OPT_3 void
/**end repeat2**/
/**end repeat1**/
-
-/**begin repeat1
- * #func = exp, log#
- * #scalarf = npy_expf, npy_logf#
- */
-
-NPY_NO_EXPORT NPY_GCC_OPT_3 void
-FLOAT_@func@_@isa@(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(data))
-{
- if (!run_unary_@isa@_@func@_FLOAT(args, dimensions, steps)) {
- UNARY_LOOP {
- /*
- * We use the AVX function to compute exp/log for scalar elements as well.
- * This is needed to ensure the output of strided and non-strided
- * cases match. SIMD code handles strided input cases, but not
- * strided output.
- */
-#if defined @CHK@ && defined NPY_HAVE_SSE2_INTRINSICS
- @ISA@_@func@_FLOAT((npy_float *)op1, (npy_float *)ip1, 1, steps[0]);
-#else
- const npy_float in1 = *(npy_float *)ip1;
- *(npy_float *)op1 = @scalarf@(in1);
-#endif
- }
- }
-}
-
-/**end repeat1**/
-
-/**begin repeat1
- * #func = cos, sin#
- * #enum = npy_compute_cos, npy_compute_sin#
- * #scalarf = npy_cosf, npy_sinf#
- */
-
-NPY_NO_EXPORT NPY_GCC_OPT_3 void
-FLOAT_@func@_@isa@(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(data))
-{
- if (!run_unary_@isa@_sincos_FLOAT(args, dimensions, steps, @enum@)) {
- UNARY_LOOP {
-#if defined @CHK@ && defined NPY_HAVE_SSE2_INTRINSICS
- @ISA@_sincos_FLOAT((npy_float *)op1, (npy_float *)ip1, 1, steps[0], @enum@);
-#else
- const npy_float in1 = *(npy_float *)ip1;
- *(npy_float *)op1 = @scalarf@(in1);
-#endif
- }
- }
-}
-
-/**end repeat1**/
-/**end repeat**/
-
-NPY_NO_EXPORT NPY_GCC_OPT_3 void
-DOUBLE_exp_avx512f(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(data))
-{
- if (!run_unary_avx512f_exp_DOUBLE(args, dimensions, steps)) {
- UNARY_LOOP {
- const npy_double in1 = *(npy_double *)ip1;
- *(npy_double *)op1 = npy_exp(in1);
- }
- }
-}
-
-NPY_NO_EXPORT NPY_GCC_OPT_3 void
-DOUBLE_log_avx512f(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(data))
-{
- if (!run_unary_avx512f_log_DOUBLE(args, dimensions, steps)) {
- UNARY_LOOP {
- const npy_double in1 = *(npy_double *)ip1;
- *(npy_double *)op1 = npy_log(in1);
- }
- }
-}
-
-/**begin repeat
- * Float types
- * #type = npy_float, npy_double, npy_longdouble, npy_float#
- * #dtype = npy_float, npy_double, npy_longdouble, npy_half#
- * #TYPE = FLOAT, DOUBLE, LONGDOUBLE, HALF#
- * #c = f, , l, #
- * #C = F, , L, #
- * #trf = , , , npy_half_to_float#
- */
-
-/*
- * Pairwise summation, rounding error O(lg n) instead of O(n).
- * The recursion depth is O(lg n) as well.
- * when updating also update similar complex floats summation
- */
-static @type@
-pairwise_sum_@TYPE@(char *a, npy_intp n, npy_intp stride)
-{
- if (n < 8) {
- npy_intp i;
- @type@ res = 0.;
-
- for (i = 0; i < n; i++) {
- res += @trf@(*((@dtype@*)(a + i * stride)));
- }
- return res;
- }
- else if (n <= PW_BLOCKSIZE) {
- npy_intp i;
- @type@ r[8], res;
-
- /*
- * sum a block with 8 accumulators
- * 8 times unroll reduces blocksize to 16 and allows vectorization with
- * avx without changing summation ordering
- */
- r[0] = @trf@(*((@dtype@ *)(a + 0 * stride)));
- r[1] = @trf@(*((@dtype@ *)(a + 1 * stride)));
- r[2] = @trf@(*((@dtype@ *)(a + 2 * stride)));
- r[3] = @trf@(*((@dtype@ *)(a + 3 * stride)));
- r[4] = @trf@(*((@dtype@ *)(a + 4 * stride)));
- r[5] = @trf@(*((@dtype@ *)(a + 5 * stride)));
- r[6] = @trf@(*((@dtype@ *)(a + 6 * stride)));
- r[7] = @trf@(*((@dtype@ *)(a + 7 * stride)));
-
- for (i = 8; i < n - (n % 8); i += 8) {
- /* small blocksizes seems to mess with hardware prefetch */
- NPY_PREFETCH(a + (i + 512/(npy_intp)sizeof(@dtype@))*stride, 0, 3);
- r[0] += @trf@(*((@dtype@ *)(a + (i + 0) * stride)));
- r[1] += @trf@(*((@dtype@ *)(a + (i + 1) * stride)));
- r[2] += @trf@(*((@dtype@ *)(a + (i + 2) * stride)));
- r[3] += @trf@(*((@dtype@ *)(a + (i + 3) * stride)));
- r[4] += @trf@(*((@dtype@ *)(a + (i + 4) * stride)));
- r[5] += @trf@(*((@dtype@ *)(a + (i + 5) * stride)));
- r[6] += @trf@(*((@dtype@ *)(a + (i + 6) * stride)));
- r[7] += @trf@(*((@dtype@ *)(a + (i + 7) * stride)));
- }
-
- /* accumulate now to avoid stack spills for single peel loop */
- res = ((r[0] + r[1]) + (r[2] + r[3])) +
- ((r[4] + r[5]) + (r[6] + r[7]));
-
- /* do non multiple of 8 rest */
- for (; i < n; i++) {
- res += @trf@(*((@dtype@ *)(a + i * stride)));
- }
- return res;
- }
- else {
- /* divide by two but avoid non-multiples of unroll factor */
- npy_intp n2 = n / 2;
-
- n2 -= n2 % 8;
- return pairwise_sum_@TYPE@(a, n2, stride) +
- pairwise_sum_@TYPE@(a + n2 * stride, n - n2, stride);
- }
-}
-
/**end repeat**/
/**begin repeat
@@ -1739,39 +1594,6 @@ pairwise_sum_@TYPE@(char *a, npy_intp n, npy_intp stride)
* #c = f, , l#
* #C = F, , L#
*/
-
-/**begin repeat1
- * Arithmetic
- * # kind = add, subtract, multiply, divide#
- * # OP = +, -, *, /#
- * # PW = 1, 0, 0, 0#
- */
-NPY_NO_EXPORT void
-@TYPE@_@kind@(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
-{
- if (IS_BINARY_REDUCE) {
-#if @PW@
- @type@ * iop1 = (@type@ *)args[0];
- npy_intp n = dimensions[0];
-
- *iop1 @OP@= pairwise_sum_@TYPE@(args[1], n, steps[1]);
-#else
- BINARY_REDUCE_LOOP(@type@) {
- io1 @OP@= *(@type@ *)ip2;
- }
- *((@type@ *)iop1) = io1;
-#endif
- }
- else if (!run_binary_simd_@kind@_@TYPE@(args, dimensions, steps)) {
- BINARY_LOOP {
- const @type@ in1 = *(@type@ *)ip1;
- const @type@ in2 = *(@type@ *)ip2;
- *((@type@ *)op1) = in1 @OP@ in2;
- }
- }
-}
-/**end repeat1**/
-
/**begin repeat1
* #kind = equal, not_equal, less, less_equal, greater, greater_equal,
* logical_and, logical_or#
@@ -2037,41 +1859,6 @@ NPY_NO_EXPORT void
}
NPY_NO_EXPORT void
-@TYPE@_frexp(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
-{
- UNARY_LOOP_TWO_OUT {
- const @type@ in1 = *(@type@ *)ip1;
- *((@type@ *)op1) = npy_frexp@c@(in1, (int *)op2);
- }
-}
-
-NPY_NO_EXPORT void
-@TYPE@_frexp_avx512_skx(char **args, npy_intp const *dimensions, npy_intp const *steps, void *func)
-{
- if (!run_unary_two_out_avx512_skx_frexp_@TYPE@(args, dimensions, steps)) {
- @TYPE@_frexp(args, dimensions, steps, func);
- }
-}
-
-NPY_NO_EXPORT void
-@TYPE@_ldexp(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
-{
- BINARY_LOOP {
- const @type@ in1 = *(@type@ *)ip1;
- const int in2 = *(int *)ip2;
- *((@type@ *)op1) = npy_ldexp@c@(in1, in2);
- }
-}
-
-NPY_NO_EXPORT void
-@TYPE@_ldexp_avx512_skx(char **args, const npy_intp *dimensions, const npy_intp *steps, void *func)
-{
- if (!run_binary_avx512_skx_ldexp_@TYPE@(args, dimensions, steps)) {
- @TYPE@_ldexp(args, dimensions, steps, func);
- }
-}
-
-NPY_NO_EXPORT void
@TYPE@_ldexp_long(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
{
/*
@@ -2101,8 +1888,6 @@ NPY_NO_EXPORT void
}
}
-#define @TYPE@_true_divide @TYPE@_divide
-
/**end repeat**/
/*
@@ -2111,6 +1896,38 @@ NPY_NO_EXPORT void
*****************************************************************************
*/
+/**begin repeat
+ * Arithmetic
+ * # kind = add, subtract, multiply, divide#
+ * # OP = +, -, *, /#
+ * # PW = 1, 0, 0, 0#
+ */
+NPY_NO_EXPORT void
+LONGDOUBLE_@kind@(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
+{
+ if (IS_BINARY_REDUCE) {
+#if @PW@
+ npy_longdouble * iop1 = (npy_longdouble *)args[0];
+ npy_intp n = dimensions[0];
+
+ *iop1 @OP@= LONGDOUBLE_pairwise_sum(args[1], n, steps[1]);
+#else
+ BINARY_REDUCE_LOOP(npy_longdouble) {
+ io1 @OP@= *(npy_longdouble *)ip2;
+ }
+ *((npy_longdouble *)iop1) = io1;
+#endif
+ }
+ else {
+ BINARY_LOOP {
+ const npy_longdouble in1 = *(npy_longdouble *)ip1;
+ const npy_longdouble in2 = *(npy_longdouble *)ip2;
+ *((npy_longdouble *)op1) = in1 @OP@ in2;
+ }
+ }
+}
+/**end repeat**/
+
NPY_NO_EXPORT void
LONGDOUBLE_reciprocal(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(data))
{
@@ -2141,6 +1958,25 @@ LONGDOUBLE_square(char **args, npy_intp const *dimensions, npy_intp const *steps
}
}
+NPY_NO_EXPORT void
+LONGDOUBLE_frexp(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
+{
+ UNARY_LOOP_TWO_OUT {
+ const npy_longdouble in1 = *(npy_longdouble *)ip1;
+ *((npy_longdouble *)op1) = npy_frexpl(in1, (int *)op2);
+ }
+}
+
+NPY_NO_EXPORT void
+LONGDOUBLE_ldexp(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
+{
+ BINARY_LOOP {
+ const npy_longdouble in1 = *(npy_longdouble *)ip1;
+ const int in2 = *(int *)ip2;
+ *((npy_longdouble *)op1) = npy_ldexpl(in1, in2);
+ }
+}
+
/*
*****************************************************************************
** HALF-FLOAT LOOPS **
@@ -2163,7 +1999,7 @@ HALF_@kind@(char **args, npy_intp const *dimensions, npy_intp const *steps, void
#if @PW@
npy_intp n = dimensions[0];
- io1 @OP@= pairwise_sum_HALF(args[1], n, steps[1]);
+ io1 @OP@= HALF_pairwise_sum(args[1], n, steps[1]);
#else
BINARY_REDUCE_LOOP_INNER {
io1 @OP@= npy_half_to_float(*(npy_half *)ip2);
@@ -2471,9 +2307,6 @@ HALF_ldexp_long(char **args, npy_intp const *dimensions, npy_intp const *steps,
}
}
-#define HALF_true_divide HALF_divide
-
-
/*
*****************************************************************************
** COMPLEX LOOPS **
@@ -2500,80 +2333,8 @@ HALF_ldexp_long(char **args, npy_intp const *dimensions, npy_intp const *steps,
* #SIMD = 1, 1, 0#
*/
-/* similar to pairwise sum of real floats */
-static void
-pairwise_sum_@TYPE@(@ftype@ *rr, @ftype@ * ri, char * a, npy_intp n,
- npy_intp stride)
-{
- assert(n % 2 == 0);
- if (n < 8) {
- npy_intp i;
-
- *rr = 0.;
- *ri = 0.;
- for (i = 0; i < n; i += 2) {
- *rr += *((@ftype@ *)(a + i * stride + 0));
- *ri += *((@ftype@ *)(a + i * stride + sizeof(@ftype@)));
- }
- return;
- }
- else if (n <= PW_BLOCKSIZE) {
- npy_intp i;
- @ftype@ r[8];
-
- /*
- * sum a block with 8 accumulators
- * 8 times unroll reduces blocksize to 16 and allows vectorization with
- * avx without changing summation ordering
- */
- r[0] = *((@ftype@ *)(a + 0 * stride));
- r[1] = *((@ftype@ *)(a + 0 * stride + sizeof(@ftype@)));
- r[2] = *((@ftype@ *)(a + 2 * stride));
- r[3] = *((@ftype@ *)(a + 2 * stride + sizeof(@ftype@)));
- r[4] = *((@ftype@ *)(a + 4 * stride));
- r[5] = *((@ftype@ *)(a + 4 * stride + sizeof(@ftype@)));
- r[6] = *((@ftype@ *)(a + 6 * stride));
- r[7] = *((@ftype@ *)(a + 6 * stride + sizeof(@ftype@)));
-
- for (i = 8; i < n - (n % 8); i += 8) {
- /* small blocksizes seems to mess with hardware prefetch */
- NPY_PREFETCH(a + (i + 512/(npy_intp)sizeof(@ftype@))*stride, 0, 3);
- r[0] += *((@ftype@ *)(a + (i + 0) * stride));
- r[1] += *((@ftype@ *)(a + (i + 0) * stride + sizeof(@ftype@)));
- r[2] += *((@ftype@ *)(a + (i + 2) * stride));
- r[3] += *((@ftype@ *)(a + (i + 2) * stride + sizeof(@ftype@)));
- r[4] += *((@ftype@ *)(a + (i + 4) * stride));
- r[5] += *((@ftype@ *)(a + (i + 4) * stride + sizeof(@ftype@)));
- r[6] += *((@ftype@ *)(a + (i + 6) * stride));
- r[7] += *((@ftype@ *)(a + (i + 6) * stride + sizeof(@ftype@)));
- }
-
- /* accumulate now to avoid stack spills for single peel loop */
- *rr = ((r[0] + r[2]) + (r[4] + r[6]));
- *ri = ((r[1] + r[3]) + (r[5] + r[7]));
-
- /* do non multiple of 8 rest */
- for (; i < n; i+=2) {
- *rr += *((@ftype@ *)(a + i * stride + 0));
- *ri += *((@ftype@ *)(a + i * stride + sizeof(@ftype@)));
- }
- return;
- }
- else {
- /* divide by two but avoid non-multiples of unroll factor */
- @ftype@ rr1, ri1, rr2, ri2;
- npy_intp n2 = n / 2;
-
- n2 -= n2 % 8;
- pairwise_sum_@TYPE@(&rr1, &ri1, a, n2, stride);
- pairwise_sum_@TYPE@(&rr2, &ri2, a + n2 * stride, n - n2, stride);
- *rr = rr1 + rr2;
- *ri = ri1 + ri2;
- return;
- }
-}
-
-
+#if !@SIMD@
+// CFLOAT & CDOUBLE defined by 'loops_arithm_fp.dispatch.c.src'
/**begin repeat1
* arithmetic
* #kind = add, subtract#
@@ -2590,7 +2351,7 @@ NPY_NO_EXPORT void
@ftype@ * oi = ((@ftype@ *)args[0]) + 1;
@ftype@ rr, ri;
- pairwise_sum_@TYPE@(&rr, &ri, args[1], n * 2, steps[1] / 2);
+ @TYPE@_pairwise_sum(&rr, &ri, args[1], n * 2, steps[1] / 2);
*or @OP@= rr;
*oi @OP@= ri;
return;
@@ -2620,6 +2381,7 @@ NPY_NO_EXPORT void
((@ftype@ *)op1)[1] = in1r*in2i + in1i*in2r;
}
}
+#endif // !SIMD
NPY_NO_EXPORT void
@TYPE@_divide(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
@@ -2653,52 +2415,6 @@ NPY_NO_EXPORT void
}
}
-#if @SIMD@
-NPY_NO_EXPORT void
-@TYPE@_add_avx512f(char **args, const npy_intp *dimensions, const npy_intp *steps, void *func)
-{
- if (IS_BINARY_REDUCE) {
- @TYPE@_add(args, dimensions, steps, func);
- }
- else if (!run_binary_avx512f_add_@TYPE@(args, dimensions, steps)) {
- @TYPE@_add(args, dimensions, steps, func);
- }
-}
-
-/**begin repeat1
- * arithmetic
- * #kind = subtract, multiply#
- */
-NPY_NO_EXPORT void
-@TYPE@_@kind@_avx512f(char **args, const npy_intp *dimensions, const npy_intp *steps, void *func)
-{
- if (!run_binary_avx512f_@kind@_@TYPE@(args, dimensions, steps)) {
- @TYPE@_@kind@(args, dimensions, steps, func);
- }
-}
-/**end repeat1**/
-#endif
-
-NPY_NO_EXPORT void
-@TYPE@_floor_divide(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
-{
- BINARY_LOOP {
- const @ftype@ in1r = ((@ftype@ *)ip1)[0];
- const @ftype@ in1i = ((@ftype@ *)ip1)[1];
- const @ftype@ in2r = ((@ftype@ *)ip2)[0];
- const @ftype@ in2i = ((@ftype@ *)ip2)[1];
- if (npy_fabs@c@(in2r) >= npy_fabs@c@(in2i)) {
- const @ftype@ rat = in2i/in2r;
- ((@ftype@ *)op1)[0] = npy_floor@c@((in1r + in1i*rat)/(in2r + in2i*rat));
- ((@ftype@ *)op1)[1] = 0;
- }
- else {
- const @ftype@ rat = in2r/in2i;
- ((@ftype@ *)op1)[0] = npy_floor@c@((in1r*rat + in1i)/(in2i + in2r*rat));
- ((@ftype@ *)op1)[1] = 0;
- }
- }
-}
/**begin repeat1
* #kind= greater, greater_equal, less, less_equal, equal, not_equal#
@@ -2923,8 +2639,6 @@ NPY_NO_EXPORT void
}
/**end repeat1**/
-#define @TYPE@_true_divide @TYPE@_divide
-
/**end repeat**/
#undef CGE
diff --git a/numpy/core/src/umath/loops.h.src b/numpy/core/src/umath/loops.h.src
index a0b68d168..02d749a5e 100644
--- a/numpy/core/src/umath/loops.h.src
+++ b/numpy/core/src/umath/loops.h.src
@@ -53,6 +53,18 @@ BOOL_@kind@(char **args, npy_intp const *dimensions, npy_intp const *steps, void
*****************************************************************************
*/
+#ifndef NPY_DISABLE_OPTIMIZATION
+ #include "loops_arithmetic.dispatch.h"
+#endif
+
+/**begin repeat
+ * #TYPE = UBYTE, USHORT, UINT, ULONG, ULONGLONG,
+ BYTE, SHORT, INT, LONG, LONGLONG#
+ */
+ NPY_CPU_DISPATCH_DECLARE(NPY_NO_EXPORT void @TYPE@_divide,
+ (char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func)))
+/**end repeat**/
+
/**begin repeat
* #TYPE = BYTE, SHORT, INT, LONG, LONGLONG#
*/
@@ -141,9 +153,6 @@ NPY_NO_EXPORT void
@S@@TYPE@_sign(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func));
NPY_NO_EXPORT void
-@S@@TYPE@_divide(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func));
-
-NPY_NO_EXPORT void
@S@@TYPE@_remainder(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func));
NPY_NO_EXPORT void
@@ -185,6 +194,22 @@ NPY_CPU_DISPATCH_DECLARE(NPY_NO_EXPORT void @TYPE@_@kind@,
/**end repeat1**/
/**end repeat**/
+#ifndef NPY_DISABLE_OPTIMIZATION
+ #include "loops_arithm_fp.dispatch.h"
+#endif
+/**begin repeat
+ * #TYPE = FLOAT, DOUBLE#
+ */
+/**begin repeat1
+ * Arithmetic
+ * # kind = add, subtract, multiply, divide#
+ * # OP = +, -, *, /#
+ */
+NPY_CPU_DISPATCH_DECLARE(NPY_NO_EXPORT void @TYPE@_@kind@,
+ (char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func)))
+/**end repeat1**/
+/**end repeat**/
+
/**begin repeat
* #TYPE = FLOAT, DOUBLE#
*/
@@ -197,31 +222,29 @@ NPY_NO_EXPORT void
/**end repeat1**/
/**end repeat**/
-NPY_NO_EXPORT void
-DOUBLE_exp(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func));
-
-NPY_NO_EXPORT void
-DOUBLE_exp_avx512f(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func));
-
-NPY_NO_EXPORT void
-DOUBLE_log(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func));
-
-NPY_NO_EXPORT void
-DOUBLE_log_avx512f(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func));
-
+#ifndef NPY_DISABLE_OPTIMIZATION
+ #include "loops_trigonometric.dispatch.h"
+#endif
/**begin repeat
- * #func = sin, cos, exp, log#
+ * #func = sin, cos#
*/
-NPY_NO_EXPORT void
-FLOAT_@func@(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func));
+NPY_CPU_DISPATCH_DECLARE(NPY_NO_EXPORT void FLOAT_@func@, (
+ char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func)
+))
+/**end repeat**/
+#ifndef NPY_DISABLE_OPTIMIZATION
+ #include "loops_exponent_log.dispatch.h"
+#endif
+/**begin repeat
+ * #TYPE = FLOAT, DOUBLE#
+ */
/**begin repeat1
- * #isa = avx512f, fma#
+ * # kind = exp, log, frexp, ldexp#
*/
-
-NPY_NO_EXPORT void
-FLOAT_@func@_@isa@(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func));
-
+NPY_CPU_DISPATCH_DECLARE(NPY_NO_EXPORT void @TYPE@_@kind@, (
+ char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func)
+))
/**end repeat1**/
/**end repeat**/
@@ -346,19 +369,10 @@ NPY_NO_EXPORT void
@TYPE@_frexp(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func));
NPY_NO_EXPORT void
-@TYPE@_frexp_avx512_skx(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func));
-
-NPY_NO_EXPORT void
@TYPE@_ldexp(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func));
NPY_NO_EXPORT void
-@TYPE@_ldexp_avx512_skx(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func));
-
-NPY_NO_EXPORT void
@TYPE@_ldexp_long(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func));
-
-#define @TYPE@_true_divide @TYPE@_divide
-
/**end repeat**/
@@ -367,6 +381,19 @@ NPY_NO_EXPORT void
** COMPLEX LOOPS **
*****************************************************************************
*/
+#ifndef NPY_DISABLE_OPTIMIZATION
+ #include "loops_arithm_fp.dispatch.h"
+#endif
+/**begin repeat
+ * #TYPE = CFLOAT, CDOUBLE#
+ */
+/**begin repeat1
+ * #kind = add, subtract, multiply#
+ */
+NPY_CPU_DISPATCH_DECLARE(NPY_NO_EXPORT void @TYPE@_@kind@,
+ (char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(data)))
+/**end repeat1**/
+/**end repeat**/
#define CGE(xr,xi,yr,yi) (xr > yr || (xr == yr && xi >= yi));
#define CLE(xr,xi,yr,yi) (xr < yr || (xr == yr && xi <= yi));
@@ -380,34 +407,19 @@ NPY_NO_EXPORT void
* #TYPE = FLOAT, DOUBLE, LONGDOUBLE#
* #c = f, , l#
* #C = F, , L#
- * #IFSIMD = 1, 1, 0#
*/
/**begin repeat1
- * #isa = , _avx512f#
- */
-
-/**begin repeat2
* arithmetic
- * #kind = add, subtract#
- * #OP = +, -#
+ * #kind = add, subtract, multiply#
*/
-
-NPY_NO_EXPORT void
-C@TYPE@_@kind@@isa@(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func));
-
-/**end repeat2**/
-
NPY_NO_EXPORT void
-C@TYPE@_multiply@isa@(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func));
+C@TYPE@_@kind@(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func));
/**end repeat1**/
NPY_NO_EXPORT void
C@TYPE@_divide(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func));
-NPY_NO_EXPORT void
-C@TYPE@_floor_divide(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func));
-
/**begin repeat1
* #kind= greater, greater_equal, less, less_equal, equal, not_equal#
* #OP = CGT, CGE, CLT, CLE, CEQ, CNE#
@@ -480,7 +492,6 @@ C@TYPE@_@kind@(char **args, npy_intp const *dimensions, npy_intp const *steps, v
NPY_NO_EXPORT void
C@TYPE@_@kind@(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func));
/**end repeat1**/
-#define C@TYPE@_true_divide C@TYPE@_divide
/**end repeat**/
@@ -593,10 +604,6 @@ NPY_NO_EXPORT void
TIMEDELTA_mm_qm_divmod(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func));
/* Special case equivalents to above functions */
-
-#define TIMEDELTA_mq_m_true_divide TIMEDELTA_mq_m_divide
-#define TIMEDELTA_md_m_true_divide TIMEDELTA_md_m_divide
-#define TIMEDELTA_mm_d_true_divide TIMEDELTA_mm_d_divide
#define TIMEDELTA_mq_m_floor_divide TIMEDELTA_mq_m_divide
#define TIMEDELTA_md_m_floor_divide TIMEDELTA_md_m_divide
/* #define TIMEDELTA_mm_d_floor_divide TIMEDELTA_mm_d_divide */
diff --git a/numpy/core/src/umath/loops_arithm_fp.dispatch.c.src b/numpy/core/src/umath/loops_arithm_fp.dispatch.c.src
new file mode 100644
index 000000000..51b167844
--- /dev/null
+++ b/numpy/core/src/umath/loops_arithm_fp.dispatch.c.src
@@ -0,0 +1,777 @@
+/*@targets
+ ** $maxopt baseline
+ ** sse2 avx2 avx512f
+ **/
+#define _UMATHMODULE
+#define _MULTIARRAYMODULE
+#define NPY_NO_DEPRECATED_API NPY_API_VERSION
+
+#include "simd/simd.h"
+#include "loops_utils.h"
+#include "loops.h"
+#include "lowlevel_strided_loops.h"
+// Provides the various *_LOOP macros
+#include "fast_loop_macros.h"
+
+// TODO: replace raw SIMD with NPYV
+//###############################################################################
+//## Real Single/Double precision
+//###############################################################################
+/********************************************************************************
+ ** Defining the SIMD kernels
+ ********************************************************************************/
+#ifdef NPY_HAVE_SSE2
+/**begin repeat
+ * #type = npy_float, npy_double#
+ * #TYPE = FLOAT, DOUBLE#
+ * #scalarf = npy_sqrtf, npy_sqrt#
+ * #c = f, #
+ * #vtype = __m128, __m128d#
+ * #vtype256 = __m256, __m256d#
+ * #vtype512 = __m512, __m512d#
+ * #vpre = _mm, _mm#
+ * #vpre256 = _mm256, _mm256#
+ * #vpre512 = _mm512, _mm512#
+ * #vsuf = ps, pd#
+ * #vsufs = ss, sd#
+ * #nan = NPY_NANF, NPY_NAN#
+ * #double = 0, 1#
+ * #cast = _mm_castps_si128, _mm_castpd_si128#
+ */
+/**begin repeat1
+* Arithmetic
+* # kind = add, subtract, multiply, divide#
+* # OP = +, -, *, /#
+* # VOP = add, sub, mul, div#
+*/
+static void
+sse2_binary_@kind@_@TYPE@(@type@ * op, @type@ * ip1, @type@ * ip2, npy_intp n)
+{
+#ifdef NPY_HAVE_AVX512F
+ const npy_intp vector_size_bytes = 64;
+ LOOP_BLOCK_ALIGN_VAR(op, @type@, vector_size_bytes)
+ op[i] = ip1[i] @OP@ ip2[i];
+ /* lots of specializations, to squeeze out max performance */
+ if (npy_is_aligned(&ip1[i], vector_size_bytes) && npy_is_aligned(&ip2[i], vector_size_bytes)) {
+ if (ip1 == ip2) {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype512@ a = @vpre512@_load_@vsuf@(&ip1[i]);
+ @vtype512@ c = @vpre512@_@VOP@_@vsuf@(a, a);
+ @vpre512@_store_@vsuf@(&op[i], c);
+ }
+ }
+ else {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype512@ a = @vpre512@_load_@vsuf@(&ip1[i]);
+ @vtype512@ b = @vpre512@_load_@vsuf@(&ip2[i]);
+ @vtype512@ c = @vpre512@_@VOP@_@vsuf@(a, b);
+ @vpre512@_store_@vsuf@(&op[i], c);
+ }
+ }
+ }
+ else if (npy_is_aligned(&ip1[i], vector_size_bytes)) {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype512@ a = @vpre512@_load_@vsuf@(&ip1[i]);
+ @vtype512@ b = @vpre512@_loadu_@vsuf@(&ip2[i]);
+ @vtype512@ c = @vpre512@_@VOP@_@vsuf@(a, b);
+ @vpre512@_store_@vsuf@(&op[i], c);
+ }
+ }
+ else if (npy_is_aligned(&ip2[i], vector_size_bytes)) {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype512@ a = @vpre512@_loadu_@vsuf@(&ip1[i]);
+ @vtype512@ b = @vpre512@_load_@vsuf@(&ip2[i]);
+ @vtype512@ c = @vpre512@_@VOP@_@vsuf@(a, b);
+ @vpre512@_store_@vsuf@(&op[i], c);
+ }
+ }
+ else {
+ if (ip1 == ip2) {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype512@ a = @vpre512@_loadu_@vsuf@(&ip1[i]);
+ @vtype512@ c = @vpre512@_@VOP@_@vsuf@(a, a);
+ @vpre512@_store_@vsuf@(&op[i], c);
+ }
+ }
+ else {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype512@ a = @vpre512@_loadu_@vsuf@(&ip1[i]);
+ @vtype512@ b = @vpre512@_loadu_@vsuf@(&ip2[i]);
+ @vtype512@ c = @vpre512@_@VOP@_@vsuf@(a, b);
+ @vpre512@_store_@vsuf@(&op[i], c);
+ }
+ }
+ }
+#elif defined NPY_HAVE_AVX2
+ const npy_intp vector_size_bytes = 32;
+ LOOP_BLOCK_ALIGN_VAR(op, @type@, vector_size_bytes)
+ op[i] = ip1[i] @OP@ ip2[i];
+ /* lots of specializations, to squeeze out max performance */
+ if (npy_is_aligned(&ip1[i], vector_size_bytes) &&
+ npy_is_aligned(&ip2[i], vector_size_bytes)) {
+ if (ip1 == ip2) {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype256@ a = @vpre256@_load_@vsuf@(&ip1[i]);
+ @vtype256@ c = @vpre256@_@VOP@_@vsuf@(a, a);
+ @vpre256@_store_@vsuf@(&op[i], c);
+ }
+ }
+ else {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype256@ a = @vpre256@_load_@vsuf@(&ip1[i]);
+ @vtype256@ b = @vpre256@_load_@vsuf@(&ip2[i]);
+ @vtype256@ c = @vpre256@_@VOP@_@vsuf@(a, b);
+ @vpre256@_store_@vsuf@(&op[i], c);
+ }
+ }
+ }
+ else if (npy_is_aligned(&ip1[i], vector_size_bytes)) {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype256@ a = @vpre256@_load_@vsuf@(&ip1[i]);
+ @vtype256@ b = @vpre256@_loadu_@vsuf@(&ip2[i]);
+ @vtype256@ c = @vpre256@_@VOP@_@vsuf@(a, b);
+ @vpre256@_store_@vsuf@(&op[i], c);
+ }
+ }
+ else if (npy_is_aligned(&ip2[i], vector_size_bytes)) {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype256@ a = @vpre256@_loadu_@vsuf@(&ip1[i]);
+ @vtype256@ b = @vpre256@_load_@vsuf@(&ip2[i]);
+ @vtype256@ c = @vpre256@_@VOP@_@vsuf@(a, b);
+ @vpre256@_store_@vsuf@(&op[i], c);
+ }
+ }
+ else {
+ if (ip1 == ip2) {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype256@ a = @vpre256@_loadu_@vsuf@(&ip1[i]);
+ @vtype256@ c = @vpre256@_@VOP@_@vsuf@(a, a);
+ @vpre256@_store_@vsuf@(&op[i], c);
+ }
+ }
+ else {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype256@ a = @vpre256@_loadu_@vsuf@(&ip1[i]);
+ @vtype256@ b = @vpre256@_loadu_@vsuf@(&ip2[i]);
+ @vtype256@ c = @vpre256@_@VOP@_@vsuf@(a, b);
+ @vpre256@_store_@vsuf@(&op[i], c);
+ }
+ }
+ }
+#else
+ const npy_intp vector_size_bytes = 16;
+ LOOP_BLOCK_ALIGN_VAR(op, @type@, vector_size_bytes)
+ op[i] = ip1[i] @OP@ ip2[i];
+ /* lots of specializations, to squeeze out max performance */
+ if (npy_is_aligned(&ip1[i], vector_size_bytes) &&
+ npy_is_aligned(&ip2[i], vector_size_bytes)) {
+ if (ip1 == ip2) {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype@ a = @vpre@_load_@vsuf@(&ip1[i]);
+ @vtype@ c = @vpre@_@VOP@_@vsuf@(a, a);
+ @vpre@_store_@vsuf@(&op[i], c);
+ }
+ }
+ else {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype@ a = @vpre@_load_@vsuf@(&ip1[i]);
+ @vtype@ b = @vpre@_load_@vsuf@(&ip2[i]);
+ @vtype@ c = @vpre@_@VOP@_@vsuf@(a, b);
+ @vpre@_store_@vsuf@(&op[i], c);
+ }
+ }
+ }
+ else if (npy_is_aligned(&ip1[i], vector_size_bytes)) {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype@ a = @vpre@_load_@vsuf@(&ip1[i]);
+ @vtype@ b = @vpre@_loadu_@vsuf@(&ip2[i]);
+ @vtype@ c = @vpre@_@VOP@_@vsuf@(a, b);
+ @vpre@_store_@vsuf@(&op[i], c);
+ }
+ }
+ else if (npy_is_aligned(&ip2[i], vector_size_bytes)) {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype@ a = @vpre@_loadu_@vsuf@(&ip1[i]);
+ @vtype@ b = @vpre@_load_@vsuf@(&ip2[i]);
+ @vtype@ c = @vpre@_@VOP@_@vsuf@(a, b);
+ @vpre@_store_@vsuf@(&op[i], c);
+ }
+ }
+ else {
+ if (ip1 == ip2) {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype@ a = @vpre@_loadu_@vsuf@(&ip1[i]);
+ @vtype@ c = @vpre@_@VOP@_@vsuf@(a, a);
+ @vpre@_store_@vsuf@(&op[i], c);
+ }
+ }
+ else {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype@ a = @vpre@_loadu_@vsuf@(&ip1[i]);
+ @vtype@ b = @vpre@_loadu_@vsuf@(&ip2[i]);
+ @vtype@ c = @vpre@_@VOP@_@vsuf@(a, b);
+ @vpre@_store_@vsuf@(&op[i], c);
+ }
+ }
+ }
+#endif
+ LOOP_BLOCKED_END {
+ op[i] = ip1[i] @OP@ ip2[i];
+ }
+}
+
+static void
+sse2_binary_scalar1_@kind@_@TYPE@(@type@ * op, @type@ * ip1, @type@ * ip2, npy_intp n)
+{
+#ifdef NPY_HAVE_AVX512F
+ const npy_intp vector_size_bytes = 64;
+ const @vtype512@ a = @vpre512@_set1_@vsuf@(ip1[0]);
+ LOOP_BLOCK_ALIGN_VAR(op, @type@, vector_size_bytes)
+ op[i] = ip1[0] @OP@ ip2[i];
+ if (npy_is_aligned(&ip2[i], vector_size_bytes)) {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype512@ b = @vpre512@_load_@vsuf@(&ip2[i]);
+ @vtype512@ c = @vpre512@_@VOP@_@vsuf@(a, b);
+ @vpre512@_store_@vsuf@(&op[i], c);
+ }
+ }
+ else {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype512@ b = @vpre512@_loadu_@vsuf@(&ip2[i]);
+ @vtype512@ c = @vpre512@_@VOP@_@vsuf@(a, b);
+ @vpre512@_store_@vsuf@(&op[i], c);
+ }
+ }
+
+
+#elif defined NPY_HAVE_AVX2
+ const npy_intp vector_size_bytes = 32;
+ const @vtype256@ a = @vpre256@_set1_@vsuf@(ip1[0]);
+ LOOP_BLOCK_ALIGN_VAR(op, @type@, vector_size_bytes)
+ op[i] = ip1[0] @OP@ ip2[i];
+ if (npy_is_aligned(&ip2[i], vector_size_bytes)) {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype256@ b = @vpre256@_load_@vsuf@(&ip2[i]);
+ @vtype256@ c = @vpre256@_@VOP@_@vsuf@(a, b);
+ @vpre256@_store_@vsuf@(&op[i], c);
+ }
+ }
+ else {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype256@ b = @vpre256@_loadu_@vsuf@(&ip2[i]);
+ @vtype256@ c = @vpre256@_@VOP@_@vsuf@(a, b);
+ @vpre256@_store_@vsuf@(&op[i], c);
+ }
+ }
+#else
+ const npy_intp vector_size_bytes = 16;
+ const @vtype@ a = @vpre@_set1_@vsuf@(ip1[0]);
+ LOOP_BLOCK_ALIGN_VAR(op, @type@, vector_size_bytes)
+ op[i] = ip1[0] @OP@ ip2[i];
+ if (npy_is_aligned(&ip2[i], vector_size_bytes)) {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype@ b = @vpre@_load_@vsuf@(&ip2[i]);
+ @vtype@ c = @vpre@_@VOP@_@vsuf@(a, b);
+ @vpre@_store_@vsuf@(&op[i], c);
+ }
+ }
+ else {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype@ b = @vpre@_loadu_@vsuf@(&ip2[i]);
+ @vtype@ c = @vpre@_@VOP@_@vsuf@(a, b);
+ @vpre@_store_@vsuf@(&op[i], c);
+ }
+ }
+#endif
+ LOOP_BLOCKED_END {
+ op[i] = ip1[0] @OP@ ip2[i];
+ }
+}
+
+static void
+sse2_binary_scalar2_@kind@_@TYPE@(@type@ * op, @type@ * ip1, @type@ * ip2, npy_intp n)
+{
+#ifdef NPY_HAVE_AVX512F
+ const npy_intp vector_size_bytes = 64;
+ const @vtype512@ b = @vpre512@_set1_@vsuf@(ip2[0]);
+ LOOP_BLOCK_ALIGN_VAR(op, @type@, vector_size_bytes)
+ op[i] = ip1[i] @OP@ ip2[0];
+ if (npy_is_aligned(&ip1[i], vector_size_bytes)) {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype512@ a = @vpre512@_load_@vsuf@(&ip1[i]);
+ @vtype512@ c = @vpre512@_@VOP@_@vsuf@(a, b);
+ @vpre512@_store_@vsuf@(&op[i], c);
+ }
+ }
+ else {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype512@ a = @vpre512@_loadu_@vsuf@(&ip1[i]);
+ @vtype512@ c = @vpre512@_@VOP@_@vsuf@(a, b);
+ @vpre512@_store_@vsuf@(&op[i], c);
+ }
+ }
+
+#elif defined NPY_HAVE_AVX2
+ const npy_intp vector_size_bytes = 32;
+ const @vtype256@ b = @vpre256@_set1_@vsuf@(ip2[0]);
+ LOOP_BLOCK_ALIGN_VAR(op, @type@, vector_size_bytes)
+ op[i] = ip1[i] @OP@ ip2[0];
+ if (npy_is_aligned(&ip1[i], vector_size_bytes)) {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype256@ a = @vpre256@_load_@vsuf@(&ip1[i]);
+ @vtype256@ c = @vpre256@_@VOP@_@vsuf@(a, b);
+ @vpre256@_store_@vsuf@(&op[i], c);
+ }
+ }
+ else {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype256@ a = @vpre256@_loadu_@vsuf@(&ip1[i]);
+ @vtype256@ c = @vpre256@_@VOP@_@vsuf@(a, b);
+ @vpre256@_store_@vsuf@(&op[i], c);
+ }
+ }
+#else
+ const npy_intp vector_size_bytes = 16;
+ const @vtype@ b = @vpre@_set1_@vsuf@(ip2[0]);
+ LOOP_BLOCK_ALIGN_VAR(op, @type@, vector_size_bytes)
+ op[i] = ip1[i] @OP@ ip2[0];
+ if (npy_is_aligned(&ip1[i], vector_size_bytes)) {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype@ a = @vpre@_load_@vsuf@(&ip1[i]);
+ @vtype@ c = @vpre@_@VOP@_@vsuf@(a, b);
+ @vpre@_store_@vsuf@(&op[i], c);
+ }
+ }
+ else {
+ LOOP_BLOCKED(@type@, vector_size_bytes) {
+ @vtype@ a = @vpre@_loadu_@vsuf@(&ip1[i]);
+ @vtype@ c = @vpre@_@VOP@_@vsuf@(a, b);
+ @vpre@_store_@vsuf@(&op[i], c);
+ }
+ }
+#endif
+ LOOP_BLOCKED_END {
+ op[i] = ip1[i] @OP@ ip2[0];
+ }
+}
+
+/**end repeat1**/
+/**end repeat**/
+
+#else // NPY_HAVE_SSE2
+
+/**begin repeat
+ * #type = npy_float, npy_double#
+ * #TYPE = FLOAT, DOUBLE#
+ * #sfx = f32, f64#
+ * #CHK = , _F64#
+ */
+#if NPY_SIMD@CHK@
+/**begin repeat1
+* Arithmetic
+* # kind = add, subtract, multiply, divide#
+* # OP = +, -, *, /#
+* # VOP = add, sub, mul, div#
+*/
+
+static void
+simd_binary_@kind@_@TYPE@(@type@ * op, @type@ * ip1, @type@ * ip2, npy_intp n)
+{
+ LOOP_BLOCK_ALIGN_VAR(op, @type@, NPY_SIMD_WIDTH) {
+ op[i] = ip1[i] @OP@ ip2[i];
+ }
+ /* lots of specializations, to squeeze out max performance */
+ if (ip1 == ip2) {
+ LOOP_BLOCKED(@type@, NPY_SIMD_WIDTH) {
+ npyv_@sfx@ a = npyv_load_@sfx@(&ip1[i]);
+ npyv_@sfx@ c = npyv_@VOP@_@sfx@(a, a);
+ npyv_store_@sfx@(&op[i], c);
+ }
+ }
+ else {
+ LOOP_BLOCKED(@type@, NPY_SIMD_WIDTH) {
+ npyv_@sfx@ a = npyv_load_@sfx@(&ip1[i]);
+ npyv_@sfx@ b = npyv_load_@sfx@(&ip2[i]);
+ npyv_@sfx@ c = npyv_@VOP@_@sfx@(a, b);
+ npyv_store_@sfx@(&op[i], c);
+ }
+ }
+ LOOP_BLOCKED_END {
+ op[i] = ip1[i] @OP@ ip2[i];
+ }
+}
+
+static void
+simd_binary_scalar1_@kind@_@TYPE@(@type@ * op, @type@ * ip1, @type@ * ip2, npy_intp n)
+{
+ const npyv_@sfx@ v1 = npyv_setall_@sfx@(ip1[0]);
+ LOOP_BLOCK_ALIGN_VAR(op, @type@, NPY_SIMD_WIDTH) {
+ op[i] = ip1[0] @OP@ ip2[i];
+ }
+ LOOP_BLOCKED(@type@, NPY_SIMD_WIDTH) {
+ npyv_@sfx@ v2 = npyv_load_@sfx@(&ip2[i]);
+ npyv_@sfx@ v3 = npyv_@VOP@_@sfx@(v1, v2);
+ npyv_store_@sfx@(&op[i], v3);
+ }
+ LOOP_BLOCKED_END {
+ op[i] = ip1[0] @OP@ ip2[i];
+ }
+}
+
+static void
+simd_binary_scalar2_@kind@_@TYPE@(@type@ * op, @type@ * ip1, @type@ * ip2, npy_intp n)
+{
+ const npyv_@sfx@ v2 = npyv_setall_@sfx@(ip2[0]);
+ LOOP_BLOCK_ALIGN_VAR(op, @type@, NPY_SIMD_WIDTH) {
+ op[i] = ip1[i] @OP@ ip2[0];
+ }
+ LOOP_BLOCKED(@type@, NPY_SIMD_WIDTH) {
+ npyv_@sfx@ v1 = npyv_load_@sfx@(&ip1[i]);
+ npyv_@sfx@ v3 = npyv_@VOP@_@sfx@(v1, v2);
+ npyv_store_@sfx@(&op[i], v3);
+ }
+ LOOP_BLOCKED_END {
+ op[i] = ip1[i] @OP@ ip2[0];
+ }
+}
+/**end repeat1**/
+#endif /* NPY_SIMD@CHK@ */
+/**end repeat**/
+#endif // NPY_HAVE_SSE2
+
+/**begin repeat
+ * Float types
+ * #type = npy_float, npy_double, npy_longdouble#
+ * #TYPE = FLOAT, DOUBLE, LONGDOUBLE#
+ * #vector = 1, 1, 0#
+ * #VECTOR = NPY_SIMD, NPY_SIMD_F64, 0 #
+ */
+/**begin repeat1
+ * Arithmetic
+ * # kind = add, subtract, multiply, divide#
+ */
+static NPY_INLINE int
+run_binary_simd_@kind@_@TYPE@(char **args, npy_intp const *dimensions, npy_intp const *steps)
+{
+#if @vector@ && defined NPY_HAVE_SSE2
+ @type@ * ip1 = (@type@ *)args[0];
+ @type@ * ip2 = (@type@ *)args[1];
+ @type@ * op = (@type@ *)args[2];
+ npy_intp n = dimensions[0];
+#if defined NPY_HAVE_AVX512F
+ const npy_uintp vector_size_bytes = 64;
+#elif defined NPY_HAVE_AVX2
+ const npy_uintp vector_size_bytes = 32;
+#else
+ const npy_uintp vector_size_bytes = 32;
+#endif
+ /* argument one scalar */
+ if (IS_BLOCKABLE_BINARY_SCALAR1(sizeof(@type@), vector_size_bytes)) {
+ sse2_binary_scalar1_@kind@_@TYPE@(op, ip1, ip2, n);
+ return 1;
+ }
+ /* argument two scalar */
+ else if (IS_BLOCKABLE_BINARY_SCALAR2(sizeof(@type@), vector_size_bytes)) {
+ sse2_binary_scalar2_@kind@_@TYPE@(op, ip1, ip2, n);
+ return 1;
+ }
+ else if (IS_BLOCKABLE_BINARY(sizeof(@type@), vector_size_bytes)) {
+ sse2_binary_@kind@_@TYPE@(op, ip1, ip2, n);
+ return 1;
+ }
+#elif @VECTOR@
+ @type@ * ip1 = (@type@ *)args[0];
+ @type@ * ip2 = (@type@ *)args[1];
+ @type@ * op = (@type@ *)args[2];
+ npy_intp n = dimensions[0];
+ /* argument one scalar */
+ if (IS_BLOCKABLE_BINARY_SCALAR1(sizeof(@type@), NPY_SIMD_WIDTH)) {
+ simd_binary_scalar1_@kind@_@TYPE@(op, ip1, ip2, n);
+ return 1;
+ }
+ /* argument two scalar */
+ else if (IS_BLOCKABLE_BINARY_SCALAR2(sizeof(@type@), NPY_SIMD_WIDTH)) {
+ simd_binary_scalar2_@kind@_@TYPE@(op, ip1, ip2, n);
+ return 1;
+ }
+ else if (IS_BLOCKABLE_BINARY(sizeof(@type@), NPY_SIMD_WIDTH)) {
+ simd_binary_@kind@_@TYPE@(op, ip1, ip2, n);
+ return 1;
+ }
+#endif
+ return 0;
+}
+/**end repeat1**/
+/**end repeat**/
+
+/********************************************************************************
+ ** Defining ufunc inner functions
+ ********************************************************************************/
+/**begin repeat
+ * Float types
+ * #type = npy_float, npy_double#
+ * #TYPE = FLOAT, DOUBLE#
+ * #c = f, #
+ * #C = F, #
+ */
+/**begin repeat1
+ * Arithmetic
+ * # kind = add, subtract, multiply, divide#
+ * # OP = +, -, *, /#
+ * # PW = 1, 0, 0, 0#
+ */
+NPY_NO_EXPORT void NPY_CPU_DISPATCH_CURFX(@TYPE@_@kind@)
+(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
+{
+ if (IS_BINARY_REDUCE) {
+#if @PW@
+ @type@ * iop1 = (@type@ *)args[0];
+ npy_intp n = dimensions[0];
+
+ *iop1 @OP@= @TYPE@_pairwise_sum(args[1], n, steps[1]);
+#else
+ BINARY_REDUCE_LOOP(@type@) {
+ io1 @OP@= *(@type@ *)ip2;
+ }
+ *((@type@ *)iop1) = io1;
+#endif
+ }
+ else if (!run_binary_simd_@kind@_@TYPE@(args, dimensions, steps)) {
+ BINARY_LOOP {
+ const @type@ in1 = *(@type@ *)ip1;
+ const @type@ in2 = *(@type@ *)ip2;
+ *((@type@ *)op1) = in1 @OP@ in2;
+ }
+ }
+}
+/**end repeat1**/
+/**end repeat**/
+
+//###############################################################################
+//## Complex Single/Double precision
+//###############################################################################
+/********************************************************************************
+ ** Defining the SIMD kernels
+ ********************************************************************************/
+#if !defined(_MSC_VER) && defined(NPY_HAVE_AVX512F)
+ /**
+ * For somehow MSVC commit aggressive optimization lead
+ * to raises 'RuntimeWarning: invalid value encountered in multiply'
+ *
+ * the issue mainly caused by '_mm512_maskz_loadu_ps', we need to
+ * investigate about it while moving to NPYV.
+ */
+ #define AVX512F_NOMSVC
+#endif
+
+#ifdef AVX512F_NOMSVC
+NPY_FINLINE __mmask16
+avx512_get_full_load_mask_ps(void)
+{
+ return 0xFFFF;
+}
+
+NPY_FINLINE __mmask8
+avx512_get_full_load_mask_pd(void)
+{
+ return 0xFF;
+}
+NPY_FINLINE __m512
+avx512_masked_load_ps(__mmask16 mask, npy_float* addr)
+{
+ return _mm512_maskz_loadu_ps(mask, (__m512 *)addr);
+}
+
+NPY_FINLINE __m512d
+avx512_masked_load_pd(__mmask8 mask, npy_double* addr)
+{
+ return _mm512_maskz_loadu_pd(mask, (__m512d *)addr);
+}
+
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __mmask16
+avx512_get_partial_load_mask_ps(const npy_int num_elem, const npy_int total_elem)
+{
+ return (0x0001 << num_elem) - 0x0001;
+}
+
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __mmask8
+avx512_get_partial_load_mask_pd(const npy_int num_elem, const npy_int total_elem)
+{
+ return (0x01 << num_elem) - 0x01;
+}
+/**begin repeat
+ * #vsub = ps, pd#
+ * #type= npy_float, npy_double#
+ * #epi_vsub = epi32, epi64#
+ * #vtype = __m512, __m512d#
+ * #mask = __mmask16, __mmask8#
+ * #and_const = 0x7fffffff, 0x7fffffffffffffffLL#
+ * #neg_mask = 0x80000000, 0x8000000000000000#
+ * #perm_ = 0xb1, 0x55#
+ * #cmpx_img_mask = 0xAAAA, 0xAA#
+ * #cmpx_re_mask = 0x5555, 0x55#
+ * #INF = NPY_INFINITYF, NPY_INFINITY#
+ * #NAN = NPY_NANF, NPY_NAN#
+ */
+NPY_FINLINE @vtype@
+avx512_hadd_@vsub@(const @vtype@ x)
+{
+ return _mm512_add_@vsub@(x, _mm512_permute_@vsub@(x, @perm_@));
+}
+
+NPY_FINLINE @vtype@
+avx512_hsub_@vsub@(const @vtype@ x)
+{
+ return _mm512_sub_@vsub@(x, _mm512_permute_@vsub@(x, @perm_@));
+}
+NPY_FINLINE @vtype@
+avx512_cmul_@vsub@(@vtype@ x1, @vtype@ x2)
+{
+ // x1 = r1, i1
+ // x2 = r2, i2
+ @vtype@ x3 = _mm512_permute_@vsub@(x2, @perm_@); // i2, r2
+ @vtype@ x12 = _mm512_mul_@vsub@(x1, x2); // r1*r2, i1*i2
+ @vtype@ x13 = _mm512_mul_@vsub@(x1, x3); // r1*i2, r2*i1
+ @vtype@ outreal = avx512_hsub_@vsub@(x12); // r1*r2 - i1*i2, r1*r2 - i1*i2
+ @vtype@ outimg = avx512_hadd_@vsub@(x13); // r1*i2 + i1*r2, r1*i2 + i1*r2
+ return _mm512_mask_blend_@vsub@(@cmpx_img_mask@, outreal, outimg);
+}
+/**end repeat**/
+#endif
+
+/**begin repeat
+ * #TYPE = CFLOAT, CDOUBLE#
+ * #type = npy_float, npy_double#
+ * #num_lanes = 16, 8#
+ * #vsuffix = ps, pd#
+ * #epi_vsub = epi32, epi64#
+ * #mask = __mmask16, __mmask8#
+ * #vtype = __m512, __m512d#
+ * #scale = 4, 8#
+ * #vindextype = __m512i, __m256i#
+ * #vindexload = _mm512_loadu_si512, _mm256_loadu_si256#
+ * #storemask = 0xFF, 0xF#
+ * #IS_FLOAT = 1, 0#
+ */
+/**begin repeat1
+ * #func = add, subtract, multiply#
+ * #vectorf = _mm512_add, _mm512_sub, avx512_cmul#
+ */
+#if defined AVX512F_NOMSVC
+static NPY_INLINE void
+AVX512F_@func@_@TYPE@(char **args, const npy_intp *dimensions, const npy_intp *steps)
+{
+ const npy_intp array_size = dimensions[0];
+ npy_intp num_remaining_elements = 2*array_size;
+ @type@* ip1 = (@type@*) args[0];
+ @type@* ip2 = (@type@*) args[1];
+ @type@* op = (@type@*) args[2];
+
+ @mask@ load_mask = avx512_get_full_load_mask_@vsuffix@();
+
+ while (num_remaining_elements > 0) {
+ if (num_remaining_elements < @num_lanes@) {
+ load_mask = avx512_get_partial_load_mask_@vsuffix@(
+ num_remaining_elements, @num_lanes@);
+ }
+ @vtype@ x1, x2;
+ x1 = avx512_masked_load_@vsuffix@(load_mask, ip1);
+ x2 = avx512_masked_load_@vsuffix@(load_mask, ip2);
+
+ @vtype@ out = @vectorf@_@vsuffix@(x1, x2);
+
+ _mm512_mask_storeu_@vsuffix@(op, load_mask, out);
+
+ ip1 += @num_lanes@;
+ ip2 += @num_lanes@;
+ op += @num_lanes@;
+ num_remaining_elements -= @num_lanes@;
+ }
+}
+#endif // AVX512F_NOMSVC
+/**end repeat1**/
+/**end repeat**/
+
+/**begin repeat
+ * #TYPE = CFLOAT, CDOUBLE#
+ * #type= npy_float, npy_double#
+ * #esize = 8, 16#
+ */
+/**begin repeat1
+ * #func = add, subtract, multiply#
+ */
+static NPY_INLINE int
+run_binary_avx512f_@func@_@TYPE@(char **args, const npy_intp *dimensions, const npy_intp *steps)
+{
+#if defined AVX512F_NOMSVC
+ if (IS_BINARY_STRIDE_ONE(@esize@, 64)) {
+ AVX512F_@func@_@TYPE@(args, dimensions, steps);
+ return 1;
+ }
+ else
+ return 0;
+#endif
+ return 0;
+}
+/**end repeat1**/
+/**end repeat**/
+
+/********************************************************************************
+ ** Defining ufunc inner functions
+ ********************************************************************************/
+/**begin repeat
+ * complex types
+ * #TYPE = CFLOAT, CDOUBLE#
+ * #ftype = npy_float, npy_double#
+ * #c = f, #
+ * #C = F, #
+ */
+/**begin repeat1
+ * arithmetic
+ * #kind = add, subtract#
+ * #OP = +, -#
+ * #PW = 1, 0#
+ */
+NPY_NO_EXPORT void NPY_CPU_DISPATCH_CURFX(@TYPE@_@kind@)
+(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
+{
+ // Parenthesis around @PW@ tells clang dead code is intentional
+ if (IS_BINARY_REDUCE && (@PW@)) {
+ npy_intp n = dimensions[0];
+ @ftype@ * or = ((@ftype@ *)args[0]);
+ @ftype@ * oi = ((@ftype@ *)args[0]) + 1;
+ @ftype@ rr, ri;
+
+ @TYPE@_pairwise_sum(&rr, &ri, args[1], n * 2, steps[1] / 2);
+ *or @OP@= rr;
+ *oi @OP@= ri;
+ return;
+ }
+ if (!run_binary_avx512f_@kind@_@TYPE@(args, dimensions, steps)) {
+ BINARY_LOOP {
+ const @ftype@ in1r = ((@ftype@ *)ip1)[0];
+ const @ftype@ in1i = ((@ftype@ *)ip1)[1];
+ const @ftype@ in2r = ((@ftype@ *)ip2)[0];
+ const @ftype@ in2i = ((@ftype@ *)ip2)[1];
+ ((@ftype@ *)op1)[0] = in1r @OP@ in2r;
+ ((@ftype@ *)op1)[1] = in1i @OP@ in2i;
+ }
+ }
+}
+/**end repeat1**/
+
+NPY_NO_EXPORT void NPY_CPU_DISPATCH_CURFX(@TYPE@_multiply)
+(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
+{
+ if (!run_binary_avx512f_multiply_@TYPE@(args, dimensions, steps)) {
+ BINARY_LOOP {
+ const @ftype@ in1r = ((@ftype@ *)ip1)[0];
+ const @ftype@ in1i = ((@ftype@ *)ip1)[1];
+ const @ftype@ in2r = ((@ftype@ *)ip2)[0];
+ const @ftype@ in2i = ((@ftype@ *)ip2)[1];
+ ((@ftype@ *)op1)[0] = in1r*in2r - in1i*in2i;
+ ((@ftype@ *)op1)[1] = in1r*in2i + in1i*in2r;
+ }
+ }
+}
+/**end repeat**/
diff --git a/numpy/core/src/umath/loops_arithmetic.dispatch.c.src b/numpy/core/src/umath/loops_arithmetic.dispatch.c.src
new file mode 100644
index 000000000..1ddf7c3b1
--- /dev/null
+++ b/numpy/core/src/umath/loops_arithmetic.dispatch.c.src
@@ -0,0 +1,262 @@
+/*@targets
+ ** $maxopt baseline
+ ** sse2 sse41 avx2 avx512f avx512_skx
+ ** vsx2
+ ** neon
+ **/
+#define _UMATHMODULE
+#define _MULTIARRAYMODULE
+#define NPY_NO_DEPRECATED_API NPY_API_VERSION
+
+#include "simd/simd.h"
+#include "loops_utils.h"
+#include "loops.h"
+#include "lowlevel_strided_loops.h"
+// Provides the various *_LOOP macros
+#include "fast_loop_macros.h"
+
+//###############################################################################
+//## Division
+//###############################################################################
+/********************************************************************************
+ ** Defining the SIMD kernels
+ *
+ * Floor division of signed is based on T. Granlund and P. L. Montgomery
+ * "Division by invariant integers using multiplication(see [Figure 6.1]
+ * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.1.2556)"
+ * For details on TRUNC division see simd/intdiv.h for more clarification
+ ***********************************************************************************
+ ** Figure 6.1: Signed division by run-time invariant divisor, rounded towards -INF
+ ***********************************************************************************
+ * For q = FLOOR(a/d), all sword:
+ * sword -dsign = SRL(d, N - 1);
+ * uword -nsign = (n < -dsign);
+ * uword -qsign = EOR(-nsign, -dsign);
+ * q = TRUNC((n - (-dsign ) + (-nsign))/d) - (-qsign);
+ ********************************************************************************/
+
+#if NPY_SIMD
+/**begin repeat
+ * Signed types
+ * #sfx = s8, s16, s32, s64#
+ * #len = 8, 16, 32, 64#
+ */
+static NPY_INLINE void
+simd_divide_by_scalar_contig_@sfx@(char **args, npy_intp len)
+{
+ npyv_lanetype_@sfx@ *src = (npyv_lanetype_@sfx@ *) args[0];
+ npyv_lanetype_@sfx@ scalar = *(npyv_lanetype_@sfx@ *) args[1];
+ npyv_lanetype_@sfx@ *dst = (npyv_lanetype_@sfx@ *) args[2];
+ const int vstep = npyv_nlanes_@sfx@;
+ const npyv_@sfx@x3 divisor = npyv_divisor_@sfx@(scalar);
+
+ if (scalar == -1) {
+ npyv_b@len@ noverflow = npyv_cvt_b@len@_@sfx@(npyv_setall_@sfx@(-1));
+ npyv_@sfx@ vzero = npyv_zero_@sfx@();
+ for (; len >= vstep; len -= vstep, src += vstep, dst += vstep) {
+ npyv_@sfx@ a = npyv_load_@sfx@(src);
+ npyv_b@len@ gt_min = npyv_cmpgt_@sfx@(a, npyv_setall_@sfx@(NPY_MIN_INT@len@));
+ noverflow = npyv_and_b@len@(noverflow, gt_min);
+ npyv_@sfx@ neg = npyv_ifsub_@sfx@(gt_min, vzero, a, vzero);
+ npyv_store_@sfx@(dst, neg);
+ }
+
+ int raise_err = npyv_tobits_b@len@(npyv_not_b@len@(noverflow)) != 0;
+ for (; len > 0; --len, ++src, ++dst) {
+ npyv_lanetype_@sfx@ a = *src;
+ if (a == NPY_MIN_INT@len@) {
+ raise_err = 1;
+ *dst = 0;
+ } else {
+ *dst = -a;
+ }
+ }
+ if (raise_err) {
+ npy_set_floatstatus_divbyzero();
+ }
+ } else {
+ for (; len >= vstep; len -= vstep, src += vstep, dst += vstep) {
+ npyv_@sfx@ nsign_d = npyv_setall_@sfx@(scalar < 0);
+ npyv_@sfx@ a = npyv_load_@sfx@(src);
+ npyv_@sfx@ nsign_a = npyv_cvt_@sfx@_b@len@(npyv_cmplt_@sfx@(a, nsign_d));
+ nsign_a = npyv_and_@sfx@(nsign_a, npyv_setall_@sfx@(1));
+ npyv_@sfx@ diff_sign = npyv_sub_@sfx@(nsign_a, nsign_d);
+ npyv_@sfx@ to_ninf = npyv_xor_@sfx@(nsign_a, nsign_d);
+ npyv_@sfx@ trunc = npyv_divc_@sfx@(npyv_add_@sfx@(a, diff_sign), divisor);
+ npyv_@sfx@ floor = npyv_sub_@sfx@(trunc, to_ninf);
+ npyv_store_@sfx@(dst, floor);
+ }
+
+ for (; len > 0; --len, ++src, ++dst) {
+ const npyv_lanetype_@sfx@ a = *src;
+ npyv_lanetype_@sfx@ r = a / scalar;
+ // Negative quotients needs to be rounded down
+ if (((a > 0) != (scalar > 0)) && ((r * scalar) != a)) {
+ r--;
+ }
+ *dst = r;
+ }
+ }
+ npyv_cleanup();
+}
+/**end repeat**/
+
+/**begin repeat
+ * Unsigned types
+ * #sfx = u8, u16, u32, u64#
+ * #len = 8, 16, 32, 64#
+ */
+static NPY_INLINE void
+simd_divide_by_scalar_contig_@sfx@(char **args, npy_intp len)
+{
+ npyv_lanetype_@sfx@ *src = (npyv_lanetype_@sfx@ *) args[0];
+ npyv_lanetype_@sfx@ scalar = *(npyv_lanetype_@sfx@ *) args[1];
+ npyv_lanetype_@sfx@ *dst = (npyv_lanetype_@sfx@ *) args[2];
+ const int vstep = npyv_nlanes_@sfx@;
+ const npyv_@sfx@x3 divisor = npyv_divisor_@sfx@(scalar);
+
+ for (; len >= vstep; len -= vstep, src += vstep, dst += vstep) {
+ npyv_@sfx@ a = npyv_load_@sfx@(src);
+ npyv_@sfx@ c = npyv_divc_@sfx@(a, divisor);
+ npyv_store_@sfx@(dst, c);
+ }
+
+ for (; len > 0; --len, ++src, ++dst) {
+ const npyv_lanetype_@sfx@ a = *src;
+ *dst = a / scalar;
+ }
+ npyv_cleanup();
+}
+/**end repeat**/
+#endif
+
+/********************************************************************************
+ ** Defining ufunc inner functions
+ ********************************************************************************/
+
+/**begin repeat
+ * Signed types
+ * #type = npy_byte, npy_short, npy_int, npy_long, npy_longlong#
+ * #TYPE = BYTE, SHORT, INT, LONG, LONGLONG#
+ */
+#undef TO_SIMD_SFX
+#if 0
+/**begin repeat1
+ * #len = 8, 16, 32, 64#
+ */
+#elif NPY_BITSOF_@TYPE@ == @len@
+ #define TO_SIMD_SFX(X) X##_s@len@
+/**end repeat1**/
+#endif
+
+#if NPY_BITSOF_@TYPE@ == 64 && !defined(NPY_HAVE_VSX4) && (defined(NPY_HAVE_VSX) || defined(NPY_HAVE_NEON))
+ #undef TO_SIMD_SFX
+#endif
+
+NPY_FINLINE @type@ floor_div_@TYPE@(const @type@ n, const @type@ d)
+{
+ /*
+ * FIXME: On x86 at least, dividing the smallest representable integer
+ * by -1 causes a SIFGPE (division overflow). We treat this case here
+ * (to avoid a SIGFPE crash at python level), but a good solution would
+ * be to treat integer division problems separately from FPU exceptions
+ * (i.e. a different approach than npy_set_floatstatus_divbyzero()).
+ */
+ if (NPY_UNLIKELY(d == 0 || (n == NPY_MIN_@TYPE@ && d == -1))) {
+ npy_set_floatstatus_divbyzero();
+ return 0;
+ }
+ @type@ r = n / d;
+ // Negative quotients needs to be rounded down
+ if (((n > 0) != (d > 0)) && ((r * d) != n)) {
+ r--;
+ }
+ return r;
+}
+
+NPY_NO_EXPORT void NPY_CPU_DISPATCH_CURFX(@TYPE@_divide)
+(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
+{
+ if (IS_BINARY_REDUCE) {
+ BINARY_REDUCE_LOOP(@type@) {
+ io1 = floor_div_@TYPE@(io1, *(@type@*)ip2);
+ }
+ *((@type@ *)iop1) = io1;
+ }
+#if NPY_SIMD && defined(TO_SIMD_SFX)
+ // for contiguous block of memory, divisor is a scalar and not 0
+ else if (IS_BLOCKABLE_BINARY_SCALAR2(sizeof(@type@), NPY_SIMD_WIDTH) &&
+ (*(@type@ *)args[1]) != 0) {
+ TO_SIMD_SFX(simd_divide_by_scalar_contig)(args, dimensions[0]);
+ }
+#endif
+ else {
+ BINARY_LOOP {
+ *((@type@ *)op1) = floor_div_@TYPE@(*(@type@*)ip1, *(@type@*)ip2);
+ }
+ }
+}
+/**end repeat**/
+
+/**begin repeat
+ * Unsigned types
+ * #type = npy_ubyte, npy_ushort, npy_uint, npy_ulong, npy_ulonglong#
+ * #TYPE = UBYTE, USHORT, UINT, ULONG, ULONGLONG#
+ * #STYPE = BYTE, SHORT, INT, LONG, LONGLONG#
+ */
+#undef TO_SIMD_SFX
+#if 0
+/**begin repeat1
+ * #len = 8, 16, 32, 64#
+ */
+#elif NPY_BITSOF_@STYPE@ == @len@
+ #define TO_SIMD_SFX(X) X##_u@len@
+/**end repeat1**/
+#endif
+/*
+ * For 64-bit division on Armv7, Aarch64, and IBM/Power, NPYV fall-backs to the scalar division
+ * because emulating multiply-high on these architectures is going to be expensive comparing
+ * to the native scalar dividers.
+ * Therefore it's better to disable NPYV in this special case to avoid any unnecessary shuffles.
+ * Power10(VSX4) is an exception here since it has native support for integer vector division,
+ * note neither infrastructure nor NPYV has supported VSX4 yet.
+ */
+#if NPY_BITSOF_@STYPE@ == 64 && !defined(NPY_HAVE_VSX4) && (defined(NPY_HAVE_VSX) || defined(NPY_HAVE_NEON))
+ #undef TO_SIMD_SFX
+#endif
+NPY_NO_EXPORT void NPY_CPU_DISPATCH_CURFX(@TYPE@_divide)
+(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
+{
+ if (IS_BINARY_REDUCE) {
+ BINARY_REDUCE_LOOP(@type@) {
+ const @type@ d = *(@type@ *)ip2;
+ if (NPY_UNLIKELY(d == 0)) {
+ npy_set_floatstatus_divbyzero();
+ io1 = 0;
+ } else {
+ io1 /= d;
+ }
+ }
+ *((@type@ *)iop1) = io1;
+ }
+#if NPY_SIMD && defined(TO_SIMD_SFX)
+ // for contiguous block of memory, divisor is a scalar and not 0
+ else if (IS_BLOCKABLE_BINARY_SCALAR2(sizeof(@type@), NPY_SIMD_WIDTH) &&
+ (*(@type@ *)args[1]) != 0) {
+ TO_SIMD_SFX(simd_divide_by_scalar_contig)(args, dimensions[0]);
+ }
+#endif
+ else {
+ BINARY_LOOP {
+ const @type@ in1 = *(@type@ *)ip1;
+ const @type@ in2 = *(@type@ *)ip2;
+ if (NPY_UNLIKELY(in2 == 0)) {
+ npy_set_floatstatus_divbyzero();
+ *((@type@ *)op1) = 0;
+ } else{
+ *((@type@ *)op1) = in1 / in2;
+ }
+ }
+ }
+}
+/**end repeat**/
diff --git a/numpy/core/src/umath/loops_exponent_log.dispatch.c.src b/numpy/core/src/umath/loops_exponent_log.dispatch.c.src
new file mode 100644
index 000000000..b17643d23
--- /dev/null
+++ b/numpy/core/src/umath/loops_exponent_log.dispatch.c.src
@@ -0,0 +1,1305 @@
+/*@targets
+ ** $maxopt baseline
+ ** (avx2 fma3) avx512f avx512_skx
+ **/
+
+#define _UMATHMODULE
+#define _MULTIARRAYMODULE
+#define NPY_NO_DEPRECATED_API NPY_API_VERSION
+
+#include <float.h>
+
+#include "numpy/npy_math.h"
+#include "simd/simd.h"
+#include "loops_utils.h"
+#include "loops.h"
+#include "lowlevel_strided_loops.h"
+// Provides the various *_LOOP macros
+#include "fast_loop_macros.h"
+#include "npy_simd_data.h"
+
+// TODO: tweak & replace raw SIMD with NPYV
+
+/********************************************************************************
+ ** bunch of helper functions used in ISA_exp/log_FLOAT
+ ********************************************************************************/
+#if !defined(_MSC_VER) && defined(NPY_HAVE_AVX512F)
+ /**
+ * For somehow MSVC commit aggressive optimization lead
+ * to raises 'RuntimeWarning: RuntimeWarning: overflow encountered in exp'
+ *
+ * the issue mainly caused by '_mm512_maskz_loadu_ps', we need to
+ * investigate about it while moving to NPYV.
+ */
+ #define SIMD_AVX512F
+#elif defined(NPY_HAVE_AVX2) && defined(NPY_HAVE_FMA3)
+ #define SIMD_AVX2_FMA3
+#endif
+#if !defined(_MSC_VER) && defined(NPY_HAVE_AVX512_SKX)
+ #define SIMD_AVX512_SKX
+#endif
+#if defined(SIMD_AVX512F) && !(defined(__clang__) && (__clang_major__ < 10 || \
+ (__clang_major__ == 10 && __clang_minor__ < 1)))
+ #define SIMD_AVX512F_NOCLANG_BUG
+#endif
+
+#ifdef SIMD_AVX2_FMA3
+
+NPY_FINLINE __m256
+fma_get_full_load_mask_ps(void)
+{
+ return _mm256_set1_ps(-1.0);
+}
+
+NPY_FINLINE __m256i
+fma_get_full_load_mask_pd(void)
+{
+ return _mm256_castpd_si256(_mm256_set1_pd(-1.0));
+}
+
+NPY_FINLINE __m256
+fma_get_partial_load_mask_ps(const npy_int num_elem, const npy_int num_lanes)
+{
+ float maskint[16] = {-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,
+ 1.0,1.0,1.0,1.0,1.0,1.0,1.0,1.0};
+ float* addr = maskint + num_lanes - num_elem;
+ return _mm256_loadu_ps(addr);
+}
+
+NPY_FINLINE __m256i
+fma_get_partial_load_mask_pd(const npy_int num_elem, const npy_int num_lanes)
+{
+ npy_int maskint[16] = {-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1};
+ npy_int* addr = maskint + 2*num_lanes - 2*num_elem;
+ return _mm256_loadu_si256((__m256i*) addr);
+}
+
+NPY_FINLINE __m256
+fma_masked_gather_ps(__m256 src,
+ npy_float* addr,
+ __m256i vindex,
+ __m256 mask)
+{
+ return _mm256_mask_i32gather_ps(src, addr, vindex, mask, 4);
+}
+
+NPY_FINLINE __m256d
+fma_masked_gather_pd(__m256d src,
+ npy_double* addr,
+ __m128i vindex,
+ __m256d mask)
+{
+ return _mm256_mask_i32gather_pd(src, addr, vindex, mask, 8);
+}
+
+NPY_FINLINE __m256
+fma_masked_load_ps(__m256 mask, npy_float* addr)
+{
+ return _mm256_maskload_ps(addr, _mm256_cvtps_epi32(mask));
+}
+
+NPY_FINLINE __m256d
+fma_masked_load_pd(__m256i mask, npy_double* addr)
+{
+ return _mm256_maskload_pd(addr, mask);
+}
+
+NPY_FINLINE __m256
+fma_set_masked_lanes_ps(__m256 x, __m256 val, __m256 mask)
+{
+ return _mm256_blendv_ps(x, val, mask);
+}
+
+NPY_FINLINE __m256d
+fma_set_masked_lanes_pd(__m256d x, __m256d val, __m256d mask)
+{
+ return _mm256_blendv_pd(x, val, mask);
+}
+
+NPY_FINLINE __m256
+fma_blend(__m256 x, __m256 y, __m256 ymask)
+{
+ return _mm256_blendv_ps(x, y, ymask);
+}
+
+NPY_FINLINE __m256
+fma_invert_mask_ps(__m256 ymask)
+{
+ return _mm256_andnot_ps(ymask, _mm256_set1_ps(-1.0));
+}
+
+NPY_FINLINE __m256i
+fma_invert_mask_pd(__m256i ymask)
+{
+ return _mm256_andnot_si256(ymask, _mm256_set1_epi32(0xFFFFFFFF));
+}
+
+NPY_FINLINE __m256
+fma_get_exponent(__m256 x)
+{
+ /*
+ * Special handling of denormals:
+ * 1) Multiply denormal elements with 2**100 (0x71800000)
+ * 2) Get the 8 bits of unbiased exponent
+ * 3) Subtract 100 from exponent of denormals
+ */
+
+ __m256 two_power_100 = _mm256_castsi256_ps(_mm256_set1_epi32(0x71800000));
+ __m256 denormal_mask = _mm256_cmp_ps(x, _mm256_set1_ps(FLT_MIN), _CMP_LT_OQ);
+ __m256 normal_mask = _mm256_cmp_ps(x, _mm256_set1_ps(FLT_MIN), _CMP_GE_OQ);
+
+ /*
+ * The volatile is probably unnecessary now since we compile clang with
+ * `-ftrapping-math`: https://github.com/numpy/numpy/issues/18005
+ */
+ volatile __m256 temp1 = _mm256_blendv_ps(x, _mm256_set1_ps(0.0f), normal_mask);
+ __m256 temp = _mm256_mul_ps(temp1, two_power_100);
+ x = _mm256_blendv_ps(x, temp, denormal_mask);
+
+ __m256 exp = _mm256_cvtepi32_ps(
+ _mm256_sub_epi32(
+ _mm256_srli_epi32(
+ _mm256_castps_si256(x), 23),_mm256_set1_epi32(0x7E)));
+
+ __m256 denorm_exp = _mm256_sub_ps(exp, _mm256_set1_ps(100.0f));
+ return _mm256_blendv_ps(exp, denorm_exp, denormal_mask);
+}
+
+NPY_FINLINE __m256
+fma_get_mantissa(__m256 x)
+{
+ /*
+ * Special handling of denormals:
+ * 1) Multiply denormal elements with 2**100 (0x71800000)
+ * 2) Get the 23 bits of mantissa
+ * 3) Mantissa for denormals is not affected by the multiplication
+ */
+
+ __m256 two_power_100 = _mm256_castsi256_ps(_mm256_set1_epi32(0x71800000));
+ __m256 denormal_mask = _mm256_cmp_ps(x, _mm256_set1_ps(FLT_MIN), _CMP_LT_OQ);
+ __m256 normal_mask = _mm256_cmp_ps(x, _mm256_set1_ps(FLT_MIN), _CMP_GE_OQ);
+
+ /*
+ * The volatile is probably unnecessary now since we compile clang with
+ * `-ftrapping-math`: https://github.com/numpy/numpy/issues/18005
+ */
+ volatile __m256 temp1 = _mm256_blendv_ps(x, _mm256_set1_ps(0.0f), normal_mask);
+ __m256 temp = _mm256_mul_ps(temp1, two_power_100);
+ x = _mm256_blendv_ps(x, temp, denormal_mask);
+
+ __m256i mantissa_bits = _mm256_set1_epi32(0x7fffff);
+ __m256i exp_126_bits = _mm256_set1_epi32(126 << 23);
+ return _mm256_castsi256_ps(
+ _mm256_or_si256(
+ _mm256_and_si256(
+ _mm256_castps_si256(x), mantissa_bits), exp_126_bits));
+}
+
+NPY_FINLINE __m256
+fma_scalef_ps(__m256 poly, __m256 quadrant)
+{
+ /*
+ * Handle denormals (which occur when quadrant <= -125):
+ * 1) This function computes poly*(2^quad) by adding the exponent of
+ poly to quad
+ * 2) When quad <= -125, the output is a denormal and the above logic
+ breaks down
+ * 3) To handle such cases, we split quadrant: -125 + (quadrant + 125)
+ * 4) poly*(2^-125) is computed the usual way
+ * 5) 2^(quad-125) can be computed by: 2 << abs(quad-125)
+ * 6) The final div operation generates the denormal
+ */
+ __m256 minquadrant = _mm256_set1_ps(-125.0f);
+ __m256 denormal_mask = _mm256_cmp_ps(quadrant, minquadrant, _CMP_LE_OQ);
+ if (_mm256_movemask_ps(denormal_mask) != 0x0000) {
+ __m256 quad_diff = _mm256_sub_ps(quadrant, minquadrant);
+ quad_diff = _mm256_sub_ps(_mm256_setzero_ps(), quad_diff);
+ quad_diff = _mm256_blendv_ps(_mm256_setzero_ps(), quad_diff, denormal_mask);
+ __m256i two_power_diff = _mm256_sllv_epi32(
+ _mm256_set1_epi32(1), _mm256_cvtps_epi32(quad_diff));
+ quadrant = _mm256_max_ps(quadrant, minquadrant); //keep quadrant >= -126
+ __m256i exponent = _mm256_slli_epi32(_mm256_cvtps_epi32(quadrant), 23);
+ poly = _mm256_castsi256_ps(
+ _mm256_add_epi32(
+ _mm256_castps_si256(poly), exponent));
+ __m256 denorm_poly = _mm256_div_ps(poly, _mm256_cvtepi32_ps(two_power_diff));
+ return _mm256_blendv_ps(poly, denorm_poly, denormal_mask);
+ }
+ else {
+ __m256i exponent = _mm256_slli_epi32(_mm256_cvtps_epi32(quadrant), 23);
+ poly = _mm256_castsi256_ps(
+ _mm256_add_epi32(
+ _mm256_castps_si256(poly), exponent));
+ return poly;
+ }
+}
+
+#endif // SIMD_AVX2_FMA3
+
+#ifdef SIMD_AVX512F
+
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __mmask16
+avx512_get_full_load_mask_ps(void)
+{
+ return 0xFFFF;
+}
+
+NPY_FINLINE __mmask8
+avx512_get_full_load_mask_pd(void)
+{
+ return 0xFF;
+}
+
+NPY_FINLINE __mmask16
+avx512_get_partial_load_mask_ps(const npy_int num_elem, const npy_int total_elem)
+{
+ return (0x0001 << num_elem) - 0x0001;
+}
+
+NPY_FINLINE __mmask8
+avx512_get_partial_load_mask_pd(const npy_int num_elem, const npy_int total_elem)
+{
+ return (0x01 << num_elem) - 0x01;
+}
+
+NPY_FINLINE __m512
+avx512_masked_gather_ps(__m512 src,
+ npy_float* addr,
+ __m512i vindex,
+ __mmask16 kmask)
+{
+ return _mm512_mask_i32gather_ps(src, kmask, vindex, addr, 4);
+}
+
+NPY_FINLINE __m512d
+avx512_masked_gather_pd(__m512d src,
+ npy_double* addr,
+ __m256i vindex,
+ __mmask8 kmask)
+{
+ return _mm512_mask_i32gather_pd(src, kmask, vindex, addr, 8);
+}
+
+NPY_FINLINE __m512
+avx512_masked_load_ps(__mmask16 mask, npy_float* addr)
+{
+ return _mm512_maskz_loadu_ps(mask, (__m512 *)addr);
+}
+
+NPY_FINLINE __m512d
+avx512_masked_load_pd(__mmask8 mask, npy_double* addr)
+{
+ return _mm512_maskz_loadu_pd(mask, (__m512d *)addr);
+}
+
+NPY_FINLINE __m512
+avx512_set_masked_lanes_ps(__m512 x, __m512 val, __mmask16 mask)
+{
+ return _mm512_mask_blend_ps(mask, x, val);
+}
+
+NPY_FINLINE __m512d
+avx512_set_masked_lanes_pd(__m512d x, __m512d val, __mmask8 mask)
+{
+ return _mm512_mask_blend_pd(mask, x, val);
+}
+
+NPY_FINLINE __m512
+avx512_blend(__m512 x, __m512 y, __mmask16 ymask)
+{
+ return _mm512_mask_mov_ps(x, ymask, y);
+}
+
+NPY_FINLINE __mmask16
+avx512_invert_mask_ps(__mmask16 ymask)
+{
+ return _mm512_knot(ymask);
+}
+
+NPY_FINLINE __mmask8
+avx512_invert_mask_pd(__mmask8 ymask)
+{
+ return _mm512_knot(ymask);
+}
+
+NPY_FINLINE __m512
+avx512_get_exponent(__m512 x)
+{
+ return _mm512_add_ps(_mm512_getexp_ps(x), _mm512_set1_ps(1.0f));
+}
+
+NPY_FINLINE __m512
+avx512_get_mantissa(__m512 x)
+{
+ return _mm512_getmant_ps(x, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src);
+}
+
+NPY_FINLINE __m512
+avx512_scalef_ps(__m512 poly, __m512 quadrant)
+{
+ return _mm512_scalef_ps(poly, quadrant);
+}
+
+NPY_FINLINE __m512d
+avx512_permute_x4var_pd(__m512d t0,
+ __m512d t1,
+ __m512d t2,
+ __m512d t3,
+ __m512i index)
+{
+ __mmask8 lut_mask = _mm512_cmp_epi64_mask(
+ _mm512_and_epi64(_mm512_set1_epi64(0x10ULL), index),
+ _mm512_set1_epi64(0), _MM_CMPINT_GT);
+ __m512d res1 = _mm512_permutex2var_pd(t0, index, t1);
+ __m512d res2 = _mm512_permutex2var_pd(t2, index, t3);
+ return _mm512_mask_blend_pd(lut_mask, res1, res2);
+}
+
+NPY_FINLINE __m512d
+avx512_permute_x8var_pd(__m512d t0, __m512d t1, __m512d t2, __m512d t3,
+ __m512d t4, __m512d t5, __m512d t6, __m512d t7,
+ __m512i index)
+{
+ __mmask8 lut_mask = _mm512_cmp_epi64_mask(
+ _mm512_and_epi64(_mm512_set1_epi64(0x20ULL), index),
+ _mm512_set1_epi64(0), _MM_CMPINT_GT);
+ __m512d res1 = avx512_permute_x4var_pd(t0, t1, t2, t3, index);
+ __m512d res2 = avx512_permute_x4var_pd(t4, t5, t6, t7, index);
+ return _mm512_mask_blend_pd(lut_mask, res1, res2);
+}
+
+#endif // SIMD_AVX512F
+
+/********************************************************************************
+ ** Defining the SIMD kernels
+ ********************************************************************************/
+/**begin repeat
+ * #ISA = FMA, AVX512F#
+ * #isa = fma, avx512#
+ * #vtype = __m256, __m512#
+ * #vsize = 256, 512#
+ * #BYTES = 32, 64#
+ * #NUM_LANES = 8, 16#
+ * #mask = __m256, __mmask16#
+ * #vsub = , _mask#
+ * #or_masks =_mm256_or_ps, _mm512_kor#
+ * #and_masks =_mm256_and_ps, _mm512_kand#
+ * #xor_masks =_mm256_xor_ps, _mm512_kxor#
+ * #fmadd = _mm256_fmadd_ps, _mm512_fmadd_ps#
+ * #mask_to_int = _mm256_movemask_ps, #
+ * #full_mask= 0xFF, 0xFFFF#
+ * #masked_store = _mm256_maskstore_ps, _mm512_mask_storeu_ps#
+ * #cvtps_epi32 = _mm256_cvtps_epi32, #
+ * #CHK = SIMD_AVX2_FMA3, SIMD_AVX512F#
+ */
+#ifdef @CHK@
+/*
+ * Vectorized Cody-Waite range reduction technique
+ * Performs the reduction step x* = x - y*C in three steps:
+ * 1) x* = x - y*c1
+ * 2) x* = x - y*c2
+ * 3) x* = x - y*c3
+ * c1, c2 are exact floating points, c3 = C - c1 - c2 simulates higher precision
+ */
+NPY_FINLINE @vtype@
+simd_range_reduction(@vtype@ x, @vtype@ y, @vtype@ c1, @vtype@ c2, @vtype@ c3)
+{
+ @vtype@ reduced_x = @fmadd@(y, c1, x);
+ reduced_x = @fmadd@(y, c2, reduced_x);
+ reduced_x = @fmadd@(y, c3, reduced_x);
+ return reduced_x;
+}
+/*
+ * Vectorized implementation of exp using AVX2 and AVX512:
+ * 1) if x >= xmax; return INF (overflow)
+ * 2) if x <= xmin; return 0.0f (underflow)
+ * 3) Range reduction (using Coyd-Waite):
+ * a) y = x - k*ln(2); k = rint(x/ln(2)); y \in [0, ln(2)]
+ * 4) Compute exp(y) = P/Q, ratio of 2 polynomials P and Q
+ * b) P = 5th order and Q = 2nd order polynomials obtained from Remez's
+ * algorithm (mini-max polynomial approximation)
+ * 5) Compute exp(x) = exp(y) * 2^k
+ * 6) Max ULP error measured across all 32-bit FP's = 2.52 (x = 0xc2781e37)
+ * 7) Max relative error measured across all 32-bit FP's= 2.1264E-07 (for the
+ * same x = 0xc2781e37)
+ */
+static void
+simd_exp_FLOAT(npy_float * op,
+ npy_float * ip,
+ const npy_intp array_size,
+ const npy_intp steps)
+{
+ const npy_intp stride = steps/(npy_intp)sizeof(npy_float);
+ const npy_int num_lanes = @BYTES@/(npy_intp)sizeof(npy_float);
+ npy_float xmax = 88.72283935546875f;
+ npy_float xmin = -103.97208404541015625f;
+
+ /*
+ * Note: while generally indices are npy_intp, we ensure that our maximum index
+ * will fit in an int32 as a precondition for this function via
+ * IS_OUTPUT_BLOCKABLE_UNARY
+ */
+ npy_int32 indexarr[16];
+ for (npy_int32 ii = 0; ii < 16; ii++) {
+ indexarr[ii] = ii*stride;
+ }
+
+ /* Load up frequently used constants */
+ @vtype@ codyw_c1 = _mm@vsize@_set1_ps(NPY_CODY_WAITE_LOGE_2_HIGHf);
+ @vtype@ codyw_c2 = _mm@vsize@_set1_ps(NPY_CODY_WAITE_LOGE_2_LOWf);
+ @vtype@ exp_p0 = _mm@vsize@_set1_ps(NPY_COEFF_P0_EXPf);
+ @vtype@ exp_p1 = _mm@vsize@_set1_ps(NPY_COEFF_P1_EXPf);
+ @vtype@ exp_p2 = _mm@vsize@_set1_ps(NPY_COEFF_P2_EXPf);
+ @vtype@ exp_p3 = _mm@vsize@_set1_ps(NPY_COEFF_P3_EXPf);
+ @vtype@ exp_p4 = _mm@vsize@_set1_ps(NPY_COEFF_P4_EXPf);
+ @vtype@ exp_p5 = _mm@vsize@_set1_ps(NPY_COEFF_P5_EXPf);
+ @vtype@ exp_q0 = _mm@vsize@_set1_ps(NPY_COEFF_Q0_EXPf);
+ @vtype@ exp_q1 = _mm@vsize@_set1_ps(NPY_COEFF_Q1_EXPf);
+ @vtype@ exp_q2 = _mm@vsize@_set1_ps(NPY_COEFF_Q2_EXPf);
+ @vtype@ cvt_magic = _mm@vsize@_set1_ps(NPY_RINT_CVT_MAGICf);
+ @vtype@ log2e = _mm@vsize@_set1_ps(NPY_LOG2Ef);
+ @vtype@ inf = _mm@vsize@_set1_ps(NPY_INFINITYF);
+ @vtype@ zeros_f = _mm@vsize@_set1_ps(0.0f);
+ @vtype@ poly, num_poly, denom_poly, quadrant;
+ @vtype@i vindex = _mm@vsize@_loadu_si@vsize@((@vtype@i*)&indexarr[0]);
+
+ @mask@ xmax_mask, xmin_mask, nan_mask, inf_mask;
+ @mask@ overflow_mask = @isa@_get_partial_load_mask_ps(0, num_lanes);
+ @mask@ underflow_mask = @isa@_get_partial_load_mask_ps(0, num_lanes);
+ @mask@ load_mask = @isa@_get_full_load_mask_ps();
+ npy_intp num_remaining_elements = array_size;
+
+ while (num_remaining_elements > 0) {
+
+ if (num_remaining_elements < num_lanes) {
+ load_mask = @isa@_get_partial_load_mask_ps(num_remaining_elements,
+ num_lanes);
+ }
+
+ @vtype@ x;
+ if (stride == 1) {
+ x = @isa@_masked_load_ps(load_mask, ip);
+ }
+ else {
+ x = @isa@_masked_gather_ps(zeros_f, ip, vindex, load_mask);
+ }
+
+ nan_mask = _mm@vsize@_cmp_ps@vsub@(x, x, _CMP_NEQ_UQ);
+ x = @isa@_set_masked_lanes_ps(x, zeros_f, nan_mask);
+
+ xmax_mask = _mm@vsize@_cmp_ps@vsub@(x, _mm@vsize@_set1_ps(xmax), _CMP_GE_OQ);
+ xmin_mask = _mm@vsize@_cmp_ps@vsub@(x, _mm@vsize@_set1_ps(xmin), _CMP_LE_OQ);
+ inf_mask = _mm@vsize@_cmp_ps@vsub@(x, inf, _CMP_EQ_OQ);
+ overflow_mask = @or_masks@(overflow_mask,
+ @xor_masks@(xmax_mask, inf_mask));
+ underflow_mask = @or_masks@(underflow_mask, xmin_mask);
+
+ x = @isa@_set_masked_lanes_ps(x, zeros_f, @or_masks@(
+ @or_masks@(nan_mask, xmin_mask), xmax_mask));
+
+ quadrant = _mm@vsize@_mul_ps(x, log2e);
+
+ /* round to nearest */
+ quadrant = _mm@vsize@_add_ps(quadrant, cvt_magic);
+ quadrant = _mm@vsize@_sub_ps(quadrant, cvt_magic);
+
+ /* Cody-Waite's range reduction algorithm */
+ x = simd_range_reduction(x, quadrant, codyw_c1, codyw_c2, zeros_f);
+
+ num_poly = @fmadd@(exp_p5, x, exp_p4);
+ num_poly = @fmadd@(num_poly, x, exp_p3);
+ num_poly = @fmadd@(num_poly, x, exp_p2);
+ num_poly = @fmadd@(num_poly, x, exp_p1);
+ num_poly = @fmadd@(num_poly, x, exp_p0);
+ denom_poly = @fmadd@(exp_q2, x, exp_q1);
+ denom_poly = @fmadd@(denom_poly, x, exp_q0);
+ poly = _mm@vsize@_div_ps(num_poly, denom_poly);
+
+ /*
+ * compute val = poly * 2^quadrant; which is same as adding the
+ * exponent of quadrant to the exponent of poly. quadrant is an int,
+ * so extracting exponent is simply extracting 8 bits.
+ */
+ poly = @isa@_scalef_ps(poly, quadrant);
+
+ /*
+ * elem > xmax; return inf
+ * elem < xmin; return 0.0f
+ * elem = +/- nan, return nan
+ */
+ poly = @isa@_set_masked_lanes_ps(poly, _mm@vsize@_set1_ps(NPY_NANF), nan_mask);
+ poly = @isa@_set_masked_lanes_ps(poly, inf, xmax_mask);
+ poly = @isa@_set_masked_lanes_ps(poly, zeros_f, xmin_mask);
+
+ @masked_store@(op, @cvtps_epi32@(load_mask), poly);
+
+ ip += num_lanes*stride;
+ op += num_lanes;
+ num_remaining_elements -= num_lanes;
+ }
+
+ if (@mask_to_int@(overflow_mask)) {
+ npy_set_floatstatus_overflow();
+ }
+
+ if (@mask_to_int@(underflow_mask)) {
+ npy_set_floatstatus_underflow();
+ }
+}
+
+/*
+ * Vectorized implementation of log using AVX2 and AVX512
+ * 1) if x < 0.0f; return -NAN (invalid input)
+ * 2) Range reduction: y = x/2^k;
+ * a) y = normalized mantissa, k is the exponent (0.5 <= y < 1)
+ * 3) Compute log(y) = P/Q, ratio of 2 polynomials P and Q
+ * b) P = 5th order and Q = 5th order polynomials obtained from Remez's
+ * algorithm (mini-max polynomial approximation)
+ * 5) Compute log(x) = log(y) + k*ln(2)
+ * 6) Max ULP error measured across all 32-bit FP's = 3.83 (x = 0x3f486945)
+ * 7) Max relative error measured across all 32-bit FP's = 2.359E-07 (for same
+ * x = 0x3f486945)
+ */
+
+static void
+simd_log_FLOAT(npy_float * op,
+ npy_float * ip,
+ const npy_intp array_size,
+ const npy_intp steps)
+{
+ const npy_intp stride = steps/(npy_intp)sizeof(npy_float);
+ const npy_int num_lanes = @BYTES@/(npy_intp)sizeof(npy_float);
+
+ /*
+ * Note: while generally indices are npy_intp, we ensure that our maximum index
+ * will fit in an int32 as a precondition for this function via
+ * IS_OUTPUT_BLOCKABLE_UNARY
+ */
+ npy_int32 indexarr[16];
+ for (npy_int32 ii = 0; ii < 16; ii++) {
+ indexarr[ii] = ii*stride;
+ }
+
+ /* Load up frequently used constants */
+ @vtype@ log_p0 = _mm@vsize@_set1_ps(NPY_COEFF_P0_LOGf);
+ @vtype@ log_p1 = _mm@vsize@_set1_ps(NPY_COEFF_P1_LOGf);
+ @vtype@ log_p2 = _mm@vsize@_set1_ps(NPY_COEFF_P2_LOGf);
+ @vtype@ log_p3 = _mm@vsize@_set1_ps(NPY_COEFF_P3_LOGf);
+ @vtype@ log_p4 = _mm@vsize@_set1_ps(NPY_COEFF_P4_LOGf);
+ @vtype@ log_p5 = _mm@vsize@_set1_ps(NPY_COEFF_P5_LOGf);
+ @vtype@ log_q0 = _mm@vsize@_set1_ps(NPY_COEFF_Q0_LOGf);
+ @vtype@ log_q1 = _mm@vsize@_set1_ps(NPY_COEFF_Q1_LOGf);
+ @vtype@ log_q2 = _mm@vsize@_set1_ps(NPY_COEFF_Q2_LOGf);
+ @vtype@ log_q3 = _mm@vsize@_set1_ps(NPY_COEFF_Q3_LOGf);
+ @vtype@ log_q4 = _mm@vsize@_set1_ps(NPY_COEFF_Q4_LOGf);
+ @vtype@ log_q5 = _mm@vsize@_set1_ps(NPY_COEFF_Q5_LOGf);
+ @vtype@ loge2 = _mm@vsize@_set1_ps(NPY_LOGE2f);
+ @vtype@ nan = _mm@vsize@_set1_ps(NPY_NANF);
+ @vtype@ neg_nan = _mm@vsize@_set1_ps(-NPY_NANF);
+ @vtype@ neg_inf = _mm@vsize@_set1_ps(-NPY_INFINITYF);
+ @vtype@ inf = _mm@vsize@_set1_ps(NPY_INFINITYF);
+ @vtype@ zeros_f = _mm@vsize@_set1_ps(0.0f);
+ @vtype@ ones_f = _mm@vsize@_set1_ps(1.0f);
+ @vtype@i vindex = _mm@vsize@_loadu_si@vsize@((@vtype@i*)indexarr);
+ @vtype@ poly, num_poly, denom_poly, exponent;
+
+ @mask@ inf_mask, nan_mask, sqrt2_mask, zero_mask, negx_mask;
+ @mask@ invalid_mask = @isa@_get_partial_load_mask_ps(0, num_lanes);
+ @mask@ divide_by_zero_mask = invalid_mask;
+ @mask@ load_mask = @isa@_get_full_load_mask_ps();
+ npy_intp num_remaining_elements = array_size;
+
+ while (num_remaining_elements > 0) {
+
+ if (num_remaining_elements < num_lanes) {
+ load_mask = @isa@_get_partial_load_mask_ps(num_remaining_elements,
+ num_lanes);
+ }
+
+ @vtype@ x_in;
+ if (stride == 1) {
+ x_in = @isa@_masked_load_ps(load_mask, ip);
+ }
+ else {
+ x_in = @isa@_masked_gather_ps(zeros_f, ip, vindex, load_mask);
+ }
+
+ negx_mask = _mm@vsize@_cmp_ps@vsub@(x_in, zeros_f, _CMP_LT_OQ);
+ zero_mask = _mm@vsize@_cmp_ps@vsub@(x_in, zeros_f, _CMP_EQ_OQ);
+ inf_mask = _mm@vsize@_cmp_ps@vsub@(x_in, inf, _CMP_EQ_OQ);
+ nan_mask = _mm@vsize@_cmp_ps@vsub@(x_in, x_in, _CMP_NEQ_UQ);
+ divide_by_zero_mask = @or_masks@(divide_by_zero_mask,
+ @and_masks@(zero_mask, load_mask));
+ invalid_mask = @or_masks@(invalid_mask, negx_mask);
+
+ @vtype@ x = @isa@_set_masked_lanes_ps(x_in, zeros_f, negx_mask);
+
+ /* set x = normalized mantissa */
+ exponent = @isa@_get_exponent(x);
+ x = @isa@_get_mantissa(x);
+
+ /* if x < sqrt(2) {exp = exp-1; x = 2*x} */
+ sqrt2_mask = _mm@vsize@_cmp_ps@vsub@(x, _mm@vsize@_set1_ps(NPY_SQRT1_2f), _CMP_LE_OQ);
+ x = @isa@_blend(x, _mm@vsize@_add_ps(x,x), sqrt2_mask);
+ exponent = @isa@_blend(exponent,
+ _mm@vsize@_sub_ps(exponent,ones_f), sqrt2_mask);
+
+ /* x = x - 1 */
+ x = _mm@vsize@_sub_ps(x, ones_f);
+
+ /* Polynomial approximation for log(1+x) */
+ num_poly = @fmadd@(log_p5, x, log_p4);
+ num_poly = @fmadd@(num_poly, x, log_p3);
+ num_poly = @fmadd@(num_poly, x, log_p2);
+ num_poly = @fmadd@(num_poly, x, log_p1);
+ num_poly = @fmadd@(num_poly, x, log_p0);
+ denom_poly = @fmadd@(log_q5, x, log_q4);
+ denom_poly = @fmadd@(denom_poly, x, log_q3);
+ denom_poly = @fmadd@(denom_poly, x, log_q2);
+ denom_poly = @fmadd@(denom_poly, x, log_q1);
+ denom_poly = @fmadd@(denom_poly, x, log_q0);
+ poly = _mm@vsize@_div_ps(num_poly, denom_poly);
+ poly = @fmadd@(exponent, loge2, poly);
+
+ /*
+ * x < 0.0f; return -NAN
+ * x = +/- NAN; return NAN
+ * x = 0.0f; return -INF
+ */
+ poly = @isa@_set_masked_lanes_ps(poly, nan, nan_mask);
+ poly = @isa@_set_masked_lanes_ps(poly, neg_nan, negx_mask);
+ poly = @isa@_set_masked_lanes_ps(poly, neg_inf, zero_mask);
+ poly = @isa@_set_masked_lanes_ps(poly, inf, inf_mask);
+
+ @masked_store@(op, @cvtps_epi32@(load_mask), poly);
+
+ ip += num_lanes*stride;
+ op += num_lanes;
+ num_remaining_elements -= num_lanes;
+ }
+
+ if (@mask_to_int@(invalid_mask)) {
+ npy_set_floatstatus_invalid();
+ }
+ if (@mask_to_int@(divide_by_zero_mask)) {
+ npy_set_floatstatus_divbyzero();
+ }
+}
+#endif // @CHK@
+/**end repeat**/
+
+#ifdef SIMD_AVX512F_NOCLANG_BUG
+/*
+ * Vectorized implementation of exp double using AVX512
+ * Reference: Tang, P.T.P., "Table-driven implementation of the
+ * exponential function in IEEE floating-point
+ * arithmetic," ACM Transactions on Mathematical
+ * Software, vol. 15, pp. 144-157, 1989.
+ * 1) if x > mTH_max or x is INF; return INF (overflow)
+ * 2) if x < mTH_min; return 0.0f (underflow)
+ * 3) if abs(x) < mTH_nearzero; return 1.0f + x
+ * 4) if x is Nan; return Nan
+ * 5) Range reduction:
+ * x = (32m + j)ln2 / 32 + r; r in [-ln2/64, ln2/64]
+ * 6) exp(r) - 1 is approximated by a polynomial function p(r)
+ * exp(x) = 2^m(2^(j/32) + 2^(j/32)p(r));
+ */
+static void
+AVX512F_exp_DOUBLE(npy_double * op,
+ npy_double * ip,
+ const npy_intp array_size,
+ const npy_intp steps)
+{
+ npy_intp num_remaining_elements = array_size;
+ const npy_intp stride = steps / (npy_intp)sizeof(npy_double);
+ const npy_int num_lanes = 64 / (npy_intp)sizeof(npy_double);
+ npy_int32 indexarr[8];
+ for (npy_int32 ii = 0; ii < 8; ii++) {
+ indexarr[ii] = ii*stride;
+ }
+
+ __m512d InvLn2N = _mm512_set1_pd(NPY_INV_LN2_MUL_32);
+ __m512d mShift = _mm512_set1_pd(NPY_RINT_CVT_MAGIC);
+ __m512d mNegL1 = _mm512_set1_pd(NPY_TANG_NEG_L1);
+ __m512d mNegL2 = _mm512_set1_pd(NPY_TANG_NEG_L2);
+ __m512i mMod = _mm512_set1_epi64(0x1f);
+ __m512d mA1 = _mm512_set1_pd(NPY_TANG_A1);
+ __m512d mA2 = _mm512_set1_pd(NPY_TANG_A2);
+ __m512d mA3 = _mm512_set1_pd(NPY_TANG_A3);
+ __m512d mA4 = _mm512_set1_pd(NPY_TANG_A4);
+ __m512d mA5 = _mm512_set1_pd(NPY_TANG_A5);
+ __m512d mTH_nearzero = _mm512_set1_pd(0x1p-54);
+ __m512d mTH_max = _mm512_set1_pd(0x1.62e42fefa39efp+9);
+ __m512d mTH_min = _mm512_set1_pd(-0x1.74910d52d3053p+9);
+ __m512d mTH_inf = _mm512_set1_pd(NPY_INFINITY);
+ __m512d zeros_d = _mm512_set1_pd(0.0f);
+ __m512d ones_d = _mm512_set1_pd(1.0f);
+ __m256i vindex = _mm256_loadu_si256((__m256i*)&indexarr[0]);
+
+ __m512d mTable_top_0 = _mm512_loadu_pd(&(EXP_Table_top[8*0]));
+ __m512d mTable_top_1 = _mm512_loadu_pd(&(EXP_Table_top[8*1]));
+ __m512d mTable_top_2 = _mm512_loadu_pd(&(EXP_Table_top[8*2]));
+ __m512d mTable_top_3 = _mm512_loadu_pd(&(EXP_Table_top[8*3]));
+ __m512d mTable_tail_0 = _mm512_loadu_pd(&(EXP_Table_tail[8*0]));
+ __m512d mTable_tail_1 = _mm512_loadu_pd(&(EXP_Table_tail[8*1]));
+ __m512d mTable_tail_2 = _mm512_loadu_pd(&(EXP_Table_tail[8*2]));
+ __m512d mTable_tail_3 = _mm512_loadu_pd(&(EXP_Table_tail[8*3]));
+
+ __mmask8 overflow_mask = avx512_get_partial_load_mask_pd(0, num_lanes);
+ __mmask8 underflow_mask = avx512_get_partial_load_mask_pd(0, num_lanes);
+ __mmask8 load_mask = avx512_get_full_load_mask_pd();
+ __mmask8 xmin_mask, xmax_mask, inf_mask, nan_mask, nearzero_mask;
+
+ while (num_remaining_elements > 0) {
+ if (num_remaining_elements < num_lanes) {
+ load_mask = avx512_get_partial_load_mask_pd(num_remaining_elements,
+ num_lanes);
+ }
+
+ __m512d x;
+ if (1 == stride) {
+ x = avx512_masked_load_pd(load_mask, ip);
+ }
+ else {
+ x = avx512_masked_gather_pd(zeros_d, ip, vindex, load_mask);
+ }
+
+ nan_mask = _mm512_cmp_pd_mask(x, x, _CMP_NEQ_UQ);
+ x = avx512_set_masked_lanes_pd(x, zeros_d, nan_mask);
+ xmax_mask = _mm512_cmp_pd_mask(x, mTH_max, _CMP_GT_OQ);
+ xmin_mask = _mm512_cmp_pd_mask(x, mTH_min, _CMP_LT_OQ);
+ inf_mask = _mm512_cmp_pd_mask(x, mTH_inf, _CMP_EQ_OQ);
+ __m512i x_abs = _mm512_and_epi64(_mm512_castpd_si512(x),
+ _mm512_set1_epi64(0x7FFFFFFFFFFFFFFF));
+ nearzero_mask = _mm512_cmp_pd_mask(_mm512_castsi512_pd(x_abs),
+ mTH_nearzero, _CMP_LT_OQ);
+ nearzero_mask = _mm512_kxor(nearzero_mask, nan_mask);
+ overflow_mask = _mm512_kor(overflow_mask,
+ _mm512_kxor(xmax_mask, inf_mask));
+ underflow_mask = _mm512_kor(underflow_mask, xmin_mask);
+ x = avx512_set_masked_lanes_pd(x, zeros_d,
+ _mm512_kor(_mm512_kor(nan_mask, xmin_mask),
+ _mm512_kor(xmax_mask, nearzero_mask)));
+
+ /* z = x * 32/ln2 */
+ __m512d z = _mm512_mul_pd(x, InvLn2N);
+
+ /* round to nearest */
+ __m512d kd = _mm512_add_pd(z, mShift);
+ __m512i ki = _mm512_castpd_si512(kd);
+ kd = _mm512_sub_pd(kd, mShift);
+
+ /* r = (x + kd*mNegL1) + kd*mNegL2 */
+ __m512d r1 = _mm512_fmadd_pd(kd, mNegL1, x);
+ __m512d r2 = _mm512_mul_pd(kd, mNegL2);
+ __m512d r = _mm512_add_pd(r1,r2);
+
+ /* Polynomial approximation for exp(r) - 1 */
+ __m512d q = _mm512_fmadd_pd(mA5, r, mA4);
+ q = _mm512_fmadd_pd(q, r, mA3);
+ q = _mm512_fmadd_pd(q, r, mA2);
+ q = _mm512_fmadd_pd(q, r, mA1);
+ q = _mm512_mul_pd(q, r);
+ __m512d p = _mm512_fmadd_pd(r, q, r2);;
+ p = _mm512_add_pd(r1, p);
+
+ /* Get 2^(j/32) from lookup table */
+ __m512i j = _mm512_and_epi64(ki, mMod);
+ __m512d top = avx512_permute_x4var_pd(mTable_top_0, mTable_top_1,
+ mTable_top_2, mTable_top_3, j);
+ __m512d tail = avx512_permute_x4var_pd(mTable_tail_0, mTable_tail_1,
+ mTable_tail_2, mTable_tail_3, j);
+
+ /*
+ * s = top + tail;
+ * exp(x) = 2^m * (top + (tail + s * p));
+ */
+ __m512d s = _mm512_add_pd(top, tail);
+ __m512d res = _mm512_fmadd_pd(s, p, tail);
+ res = _mm512_add_pd(res, top);
+ res= _mm512_scalef_pd(res, _mm512_div_pd(kd, _mm512_set1_pd(32)));
+
+ /* return special cases */
+ res = avx512_set_masked_lanes_pd(res, _mm512_add_pd(x, ones_d),
+ nearzero_mask);
+ res = avx512_set_masked_lanes_pd(res, _mm512_set1_pd(NPY_NAN),
+ nan_mask);
+ res = avx512_set_masked_lanes_pd(res, mTH_inf, xmax_mask);
+ res = avx512_set_masked_lanes_pd(res, zeros_d, xmin_mask);
+
+ _mm512_mask_storeu_pd(op, load_mask, res);
+
+ ip += num_lanes * stride;
+ op += num_lanes;
+ num_remaining_elements -= num_lanes;
+ }
+ if (overflow_mask) {
+ npy_set_floatstatus_overflow();
+ }
+
+ if (underflow_mask) {
+ npy_set_floatstatus_underflow();
+ }
+}
+/*
+ * Vectorized implementation of log double using AVX512
+ * Reference:
+ * [1] Tang, Ping Tak Peter. Table-lookup algorithms for elementary functions
+ * and their error analysis. No. CONF-9106103-1. Argonne National Lab.,
+ * IL (USA), 1991.
+ * [2] Tang, Ping-Tak Peter. "Table-driven implementation of the logarithm
+ * function in IEEE floating-point arithmetic." ACM Transactions on
+ * Mathematical Software (TOMS) 16.4 (1990): 378-400.
+ * [3] Muller, Jean-Michel. "Elementary functions: algorithms and
+ * implementation." (2016).
+ * 1) if x = 0; return -INF
+ * 2) if x < 0; return NAN
+ * 3) if x is INF; return INF
+ * 4) if x is NAN; return NAN
+ * 5) if x on (1.0 - 0x1p-4, 1.0 + 0x1.09p-4), calling npy_log()
+ * 6) Range reduction:
+ * log(x) = log(2^m * z)
+ * = mln2 + log(z)
+ * 7) log(z) = log(z / c_k) + log(c_k);
+ * where c_k = 1 + k/64, k = 0,1,...,64
+ * s.t. |x - c_k| <= 1/128 when x on[1,2].
+ * 8) r = 2(x - c_k)/(x + c_k)
+ * log(x/c_k) = log((1 + r/2) / (1 - r/2))
+ * = p(r)
+ * = 2((r/2) + 1/3*(r/2)^3 + 1/5*(r/2)^5 + ...)
+ */
+static void
+AVX512F_log_DOUBLE(npy_double * op,
+ npy_double * ip,
+ const npy_intp array_size,
+ const npy_intp steps)
+{
+ npy_intp num_remaining_elements = array_size;
+ const npy_intp stride = steps / (npy_intp)sizeof(npy_double);
+ const npy_int num_lanes = 64 / (npy_intp)sizeof(npy_double);
+ npy_int32 indexarr[8];
+ for (npy_int32 ii = 0; ii < 8; ii++) {
+ indexarr[ii] = ii*stride;
+ }
+
+ __m512d zeros_d = _mm512_set1_pd(0.0f);
+ __m512d ones_d = _mm512_set1_pd(1.0f);
+ __m512d mInf = _mm512_set1_pd(NPY_INFINITY);
+ __m512d mInv64 = _mm512_castsi512_pd(_mm512_set1_epi64(0x3f90000000000000));
+ __m512d mNeg_nan = _mm512_set1_pd(-NPY_NAN);
+ __m512d mNan = _mm512_set1_pd(NPY_NAN);
+ __m512d mNeg_inf = _mm512_set1_pd(-NPY_INFINITY);
+ __m512d mA1 = _mm512_set1_pd(NPY_TANG_LOG_A1);
+ __m512d mA2 = _mm512_set1_pd(NPY_TANG_LOG_A2);
+ __m512d mA3 = _mm512_set1_pd(NPY_TANG_LOG_A3);
+ __m512d mA4 = _mm512_set1_pd(NPY_TANG_LOG_A4);
+ __m512d mLN2HI = _mm512_set1_pd(NPY_TANG_LOG_LN2HI);
+ __m512d mLN2LO = _mm512_set1_pd(NPY_TANG_LOG_LN2LO);
+
+ __m512d mTo_glibc_min = _mm512_set1_pd(1.0 - 0x1p-4);
+ __m512d mTo_glibc_max = _mm512_set1_pd(1.0 + 0x1.09p-4);
+ __m256i vindex = _mm256_loadu_si256((__m256i*)&indexarr[0]);
+
+ /* Load lookup table data */
+ /**begin repeat
+ * #i = 0, 1, 2, 3, 4, 5, 6, 7#
+ */
+
+ __m512d mLUT_TOP_@i@ = _mm512_loadu_pd(&(LOG_TABLE_TOP[8*@i@]));
+ __m512d mLUT_TAIL_@i@ = _mm512_loadu_pd(&(LOG_TABLE_TAIL[8*@i@]));
+
+ /**end repeat**/
+
+ __mmask8 load_mask = avx512_get_full_load_mask_pd();
+ __mmask8 invalid_mask = avx512_get_partial_load_mask_pd(0, num_lanes);
+ __mmask8 divide_by_zero_mask = invalid_mask;
+
+ __mmask8 inf_mask, nan_mask, zero_mask, negx_mask, denormal_mask,
+ glibc_mask;
+
+ __m512d x_in;
+ while (num_remaining_elements > 0) {
+ if (num_remaining_elements < num_lanes) {
+ load_mask = avx512_get_partial_load_mask_pd(num_remaining_elements,
+ num_lanes);
+ }
+
+ if (1 == stride) {
+ x_in = avx512_masked_load_pd(load_mask, ip);
+ }
+ else {
+ x_in = avx512_masked_gather_pd(zeros_d, ip, vindex, load_mask);
+ }
+
+ /* call glibc when x on [1.0 - 0x1p-4, 1.0 + 0x1.09p-4] */
+ __mmask8 m1 = _mm512_cmp_pd_mask(x_in, mTo_glibc_max, _CMP_LT_OQ);
+ __mmask8 m2 = _mm512_cmp_pd_mask(x_in, mTo_glibc_min, _CMP_GT_OQ);
+ glibc_mask = m1 & m2;
+
+ if (glibc_mask != 0xFF) {
+ zero_mask = _mm512_cmp_pd_mask(x_in, zeros_d, _CMP_EQ_OQ);
+ inf_mask = _mm512_cmp_pd_mask(x_in, mInf, _CMP_EQ_OQ);
+ negx_mask = _mm512_cmp_pd_mask(x_in, zeros_d, _CMP_LT_OQ);
+ nan_mask = _mm512_cmp_pd_mask(x_in, x_in, _CMP_NEQ_UQ);
+
+ divide_by_zero_mask = divide_by_zero_mask | (zero_mask & load_mask);
+ invalid_mask = invalid_mask | negx_mask;
+
+ __m512d x = avx512_set_masked_lanes_pd(x_in, zeros_d, negx_mask);
+ __m512i ix = _mm512_castpd_si512(x);
+
+ /* Normalize x when it is denormal */
+ __m512i top12 = _mm512_and_epi64(ix,
+ _mm512_set1_epi64(0xfff0000000000000));
+ denormal_mask = _mm512_cmp_epi64_mask(top12, _mm512_set1_epi64(0),
+ _CMP_EQ_OQ);
+ denormal_mask = (~zero_mask) & denormal_mask;
+ ix = _mm512_castpd_si512(_mm512_mask_mul_pd(x, denormal_mask,
+ x, _mm512_set1_pd(0x1p52)));
+ ix = _mm512_mask_sub_epi64(ix, denormal_mask,
+ ix, _mm512_set1_epi64(52ULL << 52));
+
+ /*
+ * x = 2^k * z; where z in range [1,2]
+ */
+ __m512i tmp = _mm512_sub_epi64(ix,
+ _mm512_set1_epi64(0x3ff0000000000000));
+ __m512i i = _mm512_and_epi64(_mm512_srai_epi64(tmp, 52 - 6),
+ _mm512_set1_epi64(0x3fULL));
+ __m512i ik = _mm512_srai_epi64(tmp, 52);
+ __m512d z = _mm512_castsi512_pd(_mm512_sub_epi64(ix, _mm512_and_epi64(tmp,
+ _mm512_set1_epi64(0xfff0000000000000))));
+ /* c = i/64 + 1 */
+ __m256i i_32 = _mm512_cvtepi64_epi32(i);
+ __m512d c = _mm512_fmadd_pd(_mm512_cvtepi32_pd(i_32), mInv64, ones_d);
+
+ /* u = 2 * (z - c) / (z + c) */
+ __m512d u = _mm512_div_pd(_mm512_sub_pd(z, c), _mm512_add_pd(z, c));
+ u = _mm512_mul_pd(_mm512_set1_pd(2.0), u);
+
+ /* v = u * u */
+ __m512d v = _mm512_mul_pd(u,u);
+
+ /* log(z/c) = u + u*v*(A1 + v*(A2 + v*(A3 + v*A4))) */
+ __m512d res = _mm512_fmadd_pd(v, mA4, mA3);
+ res = _mm512_fmadd_pd(v, res, mA2);
+ res = _mm512_fmadd_pd(v, res, mA1);
+ res = _mm512_mul_pd(v, res);
+ res = _mm512_fmadd_pd(u, res, u);
+
+ /* Load lookup table data */
+ __m512d c_hi = avx512_permute_x8var_pd(mLUT_TOP_0, mLUT_TOP_1,
+ mLUT_TOP_2, mLUT_TOP_3, mLUT_TOP_4, mLUT_TOP_5,
+ mLUT_TOP_6, mLUT_TOP_7, i);
+ __m512d c_lo = avx512_permute_x8var_pd(mLUT_TAIL_0, mLUT_TAIL_1,
+ mLUT_TAIL_2, mLUT_TAIL_3, mLUT_TAIL_4, mLUT_TAIL_5,
+ mLUT_TAIL_6, mLUT_TAIL_7, i);
+
+ /*
+ * log(x) = k * ln2_hi + c_hi +
+ * k * ln2_lo + c_lo +
+ * log(z/c)
+ */
+ __m256i ik_32 = _mm512_cvtepi64_epi32(ik);
+ __m512d k = _mm512_cvtepi32_pd(ik_32);
+ __m512d tt = _mm512_fmadd_pd(k, mLN2HI, c_hi);
+ __m512d tt2 = _mm512_fmadd_pd(k, mLN2LO, c_lo);
+ tt = _mm512_add_pd(tt, tt2);
+ res = _mm512_add_pd(tt, res);
+
+ /* return special cases */
+ res = avx512_set_masked_lanes_pd(res, mNan, nan_mask);
+ res = avx512_set_masked_lanes_pd(res, mNeg_nan, negx_mask);
+ res = avx512_set_masked_lanes_pd(res, mNeg_inf, zero_mask);
+ res = avx512_set_masked_lanes_pd(res, mInf, inf_mask);
+
+ _mm512_mask_storeu_pd(op, load_mask, res);
+ }
+
+ /* call glibc's log func when x around 1.0f */
+ if (glibc_mask != 0) {
+ double NPY_DECL_ALIGNED(64) ip_fback[8];
+ _mm512_store_pd(ip_fback, x_in);
+
+ for (int ii = 0; ii < 8; ++ii, glibc_mask >>= 1) {
+ if (glibc_mask & 0x01) {
+ op[ii] = npy_log(ip_fback[ii]);
+ }
+ }
+ }
+ ip += num_lanes * stride;
+ op += num_lanes;
+ num_remaining_elements -= num_lanes;
+ }
+
+ if (invalid_mask) {
+ npy_set_floatstatus_invalid();
+ }
+ if (divide_by_zero_mask) {
+ npy_set_floatstatus_divbyzero();
+ }
+}
+#endif // AVX512F_NOCLANG_BUG
+
+#ifdef SIMD_AVX512_SKX
+/**begin repeat
+ * #type = npy_float, npy_double#
+ * #TYPE = FLOAT, DOUBLE#
+ * #num_lanes = 16, 8#
+ * #vsuffix = ps, pd#
+ * #mask = __mmask16, __mmask8#
+ * #vtype1 = __m512, __m512d#
+ * #vtype2 = __m512i, __m256i#
+ * #scale = 4, 8#
+ * #vindextype = __m512i, __m256i#
+ * #vindexsize = 512, 256#
+ * #vindexload = _mm512_loadu_si512, _mm256_loadu_si256#
+ * #vtype2_load = _mm512_maskz_loadu_epi32, _mm256_maskz_loadu_epi32#
+ * #vtype2_gather = _mm512_mask_i32gather_epi32, _mm256_mmask_i32gather_epi32#
+ * #vtype2_store = _mm512_mask_storeu_epi32, _mm256_mask_storeu_epi32#
+ * #vtype2_scatter = _mm512_mask_i32scatter_epi32, _mm256_mask_i32scatter_epi32#
+ * #setzero = _mm512_setzero_epi32, _mm256_setzero_si256#
+ */
+static NPY_INLINE void
+AVX512_SKX_ldexp_@TYPE@(char **args, npy_intp const *dimensions, npy_intp const *steps)
+{
+ const npy_intp stride_ip1 = steps[0]/(npy_intp)sizeof(@type@);
+ const npy_intp stride_ip2 = steps[1]/(npy_intp)sizeof(int);
+ const npy_intp stride_op = steps[2]/(npy_intp)sizeof(@type@);
+ const npy_intp array_size = dimensions[0];
+ npy_intp num_remaining_elements = array_size;
+ @type@* ip1 = (@type@*) args[0];
+ int* ip2 = (int*) args[1];
+ @type@* op = (@type@*) args[2];
+
+ @mask@ load_mask = avx512_get_full_load_mask_@vsuffix@();
+
+ /*
+ * Note: while generally indices are npy_intp, we ensure that our maximum index
+ * will fit in an int32 as a precondition for this function via
+ * IS_BINARY_SMALL_STEPS_AND_NOMEMOVERLAP
+ */
+
+ npy_int32 index_ip1[@num_lanes@], index_ip2[@num_lanes@], index_op[@num_lanes@];
+ for (npy_int32 ii = 0; ii < @num_lanes@; ii++) {
+ index_ip1[ii] = ii*stride_ip1;
+ index_ip2[ii] = ii*stride_ip2;
+ index_op[ii] = ii*stride_op;
+ }
+ @vindextype@ vindex_ip1 = @vindexload@((@vindextype@*)&index_ip1[0]);
+ @vindextype@ vindex_ip2 = @vindexload@((@vindextype@*)&index_ip2[0]);
+ @vindextype@ vindex_op = @vindexload@((@vindextype@*)&index_op[0]);
+ @vtype1@ zeros_f = _mm512_setzero_@vsuffix@();
+ @vtype2@ zeros = @setzero@();
+
+ while (num_remaining_elements > 0) {
+ if (num_remaining_elements < @num_lanes@) {
+ load_mask = avx512_get_partial_load_mask_@vsuffix@(
+ num_remaining_elements, @num_lanes@);
+ }
+ @vtype1@ x1;
+ @vtype2@ x2;
+ if (stride_ip1 == 1) {
+ x1 = avx512_masked_load_@vsuffix@(load_mask, ip1);
+ }
+ else {
+ x1 = avx512_masked_gather_@vsuffix@(zeros_f, ip1, vindex_ip1, load_mask);
+ }
+ if (stride_ip2 == 1) {
+ x2 = @vtype2_load@(load_mask, ip2);
+ }
+ else {
+ x2 = @vtype2_gather@(zeros, load_mask, vindex_ip2, ip2, 4);
+ }
+
+ @vtype1@ out = _mm512_scalef_@vsuffix@(x1, _mm512_cvtepi32_@vsuffix@(x2));
+
+ if (stride_op == 1) {
+ _mm512_mask_storeu_@vsuffix@(op, load_mask, out);
+ }
+ else {
+ /* scatter! */
+ _mm512_mask_i32scatter_@vsuffix@(op, load_mask, vindex_op, out, @scale@);
+ }
+
+ ip1 += @num_lanes@*stride_ip1;
+ ip2 += @num_lanes@*stride_ip2;
+ op += @num_lanes@*stride_op;
+ num_remaining_elements -= @num_lanes@;
+ }
+}
+
+static NPY_INLINE void
+AVX512_SKX_frexp_@TYPE@(char **args, npy_intp const *dimensions, npy_intp const *steps)
+{
+ const npy_intp stride_ip1 = steps[0]/(npy_intp)sizeof(@type@);
+ const npy_intp stride_op1 = steps[1]/(npy_intp)sizeof(@type@);
+ const npy_intp stride_op2 = steps[2]/(npy_intp)sizeof(int);
+ const npy_intp array_size = dimensions[0];
+ npy_intp num_remaining_elements = array_size;
+ @type@* ip1 = (@type@*) args[0];
+ @type@* op1 = (@type@*) args[1];
+ int* op2 = (int*) args[2];
+
+ @mask@ load_mask = avx512_get_full_load_mask_@vsuffix@();
+
+ /*
+ * Note: while generally indices are npy_intp, we ensure that our maximum index
+ * will fit in an int32 as a precondition for this function via
+ * IS_BINARY_SMALL_STEPS_AND_NOMEMOVERLAP
+ */
+
+ npy_int32 index_ip1[@num_lanes@], index_op1[@num_lanes@], index_op2[@num_lanes@];
+ for (npy_int32 ii = 0; ii < @num_lanes@; ii++) {
+ index_ip1[ii] = ii*stride_ip1;
+ index_op1[ii] = ii*stride_op1;
+ index_op2[ii] = ii*stride_op2;
+ }
+ @vindextype@ vindex_ip1 = @vindexload@((@vindextype@*)&index_ip1[0]);
+ @vindextype@ vindex_op1 = @vindexload@((@vindextype@*)&index_op1[0]);
+ @vindextype@ vindex_op2 = @vindexload@((@vindextype@*)&index_op2[0]);
+ @vtype1@ zeros_f = _mm512_setzero_@vsuffix@();
+
+ while (num_remaining_elements > 0) {
+ if (num_remaining_elements < @num_lanes@) {
+ load_mask = avx512_get_partial_load_mask_@vsuffix@(
+ num_remaining_elements, @num_lanes@);
+ }
+ @vtype1@ x1;
+ if (stride_ip1 == 1) {
+ x1 = avx512_masked_load_@vsuffix@(load_mask, ip1);
+ }
+ else {
+ x1 = avx512_masked_gather_@vsuffix@(zeros_f, ip1, vindex_ip1, load_mask);
+ }
+
+ /*
+ * The x86 instructions vpgetmant and vpgetexp do not conform
+ * with NumPy's output for special floating points: NAN, +/-INF, +/-0.0
+ * We mask these values with spmask to avoid invalid exceptions.
+ */
+ @mask@ spmask =_mm512_knot(_mm512_fpclass_@vsuffix@_mask(
+ x1, 0b10011111));
+ @vtype1@ out1 = _mm512_maskz_getmant_@vsuffix@(
+ spmask, x1, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src);
+ out1 = _mm512_mask_mov_@vsuffix@(x1, spmask, out1);
+ @vtype2@ out2 = _mm512_cvt@vsuffix@_epi32(
+ _mm512_maskz_add_@vsuffix@(spmask, _mm512_set1_@vsuffix@(1.0),
+ _mm512_maskz_getexp_@vsuffix@(spmask, x1)));
+ if (stride_op1 == 1) {
+ _mm512_mask_storeu_@vsuffix@(op1, load_mask, out1);
+ }
+ else {
+ _mm512_mask_i32scatter_@vsuffix@(op1, load_mask, vindex_op1, out1, @scale@);
+ }
+ if (stride_op2 == 1) {
+ @vtype2_store@(op2, load_mask, out2);
+ }
+ else {
+ @vtype2_scatter@(op2, load_mask, vindex_op2, out2, 4);
+ }
+
+ ip1 += @num_lanes@*stride_ip1;
+ op1 += @num_lanes@*stride_op1;
+ op2 += @num_lanes@*stride_op2;
+ num_remaining_elements -= @num_lanes@;
+ }
+}
+/**end repeat**/
+#endif // SIMD_AVX512_SKX
+
+
+/********************************************************************************
+ ** Defining ufunc inner functions
+ ********************************************************************************/
+/**begin repeat
+ * #func = exp, log#
+ * #scalarf = npy_expf, npy_logf#
+ */
+NPY_NO_EXPORT void NPY_CPU_DISPATCH_CURFX(FLOAT_@func@)
+(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(data))
+{
+#if defined(SIMD_AVX2_FMA3) || defined(SIMD_AVX512F)
+ // third arg in `IS_OUTPUT_BLOCKABLE_UNARY` is dummy
+ // TODO: get ride of this macro during the move to NPYV
+ if (IS_OUTPUT_BLOCKABLE_UNARY(sizeof(npy_float), sizeof(npy_float), 64)) {
+ simd_@func@_FLOAT((npy_float*)args[1], (npy_float*)args[0], dimensions[0], steps[0]);
+ }
+ else {
+ UNARY_LOOP {
+ /*
+ * We use the AVX function to compute exp/log for scalar elements as well.
+ * This is needed to ensure the output of strided and non-strided
+ * cases match. SIMD code handles strided input cases, but not
+ * strided output.
+ */
+ simd_@func@_FLOAT((npy_float *)op1, (npy_float *)ip1, 1, steps[0]);
+ }
+ }
+#else
+ UNARY_LOOP {
+ const npy_float in1 = *(npy_float *)ip1;
+ *(npy_float *)op1 = @scalarf@(in1);
+ }
+#endif
+}
+/**end repeat**/
+
+/**begin repeat
+ * #func = exp, log#
+ * #scalar = npy_exp, npy_log#
+ */
+NPY_NO_EXPORT void NPY_CPU_DISPATCH_CURFX(DOUBLE_@func@)
+(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(data))
+{
+#ifdef SIMD_AVX512F_NOCLANG_BUG
+ if (IS_OUTPUT_BLOCKABLE_UNARY(sizeof(npy_double), sizeof(npy_double), 64)) {
+ AVX512F_@func@_DOUBLE((npy_double*)args[1], (npy_double*)args[0], dimensions[0], steps[0]);
+ return;
+ }
+#endif
+ UNARY_LOOP {
+ const npy_double in1 = *(npy_double *)ip1;
+ *(npy_double *)op1 = @scalar@(in1);
+ }
+}
+/**end repeat**/
+
+/**begin repeat
+ * Float types
+ * #type = npy_float, npy_double#
+ * #TYPE = FLOAT, DOUBLE#
+ * #c = f, #
+ * #C = F, #
+ */
+NPY_NO_EXPORT void NPY_CPU_DISPATCH_CURFX(@TYPE@_frexp)
+(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
+{
+#ifdef SIMD_AVX512_SKX
+ if (IS_UNARY_TWO_OUT_SMALL_STEPS_AND_NOMEMOVERLAP) {
+ AVX512_SKX_frexp_@TYPE@(args, dimensions, steps);
+ return;
+ }
+#endif
+ UNARY_LOOP_TWO_OUT {
+ const @type@ in1 = *(@type@ *)ip1;
+ *((@type@ *)op1) = npy_frexp@c@(in1, (int *)op2);
+ }
+}
+
+NPY_NO_EXPORT void NPY_CPU_DISPATCH_CURFX(@TYPE@_ldexp)
+(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(func))
+{
+#ifdef SIMD_AVX512_SKX
+ if (IS_BINARY_SMALL_STEPS_AND_NOMEMOVERLAP) {
+ AVX512_SKX_ldexp_@TYPE@(args, dimensions, steps);
+ return;
+ }
+#endif
+ BINARY_LOOP {
+ const @type@ in1 = *(@type@ *)ip1;
+ const int in2 = *(int *)ip2;
+ *((@type@ *)op1) = npy_ldexp@c@(in1, in2);
+ }
+}
+/**end repeat**/
diff --git a/numpy/core/src/umath/loops_trigonometric.dispatch.c.src b/numpy/core/src/umath/loops_trigonometric.dispatch.c.src
new file mode 100644
index 000000000..8c2c83e7c
--- /dev/null
+++ b/numpy/core/src/umath/loops_trigonometric.dispatch.c.src
@@ -0,0 +1,230 @@
+/*@targets
+ ** $maxopt baseline
+ ** (avx2 fma3) avx512f
+ ** vsx2
+ ** neon_vfpv4
+ **/
+#include "numpy/npy_math.h"
+#include "simd/simd.h"
+#include "loops_utils.h"
+#include "loops.h"
+/*
+ * TODO:
+ * - use vectorized version of Payne-Hanek style reduction for large elements or
+ * when there's no native FUSED support instead of fallback to libc
+ */
+#if NPY_SIMD_FMA3 // native support
+/*
+ * Vectorized Cody-Waite range reduction technique
+ * Performs the reduction step x* = x - y*C in three steps:
+ * 1) x* = x - y*c1
+ * 2) x* = x - y*c2
+ * 3) x* = x - y*c3
+ * c1, c2 are exact floating points, c3 = C - c1 - c2 simulates higher precision
+ */
+NPY_FINLINE npyv_f32
+simd_range_reduction_f32(npyv_f32 x, npyv_f32 y, npyv_f32 c1, npyv_f32 c2, npyv_f32 c3)
+{
+ npyv_f32 reduced_x = npyv_muladd_f32(y, c1, x);
+ reduced_x = npyv_muladd_f32(y, c2, reduced_x);
+ reduced_x = npyv_muladd_f32(y, c3, reduced_x);
+ return reduced_x;
+}
+/*
+ * Approximate cosine algorithm for x \in [-PI/4, PI/4]
+ * Maximum ULP across all 32-bit floats = 0.875
+ */
+NPY_FINLINE npyv_f32
+simd_cosine_poly_f32(npyv_f32 x2)
+{
+ const npyv_f32 invf8 = npyv_setall_f32(0x1.98e616p-16f);
+ const npyv_f32 invf6 = npyv_setall_f32(-0x1.6c06dcp-10f);
+ const npyv_f32 invf4 = npyv_setall_f32(0x1.55553cp-05f);
+ const npyv_f32 invf2 = npyv_setall_f32(-0x1.000000p-01f);
+ const npyv_f32 invf0 = npyv_setall_f32(0x1.000000p+00f);
+
+ npyv_f32 r = npyv_muladd_f32(invf8, x2, invf6);
+ r = npyv_muladd_f32(r, x2, invf4);
+ r = npyv_muladd_f32(r, x2, invf2);
+ r = npyv_muladd_f32(r, x2, invf0);
+ return r;
+}
+/*
+ * Approximate sine algorithm for x \in [-PI/4, PI/4]
+ * Maximum ULP across all 32-bit floats = 0.647
+ * Polynomial approximation based on unpublished work by T. Myklebust
+ */
+NPY_FINLINE npyv_f32
+simd_sine_poly_f32(npyv_f32 x, npyv_f32 x2)
+{
+ const npyv_f32 invf9 = npyv_setall_f32(0x1.7d3bbcp-19f);
+ const npyv_f32 invf7 = npyv_setall_f32(-0x1.a06bbap-13f);
+ const npyv_f32 invf5 = npyv_setall_f32(0x1.11119ap-07f);
+ const npyv_f32 invf3 = npyv_setall_f32(-0x1.555556p-03f);
+
+ npyv_f32 r = npyv_muladd_f32(invf9, x2, invf7);
+ r = npyv_muladd_f32(r, x2, invf5);
+ r = npyv_muladd_f32(r, x2, invf3);
+ r = npyv_muladd_f32(r, x2, npyv_zero_f32());
+ r = npyv_muladd_f32(r, x, x);
+ return r;
+}
+/*
+ * Vectorized approximate sine/cosine algorithms: The following code is a
+ * vectorized version of the algorithm presented here:
+ * https://stackoverflow.com/questions/30463616/payne-hanek-algorithm-implementation-in-c/30465751#30465751
+ * (1) Load data in registers and generate mask for elements that are
+ * within range [-71476.0625f, 71476.0625f] for cosine and [-117435.992f,
+ * 117435.992f] for sine.
+ * (2) For elements within range, perform range reduction using Cody-Waite's
+ * method: x* = x - y*PI/2, where y = rint(x*2/PI). x* \in [-PI/4, PI/4].
+ * (3) Map cos(x) to (+/-)sine or (+/-)cosine of x* based on the quadrant k =
+ * int(y).
+ * (4) For elements outside that range, Cody-Waite reduction performs poorly
+ * leading to catastrophic cancellation. We compute cosine by calling glibc in
+ * a scalar fashion.
+ * (5) Vectorized implementation has a max ULP of 1.49 and performs at least
+ * 5-7x(x86) - 2.5-3x(Power) - 1-2x(Arm) faster than scalar implementations
+ * when magnitude of all elements in the array < 71476.0625f (117435.992f for sine).
+ * Worst case performance is when all the elements are large leading to about 1-2% reduction in
+ * performance.
+ */
+typedef enum
+{
+ SIMD_COMPUTE_SIN,
+ SIMD_COMPUTE_COS
+} SIMD_TRIG_OP;
+
+static void SIMD_MSVC_NOINLINE
+simd_sincos_f32(const float *src, npy_intp ssrc, float *dst, npy_intp sdst,
+ npy_intp len, SIMD_TRIG_OP trig_op)
+{
+ // Load up frequently used constants
+ const npyv_f32 zerosf = npyv_zero_f32();
+ const npyv_s32 ones = npyv_setall_s32(1);
+ const npyv_s32 twos = npyv_setall_s32(2);
+ const npyv_f32 two_over_pi = npyv_setall_f32(0x1.45f306p-1f);
+ const npyv_f32 codyw_pio2_highf = npyv_setall_f32(-0x1.921fb0p+00f);
+ const npyv_f32 codyw_pio2_medf = npyv_setall_f32(-0x1.5110b4p-22f);
+ const npyv_f32 codyw_pio2_lowf = npyv_setall_f32(-0x1.846988p-48f);
+ const npyv_f32 rint_cvt_magic = npyv_setall_f32(0x1.800000p+23f);
+ // Cody-Waite's range
+ float max_codi = 117435.992f;
+ if (trig_op == SIMD_COMPUTE_COS) {
+ max_codi = 71476.0625f;
+ }
+ const npyv_f32 max_cody = npyv_setall_f32(max_codi);
+ const int vstep = npyv_nlanes_f32;
+
+ for (; len > 0; len -= vstep, src += ssrc*vstep, dst += sdst*vstep) {
+ npyv_f32 x_in;
+ if (ssrc == 1) {
+ x_in = npyv_load_tillz_f32(src, len);
+ } else {
+ x_in = npyv_loadn_tillz_f32(src, ssrc, len);
+ }
+ npyv_b32 simd_mask = npyv_cmple_f32(npyv_abs_f32(x_in), max_cody);
+ npy_uint64 simd_maski = npyv_tobits_b32(simd_mask);
+ /*
+ * For elements outside of this range, Cody-Waite's range reduction
+ * becomes inaccurate and we will call libc to compute cosine for
+ * these numbers
+ */
+ if (simd_maski != 0) {
+ npyv_b32 nnan_mask = npyv_notnan_f32(x_in);
+ npyv_f32 x = npyv_select_f32(npyv_and_b32(nnan_mask, simd_mask), x_in, zerosf);
+
+ npyv_f32 quadrant = npyv_mul_f32(x, two_over_pi);
+ // round to nearest, -0.0f -> +0.0f, and |a| must be <= 0x1.0p+22
+ quadrant = npyv_add_f32(quadrant, rint_cvt_magic);
+ quadrant = npyv_sub_f32(quadrant, rint_cvt_magic);
+
+ // Cody-Waite's range reduction algorithm
+ npyv_f32 reduced_x = simd_range_reduction_f32(
+ x, quadrant, codyw_pio2_highf, codyw_pio2_medf, codyw_pio2_lowf
+ );
+ npyv_f32 reduced_x2 = npyv_square_f32(reduced_x);
+
+ // compute cosine and sine
+ npyv_f32 cos = simd_cosine_poly_f32(reduced_x2);
+ npyv_f32 sin = simd_sine_poly_f32(reduced_x, reduced_x2);
+
+ npyv_s32 iquadrant = npyv_round_s32_f32(quadrant);
+ if (trig_op == SIMD_COMPUTE_COS) {
+ iquadrant = npyv_add_s32(iquadrant, ones);
+ }
+ // blend sin and cos based on the quadrant
+ npyv_b32 sine_mask = npyv_cmpeq_s32(npyv_and_s32(iquadrant, ones), npyv_zero_s32());
+ cos = npyv_select_f32(sine_mask, sin, cos);
+
+ // multiply by -1 for appropriate elements
+ npyv_b32 negate_mask = npyv_cmpeq_s32(npyv_and_s32(iquadrant, twos), twos);
+ cos = npyv_ifsub_f32(negate_mask, zerosf, cos, cos);
+ cos = npyv_select_f32(nnan_mask, cos, npyv_setall_f32(NPY_NANF));
+
+ if (sdst == 1) {
+ npyv_store_till_f32(dst, len, cos);
+ } else {
+ npyv_storen_till_f32(dst, sdst, len, cos);
+ }
+ }
+ if (simd_maski != ((1 << vstep) - 1)) {
+ float NPY_DECL_ALIGNED(NPY_SIMD_WIDTH) ip_fback[npyv_nlanes_f32];
+ npyv_storea_f32(ip_fback, x_in);
+
+ // process elements using libc for large elements
+ if (trig_op == SIMD_COMPUTE_COS) {
+ for (unsigned i = 0; i < npyv_nlanes_f32; ++i) {
+ if ((simd_maski >> i) & 1) {
+ continue;
+ }
+ dst[sdst*i] = npy_cosf(ip_fback[i]);
+ }
+ }
+ else {
+ for (unsigned i = 0; i < npyv_nlanes_f32; ++i) {
+ if ((simd_maski >> i) & 1) {
+ continue;
+ }
+ dst[sdst*i] = npy_sinf(ip_fback[i]);
+ }
+ }
+ }
+ }
+ npyv_cleanup();
+}
+#endif // NPY_SIMD_FMA3
+
+/**begin repeat
+ * #func = cos, sin#
+ * #enum = SIMD_COMPUTE_COS, SIMD_COMPUTE_SIN#
+ */
+NPY_NO_EXPORT void NPY_CPU_DISPATCH_CURFX(FLOAT_@func@)
+(char **args, npy_intp const *dimensions, npy_intp const *steps, void *NPY_UNUSED(data))
+{
+ const float *src = (float*)args[0];
+ float *dst = (float*)args[1];
+
+ const int lsize = sizeof(src[0]);
+ const npy_intp ssrc = steps[0] / lsize;
+ const npy_intp sdst = steps[1] / lsize;
+ npy_intp len = dimensions[0];
+ assert(steps[0] % lsize == 0 && steps[1] % lsize == 0);
+#if NPY_SIMD_FMA3
+ if (is_mem_overlap(src, steps[0], dst, steps[1], len) ||
+ !npyv_loadable_stride_f32(ssrc) || !npyv_storable_stride_f32(sdst)
+ ) {
+ for (; len > 0; --len, src += ssrc, dst += sdst) {
+ simd_sincos_f32(src, 1, dst, 1, 1, @enum@);
+ }
+ } else {
+ simd_sincos_f32(src, ssrc, dst, sdst, len, @enum@);
+ }
+#else
+ for (; len > 0; --len, src += ssrc, dst += sdst) {
+ const float src0 = *src;
+ *dst = npy_@func@f(src0);
+ }
+#endif
+}
+/**end repeat**/
diff --git a/numpy/core/src/umath/loops_utils.h b/numpy/core/src/umath/loops_utils.h
deleted file mode 100644
index f5540bdae..000000000
--- a/numpy/core/src/umath/loops_utils.h
+++ /dev/null
@@ -1,42 +0,0 @@
-#ifndef _NPY_UMATH_LOOPS_UTILS_H_
-#define _NPY_UMATH_LOOPS_UTILS_H_
-
-#include "numpy/npy_common.h" // NPY_FINLINE
-/*
- * nomemoverlap - returns false if two strided arrays have an overlapping
- * region in memory. ip_size/op_size = size of the arrays which can be negative
- * indicating negative steps.
- */
-NPY_FINLINE npy_bool
-nomemoverlap(char *ip, npy_intp ip_size, char *op, npy_intp op_size)
-{
- char *ip_start, *ip_end, *op_start, *op_end;
- if (ip_size < 0) {
- ip_start = ip + ip_size;
- ip_end = ip;
- }
- else {
- ip_start = ip;
- ip_end = ip + ip_size;
- }
- if (op_size < 0) {
- op_start = op + op_size;
- op_end = op;
- }
- else {
- op_start = op;
- op_end = op + op_size;
- }
- return (ip_start == op_start && op_end == ip_end) ||
- (ip_start > op_end) || (op_start > ip_end);
-}
-
-// returns true if two strided arrays have an overlapping region in memory
-// same as `nomemoverlap()` but requires array length and step sizes
-NPY_FINLINE npy_bool
-is_mem_overlap(const void *src, npy_intp src_step, const void *dst, npy_intp dst_step, npy_intp len)
-{
- return !(nomemoverlap((char*)src, src_step*len, (char*)dst, dst_step*len));
-}
-
-#endif // _NPY_UMATH_LOOPS_UTILS_H_
diff --git a/numpy/core/src/umath/loops_utils.h.src b/numpy/core/src/umath/loops_utils.h.src
new file mode 100644
index 000000000..1a2a5a32b
--- /dev/null
+++ b/numpy/core/src/umath/loops_utils.h.src
@@ -0,0 +1,224 @@
+#ifndef _NPY_UMATH_LOOPS_UTILS_H_
+#define _NPY_UMATH_LOOPS_UTILS_H_
+
+#include "numpy/npy_common.h" // NPY_FINLINE
+#include "numpy/halffloat.h" // npy_half_to_float
+
+/**
+ * Old versions of MSVC causes ambiguous link errors when we deal with large SIMD kernels
+ * which lead to break the build, probably releated to the following bug:
+ * https://developercommunity.visualstudio.com/content/problem/415095/internal-compiler-error-with-perfectly-forwarded-r.html
+ */
+#if defined(_MSC_VER) && _MSC_VER < 1916
+ #define SIMD_MSVC_NOINLINE __declspec(noinline)
+#else
+ #define SIMD_MSVC_NOINLINE
+#endif
+/*
+ * nomemoverlap - returns false if two strided arrays have an overlapping
+ * region in memory. ip_size/op_size = size of the arrays which can be negative
+ * indicating negative steps.
+ */
+NPY_FINLINE npy_bool
+nomemoverlap(char *ip, npy_intp ip_size, char *op, npy_intp op_size)
+{
+ char *ip_start, *ip_end, *op_start, *op_end;
+ if (ip_size < 0) {
+ ip_start = ip + ip_size;
+ ip_end = ip;
+ }
+ else {
+ ip_start = ip;
+ ip_end = ip + ip_size;
+ }
+ if (op_size < 0) {
+ op_start = op + op_size;
+ op_end = op;
+ }
+ else {
+ op_start = op;
+ op_end = op + op_size;
+ }
+ return (ip_start == op_start && op_end == ip_end) ||
+ (ip_start > op_end) || (op_start > ip_end);
+}
+
+// returns true if two strided arrays have an overlapping region in memory
+// same as `nomemoverlap()` but requires array length and step sizes
+NPY_FINLINE npy_bool
+is_mem_overlap(const void *src, npy_intp src_step, const void *dst, npy_intp dst_step, npy_intp len)
+{
+ return !(nomemoverlap((char*)src, src_step*len, (char*)dst, dst_step*len));
+}
+
+/*
+ * cutoff blocksize for pairwise summation
+ * decreasing it decreases errors slightly as more pairs are summed but
+ * also lowers performance, as the inner loop is unrolled eight times it is
+ * effectively 16
+ */
+#define PW_BLOCKSIZE 128
+
+/**begin repeat
+ * Float types
+ * #type = npy_float, npy_double, npy_longdouble, npy_float#
+ * #dtype = npy_float, npy_double, npy_longdouble, npy_half#
+ * #TYPE = FLOAT, DOUBLE, LONGDOUBLE, HALF#
+ * #c = f, , l, #
+ * #C = F, , L, #
+ * #trf = , , , npy_half_to_float#
+ */
+
+/*
+ * Pairwise summation, rounding error O(lg n) instead of O(n).
+ * The recursion depth is O(lg n) as well.
+ * when updating also update similar complex floats summation
+ */
+static NPY_INLINE @type@
+@TYPE@_pairwise_sum(char *a, npy_intp n, npy_intp stride)
+{
+ if (n < 8) {
+ npy_intp i;
+ @type@ res = 0.;
+
+ for (i = 0; i < n; i++) {
+ res += @trf@(*((@dtype@*)(a + i * stride)));
+ }
+ return res;
+ }
+ else if (n <= PW_BLOCKSIZE) {
+ npy_intp i;
+ @type@ r[8], res;
+
+ /*
+ * sum a block with 8 accumulators
+ * 8 times unroll reduces blocksize to 16 and allows vectorization with
+ * avx without changing summation ordering
+ */
+ r[0] = @trf@(*((@dtype@ *)(a + 0 * stride)));
+ r[1] = @trf@(*((@dtype@ *)(a + 1 * stride)));
+ r[2] = @trf@(*((@dtype@ *)(a + 2 * stride)));
+ r[3] = @trf@(*((@dtype@ *)(a + 3 * stride)));
+ r[4] = @trf@(*((@dtype@ *)(a + 4 * stride)));
+ r[5] = @trf@(*((@dtype@ *)(a + 5 * stride)));
+ r[6] = @trf@(*((@dtype@ *)(a + 6 * stride)));
+ r[7] = @trf@(*((@dtype@ *)(a + 7 * stride)));
+
+ for (i = 8; i < n - (n % 8); i += 8) {
+ /* small blocksizes seems to mess with hardware prefetch */
+ NPY_PREFETCH(a + (i + 512/(npy_intp)sizeof(@dtype@))*stride, 0, 3);
+ r[0] += @trf@(*((@dtype@ *)(a + (i + 0) * stride)));
+ r[1] += @trf@(*((@dtype@ *)(a + (i + 1) * stride)));
+ r[2] += @trf@(*((@dtype@ *)(a + (i + 2) * stride)));
+ r[3] += @trf@(*((@dtype@ *)(a + (i + 3) * stride)));
+ r[4] += @trf@(*((@dtype@ *)(a + (i + 4) * stride)));
+ r[5] += @trf@(*((@dtype@ *)(a + (i + 5) * stride)));
+ r[6] += @trf@(*((@dtype@ *)(a + (i + 6) * stride)));
+ r[7] += @trf@(*((@dtype@ *)(a + (i + 7) * stride)));
+ }
+
+ /* accumulate now to avoid stack spills for single peel loop */
+ res = ((r[0] + r[1]) + (r[2] + r[3])) +
+ ((r[4] + r[5]) + (r[6] + r[7]));
+
+ /* do non multiple of 8 rest */
+ for (; i < n; i++) {
+ res += @trf@(*((@dtype@ *)(a + i * stride)));
+ }
+ return res;
+ }
+ else {
+ /* divide by two but avoid non-multiples of unroll factor */
+ npy_intp n2 = n / 2;
+
+ n2 -= n2 % 8;
+ return @TYPE@_pairwise_sum(a, n2, stride) +
+ @TYPE@_pairwise_sum(a + n2 * stride, n - n2, stride);
+ }
+}
+
+/**end repeat**/
+
+/**begin repeat
+ * complex types
+ * #TYPE = CFLOAT, CDOUBLE, CLONGDOUBLE#
+ * #ftype = npy_float, npy_double, npy_longdouble#
+ * #c = f, , l#
+ * #C = F, , L#
+ * #SIMD = 1, 1, 0#
+ */
+/* similar to pairwise sum of real floats */
+static NPY_INLINE void
+@TYPE@_pairwise_sum(@ftype@ *rr, @ftype@ * ri, char * a, npy_intp n,
+ npy_intp stride)
+{
+ assert(n % 2 == 0);
+ if (n < 8) {
+ npy_intp i;
+
+ *rr = 0.;
+ *ri = 0.;
+ for (i = 0; i < n; i += 2) {
+ *rr += *((@ftype@ *)(a + i * stride + 0));
+ *ri += *((@ftype@ *)(a + i * stride + sizeof(@ftype@)));
+ }
+ return;
+ }
+ else if (n <= PW_BLOCKSIZE) {
+ npy_intp i;
+ @ftype@ r[8];
+
+ /*
+ * sum a block with 8 accumulators
+ * 8 times unroll reduces blocksize to 16 and allows vectorization with
+ * avx without changing summation ordering
+ */
+ r[0] = *((@ftype@ *)(a + 0 * stride));
+ r[1] = *((@ftype@ *)(a + 0 * stride + sizeof(@ftype@)));
+ r[2] = *((@ftype@ *)(a + 2 * stride));
+ r[3] = *((@ftype@ *)(a + 2 * stride + sizeof(@ftype@)));
+ r[4] = *((@ftype@ *)(a + 4 * stride));
+ r[5] = *((@ftype@ *)(a + 4 * stride + sizeof(@ftype@)));
+ r[6] = *((@ftype@ *)(a + 6 * stride));
+ r[7] = *((@ftype@ *)(a + 6 * stride + sizeof(@ftype@)));
+
+ for (i = 8; i < n - (n % 8); i += 8) {
+ /* small blocksizes seems to mess with hardware prefetch */
+ NPY_PREFETCH(a + (i + 512/(npy_intp)sizeof(@ftype@))*stride, 0, 3);
+ r[0] += *((@ftype@ *)(a + (i + 0) * stride));
+ r[1] += *((@ftype@ *)(a + (i + 0) * stride + sizeof(@ftype@)));
+ r[2] += *((@ftype@ *)(a + (i + 2) * stride));
+ r[3] += *((@ftype@ *)(a + (i + 2) * stride + sizeof(@ftype@)));
+ r[4] += *((@ftype@ *)(a + (i + 4) * stride));
+ r[5] += *((@ftype@ *)(a + (i + 4) * stride + sizeof(@ftype@)));
+ r[6] += *((@ftype@ *)(a + (i + 6) * stride));
+ r[7] += *((@ftype@ *)(a + (i + 6) * stride + sizeof(@ftype@)));
+ }
+
+ /* accumulate now to avoid stack spills for single peel loop */
+ *rr = ((r[0] + r[2]) + (r[4] + r[6]));
+ *ri = ((r[1] + r[3]) + (r[5] + r[7]));
+
+ /* do non multiple of 8 rest */
+ for (; i < n; i+=2) {
+ *rr += *((@ftype@ *)(a + i * stride + 0));
+ *ri += *((@ftype@ *)(a + i * stride + sizeof(@ftype@)));
+ }
+ return;
+ }
+ else {
+ /* divide by two but avoid non-multiples of unroll factor */
+ @ftype@ rr1, ri1, rr2, ri2;
+ npy_intp n2 = n / 2;
+
+ n2 -= n2 % 8;
+ @TYPE@_pairwise_sum(&rr1, &ri1, a, n2, stride);
+ @TYPE@_pairwise_sum(&rr2, &ri2, a + n2 * stride, n - n2, stride);
+ *rr = rr1 + rr2;
+ *ri = ri1 + ri2;
+ return;
+ }
+}
+/**end repeat**/
+
+#endif // _NPY_UMATH_LOOPS_UTILS_H_
diff --git a/numpy/core/src/umath/npy_simd_data.h b/numpy/core/src/umath/npy_simd_data.h
index 45487d0a8..62438d7a3 100644
--- a/numpy/core/src/umath/npy_simd_data.h
+++ b/numpy/core/src/umath/npy_simd_data.h
@@ -1,6 +1,6 @@
#ifndef __NPY_SIMD_DATA_H_
#define __NPY_SIMD_DATA_H_
-#if defined HAVE_ATTRIBUTE_TARGET_AVX512F_WITH_INTRINSICS && defined NPY_HAVE_SSE2_INTRINSICS
+#if defined NPY_HAVE_AVX512F
#if !(defined(__clang__) && (__clang_major__ < 10 || (__clang_major__ == 10 && __clang_minor__ < 1)))
/*
* Constants used in vector implementation of float64 exp(x)
@@ -119,30 +119,14 @@ static npy_uint64 EXP_Table_tail[32] = {
#define NPY_COEFF_Q3_LOGf 9.864942958519418960339e-01f
#define NPY_COEFF_Q4_LOGf 1.546476374983906719538e-01f
#define NPY_COEFF_Q5_LOGf 5.875095403124574342950e-03f
-/*
- * Constants used in vector implementation of sinf/cosf(x)
- */
-#define NPY_TWO_O_PIf 0x1.45f306p-1f
-#define NPY_CODY_WAITE_PI_O_2_HIGHf -0x1.921fb0p+00f
-#define NPY_CODY_WAITE_PI_O_2_MEDf -0x1.5110b4p-22f
-#define NPY_CODY_WAITE_PI_O_2_LOWf -0x1.846988p-48f
-#define NPY_COEFF_INVF0_COSINEf 0x1.000000p+00f
-#define NPY_COEFF_INVF2_COSINEf -0x1.000000p-01f
-#define NPY_COEFF_INVF4_COSINEf 0x1.55553cp-05f
-#define NPY_COEFF_INVF6_COSINEf -0x1.6c06dcp-10f
-#define NPY_COEFF_INVF8_COSINEf 0x1.98e616p-16f
-#define NPY_COEFF_INVF3_SINEf -0x1.555556p-03f
-#define NPY_COEFF_INVF5_SINEf 0x1.11119ap-07f
-#define NPY_COEFF_INVF7_SINEf -0x1.a06bbap-13f
-#define NPY_COEFF_INVF9_SINEf 0x1.7d3bbcp-19f
/*
* Lookup table of log(c_k)
- * Reference form: Tang, Ping-Tak Peter. "Table-driven implementation of the
- * logarithm function in IEEE floating-point arithmetic." ACM Transactions
+ * Reference form: Tang, Ping-Tak Peter. "Table-driven implementation of the
+ * logarithm function in IEEE floating-point arithmetic." ACM Transactions
* on Mathematical Software (TOMS) 16.4 (1990): 378-400.
*/
-#if defined HAVE_ATTRIBUTE_TARGET_AVX512F_WITH_INTRINSICS && defined NPY_HAVE_SSE2_INTRINSICS
+#if defined NPY_HAVE_AVX512F
#if !(defined(__clang__) && (__clang_major__ < 10 || (__clang_major__ == 10 && __clang_minor__ < 1)))
static npy_uint64 LOG_TABLE_TOP[64] = {
0x0000000000000000,
diff --git a/numpy/core/src/umath/override.c b/numpy/core/src/umath/override.c
index a0090e302..d247c2639 100644
--- a/numpy/core/src/umath/override.c
+++ b/numpy/core/src/umath/override.c
@@ -8,6 +8,7 @@
#include "override.h"
#include "ufunc_override.h"
+
/*
* For each positional argument and each argument in a possible "out"
* keyword, look for overrides of the standard ufunc behaviour, i.e.,
@@ -22,25 +23,16 @@
* Returns -1 on failure.
*/
static int
-get_array_ufunc_overrides(PyObject *args, PyObject *kwds,
+get_array_ufunc_overrides(PyObject *in_args, PyObject *out_args,
PyObject **with_override, PyObject **methods)
{
int i;
int num_override_args = 0;
- int narg, nout = 0;
- PyObject *out_kwd_obj;
- PyObject **arg_objs, **out_objs;
+ int narg, nout;
- narg = PyTuple_Size(args);
- if (narg < 0) {
- return -1;
- }
- arg_objs = PySequence_Fast_ITEMS(args);
-
- nout = PyUFuncOverride_GetOutObjects(kwds, &out_kwd_obj, &out_objs);
- if (nout < 0) {
- return -1;
- }
+ narg = (int)PyTuple_GET_SIZE(in_args);
+ /* It is valid for out_args to be NULL: */
+ nout = (out_args != NULL) ? (int)PyTuple_GET_SIZE(out_args) : 0;
for (i = 0; i < narg + nout; ++i) {
PyObject *obj;
@@ -48,10 +40,10 @@ get_array_ufunc_overrides(PyObject *args, PyObject *kwds,
int new_class = 1;
if (i < narg) {
- obj = arg_objs[i];
+ obj = PyTuple_GET_ITEM(in_args, i);
}
else {
- obj = out_objs[i - narg];
+ obj = PyTuple_GET_ITEM(out_args, i - narg);
}
/*
* Have we seen this class before? If so, ignore.
@@ -86,7 +78,6 @@ get_array_ufunc_overrides(PyObject *args, PyObject *kwds,
++num_override_args;
}
}
- Py_DECREF(out_kwd_obj);
return num_override_args;
fail:
@@ -94,359 +85,116 @@ fail:
Py_DECREF(with_override[i]);
Py_DECREF(methods[i]);
}
- Py_DECREF(out_kwd_obj);
return -1;
}
-/*
- * The following functions normalize ufunc arguments. The work done is similar
- * to what is done inside ufunc_object by get_ufunc_arguments for __call__ and
- * generalized ufuncs, and by PyUFunc_GenericReduction for the other methods.
- * It would be good to unify (see gh-8892).
- */
/*
- * ufunc() and ufunc.outer() accept 'sig' or 'signature';
- * normalize to 'signature'
+ * Build a dictionary from the keyword arguments, but replace out with the
+ * normalized version (and always pass it even if it was passed by position).
*/
static int
-normalize_signature_keyword(PyObject *normal_kwds)
-{
- PyObject *obj = _PyDict_GetItemStringWithError(normal_kwds, "sig");
- if (obj == NULL && PyErr_Occurred()){
- return -1;
- }
- if (obj != NULL) {
- PyObject *sig = _PyDict_GetItemStringWithError(normal_kwds, "signature");
- if (sig == NULL && PyErr_Occurred()) {
- return -1;
- }
- if (sig) {
- PyErr_SetString(PyExc_TypeError,
- "cannot specify both 'sig' and 'signature'");
- return -1;
- }
- /*
- * No INCREF or DECREF needed: got a borrowed reference above,
- * and, unlike e.g. PyList_SetItem, PyDict_SetItem INCREF's it.
- */
- PyDict_SetItemString(normal_kwds, "signature", obj);
- PyDict_DelItemString(normal_kwds, "sig");
- }
- return 0;
-}
-
-static int
-normalize___call___args(PyUFuncObject *ufunc, PyObject *args,
- PyObject **normal_args, PyObject **normal_kwds)
+initialize_normal_kwds(PyObject *out_args,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames,
+ PyObject *normal_kwds)
{
- /*
- * ufunc.__call__(*args, **kwds)
- */
- npy_intp i;
- int not_all_none;
- npy_intp nin = ufunc->nin;
- npy_intp nout = ufunc->nout;
- npy_intp nargs = PyTuple_GET_SIZE(args);
- npy_intp nkwds = PyDict_Size(*normal_kwds);
- PyObject *obj;
-
- if (nargs < nin) {
- PyErr_Format(PyExc_TypeError,
- "ufunc() missing %"NPY_INTP_FMT" of %"NPY_INTP_FMT
- "required positional argument(s)", nin - nargs, nin);
- return -1;
- }
- if (nargs > nin+nout) {
- PyErr_Format(PyExc_TypeError,
- "ufunc() takes from %"NPY_INTP_FMT" to %"NPY_INTP_FMT
- "arguments but %"NPY_INTP_FMT" were given",
- nin, nin+nout, nargs);
- return -1;
- }
-
- *normal_args = PyTuple_GetSlice(args, 0, nin);
- if (*normal_args == NULL) {
- return -1;
- }
-
- /* If we have more args than nin, they must be the output variables.*/
- if (nargs > nin) {
- if (nkwds > 0) {
- PyObject *out_kwd = _PyDict_GetItemStringWithError(*normal_kwds, "out");
- if (out_kwd == NULL && PyErr_Occurred()) {
- return -1;
- }
- else if (out_kwd) {
- PyErr_Format(PyExc_TypeError,
- "argument given by name ('out') and position "
- "(%"NPY_INTP_FMT")", nin);
+ if (kwnames != NULL) {
+ for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(kwnames); i++) {
+ if (PyDict_SetItem(normal_kwds,
+ PyTuple_GET_ITEM(kwnames, i), args[i + len_args]) < 0) {
return -1;
}
}
- for (i = nin; i < nargs; i++) {
- not_all_none = (PyTuple_GET_ITEM(args, i) != Py_None);
- if (not_all_none) {
- break;
- }
- }
- if (not_all_none) {
- if (nargs - nin == nout) {
- obj = PyTuple_GetSlice(args, nin, nargs);
- }
- else {
- PyObject *item;
-
- obj = PyTuple_New(nout);
- if (obj == NULL) {
- return -1;
- }
- for (i = 0; i < nout; i++) {
- if (i + nin < nargs) {
- item = PyTuple_GET_ITEM(args, nin+i);
- }
- else {
- item = Py_None;
- }
- Py_INCREF(item);
- PyTuple_SET_ITEM(obj, i, item);
- }
- }
- PyDict_SetItemString(*normal_kwds, "out", obj);
- Py_DECREF(obj);
- }
}
- /* gufuncs accept either 'axes' or 'axis', but not both */
- if (nkwds >= 2) {
- PyObject *axis_kwd = _PyDict_GetItemStringWithError(*normal_kwds, "axis");
- if (axis_kwd == NULL && PyErr_Occurred()) {
+ static PyObject *out_str = NULL;
+ if (out_str == NULL) {
+ out_str = PyUnicode_InternFromString("out");
+ if (out_str == NULL) {
return -1;
}
- PyObject *axes_kwd = _PyDict_GetItemStringWithError(*normal_kwds, "axes");
- if (axes_kwd == NULL && PyErr_Occurred()) {
- return -1;
- }
- if (axis_kwd && axes_kwd) {
- PyErr_SetString(PyExc_TypeError,
- "cannot specify both 'axis' and 'axes'");
- return -1;
- }
- }
- /* finally, ufuncs accept 'sig' or 'signature' normalize to 'signature' */
- return nkwds == 0 ? 0 : normalize_signature_keyword(*normal_kwds);
-}
-
-static int
-normalize_reduce_args(PyUFuncObject *ufunc, PyObject *args,
- PyObject **normal_args, PyObject **normal_kwds)
-{
- /*
- * ufunc.reduce(a[, axis, dtype, out, keepdims])
- */
- npy_intp nargs = PyTuple_GET_SIZE(args);
- npy_intp i;
- PyObject *obj;
- static PyObject *NoValue = NULL;
- static char *kwlist[] = {"array", "axis", "dtype", "out", "keepdims",
- "initial", "where"};
-
- npy_cache_import("numpy", "_NoValue", &NoValue);
- if (NoValue == NULL) return -1;
-
- if (nargs < 1 || nargs > 7) {
- PyErr_Format(PyExc_TypeError,
- "ufunc.reduce() takes from 1 to 7 positional "
- "arguments but %"NPY_INTP_FMT" were given", nargs);
- return -1;
- }
- *normal_args = PyTuple_GetSlice(args, 0, 1);
- if (*normal_args == NULL) {
- return -1;
}
- for (i = 1; i < nargs; i++) {
- PyObject *kwd = _PyDict_GetItemStringWithError(*normal_kwds, kwlist[i]);
- if (kwd == NULL && PyErr_Occurred()) {
+ if (out_args != NULL) {
+ /* Replace `out` argument with the normalized version */
+ int res = PyDict_SetItem(normal_kwds, out_str, out_args);
+ if (res < 0) {
return -1;
}
- else if (kwd) {
- PyErr_Format(PyExc_TypeError,
- "argument given by name ('%s') and position "
- "(%"NPY_INTP_FMT")", kwlist[i], i);
+ }
+ else {
+ /* Ensure that `out` is not present. */
+ int res = PyDict_Contains(normal_kwds, out_str);
+ if (res < 0) {
return -1;
}
- obj = PyTuple_GET_ITEM(args, i);
- if (i == 3) {
- /* remove out=None */
- if (obj == Py_None) {
- continue;
- }
- obj = PyTuple_GetSlice(args, 3, 4);
- }
- /* Remove initial=np._NoValue */
- if (i == 5 && obj == NoValue) {
- continue;
- }
- PyDict_SetItemString(*normal_kwds, kwlist[i], obj);
- if (i == 3) {
- Py_DECREF(obj);
+ if (res) {
+ return PyDict_DelItem(normal_kwds, out_str);
}
}
return 0;
}
+/*
+ * ufunc() and ufunc.outer() accept 'sig' or 'signature'. We guarantee
+ * that it is passed as 'signature' by renaming 'sig' if present.
+ * Note that we have already validated that only one of them was passed
+ * before checking for overrides.
+ */
static int
-normalize_accumulate_args(PyUFuncObject *ufunc, PyObject *args,
- PyObject **normal_args, PyObject **normal_kwds)
+normalize_signature_keyword(PyObject *normal_kwds)
{
- /*
- * ufunc.accumulate(a[, axis, dtype, out])
- */
- npy_intp nargs = PyTuple_GET_SIZE(args);
- npy_intp i;
- PyObject *obj;
- static char *kwlist[] = {"array", "axis", "dtype", "out", "keepdims"};
-
- if (nargs < 1 || nargs > 4) {
- PyErr_Format(PyExc_TypeError,
- "ufunc.accumulate() takes from 1 to 4 positional "
- "arguments but %"NPY_INTP_FMT" were given", nargs);
- return -1;
- }
- *normal_args = PyTuple_GetSlice(args, 0, 1);
- if (*normal_args == NULL) {
+ /* If the keywords include `sig` rename to `signature`. */
+ PyObject* obj = _PyDict_GetItemStringWithError(normal_kwds, "sig");
+ if (obj == NULL && PyErr_Occurred()) {
return -1;
}
-
- for (i = 1; i < nargs; i++) {
- PyObject *kwd = _PyDict_GetItemStringWithError(*normal_kwds, kwlist[i]);
- if (kwd == NULL && PyErr_Occurred()) {
+ if (obj != NULL) {
+ /*
+ * No INCREF or DECREF needed: got a borrowed reference above,
+ * and, unlike e.g. PyList_SetItem, PyDict_SetItem INCREF's it.
+ */
+ if (PyDict_SetItemString(normal_kwds, "signature", obj) < 0) {
return -1;
}
- else if (kwd) {
- PyErr_Format(PyExc_TypeError,
- "argument given by name ('%s') and position "
- "(%"NPY_INTP_FMT")", kwlist[i], i);
+ if (PyDict_DelItemString(normal_kwds, "sig") < 0) {
return -1;
}
- obj = PyTuple_GET_ITEM(args, i);
- if (i == 3) {
- /* remove out=None */
- if (obj == Py_None) {
- continue;
- }
- obj = PyTuple_GetSlice(args, 3, 4);
- }
- PyDict_SetItemString(*normal_kwds, kwlist[i], obj);
- if (i == 3) {
- Py_DECREF(obj);
- }
}
return 0;
}
+
static int
-normalize_reduceat_args(PyUFuncObject *ufunc, PyObject *args,
- PyObject **normal_args, PyObject **normal_kwds)
+copy_positional_args_to_kwargs(const char **keywords,
+ PyObject *const *args, Py_ssize_t len_args,
+ PyObject *normal_kwds)
{
- /*
- * ufunc.reduceat(a, indices[, axis, dtype, out])
- * the number of arguments has been checked in PyUFunc_GenericReduction.
- */
- npy_intp i;
- npy_intp nargs = PyTuple_GET_SIZE(args);
- PyObject *obj;
- static char *kwlist[] = {"array", "indices", "axis", "dtype", "out"};
-
- if (nargs < 2 || nargs > 5) {
- PyErr_Format(PyExc_TypeError,
- "ufunc.reduceat() takes from 2 to 4 positional "
- "arguments but %"NPY_INTP_FMT" were given", nargs);
- return -1;
- }
- /* a and indices */
- *normal_args = PyTuple_GetSlice(args, 0, 2);
- if (*normal_args == NULL) {
- return -1;
- }
-
- for (i = 2; i < nargs; i++) {
- PyObject *kwd = _PyDict_GetItemStringWithError(*normal_kwds, kwlist[i]);
- if (kwd == NULL && PyErr_Occurred()) {
- return -1;
- }
- else if (kwd) {
- PyErr_Format(PyExc_TypeError,
- "argument given by name ('%s') and position "
- "(%"NPY_INTP_FMT")", kwlist[i], i);
- return -1;
+ for (Py_ssize_t i = 0; i < len_args; i++) {
+ if (keywords[i] == NULL) {
+ /* keyword argument is either input or output and not set here */
+ continue;
}
- obj = PyTuple_GET_ITEM(args, i);
- if (i == 4) {
- /* remove out=None */
- if (obj == Py_None) {
+ if (NPY_UNLIKELY(i == 5)) {
+ /*
+ * This is only relevant for reduce, which is the only one with
+ * 5 keyword arguments.
+ */
+ static PyObject *NoValue = NULL;
+ assert(strcmp(keywords[i], "initial") == 0);
+ npy_cache_import("numpy", "_NoValue", &NoValue);
+ if (args[i] == NoValue) {
continue;
}
- obj = PyTuple_GetSlice(args, 4, 5);
}
- PyDict_SetItemString(*normal_kwds, kwlist[i], obj);
- if (i == 4) {
- Py_DECREF(obj);
+
+ int res = PyDict_SetItemString(normal_kwds, keywords[i], args[i]);
+ if (res < 0) {
+ return -1;
}
}
return 0;
}
-static int
-normalize_outer_args(PyUFuncObject *ufunc, PyObject *args,
- PyObject **normal_args, PyObject **normal_kwds)
-{
- /*
- * ufunc.outer(*args, **kwds)
- * all positional arguments should be inputs.
- * for the keywords, we only need to check 'sig' vs 'signature'.
- */
- npy_intp nin = ufunc->nin;
- npy_intp nargs = PyTuple_GET_SIZE(args);
-
- if (nargs < nin) {
- PyErr_Format(PyExc_TypeError,
- "ufunc.outer() missing %"NPY_INTP_FMT" of %"NPY_INTP_FMT
- "required positional " "argument(s)", nin - nargs, nin);
- return -1;
- }
- if (nargs > nin) {
- PyErr_Format(PyExc_TypeError,
- "ufunc.outer() takes %"NPY_INTP_FMT" arguments but"
- "%"NPY_INTP_FMT" were given", nin, nargs);
- return -1;
- }
-
- *normal_args = PyTuple_GetSlice(args, 0, nin);
- if (*normal_args == NULL) {
- return -1;
- }
- /* ufuncs accept 'sig' or 'signature' normalize to 'signature' */
- return normalize_signature_keyword(*normal_kwds);
-}
-
-static int
-normalize_at_args(PyUFuncObject *ufunc, PyObject *args,
- PyObject **normal_args, PyObject **normal_kwds)
-{
- /* ufunc.at(a, indices[, b]) */
- npy_intp nargs = PyTuple_GET_SIZE(args);
-
- if (nargs < 2 || nargs > 3) {
- PyErr_Format(PyExc_TypeError,
- "ufunc.at() takes from 2 to 3 positional "
- "arguments but %"NPY_INTP_FMT" were given", nargs);
- return -1;
- }
- *normal_args = PyTuple_GetSlice(args, 0, nargs);
- return (*normal_args == NULL);
-}
-
/*
* Check a set of args for the `__array_ufunc__` method. If more than one of
* the input arguments implements `__array_ufunc__`, they are tried in the
@@ -460,31 +208,26 @@ normalize_at_args(PyUFuncObject *ufunc, PyObject *args,
*/
NPY_NO_EXPORT int
PyUFunc_CheckOverride(PyUFuncObject *ufunc, char *method,
- PyObject *args, PyObject *kwds,
- PyObject **result)
+ PyObject *in_args, PyObject *out_args,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames,
+ PyObject **result)
{
- int i;
- int j;
int status;
int num_override_args;
PyObject *with_override[NPY_MAXARGS];
PyObject *array_ufunc_methods[NPY_MAXARGS];
- PyObject *out;
-
PyObject *method_name = NULL;
- PyObject *normal_args = NULL; /* normal_* holds normalized arguments. */
PyObject *normal_kwds = NULL;
PyObject *override_args = NULL;
- Py_ssize_t len;
/*
* Check inputs for overrides
*/
num_override_args = get_array_ufunc_overrides(
- args, kwds, with_override, array_ufunc_methods);
+ in_args, out_args, with_override, array_ufunc_methods);
if (num_override_args == -1) {
goto fail;
}
@@ -495,104 +238,58 @@ PyUFunc_CheckOverride(PyUFuncObject *ufunc, char *method,
}
/*
- * Normalize ufunc arguments.
+ * Normalize ufunc arguments, note that any input and output arguments
+ * have already been stored in `in_args` and `out_args`.
*/
-
- /* Build new kwds */
- if (kwds && PyDict_CheckExact(kwds)) {
-
- /* ensure out is always a tuple */
- normal_kwds = PyDict_Copy(kwds);
- out = _PyDict_GetItemStringWithError(normal_kwds, "out");
- if (out == NULL && PyErr_Occurred()) {
- goto fail;
- }
- else if (out) {
- int nout = ufunc->nout;
-
- if (PyTuple_CheckExact(out)) {
- int all_none = 1;
-
- if (PyTuple_GET_SIZE(out) != nout) {
- PyErr_Format(PyExc_ValueError,
- "The 'out' tuple must have exactly "
- "%d entries: one per ufunc output", nout);
- goto fail;
- }
- for (i = 0; i < PyTuple_GET_SIZE(out); i++) {
- all_none = (PyTuple_GET_ITEM(out, i) == Py_None);
- if (!all_none) {
- break;
- }
- }
- if (all_none) {
- PyDict_DelItemString(normal_kwds, "out");
- }
- }
- else {
- /* not a tuple */
- if (nout > 1) {
- PyErr_SetString(PyExc_TypeError,
- "'out' must be a tuple of arguments");
- goto fail;
- }
- if (out != Py_None) {
- /* not already a tuple and not None */
- PyObject *out_tuple = PyTuple_New(1);
-
- if (out_tuple == NULL) {
- goto fail;
- }
- /* out was borrowed ref; make it permanent */
- Py_INCREF(out);
- /* steals reference */
- PyTuple_SET_ITEM(out_tuple, 0, out);
- PyDict_SetItemString(normal_kwds, "out", out_tuple);
- Py_DECREF(out_tuple);
- }
- else {
- /* out=None; remove it */
- PyDict_DelItemString(normal_kwds, "out");
- }
- }
- }
- }
- else {
- normal_kwds = PyDict_New();
- }
+ normal_kwds = PyDict_New();
if (normal_kwds == NULL) {
goto fail;
}
+ if (initialize_normal_kwds(out_args,
+ args, len_args, kwnames, normal_kwds) < 0) {
+ goto fail;
+ }
- /* decide what to do based on the method. */
+ /*
+ * Reduce-like methods can pass keyword arguments also by position,
+ * in which case the additional positional arguments have to be copied
+ * into the keyword argument dictionary. The `__call__` and `__outer__`
+ * method have to normalize sig and signature.
+ */
/* ufunc.__call__ */
if (strcmp(method, "__call__") == 0) {
- status = normalize___call___args(ufunc, args, &normal_args,
- &normal_kwds);
+ status = normalize_signature_keyword(normal_kwds);
}
/* ufunc.reduce */
else if (strcmp(method, "reduce") == 0) {
- status = normalize_reduce_args(ufunc, args, &normal_args,
- &normal_kwds);
+ static const char *keywords[] = {
+ NULL, "axis", "dtype", NULL, "keepdims",
+ "initial", "where"};
+ status = copy_positional_args_to_kwargs(keywords,
+ args, len_args, normal_kwds);
}
/* ufunc.accumulate */
else if (strcmp(method, "accumulate") == 0) {
- status = normalize_accumulate_args(ufunc, args, &normal_args,
- &normal_kwds);
+ static const char *keywords[] = {
+ NULL, "axis", "dtype", NULL};
+ status = copy_positional_args_to_kwargs(keywords,
+ args, len_args, normal_kwds);
}
/* ufunc.reduceat */
else if (strcmp(method, "reduceat") == 0) {
- status = normalize_reduceat_args(ufunc, args, &normal_args,
- &normal_kwds);
+ static const char *keywords[] = {
+ NULL, NULL, "axis", "dtype", NULL};
+ status = copy_positional_args_to_kwargs(keywords,
+ args, len_args, normal_kwds);
}
- /* ufunc.outer */
+ /* ufunc.outer (identical to call) */
else if (strcmp(method, "outer") == 0) {
- status = normalize_outer_args(ufunc, args, &normal_args, &normal_kwds);
+ status = normalize_signature_keyword(normal_kwds);
}
/* ufunc.at */
else if (strcmp(method, "at") == 0) {
- status = normalize_at_args(ufunc, args, &normal_args, &normal_kwds);
+ status = 0;
}
/* unknown method */
else {
@@ -610,7 +307,7 @@ PyUFunc_CheckOverride(PyUFuncObject *ufunc, char *method,
goto fail;
}
- len = PyTuple_GET_SIZE(normal_args);
+ int len = (int)PyTuple_GET_SIZE(in_args);
/* Call __array_ufunc__ functions in correct order */
while (1) {
@@ -621,14 +318,14 @@ PyUFunc_CheckOverride(PyUFuncObject *ufunc, char *method,
*result = NULL;
/* Choose an overriding argument */
- for (i = 0; i < num_override_args; i++) {
+ for (int i = 0; i < num_override_args; i++) {
override_obj = with_override[i];
if (override_obj == NULL) {
continue;
}
/* Check for sub-types to the right of obj. */
- for (j = i + 1; j < num_override_args; j++) {
+ for (int j = i + 1; j < num_override_args; j++) {
PyObject *other_obj = with_override[j];
if (other_obj != NULL &&
Py_TYPE(other_obj) != Py_TYPE(override_obj) &&
@@ -662,8 +359,8 @@ PyUFunc_CheckOverride(PyUFuncObject *ufunc, char *method,
PyTuple_SET_ITEM(override_args, 1, (PyObject *)ufunc);
Py_INCREF(method_name);
PyTuple_SET_ITEM(override_args, 2, method_name);
- for (i = 0; i < len; i++) {
- PyObject *item = PyTuple_GET_ITEM(normal_args, i);
+ for (int i = 0; i < len; i++) {
+ PyObject *item = PyTuple_GET_ITEM(in_args, i);
Py_INCREF(item);
PyTuple_SET_ITEM(override_args, i + 3, item);
@@ -724,11 +421,10 @@ PyUFunc_CheckOverride(PyUFuncObject *ufunc, char *method,
fail:
status = -1;
cleanup:
- for (i = 0; i < num_override_args; i++) {
+ for (int i = 0; i < num_override_args; i++) {
Py_XDECREF(with_override[i]);
Py_XDECREF(array_ufunc_methods[i]);
}
- Py_XDECREF(normal_args);
Py_XDECREF(method_name);
Py_XDECREF(normal_kwds);
return status;
diff --git a/numpy/core/src/umath/override.h b/numpy/core/src/umath/override.h
index 68f3c6ef0..4e9a323ca 100644
--- a/numpy/core/src/umath/override.h
+++ b/numpy/core/src/umath/override.h
@@ -6,6 +6,9 @@
NPY_NO_EXPORT int
PyUFunc_CheckOverride(PyUFuncObject *ufunc, char *method,
- PyObject *args, PyObject *kwds,
- PyObject **result);
+ PyObject *in_args, PyObject *out_args,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames,
+ PyObject **result);
+
+
#endif
diff --git a/numpy/core/src/umath/reduction.c b/numpy/core/src/umath/reduction.c
index f1423d8b9..86cc20eb1 100644
--- a/numpy/core/src/umath/reduction.c
+++ b/numpy/core/src/umath/reduction.c
@@ -166,7 +166,7 @@ PyArray_CopyInitialReduceValues(
* identity : If Py_None, PyArray_CopyInitialReduceValues is used, otherwise
* this value is used to initialize the result to
* the reduction's unit.
- * loop : The loop which does the reduction.
+ * loop : `reduce_loop` from `ufunc_object.c`. TODO: Refactor
* data : Data which is passed to the inner loop.
* buffersize : Buffer size for the iterator. For the default, pass in 0.
* funcname : The name of the reduction function, for error messages.
@@ -182,18 +182,15 @@ PyArray_CopyInitialReduceValues(
* generalized ufuncs!)
*/
NPY_NO_EXPORT PyArrayObject *
-PyUFunc_ReduceWrapper(PyArrayObject *operand, PyArrayObject *out,
- PyArrayObject *wheremask,
- PyArray_Descr *operand_dtype,
- PyArray_Descr *result_dtype,
- NPY_CASTING casting,
- npy_bool *axis_flags, int reorderable,
- int keepdims,
- PyObject *identity,
- PyArray_ReduceLoopFunc *loop,
- void *data, npy_intp buffersize, const char *funcname,
- int errormask)
+PyUFunc_ReduceWrapper(
+ PyArrayObject *operand, PyArrayObject *out, PyArrayObject *wheremask,
+ PyArray_Descr *operand_dtype, PyArray_Descr *result_dtype,
+ NPY_CASTING casting,
+ npy_bool *axis_flags, int reorderable, int keepdims,
+ PyObject *identity, PyArray_ReduceLoopFunc *loop,
+ void *data, npy_intp buffersize, const char *funcname, int errormask)
{
+ assert(loop != NULL);
PyArrayObject *result = NULL;
npy_intp skip_first_count = 0;
@@ -201,7 +198,7 @@ PyUFunc_ReduceWrapper(PyArrayObject *operand, PyArrayObject *out,
NpyIter *iter = NULL;
PyArrayObject *op[3];
PyArray_Descr *op_dtypes[3];
- npy_uint32 flags, op_flags[3];
+ npy_uint32 it_flags, op_flags[3];
/* More than one axis means multiple orders are possible */
if (!reorderable && count_axes(PyArray_NDIM(operand), axis_flags) > 1) {
@@ -227,7 +224,7 @@ PyUFunc_ReduceWrapper(PyArrayObject *operand, PyArrayObject *out,
op_dtypes[0] = result_dtype;
op_dtypes[1] = operand_dtype;
- flags = NPY_ITER_BUFFERED |
+ it_flags = NPY_ITER_BUFFERED |
NPY_ITER_EXTERNAL_LOOP |
NPY_ITER_GROWINNER |
NPY_ITER_DONT_NEGATE_STRIDES |
@@ -293,7 +290,7 @@ PyUFunc_ReduceWrapper(PyArrayObject *operand, PyArrayObject *out,
}
}
- iter = NpyIter_AdvancedNew(wheremask == NULL ? 2 : 3, op, flags,
+ iter = NpyIter_AdvancedNew(wheremask == NULL ? 2 : 3, op, it_flags,
NPY_KEEPORDER, casting,
op_flags,
op_dtypes,
@@ -304,11 +301,14 @@ PyUFunc_ReduceWrapper(PyArrayObject *operand, PyArrayObject *out,
result = NpyIter_GetOperandArray(iter)[0];
+ int needs_api = NpyIter_IterationNeedsAPI(iter);
+ /* Start with the floating-point exception flags cleared */
+ npy_clear_floatstatus_barrier((char*)&iter);
+
/*
* Initialize the result to the reduction unit if possible,
* otherwise copy the initial values and get a view to the rest.
*/
-
if (identity != Py_None) {
if (PyArray_FillWithScalar(result, identity) < 0) {
goto fail;
@@ -331,15 +331,11 @@ PyUFunc_ReduceWrapper(PyArrayObject *operand, PyArrayObject *out,
goto fail;
}
- /* Start with the floating-point exception flags cleared */
- npy_clear_floatstatus_barrier((char*)&iter);
-
if (NpyIter_GetIterSize(iter) != 0) {
NpyIter_IterNextFunc *iternext;
char **dataptr;
npy_intp *strideptr;
npy_intp *countptr;
- int needs_api;
iternext = NpyIter_GetIterNext(iter, NULL);
if (iternext == NULL) {
@@ -349,16 +345,6 @@ PyUFunc_ReduceWrapper(PyArrayObject *operand, PyArrayObject *out,
strideptr = NpyIter_GetInnerStrideArray(iter);
countptr = NpyIter_GetInnerLoopSizePtr(iter);
- needs_api = NpyIter_IterationNeedsAPI(iter);
-
- /* Straightforward reduction */
- if (loop == NULL) {
- PyErr_Format(PyExc_RuntimeError,
- "reduction operation %s did not supply an "
- "inner loop function", funcname);
- goto fail;
- }
-
if (loop(iter, dataptr, strideptr, countptr,
iternext, needs_api, skip_first_count, data) < 0) {
goto fail;
diff --git a/numpy/core/src/umath/scalarmath.c.src b/numpy/core/src/umath/scalarmath.c.src
index 86dade0f1..5836545f8 100644
--- a/numpy/core/src/umath/scalarmath.c.src
+++ b/numpy/core/src/umath/scalarmath.c.src
@@ -283,19 +283,13 @@ static void
static void
@name@_ctype_floor_divide(@type@ a, @type@ b, @type@ *out) {
- @type@ mod;
-
- if (!b) {
- *out = a / b;
- } else {
- *out = npy_divmod@c@(a, b, &mod);
- }
+ *out = npy_floor_divide@c@(a, b);
}
static void
@name@_ctype_remainder(@type@ a, @type@ b, @type@ *out) {
- npy_divmod@c@(a, b, out);
+ *out = npy_remainder@c@(a, b);
}
@@ -737,6 +731,9 @@ _@name@_convert2_to_ctypes(PyObject *a, @type@ *arg1,
{
int ret;
ret = _@name@_convert_to_ctype(a, arg1);
+ if (ret == -2) {
+ ret = -3;
+ }
if (ret < 0) {
return ret;
}
@@ -1029,7 +1026,7 @@ static PyObject *
/**begin repeat
*
- * #name = cfloat, cdouble, clongdouble#
+ * #name = cfloat, cdouble#
*
*/
@@ -1047,6 +1044,60 @@ static PyObject *
/**begin repeat
*
+ * #oper = divmod, remainder#
+ *
+ */
+
+/*
+Complex numbers do not support remainder operations. Unfortunately,
+the type inference for long doubles is complicated, and if a remainder
+operation is not defined - if the relevant field is left NULL - then
+operations between long doubles and objects lead to an infinite recursion
+instead of a TypeError. This should ensure that once everything gets
+converted to complex long doubles you correctly get a reasonably
+informative TypeError. This fixes the last part of bug gh-18548.
+*/
+
+static PyObject *
+clongdouble_@oper@(PyObject *a, PyObject *b)
+{
+ npy_clongdouble arg1, arg2;
+
+ BINOP_GIVE_UP_IF_NEEDED(a, b, nb_@oper@, clongdouble_@oper@);
+
+ switch(_clongdouble_convert2_to_ctypes(a, &arg1, b, &arg2)) {
+ case 0:
+ break;
+ case -1:
+ /* one of them can't be cast safely must be mixed-types*/
+ return PyArray_Type.tp_as_number->nb_@oper@(a,b);
+ case -2:
+ /* use default handling */
+ if (PyErr_Occurred()) {
+ return NULL;
+ }
+ return PyGenericArrType_Type.tp_as_number->nb_@oper@(a,b);
+ case -3:
+ /*
+ * special case for longdouble and clongdouble
+ * because they have a recursive getitem in their dtype
+ */
+ Py_INCREF(Py_NotImplemented);
+ return Py_NotImplemented;
+ }
+
+ /*
+ * here we do the actual calculation with arg1 and arg2
+ * as a function call.
+ */
+ PyErr_SetString(PyExc_TypeError, "complex long doubles do not support remainder");
+ return NULL;
+}
+
+/**end repeat**/
+
+/**begin repeat
+ *
* #name = half, float, double, longdouble, cfloat, cdouble, clongdouble#
*
*/
diff --git a/numpy/core/src/umath/simd.inc.src b/numpy/core/src/umath/simd.inc.src
index 71ee7e07e..654ab81cc 100644
--- a/numpy/core/src/umath/simd.inc.src
+++ b/numpy/core/src/umath/simd.inc.src
@@ -28,7 +28,6 @@
#undef __AVX512F__
#endif
#endif
-#include "simd/simd.h"
#include "loops_utils.h" // nomemoverlap
#include <assert.h>
#include <stdlib.h>
@@ -38,134 +37,6 @@
#define VECTOR_SIZE_BYTES 16
/*
- * MAX_STEP_SIZE is used to determine if we need to use SIMD version of the ufunc.
- * Very large step size can be as slow as processing it using scalar. The
- * value of 2097152 ( = 2MB) was chosen using 2 considerations:
- * 1) Typical linux kernel page size is 4Kb, but sometimes it could also be 2MB
- * which is == 2097152 Bytes. For a step size as large as this, surely all
- * the loads/stores of gather/scatter instructions falls on 16 different pages
- * which one would think would slow down gather/scatter instructions.
- * 2) It additionally satisfies MAX_STEP_SIZE*16/esize < NPY_MAX_INT32 which
- * allows us to use i32 version of gather/scatter (as opposed to the i64 version)
- * without problems (step larger than NPY_MAX_INT32*esize/16 would require use of
- * i64gather/scatter). esize = element size = 4/8 bytes for float/double.
- */
-#define MAX_STEP_SIZE 2097152
-
-#define IS_BINARY_STRIDE_ONE(esize, vsize) \
- ((steps[0] == esize) && \
- (steps[1] == esize) && \
- (steps[2] == esize) && \
- (abs_ptrdiff(args[2], args[0]) >= vsize) && \
- (abs_ptrdiff(args[2], args[1]) >= vsize))
-
-/*
- * stride is equal to element size and input and destination are equal or
- * don't overlap within one register. The check of the steps against
- * esize also quarantees that steps are >= 0.
- */
-#define IS_BLOCKABLE_UNARY(esize, vsize) \
- (steps[0] == (esize) && steps[0] == steps[1] && \
- (npy_is_aligned(args[0], esize) && npy_is_aligned(args[1], esize)) && \
- ((abs_ptrdiff(args[1], args[0]) >= (vsize)) || \
- ((abs_ptrdiff(args[1], args[0]) == 0))))
-
-/*
- * Avoid using SIMD for very large step sizes for several reasons:
- * 1) Supporting large step sizes requires use of i64gather/scatter_ps instructions,
- * in which case we need two i64gather instructions and an additional vinsertf32x8
- * instruction to load a single zmm register (since one i64gather instruction
- * loads into a ymm register). This is not ideal for performance.
- * 2) Gather and scatter instructions can be slow when the loads/stores
- * cross page boundaries.
- *
- * We instead rely on i32gather/scatter_ps instructions which use a 32-bit index
- * element. The index needs to be < INT_MAX to avoid overflow. MAX_STEP_SIZE
- * ensures this. The condition also requires that the input and output arrays
- * should have no overlap in memory.
- */
-#define IS_BINARY_SMALL_STEPS_AND_NOMEMOVERLAP \
- ((labs(steps[0]) < MAX_STEP_SIZE) && \
- (labs(steps[1]) < MAX_STEP_SIZE) && \
- (labs(steps[2]) < MAX_STEP_SIZE) && \
- (nomemoverlap(args[0], steps[0] * dimensions[0], args[2], steps[2] * dimensions[0])) && \
- (nomemoverlap(args[1], steps[1] * dimensions[0], args[2], steps[2] * dimensions[0])))
-
-#define IS_UNARY_TWO_OUT_SMALL_STEPS_AND_NOMEMOVERLAP \
- ((labs(steps[0]) < MAX_STEP_SIZE) && \
- (labs(steps[1]) < MAX_STEP_SIZE) && \
- (labs(steps[2]) < MAX_STEP_SIZE) && \
- (nomemoverlap(args[0], steps[0] * dimensions[0], args[2], steps[2] * dimensions[0])) && \
- (nomemoverlap(args[0], steps[0] * dimensions[0], args[1], steps[1] * dimensions[0])))
-
-/*
- * 1) Output should be contiguous, can handle strided input data
- * 2) Input step should be smaller than MAX_STEP_SIZE for performance
- * 3) Input and output arrays should have no overlap in memory
- */
-#define IS_OUTPUT_BLOCKABLE_UNARY(esizein, esizeout, vsize) \
- ((steps[0] & (esizein-1)) == 0 && \
- steps[1] == (esizeout) && labs(steps[0]) < MAX_STEP_SIZE && \
- (nomemoverlap(args[1], steps[1] * dimensions[0], args[0], steps[0] * dimensions[0])))
-
-#define IS_BLOCKABLE_REDUCE(esize, vsize) \
- (steps[1] == (esize) && abs_ptrdiff(args[1], args[0]) >= (vsize) && \
- npy_is_aligned(args[1], (esize)) && \
- npy_is_aligned(args[0], (esize)))
-
-#define IS_BLOCKABLE_BINARY(esize, vsize) \
- (steps[0] == steps[1] && steps[1] == steps[2] && steps[2] == (esize) && \
- npy_is_aligned(args[2], (esize)) && npy_is_aligned(args[1], (esize)) && \
- npy_is_aligned(args[0], (esize)) && \
- (abs_ptrdiff(args[2], args[0]) >= (vsize) || \
- abs_ptrdiff(args[2], args[0]) == 0) && \
- (abs_ptrdiff(args[2], args[1]) >= (vsize) || \
- abs_ptrdiff(args[2], args[1]) >= 0))
-
-#define IS_BLOCKABLE_BINARY_SCALAR1(esize, vsize) \
- (steps[0] == 0 && steps[1] == steps[2] && steps[2] == (esize) && \
- npy_is_aligned(args[2], (esize)) && npy_is_aligned(args[1], (esize)) && \
- ((abs_ptrdiff(args[2], args[1]) >= (vsize)) || \
- (abs_ptrdiff(args[2], args[1]) == 0)) && \
- abs_ptrdiff(args[2], args[0]) >= (esize))
-
-#define IS_BLOCKABLE_BINARY_SCALAR2(esize, vsize) \
- (steps[1] == 0 && steps[0] == steps[2] && steps[2] == (esize) && \
- npy_is_aligned(args[2], (esize)) && npy_is_aligned(args[0], (esize)) && \
- ((abs_ptrdiff(args[2], args[0]) >= (vsize)) || \
- (abs_ptrdiff(args[2], args[0]) == 0)) && \
- abs_ptrdiff(args[2], args[1]) >= (esize))
-
-#undef abs_ptrdiff
-
-#define IS_BLOCKABLE_BINARY_BOOL(esize, vsize) \
- (steps[0] == (esize) && steps[0] == steps[1] && steps[2] == (1) && \
- npy_is_aligned(args[1], (esize)) && \
- npy_is_aligned(args[0], (esize)))
-
-#define IS_BLOCKABLE_BINARY_SCALAR1_BOOL(esize, vsize) \
- (steps[0] == 0 && steps[1] == (esize) && steps[2] == (1) && \
- npy_is_aligned(args[1], (esize)))
-
-#define IS_BLOCKABLE_BINARY_SCALAR2_BOOL(esize, vsize) \
- (steps[0] == (esize) && steps[1] == 0 && steps[2] == (1) && \
- npy_is_aligned(args[0], (esize)))
-
-/* align var to alignment */
-#define LOOP_BLOCK_ALIGN_VAR(var, type, alignment)\
- npy_intp i, peel = npy_aligned_block_offset(var, sizeof(type),\
- alignment, n);\
- for(i = 0; i < peel; i++)
-
-#define LOOP_BLOCKED(type, vsize)\
- for(; i < npy_blocked_end(peel, sizeof(type), vsize, n);\
- i += (vsize / sizeof(type)))
-
-#define LOOP_BLOCKED_END\
- for (; i < n; i++)
-
-
-/*
* Dispatcher functions
* decide whether the operation can be vectorized and run it
* if it was run returns true and false if nothing was done
@@ -184,31 +55,6 @@
*/
/**begin repeat1
- * #func = add, subtract, multiply#
- */
-
-#if defined HAVE_ATTRIBUTE_TARGET_AVX512F_WITH_INTRINSICS && defined NPY_HAVE_SSE2_INTRINSICS
-static NPY_INLINE NPY_GCC_TARGET_AVX512F void
-AVX512F_@func@_@TYPE@(char **args, const npy_intp *dimensions, const npy_intp *steps);
-#endif
-
-static NPY_INLINE int
-run_binary_avx512f_@func@_@TYPE@(char **args, const npy_intp *dimensions, const npy_intp *steps)
-{
-#if defined HAVE_ATTRIBUTE_TARGET_AVX512F_WITH_INTRINSICS && defined NPY_HAVE_SSE2_INTRINSICS
- if (IS_BINARY_STRIDE_ONE(@esize@, 64)) {
- AVX512F_@func@_@TYPE@(args, dimensions, steps);
- return 1;
- }
- else
- return 0;
-#endif
- return 0;
-}
-
-/**end repeat1**/
-
-/**begin repeat1
* #func = square, absolute, conjugate#
* #outsize = 1, 2, 1#
* #max_stride = 2, 8, 8#
@@ -273,42 +119,6 @@ run_binary_avx512f_@func@_@TYPE@(char **args, npy_intp const *dimensions, npy_in
/**end repeat1**/
-
-#if defined HAVE_ATTRIBUTE_TARGET_AVX512_SKX_WITH_INTRINSICS && defined NPY_HAVE_SSE2_INTRINSICS && @EXISTS@
-static NPY_INLINE NPY_GCC_TARGET_AVX512_SKX void
-AVX512_SKX_ldexp_@TYPE@(char **args, npy_intp const *dimensions, npy_intp const *steps);
-
-static NPY_INLINE NPY_GCC_TARGET_AVX512_SKX void
-AVX512_SKX_frexp_@TYPE@(char **args, npy_intp const *dimensions, npy_intp const *steps);
-#endif
-
-static NPY_INLINE int
-run_binary_avx512_skx_ldexp_@TYPE@(char **args, npy_intp const *dimensions, npy_intp const *steps)
-{
-#if defined HAVE_ATTRIBUTE_TARGET_AVX512_SKX_WITH_INTRINSICS && defined NPY_HAVE_SSE2_INTRINSICS && @EXISTS@
- if (IS_BINARY_SMALL_STEPS_AND_NOMEMOVERLAP) {
- AVX512_SKX_ldexp_@TYPE@(args, dimensions, steps);
- return 1;
- }
- else
- return 0;
-#endif
- return 0;
-}
-
-static NPY_INLINE int
-run_unary_two_out_avx512_skx_frexp_@TYPE@(char **args, npy_intp const *dimensions, npy_intp const *steps)
-{
-#if defined HAVE_ATTRIBUTE_TARGET_AVX512_SKX_WITH_INTRINSICS && defined NPY_HAVE_SSE2_INTRINSICS && @EXISTS@
- if (IS_UNARY_TWO_OUT_SMALL_STEPS_AND_NOMEMOVERLAP) {
- AVX512_SKX_frexp_@TYPE@(args, dimensions, steps);
- return 1;
- }
- else
- return 0;
-#endif
- return 0;
-}
/**end repeat**/
/**begin repeat
@@ -384,93 +194,8 @@ run_unary_@isa@_@func@_@TYPE@(char **args, npy_intp const *dimensions, npy_intp
/**end repeat2**/
/**end repeat1**/
-
-/**begin repeat1
- * #func = exp, log#
- */
-
-#if defined @CHK@ && defined NPY_HAVE_SSE2_INTRINSICS
-static NPY_INLINE void
-@ISA@_@func@_FLOAT(npy_float *, npy_float *, const npy_intp n, const npy_intp stride);
-#endif
-
-static NPY_INLINE int
-run_unary_@isa@_@func@_FLOAT(char **args, npy_intp const *dimensions, npy_intp const *steps)
-{
-#if defined @CHK@ && defined NPY_HAVE_SSE2_INTRINSICS
- if (IS_OUTPUT_BLOCKABLE_UNARY(sizeof(npy_float), sizeof(npy_float), @REGISTER_SIZE@)) {
- @ISA@_@func@_FLOAT((npy_float*)args[1], (npy_float*)args[0], dimensions[0], steps[0]);
- return 1;
- }
- else
- return 0;
-#endif
- return 0;
-}
-
-/**end repeat1**/
-
-#if defined @CHK@ && defined NPY_HAVE_SSE2_INTRINSICS
-static NPY_INLINE void
-@ISA@_sincos_FLOAT(npy_float *, npy_float *, const npy_intp n, const npy_intp steps, NPY_TRIG_OP);
-#endif
-
-static NPY_INLINE int
-run_unary_@isa@_sincos_FLOAT(char **args, npy_intp const *dimensions, npy_intp const *steps, NPY_TRIG_OP my_trig_op)
-{
-#if defined @CHK@ && defined NPY_HAVE_SSE2_INTRINSICS
- if (IS_OUTPUT_BLOCKABLE_UNARY(sizeof(npy_float), sizeof(npy_float), @REGISTER_SIZE@)) {
- @ISA@_sincos_FLOAT((npy_float*)args[1], (npy_float*)args[0], dimensions[0], steps[0], my_trig_op);
- return 1;
- }
- else
- return 0;
-#endif
- return 0;
-}
-
/**end repeat**/
-#if defined HAVE_ATTRIBUTE_TARGET_AVX512F_WITH_INTRINSICS && defined NPY_HAVE_SSE2_INTRINSICS
-static NPY_INLINE void
-AVX512F_exp_DOUBLE(npy_double *, npy_double *, const npy_intp n, const npy_intp stride);
-#endif
-static NPY_INLINE int
-run_unary_avx512f_exp_DOUBLE(char **args, npy_intp const *dimensions, npy_intp const *steps)
-{
-#if defined HAVE_ATTRIBUTE_TARGET_AVX512F_WITH_INTRINSICS && defined NPY_HAVE_SSE2_INTRINSICS
-#if !(defined(__clang__) && (__clang_major__ < 10 || (__clang_major__ == 10 && __clang_minor__ < 1)))
- if (IS_OUTPUT_BLOCKABLE_UNARY(sizeof(npy_double), sizeof(npy_double), 64)) {
- AVX512F_exp_DOUBLE((npy_double*)args[1], (npy_double*)args[0], dimensions[0], steps[0]);
- return 1;
- }
- else
- return 0;
-#endif
-#endif
- return 0;
-}
-
-#if defined HAVE_ATTRIBUTE_TARGET_AVX512F_WITH_INTRINSICS && defined NPY_HAVE_SSE2_INTRINSICS
-static NPY_INLINE void
-AVX512F_log_DOUBLE(npy_double *, npy_double *, const npy_intp n, const npy_intp stride);
-#endif
-static NPY_INLINE int
-run_unary_avx512f_log_DOUBLE(char **args, npy_intp const *dimensions, npy_intp const *steps)
-{
-#if defined HAVE_ATTRIBUTE_TARGET_AVX512F_WITH_INTRINSICS && defined NPY_HAVE_SSE2_INTRINSICS
-#if !(defined(__clang__) && (__clang_major__ < 10 || (__clang_major__ == 10 && __clang_minor__ < 1)))
- if (IS_OUTPUT_BLOCKABLE_UNARY(sizeof(npy_double), sizeof(npy_double), 64)) {
- AVX512F_log_DOUBLE((npy_double*)args[1], (npy_double*)args[0], dimensions[0], steps[0]);
- return 1;
- }
- else
- return 0;
-#endif
-#endif
- return 0;
-}
-
/**begin repeat
* Float types
* #type = npy_float, npy_double, npy_longdouble#
@@ -480,9 +205,9 @@ run_unary_avx512f_log_DOUBLE(char **args, npy_intp const *dimensions, npy_intp c
*/
/**begin repeat1
- * #func = absolute, negative, minimum, maximum#
- * #check = IS_BLOCKABLE_UNARY*2, IS_BLOCKABLE_REDUCE*2 #
- * #name = unary*2, unary_reduce*2#
+ * #func = negative, minimum, maximum#
+ * #check = IS_BLOCKABLE_UNARY, IS_BLOCKABLE_REDUCE*2 #
+ * #name = unary, unary_reduce*2#
*/
#if @vector@ && defined NPY_HAVE_SSE2_INTRINSICS
@@ -508,92 +233,6 @@ run_@name@_simd_@func@_@TYPE@(char **args, npy_intp const *dimensions, npy_intp
/**end repeat1**/
/**begin repeat1
- * Arithmetic
- * # kind = add, subtract, multiply, divide#
- */
-
-#if @vector@ && defined NPY_HAVE_SSE2_INTRINSICS
-
-/* prototypes */
-static void
-sse2_binary_@kind@_@TYPE@(@type@ * op, @type@ * ip1, @type@ * ip2,
- npy_intp n);
-static void
-sse2_binary_scalar1_@kind@_@TYPE@(@type@ * op, @type@ * ip1, @type@ * ip2,
- npy_intp n);
-static void
-sse2_binary_scalar2_@kind@_@TYPE@(@type@ * op, @type@ * ip1, @type@ * ip2,
- npy_intp n);
-
-#elif @VECTOR@
-
-static void
-simd_binary_@kind@_@TYPE@(@type@ * op, @type@ * ip1, @type@ * ip2,
- npy_intp n);
-static void
-simd_binary_scalar1_@kind@_@TYPE@(@type@ * op, @type@ * ip1, @type@ * ip2,
- npy_intp n);
-static void
-simd_binary_scalar2_@kind@_@TYPE@(@type@ * op, @type@ * ip1, @type@ * ip2,
- npy_intp n);
-
-#endif
-
-static NPY_INLINE int
-run_binary_simd_@kind@_@TYPE@(char **args, npy_intp const *dimensions, npy_intp const *steps)
-{
-#if @vector@ && defined NPY_HAVE_SSE2_INTRINSICS
- @type@ * ip1 = (@type@ *)args[0];
- @type@ * ip2 = (@type@ *)args[1];
- @type@ * op = (@type@ *)args[2];
- npy_intp n = dimensions[0];
-#if defined __AVX512F__
- const npy_uintp vector_size_bytes = 64;
-#elif defined __AVX2__
- const npy_uintp vector_size_bytes = 32;
-#else
- const npy_uintp vector_size_bytes = 32;
-#endif
- /* argument one scalar */
- if (IS_BLOCKABLE_BINARY_SCALAR1(sizeof(@type@), vector_size_bytes)) {
- sse2_binary_scalar1_@kind@_@TYPE@(op, ip1, ip2, n);
- return 1;
- }
- /* argument two scalar */
- else if (IS_BLOCKABLE_BINARY_SCALAR2(sizeof(@type@), vector_size_bytes)) {
- sse2_binary_scalar2_@kind@_@TYPE@(op, ip1, ip2, n);
- return 1;
- }
- else if (IS_BLOCKABLE_BINARY(sizeof(@type@), vector_size_bytes)) {
- sse2_binary_@kind@_@TYPE@(op, ip1, ip2, n);
- return 1;
- }
-#elif @VECTOR@
- @type@ * ip1 = (@type@ *)args[0];
- @type@ * ip2 = (@type@ *)args[1];
- @type@ * op = (@type@ *)args[2];
- npy_intp n = dimensions[0];
- /* argument one scalar */
- if (IS_BLOCKABLE_BINARY_SCALAR1(sizeof(@type@), NPY_SIMD_WIDTH)) {
- simd_binary_scalar1_@kind@_@TYPE@(op, ip1, ip2, n);
- return 1;
- }
- /* argument two scalar */
- else if (IS_BLOCKABLE_BINARY_SCALAR2(sizeof(@type@), NPY_SIMD_WIDTH)) {
- simd_binary_scalar2_@kind@_@TYPE@(op, ip1, ip2, n);
- return 1;
- }
- else if (IS_BLOCKABLE_BINARY(sizeof(@type@), NPY_SIMD_WIDTH)) {
- simd_binary_@kind@_@TYPE@(op, ip1, ip2, n);
- return 1;
- }
-#endif
- return 0;
-}
-
-/**end repeat1**/
-
-/**begin repeat1
* #kind = equal, not_equal, less, less_equal, greater, greater_equal,
* logical_and, logical_or#
* #simd = 1, 1, 1, 1, 1, 1, 0, 0#
@@ -760,7 +399,7 @@ run_unary_simd_@kind@_BOOL(char **args, npy_intp const *dimensions, npy_intp con
* # VOP = min, max#
*/
-static NPY_INLINE npy_float sse2_horizontal_@VOP@___m128(__m128 v)
+NPY_FINLINE npy_float sse2_horizontal_@VOP@___m128(__m128 v)
{
npy_float r;
__m128 tmp = _mm_movehl_ps(v, v); /* c d ... */
@@ -770,14 +409,13 @@ static NPY_INLINE npy_float sse2_horizontal_@VOP@___m128(__m128 v)
return r;
}
-static NPY_INLINE npy_double sse2_horizontal_@VOP@___m128d(__m128d v)
+NPY_FINLINE npy_double sse2_horizontal_@VOP@___m128d(__m128d v)
{
npy_double r;
__m128d tmp = _mm_unpackhi_pd(v, v); /* b b */
_mm_store_sd(&r, _mm_@VOP@_pd(tmp, v)); /* m(ab) m(bb) */
return r;
}
-
/**end repeat**/
/**begin repeat
@@ -797,333 +435,12 @@ static NPY_INLINE npy_double sse2_horizontal_@VOP@___m128d(__m128d v)
* #double = 0, 1#
* #cast = _mm_castps_si128, _mm_castpd_si128#
*/
-
-
-/**begin repeat1
-* Arithmetic
-* # kind = add, subtract, multiply, divide#
-* # OP = +, -, *, /#
-* # VOP = add, sub, mul, div#
-*/
-
-static void
-sse2_binary_@kind@_@TYPE@(@type@ * op, @type@ * ip1, @type@ * ip2, npy_intp n)
-{
-#ifdef __AVX512F__
- const npy_intp vector_size_bytes = 64;
- LOOP_BLOCK_ALIGN_VAR(op, @type@, vector_size_bytes)
- op[i] = ip1[i] @OP@ ip2[i];
- /* lots of specializations, to squeeze out max performance */
- if (npy_is_aligned(&ip1[i], vector_size_bytes) && npy_is_aligned(&ip2[i], vector_size_bytes)) {
- if (ip1 == ip2) {
- LOOP_BLOCKED(@type@, vector_size_bytes) {
- @vtype512@ a = @vpre512@_load_@vsuf@(&ip1[i]);
- @vtype512@ c = @vpre512@_@VOP@_@vsuf@(a, a);
- @vpre512@_store_@vsuf@(&op[i], c);
- }
- }
- else {
- LOOP_BLOCKED(@type@, vector_size_bytes) {
- @vtype512@ a = @vpre512@_load_@vsuf@(&ip1[i]);
- @vtype512@ b = @vpre512@_load_@vsuf@(&ip2[i]);
- @vtype512@ c = @vpre512@_@VOP@_@vsuf@(a, b);
- @vpre512@_store_@vsuf@(&op[i], c);
- }
- }
- }
- else if (npy_is_aligned(&ip1[i], vector_size_bytes)) {
- LOOP_BLOCKED(@type@, vector_size_bytes) {
- @vtype512@ a = @vpre512@_load_@vsuf@(&ip1[i]);
- @vtype512@ b = @vpre512@_loadu_@vsuf@(&ip2[i]);
- @vtype512@ c = @vpre512@_@VOP@_@vsuf@(a, b);
- @vpre512@_store_@vsuf@(&op[i], c);
- }
- }
- else if (npy_is_aligned(&ip2[i], vector_size_bytes)) {
- LOOP_BLOCKED(@type@, vector_size_bytes) {
- @vtype512@ a = @vpre512@_loadu_@vsuf@(&ip1[i]);
- @vtype512@ b = @vpre512@_load_@vsuf@(&ip2[i]);
- @vtype512@ c = @vpre512@_@VOP@_@vsuf@(a, b);
- @vpre512@_store_@vsuf@(&op[i], c);
- }
- }
- else {
- if (ip1 == ip2) {
- LOOP_BLOCKED(@type@, vector_size_bytes) {
- @vtype512@ a = @vpre512@_loadu_@vsuf@(&ip1[i]);
- @vtype512@ c = @vpre512@_@VOP@_@vsuf@(a, a);
- @vpre512@_store_@vsuf@(&op[i], c);
- }
- }
- else {
- LOOP_BLOCKED(@type@, vector_size_bytes) {
- @vtype512@ a = @vpre512@_loadu_@vsuf@(&ip1[i]);
- @vtype512@ b = @vpre512@_loadu_@vsuf@(&ip2[i]);
- @vtype512@ c = @vpre512@_@VOP@_@vsuf@(a, b);
- @vpre512@_store_@vsuf@(&op[i], c);
- }
- }
- }
-#elif __AVX2__
- const npy_intp vector_size_bytes = 32;
- LOOP_BLOCK_ALIGN_VAR(op, @type@, vector_size_bytes)
- op[i] = ip1[i] @OP@ ip2[i];
- /* lots of specializations, to squeeze out max performance */
- if (npy_is_aligned(&ip1[i], vector_size_bytes) &&
- npy_is_aligned(&ip2[i], vector_size_bytes)) {
- if (ip1 == ip2) {
- LOOP_BLOCKED(@type@, vector_size_bytes) {
- @vtype256@ a = @vpre256@_load_@vsuf@(&ip1[i]);
- @vtype256@ c = @vpre256@_@VOP@_@vsuf@(a, a);
- @vpre256@_store_@vsuf@(&op[i], c);
- }
- }
- else {
- LOOP_BLOCKED(@type@, vector_size_bytes) {
- @vtype256@ a = @vpre256@_load_@vsuf@(&ip1[i]);
- @vtype256@ b = @vpre256@_load_@vsuf@(&ip2[i]);
- @vtype256@ c = @vpre256@_@VOP@_@vsuf@(a, b);
- @vpre256@_store_@vsuf@(&op[i], c);
- }
- }
- }
- else if (npy_is_aligned(&ip1[i], vector_size_bytes)) {
- LOOP_BLOCKED(@type@, vector_size_bytes) {
- @vtype256@ a = @vpre256@_load_@vsuf@(&ip1[i]);
- @vtype256@ b = @vpre256@_loadu_@vsuf@(&ip2[i]);
- @vtype256@ c = @vpre256@_@VOP@_@vsuf@(a, b);
- @vpre256@_store_@vsuf@(&op[i], c);
- }
- }
- else if (npy_is_aligned(&ip2[i], vector_size_bytes)) {
- LOOP_BLOCKED(@type@, vector_size_bytes) {
- @vtype256@ a = @vpre256@_loadu_@vsuf@(&ip1[i]);
- @vtype256@ b = @vpre256@_load_@vsuf@(&ip2[i]);
- @vtype256@ c = @vpre256@_@VOP@_@vsuf@(a, b);
- @vpre256@_store_@vsuf@(&op[i], c);
- }
- }
- else {
- if (ip1 == ip2) {
- LOOP_BLOCKED(@type@, vector_size_bytes) {
- @vtype256@ a = @vpre256@_loadu_@vsuf@(&ip1[i]);
- @vtype256@ c = @vpre256@_@VOP@_@vsuf@(a, a);
- @vpre256@_store_@vsuf@(&op[i], c);
- }
- }
- else {
- LOOP_BLOCKED(@type@, vector_size_bytes) {
- @vtype256@ a = @vpre256@_loadu_@vsuf@(&ip1[i]);
- @vtype256@ b = @vpre256@_loadu_@vsuf@(&ip2[i]);
- @vtype256@ c = @vpre256@_@VOP@_@vsuf@(a, b);
- @vpre256@_store_@vsuf@(&op[i], c);
- }
- }
- }
-#else
- LOOP_BLOCK_ALIGN_VAR(op, @type@, VECTOR_SIZE_BYTES)
- op[i] = ip1[i] @OP@ ip2[i];
- /* lots of specializations, to squeeze out max performance */
- if (npy_is_aligned(&ip1[i], VECTOR_SIZE_BYTES) &&
- npy_is_aligned(&ip2[i], VECTOR_SIZE_BYTES)) {
- if (ip1 == ip2) {
- LOOP_BLOCKED(@type@, VECTOR_SIZE_BYTES) {
- @vtype@ a = @vpre@_load_@vsuf@(&ip1[i]);
- @vtype@ c = @vpre@_@VOP@_@vsuf@(a, a);
- @vpre@_store_@vsuf@(&op[i], c);
- }
- }
- else {
- LOOP_BLOCKED(@type@, VECTOR_SIZE_BYTES) {
- @vtype@ a = @vpre@_load_@vsuf@(&ip1[i]);
- @vtype@ b = @vpre@_load_@vsuf@(&ip2[i]);
- @vtype@ c = @vpre@_@VOP@_@vsuf@(a, b);
- @vpre@_store_@vsuf@(&op[i], c);
- }
- }
- }
- else if (npy_is_aligned(&ip1[i], VECTOR_SIZE_BYTES)) {
- LOOP_BLOCKED(@type@, VECTOR_SIZE_BYTES) {
- @vtype@ a = @vpre@_load_@vsuf@(&ip1[i]);
- @vtype@ b = @vpre@_loadu_@vsuf@(&ip2[i]);
- @vtype@ c = @vpre@_@VOP@_@vsuf@(a, b);
- @vpre@_store_@vsuf@(&op[i], c);
- }
- }
- else if (npy_is_aligned(&ip2[i], VECTOR_SIZE_BYTES)) {
- LOOP_BLOCKED(@type@, VECTOR_SIZE_BYTES) {
- @vtype@ a = @vpre@_loadu_@vsuf@(&ip1[i]);
- @vtype@ b = @vpre@_load_@vsuf@(&ip2[i]);
- @vtype@ c = @vpre@_@VOP@_@vsuf@(a, b);
- @vpre@_store_@vsuf@(&op[i], c);
- }
- }
- else {
- if (ip1 == ip2) {
- LOOP_BLOCKED(@type@, VECTOR_SIZE_BYTES) {
- @vtype@ a = @vpre@_loadu_@vsuf@(&ip1[i]);
- @vtype@ c = @vpre@_@VOP@_@vsuf@(a, a);
- @vpre@_store_@vsuf@(&op[i], c);
- }
- }
- else {
- LOOP_BLOCKED(@type@, VECTOR_SIZE_BYTES) {
- @vtype@ a = @vpre@_loadu_@vsuf@(&ip1[i]);
- @vtype@ b = @vpre@_loadu_@vsuf@(&ip2[i]);
- @vtype@ c = @vpre@_@VOP@_@vsuf@(a, b);
- @vpre@_store_@vsuf@(&op[i], c);
- }
- }
- }
-#endif
- LOOP_BLOCKED_END {
- op[i] = ip1[i] @OP@ ip2[i];
- }
-}
-
-
-static void
-sse2_binary_scalar1_@kind@_@TYPE@(@type@ * op, @type@ * ip1, @type@ * ip2, npy_intp n)
-{
-#ifdef __AVX512F__
- const npy_intp vector_size_bytes = 64;
- const @vtype512@ a = @vpre512@_set1_@vsuf@(ip1[0]);
- LOOP_BLOCK_ALIGN_VAR(op, @type@, vector_size_bytes)
- op[i] = ip1[0] @OP@ ip2[i];
- if (npy_is_aligned(&ip2[i], vector_size_bytes)) {
- LOOP_BLOCKED(@type@, vector_size_bytes) {
- @vtype512@ b = @vpre512@_load_@vsuf@(&ip2[i]);
- @vtype512@ c = @vpre512@_@VOP@_@vsuf@(a, b);
- @vpre512@_store_@vsuf@(&op[i], c);
- }
- }
- else {
- LOOP_BLOCKED(@type@, vector_size_bytes) {
- @vtype512@ b = @vpre512@_loadu_@vsuf@(&ip2[i]);
- @vtype512@ c = @vpre512@_@VOP@_@vsuf@(a, b);
- @vpre512@_store_@vsuf@(&op[i], c);
- }
- }
-
-
-#elif __AVX2__
- const npy_intp vector_size_bytes = 32;
- const @vtype256@ a = @vpre256@_set1_@vsuf@(ip1[0]);
- LOOP_BLOCK_ALIGN_VAR(op, @type@, vector_size_bytes)
- op[i] = ip1[0] @OP@ ip2[i];
- if (npy_is_aligned(&ip2[i], vector_size_bytes)) {
- LOOP_BLOCKED(@type@, vector_size_bytes) {
- @vtype256@ b = @vpre256@_load_@vsuf@(&ip2[i]);
- @vtype256@ c = @vpre256@_@VOP@_@vsuf@(a, b);
- @vpre256@_store_@vsuf@(&op[i], c);
- }
- }
- else {
- LOOP_BLOCKED(@type@, vector_size_bytes) {
- @vtype256@ b = @vpre256@_loadu_@vsuf@(&ip2[i]);
- @vtype256@ c = @vpre256@_@VOP@_@vsuf@(a, b);
- @vpre256@_store_@vsuf@(&op[i], c);
- }
- }
-#else
- const @vtype@ a = @vpre@_set1_@vsuf@(ip1[0]);
- LOOP_BLOCK_ALIGN_VAR(op, @type@, VECTOR_SIZE_BYTES)
- op[i] = ip1[0] @OP@ ip2[i];
- if (npy_is_aligned(&ip2[i], VECTOR_SIZE_BYTES)) {
- LOOP_BLOCKED(@type@, VECTOR_SIZE_BYTES) {
- @vtype@ b = @vpre@_load_@vsuf@(&ip2[i]);
- @vtype@ c = @vpre@_@VOP@_@vsuf@(a, b);
- @vpre@_store_@vsuf@(&op[i], c);
- }
- }
- else {
- LOOP_BLOCKED(@type@, VECTOR_SIZE_BYTES) {
- @vtype@ b = @vpre@_loadu_@vsuf@(&ip2[i]);
- @vtype@ c = @vpre@_@VOP@_@vsuf@(a, b);
- @vpre@_store_@vsuf@(&op[i], c);
- }
- }
-#endif
- LOOP_BLOCKED_END {
- op[i] = ip1[0] @OP@ ip2[i];
- }
-}
-
-
-static void
-sse2_binary_scalar2_@kind@_@TYPE@(@type@ * op, @type@ * ip1, @type@ * ip2, npy_intp n)
-{
-#ifdef __AVX512F__
- const npy_intp vector_size_bytes = 64;
- const @vtype512@ b = @vpre512@_set1_@vsuf@(ip2[0]);
- LOOP_BLOCK_ALIGN_VAR(op, @type@, vector_size_bytes)
- op[i] = ip1[i] @OP@ ip2[0];
- if (npy_is_aligned(&ip1[i], vector_size_bytes)) {
- LOOP_BLOCKED(@type@, vector_size_bytes) {
- @vtype512@ a = @vpre512@_load_@vsuf@(&ip1[i]);
- @vtype512@ c = @vpre512@_@VOP@_@vsuf@(a, b);
- @vpre512@_store_@vsuf@(&op[i], c);
- }
- }
- else {
- LOOP_BLOCKED(@type@, vector_size_bytes) {
- @vtype512@ a = @vpre512@_loadu_@vsuf@(&ip1[i]);
- @vtype512@ c = @vpre512@_@VOP@_@vsuf@(a, b);
- @vpre512@_store_@vsuf@(&op[i], c);
- }
- }
-
-#elif __AVX2__
- const npy_intp vector_size_bytes = 32;
- const @vtype256@ b = @vpre256@_set1_@vsuf@(ip2[0]);
- LOOP_BLOCK_ALIGN_VAR(op, @type@, vector_size_bytes)
- op[i] = ip1[i] @OP@ ip2[0];
- if (npy_is_aligned(&ip1[i], vector_size_bytes)) {
- LOOP_BLOCKED(@type@, vector_size_bytes) {
- @vtype256@ a = @vpre256@_load_@vsuf@(&ip1[i]);
- @vtype256@ c = @vpre256@_@VOP@_@vsuf@(a, b);
- @vpre256@_store_@vsuf@(&op[i], c);
- }
- }
- else {
- LOOP_BLOCKED(@type@, vector_size_bytes) {
- @vtype256@ a = @vpre256@_loadu_@vsuf@(&ip1[i]);
- @vtype256@ c = @vpre256@_@VOP@_@vsuf@(a, b);
- @vpre256@_store_@vsuf@(&op[i], c);
- }
- }
-#else
- const @vtype@ b = @vpre@_set1_@vsuf@(ip2[0]);
- LOOP_BLOCK_ALIGN_VAR(op, @type@, VECTOR_SIZE_BYTES)
- op[i] = ip1[i] @OP@ ip2[0];
- if (npy_is_aligned(&ip1[i], VECTOR_SIZE_BYTES)) {
- LOOP_BLOCKED(@type@, VECTOR_SIZE_BYTES) {
- @vtype@ a = @vpre@_load_@vsuf@(&ip1[i]);
- @vtype@ c = @vpre@_@VOP@_@vsuf@(a, b);
- @vpre@_store_@vsuf@(&op[i], c);
- }
- }
- else {
- LOOP_BLOCKED(@type@, VECTOR_SIZE_BYTES) {
- @vtype@ a = @vpre@_loadu_@vsuf@(&ip1[i]);
- @vtype@ c = @vpre@_@VOP@_@vsuf@(a, b);
- @vpre@_store_@vsuf@(&op[i], c);
- }
- }
-#endif
- LOOP_BLOCKED_END {
- op[i] = ip1[i] @OP@ ip2[0];
- }
-}
-
-/**end repeat1**/
-
/*
* compress 4 vectors to 4/8 bytes in op with filled with 0 or 1
* the last vector is passed as a pointer as MSVC 2010 is unable to ignore the
* calling convention leading to C2719 on 32 bit, see #4795
*/
-static NPY_INLINE void
+NPY_FINLINE void
sse2_compress4_to_byte_@TYPE@(@vtype@ r1, @vtype@ r2, @vtype@ r3, @vtype@ * r4,
npy_bool * op)
{
@@ -1240,7 +557,7 @@ sse2_@kind@_@TYPE@(npy_bool * op, @type@ * ip1, npy_intp n)
*/
/* sets invalid fpu flag on QNaN for consistency with packed compare */
-static NPY_INLINE int
+NPY_FINLINE int
sse2_ordered_cmp_@kind@_@TYPE@(const @type@ a, const @type@ b)
{
@vtype@ one = @vpre@_set1_@vsuf@(1);
@@ -1327,26 +644,9 @@ sse2_binary_scalar2_@kind@_@TYPE@(npy_bool * op, @type@ * ip1, @type@ * ip2, npy
}
/**end repeat1**/
-static NPY_INLINE
-@type@ scalar_abs_@type@(@type@ v)
-{
- /* add 0 to clear -0.0 */
- return (v > 0 ? v: -v) + 0;
-}
-
-static NPY_INLINE
-@type@ scalar_neg_@type@(@type@ v)
-{
- return -v;
-}
-/**begin repeat1
- * #kind = absolute, negative#
- * #VOP = andnot, xor#
- * #scalar = scalar_abs, scalar_neg#
- **/
static void
-sse2_@kind@_@TYPE@(@type@ * op, @type@ * ip, const npy_intp n)
+sse2_negative_@TYPE@(@type@ * op, @type@ * ip, const npy_intp n)
{
/*
* get 0x7FFFFFFF mask (everything but signbit set)
@@ -1357,24 +657,24 @@ sse2_@kind@_@TYPE@(@type@ * op, @type@ * ip, const npy_intp n)
/* align output to VECTOR_SIZE_BYTES bytes */
LOOP_BLOCK_ALIGN_VAR(op, @type@, VECTOR_SIZE_BYTES) {
- op[i] = @scalar@_@type@(ip[i]);
+ op[i] = -ip[i];
}
assert((npy_uintp)n < (VECTOR_SIZE_BYTES / sizeof(@type@)) ||
npy_is_aligned(&op[i], VECTOR_SIZE_BYTES));
if (npy_is_aligned(&ip[i], VECTOR_SIZE_BYTES)) {
LOOP_BLOCKED(@type@, VECTOR_SIZE_BYTES) {
@vtype@ a = @vpre@_load_@vsuf@(&ip[i]);
- @vpre@_store_@vsuf@(&op[i], @vpre@_@VOP@_@vsuf@(mask, a));
+ @vpre@_store_@vsuf@(&op[i], @vpre@_xor_@vsuf@(mask, a));
}
}
else {
LOOP_BLOCKED(@type@, VECTOR_SIZE_BYTES) {
@vtype@ a = @vpre@_loadu_@vsuf@(&ip[i]);
- @vpre@_store_@vsuf@(&op[i], @vpre@_@VOP@_@vsuf@(mask, a));
+ @vpre@_store_@vsuf@(&op[i], @vpre@_xor_@vsuf@(mask, a));
}
}
LOOP_BLOCKED_END {
- op[i] = @scalar@_@type@(ip[i]);
+ op[i] = -ip[i];
}
}
/**end repeat1**/
@@ -1433,19 +733,19 @@ sse2_@kind@_@TYPE@(@type@ * ip, @type@ * op, const npy_intp n)
/* bunch of helper functions used in ISA_exp/log_FLOAT*/
#if defined HAVE_ATTRIBUTE_TARGET_AVX2_WITH_INTRINSICS
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256
fma_get_full_load_mask_ps(void)
{
return _mm256_set1_ps(-1.0);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256i
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256i
fma_get_full_load_mask_pd(void)
{
return _mm256_castpd_si256(_mm256_set1_pd(-1.0));
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256
fma_get_partial_load_mask_ps(const npy_int num_elem, const npy_int num_lanes)
{
float maskint[16] = {-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,-1.0,
@@ -1454,7 +754,7 @@ fma_get_partial_load_mask_ps(const npy_int num_elem, const npy_int num_lanes)
return _mm256_loadu_ps(addr);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256i
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256i
fma_get_partial_load_mask_pd(const npy_int num_elem, const npy_int num_lanes)
{
npy_int maskint[16] = {-1,-1,-1,-1,-1,-1,-1,-1,1,1,1,1,1,1,1,1};
@@ -1462,7 +762,7 @@ fma_get_partial_load_mask_pd(const npy_int num_elem, const npy_int num_lanes)
return _mm256_loadu_si256((__m256i*) addr);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256
fma_masked_gather_ps(__m256 src,
npy_float* addr,
__m256i vindex,
@@ -1471,7 +771,7 @@ fma_masked_gather_ps(__m256 src,
return _mm256_mask_i32gather_ps(src, addr, vindex, mask, 4);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256d
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256d
fma_masked_gather_pd(__m256d src,
npy_double* addr,
__m128i vindex,
@@ -1480,188 +780,83 @@ fma_masked_gather_pd(__m256d src,
return _mm256_mask_i32gather_pd(src, addr, vindex, mask, 8);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256
fma_masked_load_ps(__m256 mask, npy_float* addr)
{
return _mm256_maskload_ps(addr, _mm256_cvtps_epi32(mask));
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256d
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256d
fma_masked_load_pd(__m256i mask, npy_double* addr)
{
return _mm256_maskload_pd(addr, mask);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256
fma_set_masked_lanes_ps(__m256 x, __m256 val, __m256 mask)
{
return _mm256_blendv_ps(x, val, mask);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256d
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256d
fma_set_masked_lanes_pd(__m256d x, __m256d val, __m256d mask)
{
return _mm256_blendv_pd(x, val, mask);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256
fma_blend(__m256 x, __m256 y, __m256 ymask)
{
return _mm256_blendv_ps(x, y, ymask);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256
fma_invert_mask_ps(__m256 ymask)
{
return _mm256_andnot_ps(ymask, _mm256_set1_ps(-1.0));
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256i
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256i
fma_invert_mask_pd(__m256i ymask)
{
return _mm256_andnot_si256(ymask, _mm256_set1_epi32(0xFFFFFFFF));
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256
-fma_should_calculate_sine(__m256i k, __m256i andop, __m256i cmp)
-{
- return _mm256_cvtepi32_ps(
- _mm256_cmpeq_epi32(_mm256_and_si256(k, andop), cmp));
-}
-
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256
-fma_should_negate(__m256i k, __m256i andop, __m256i cmp)
-{
- return fma_should_calculate_sine(k, andop, cmp);
-}
-
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256
-fma_get_exponent(__m256 x)
-{
- /*
- * Special handling of denormals:
- * 1) Multiply denormal elements with 2**100 (0x71800000)
- * 2) Get the 8 bits of unbiased exponent
- * 3) Subtract 100 from exponent of denormals
- */
-
- __m256 two_power_100 = _mm256_castsi256_ps(_mm256_set1_epi32(0x71800000));
- __m256 denormal_mask = _mm256_cmp_ps(x, _mm256_set1_ps(FLT_MIN), _CMP_LT_OQ);
- __m256 normal_mask = _mm256_cmp_ps(x, _mm256_set1_ps(FLT_MIN), _CMP_GE_OQ);
-
- __m256 temp1 = _mm256_blendv_ps(x, _mm256_set1_ps(0.0f), normal_mask);
- __m256 temp = _mm256_mul_ps(temp1, two_power_100);
- x = _mm256_blendv_ps(x, temp, denormal_mask);
-
- __m256 exp = _mm256_cvtepi32_ps(
- _mm256_sub_epi32(
- _mm256_srli_epi32(
- _mm256_castps_si256(x), 23),_mm256_set1_epi32(0x7E)));
-
- __m256 denorm_exp = _mm256_sub_ps(exp, _mm256_set1_ps(100.0f));
- return _mm256_blendv_ps(exp, denorm_exp, denormal_mask);
-}
-
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA __m256
-fma_get_mantissa(__m256 x)
-{
- /*
- * Special handling of denormals:
- * 1) Multiply denormal elements with 2**100 (0x71800000)
- * 2) Get the 23 bits of mantissa
- * 3) Mantissa for denormals is not affected by the multiplication
- */
-
- __m256 two_power_100 = _mm256_castsi256_ps(_mm256_set1_epi32(0x71800000));
- __m256 denormal_mask = _mm256_cmp_ps(x, _mm256_set1_ps(FLT_MIN), _CMP_LT_OQ);
- __m256 normal_mask = _mm256_cmp_ps(x, _mm256_set1_ps(FLT_MIN), _CMP_GE_OQ);
-
- __m256 temp1 = _mm256_blendv_ps(x, _mm256_set1_ps(0.0f), normal_mask);
- __m256 temp = _mm256_mul_ps(temp1, two_power_100);
- x = _mm256_blendv_ps(x, temp, denormal_mask);
-
- __m256i mantissa_bits = _mm256_set1_epi32(0x7fffff);
- __m256i exp_126_bits = _mm256_set1_epi32(126 << 23);
- return _mm256_castsi256_ps(
- _mm256_or_si256(
- _mm256_and_si256(
- _mm256_castps_si256(x), mantissa_bits), exp_126_bits));
-}
-
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX2 __m256
-fma_scalef_ps(__m256 poly, __m256 quadrant)
-{
- /*
- * Handle denormals (which occur when quadrant <= -125):
- * 1) This function computes poly*(2^quad) by adding the exponent of
- poly to quad
- * 2) When quad <= -125, the output is a denormal and the above logic
- breaks down
- * 3) To handle such cases, we split quadrant: -125 + (quadrant + 125)
- * 4) poly*(2^-125) is computed the usual way
- * 5) 2^(quad-125) can be computed by: 2 << abs(quad-125)
- * 6) The final div operation generates the denormal
- */
- __m256 minquadrant = _mm256_set1_ps(-125.0f);
- __m256 denormal_mask = _mm256_cmp_ps(quadrant, minquadrant, _CMP_LE_OQ);
- if (_mm256_movemask_ps(denormal_mask) != 0x0000) {
- __m256 quad_diff = _mm256_sub_ps(quadrant, minquadrant);
- quad_diff = _mm256_sub_ps(_mm256_setzero_ps(), quad_diff);
- quad_diff = _mm256_blendv_ps(_mm256_setzero_ps(), quad_diff, denormal_mask);
- __m256i two_power_diff = _mm256_sllv_epi32(
- _mm256_set1_epi32(1), _mm256_cvtps_epi32(quad_diff));
- quadrant = _mm256_max_ps(quadrant, minquadrant); //keep quadrant >= -126
- __m256i exponent = _mm256_slli_epi32(_mm256_cvtps_epi32(quadrant), 23);
- poly = _mm256_castsi256_ps(
- _mm256_add_epi32(
- _mm256_castps_si256(poly), exponent));
- __m256 denorm_poly = _mm256_div_ps(poly, _mm256_cvtepi32_ps(two_power_diff));
- return _mm256_blendv_ps(poly, denorm_poly, denormal_mask);
- }
- else {
- __m256i exponent = _mm256_slli_epi32(_mm256_cvtps_epi32(quadrant), 23);
- poly = _mm256_castsi256_ps(
- _mm256_add_epi32(
- _mm256_castps_si256(poly), exponent));
- return poly;
- }
-}
-
/**begin repeat
* #vsub = ps, pd#
* #vtype = __m256, __m256d#
*/
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA @vtype@
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA @vtype@
fma_abs_@vsub@(@vtype@ x)
{
return _mm256_andnot_@vsub@(_mm256_set1_@vsub@(-0.0), x);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA @vtype@
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA @vtype@
fma_reciprocal_@vsub@(@vtype@ x)
{
return _mm256_div_@vsub@(_mm256_set1_@vsub@(1.0f), x);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA @vtype@
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA @vtype@
fma_rint_@vsub@(@vtype@ x)
{
return _mm256_round_@vsub@(x, _MM_FROUND_TO_NEAREST_INT);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA @vtype@
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA @vtype@
fma_floor_@vsub@(@vtype@ x)
{
return _mm256_round_@vsub@(x, _MM_FROUND_TO_NEG_INF);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA @vtype@
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA @vtype@
fma_ceil_@vsub@(@vtype@ x)
{
return _mm256_round_@vsub@(x, _MM_FROUND_TO_POS_INF);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA @vtype@
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_FMA @vtype@
fma_trunc_@vsub@(@vtype@ x)
{
return _mm256_round_@vsub@(x, _MM_FROUND_TO_ZERO);
@@ -1670,31 +865,31 @@ fma_trunc_@vsub@(@vtype@ x)
#endif
#if defined HAVE_ATTRIBUTE_TARGET_AVX512F_WITH_INTRINSICS
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __mmask16
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __mmask16
avx512_get_full_load_mask_ps(void)
{
return 0xFFFF;
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __mmask8
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __mmask8
avx512_get_full_load_mask_pd(void)
{
return 0xFF;
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __mmask16
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __mmask16
avx512_get_partial_load_mask_ps(const npy_int num_elem, const npy_int total_elem)
{
return (0x0001 << num_elem) - 0x0001;
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __mmask8
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __mmask8
avx512_get_partial_load_mask_pd(const npy_int num_elem, const npy_int total_elem)
{
return (0x01 << num_elem) - 0x01;
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __m512
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __m512
avx512_masked_gather_ps(__m512 src,
npy_float* addr,
__m512i vindex,
@@ -1703,7 +898,7 @@ avx512_masked_gather_ps(__m512 src,
return _mm512_mask_i32gather_ps(src, kmask, vindex, addr, 4);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __m512d
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __m512d
avx512_masked_gather_pd(__m512d src,
npy_double* addr,
__m256i vindex,
@@ -1712,106 +907,48 @@ avx512_masked_gather_pd(__m512d src,
return _mm512_mask_i32gather_pd(src, kmask, vindex, addr, 8);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __m512
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __m512
avx512_masked_load_ps(__mmask16 mask, npy_float* addr)
{
return _mm512_maskz_loadu_ps(mask, (__m512 *)addr);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __m512d
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __m512d
avx512_masked_load_pd(__mmask8 mask, npy_double* addr)
{
return _mm512_maskz_loadu_pd(mask, (__m512d *)addr);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __m512
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __m512
avx512_set_masked_lanes_ps(__m512 x, __m512 val, __mmask16 mask)
{
return _mm512_mask_blend_ps(mask, x, val);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __m512d
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __m512d
avx512_set_masked_lanes_pd(__m512d x, __m512d val, __mmask8 mask)
{
return _mm512_mask_blend_pd(mask, x, val);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __m512
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __m512
avx512_blend(__m512 x, __m512 y, __mmask16 ymask)
{
return _mm512_mask_mov_ps(x, ymask, y);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __mmask16
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __mmask16
avx512_invert_mask_ps(__mmask16 ymask)
{
return _mm512_knot(ymask);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __mmask8
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __mmask8
avx512_invert_mask_pd(__mmask8 ymask)
{
return _mm512_knot(ymask);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __mmask16
-avx512_should_calculate_sine(__m512i k, __m512i andop, __m512i cmp)
-{
- return _mm512_cmpeq_epi32_mask(_mm512_and_epi32(k, andop), cmp);
-}
-
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __mmask16
-avx512_should_negate(__m512i k, __m512i andop, __m512i cmp)
-{
- return avx512_should_calculate_sine(k, andop, cmp);
-}
-
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __m512
-avx512_get_exponent(__m512 x)
-{
- return _mm512_add_ps(_mm512_getexp_ps(x), _mm512_set1_ps(1.0f));
-}
-
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __m512
-avx512_get_mantissa(__m512 x)
-{
- return _mm512_getmant_ps(x, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src);
-}
-
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __m512
-avx512_scalef_ps(__m512 poly, __m512 quadrant)
-{
- return _mm512_scalef_ps(poly, quadrant);
-}
-
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __m512d
-avx512_permute_x4var_pd(__m512d t0,
- __m512d t1,
- __m512d t2,
- __m512d t3,
- __m512i index)
-{
- __mmask8 lut_mask = _mm512_cmp_epi64_mask(
- _mm512_and_epi64(_mm512_set1_epi64(0x10ULL), index),
- _mm512_set1_epi64(0), _MM_CMPINT_GT);
- __m512d res1 = _mm512_permutex2var_pd(t0, index, t1);
- __m512d res2 = _mm512_permutex2var_pd(t2, index, t3);
- return _mm512_mask_blend_pd(lut_mask, res1, res2);
-}
-
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F __m512d
-avx512_permute_x8var_pd(__m512d t0, __m512d t1, __m512d t2, __m512d t3,
- __m512d t4, __m512d t5, __m512d t6, __m512d t7,
- __m512i index)
-{
- __mmask8 lut_mask = _mm512_cmp_epi64_mask(
- _mm512_and_epi64(_mm512_set1_epi64(0x20ULL), index),
- _mm512_set1_epi64(0), _MM_CMPINT_GT);
- __m512d res1 = avx512_permute_x4var_pd(t0, t1, t2, t3, index);
- __m512d res2 = avx512_permute_x4var_pd(t4, t5, t6, t7, index);
- return _mm512_mask_blend_pd(lut_mask, res1, res2);
-}
-
/**begin repeat
* #vsub = ps, pd#
* #type= npy_float, npy_double#
@@ -1826,56 +963,56 @@ avx512_permute_x8var_pd(__m512d t0, __m512d t1, __m512d t2, __m512d t3,
* #INF = NPY_INFINITYF, NPY_INFINITY#
* #NAN = NPY_NANF, NPY_NAN#
*/
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
avx512_abs_@vsub@(@vtype@ x)
{
return (@vtype@) _mm512_and_@epi_vsub@((__m512i) x,
_mm512_set1_@epi_vsub@ (@and_const@));
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
avx512_reciprocal_@vsub@(@vtype@ x)
{
return _mm512_div_@vsub@(_mm512_set1_@vsub@(1.0f), x);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
avx512_rint_@vsub@(@vtype@ x)
{
return _mm512_roundscale_@vsub@(x, 0x08);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
avx512_floor_@vsub@(@vtype@ x)
{
return _mm512_roundscale_@vsub@(x, 0x09);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
avx512_ceil_@vsub@(@vtype@ x)
{
return _mm512_roundscale_@vsub@(x, 0x0A);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
avx512_trunc_@vsub@(@vtype@ x)
{
return _mm512_roundscale_@vsub@(x, 0x0B);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
avx512_hadd_@vsub@(const @vtype@ x)
{
return _mm512_add_@vsub@(x, _mm512_permute_@vsub@(x, @perm_@));
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
avx512_hsub_@vsub@(const @vtype@ x)
{
return _mm512_sub_@vsub@(x, _mm512_permute_@vsub@(x, @perm_@));
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
avx512_cabsolute_@vsub@(const @vtype@ x1,
const @vtype@ x2,
const __m512i re_indices,
@@ -1920,7 +1057,7 @@ avx512_cabsolute_@vsub@(const @vtype@ x1,
return _mm512_mul_@vsub@(hypot, larger);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
avx512_conjugate_@vsub@(const @vtype@ x)
{
/*
@@ -1933,7 +1070,7 @@ avx512_conjugate_@vsub@(const @vtype@ x)
return _mm512_castsi512_@vsub@(res);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
avx512_cmul_@vsub@(@vtype@ x1, @vtype@ x2)
{
// x1 = r1, i1
@@ -1946,7 +1083,7 @@ avx512_cmul_@vsub@(@vtype@ x1, @vtype@ x2)
return _mm512_mask_blend_@vsub@(@cmpx_img_mask@, outreal, outimg);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F @vtype@
avx512_csquare_@vsub@(@vtype@ x)
{
return avx512_cmul_@vsub@(x, x);
@@ -1969,87 +1106,25 @@ avx512_csquare_@vsub@(@vtype@ x)
#if defined @CHK@
-/*
- * Vectorized Cody-Waite range reduction technique
- * Performs the reduction step x* = x - y*C in three steps:
- * 1) x* = x - y*c1
- * 2) x* = x - y*c2
- * 3) x* = x - y*c3
- * c1, c2 are exact floating points, c3 = C - c1 - c2 simulates higher precision
- */
-
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ @vtype@
-@isa@_range_reduction(@vtype@ x, @vtype@ y, @vtype@ c1, @vtype@ c2, @vtype@ c3)
-{
- @vtype@ reduced_x = @fmadd@(y, c1, x);
- reduced_x = @fmadd@(y, c2, reduced_x);
- reduced_x = @fmadd@(y, c3, reduced_x);
- return reduced_x;
-}
-
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ @mask@
-@isa@_in_range_mask(@vtype@ x, npy_float fmax, npy_float fmin)
-{
- @mask@ m1 = _mm@vsize@_cmp_ps@vsub@(
- x, _mm@vsize@_set1_ps(fmax), _CMP_GT_OQ);
- @mask@ m2 = _mm@vsize@_cmp_ps@vsub@(
- x, _mm@vsize@_set1_ps(fmin), _CMP_LT_OQ);
- return _mm@vsize@_@or@(m1,m2);
-}
-
-/*
- * Approximate cosine algorithm for x \in [-PI/4, PI/4]
- * Maximum ULP across all 32-bit floats = 0.875
- */
-
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ @vtype@
-@isa@_cosine(@vtype@ x2, @vtype@ invf8, @vtype@ invf6, @vtype@ invf4,
- @vtype@ invf2, @vtype@ invf0)
-{
- @vtype@ cos = @fmadd@(invf8, x2, invf6);
- cos = @fmadd@(cos, x2, invf4);
- cos = @fmadd@(cos, x2, invf2);
- cos = @fmadd@(cos, x2, invf0);
- return cos;
-}
-
-/*
- * Approximate sine algorithm for x \in [-PI/4, PI/4]
- * Maximum ULP across all 32-bit floats = 0.647
- */
-
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ @vtype@
-@isa@_sine(@vtype@ x, @vtype@ x2, @vtype@ invf9, @vtype@ invf7,
- @vtype@ invf5, @vtype@ invf3,
- @vtype@ zero)
-{
- @vtype@ sin = @fmadd@(invf9, x2, invf7);
- sin = @fmadd@(sin, x2, invf5);
- sin = @fmadd@(sin, x2, invf3);
- sin = @fmadd@(sin, x2, zero);
- sin = @fmadd@(sin, x, x);
- return sin;
-}
-
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ @vtype@
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ @vtype@
@isa@_sqrt_ps(@vtype@ x)
{
return _mm@vsize@_sqrt_ps(x);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ @vtype@d
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ @vtype@d
@isa@_sqrt_pd(@vtype@d x)
{
return _mm@vsize@_sqrt_pd(x);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ @vtype@
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ @vtype@
@isa@_square_ps(@vtype@ x)
{
return _mm@vsize@_mul_ps(x,x);
}
-static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ @vtype@d
+NPY_FINLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ @vtype@d
@isa@_square_pd(@vtype@d x)
{
return _mm@vsize@_mul_pd(x,x);
@@ -2116,7 +1191,7 @@ AVX512_SKX_@func@_@TYPE@(npy_bool* op, @type@* ip, const npy_intp array_size, co
x1 = avx512_masked_gather_@vsuffix@(zeros_f, ip, vindex_ip, load_mask);
}
#if @is_signbit@
- x1 = _mm512_and_@vsuffix@(x1,signbit);
+ x1 = _mm512_and_@vsuffix@(x1,signbit);
#endif
@mask@ fpclassmask = _mm512_fpclass_@vsuffix@_mask(x1, @IMM8@);
@@ -2154,155 +1229,6 @@ AVX512_SKX_@func@_@TYPE@(npy_bool* op, @type@* ip, const npy_intp array_size, co
* #vtype2_scatter = _mm512_mask_i32scatter_epi32, _mm256_mask_i32scatter_epi32#
* #setzero = _mm512_setzero_epi32, _mm256_setzero_si256#
*/
-
-#if defined HAVE_ATTRIBUTE_TARGET_AVX512_SKX_WITH_INTRINSICS && defined NPY_HAVE_SSE2_INTRINSICS
-static NPY_INLINE NPY_GCC_TARGET_AVX512_SKX void
-AVX512_SKX_ldexp_@TYPE@(char **args, npy_intp const *dimensions, npy_intp const *steps)
-{
- const npy_intp stride_ip1 = steps[0]/(npy_intp)sizeof(@type@);
- const npy_intp stride_ip2 = steps[1]/(npy_intp)sizeof(int);
- const npy_intp stride_op = steps[2]/(npy_intp)sizeof(@type@);
- const npy_intp array_size = dimensions[0];
- npy_intp num_remaining_elements = array_size;
- @type@* ip1 = (@type@*) args[0];
- int* ip2 = (int*) args[1];
- @type@* op = (@type@*) args[2];
-
- @mask@ load_mask = avx512_get_full_load_mask_@vsuffix@();
-
- /*
- * Note: while generally indices are npy_intp, we ensure that our maximum index
- * will fit in an int32 as a precondition for this function via
- * IS_BINARY_SMALL_STEPS_AND_NOMEMOVERLAP
- */
-
- npy_int32 index_ip1[@num_lanes@], index_ip2[@num_lanes@], index_op[@num_lanes@];
- for (npy_int32 ii = 0; ii < @num_lanes@; ii++) {
- index_ip1[ii] = ii*stride_ip1;
- index_ip2[ii] = ii*stride_ip2;
- index_op[ii] = ii*stride_op;
- }
- @vindextype@ vindex_ip1 = @vindexload@((@vindextype@*)&index_ip1[0]);
- @vindextype@ vindex_ip2 = @vindexload@((@vindextype@*)&index_ip2[0]);
- @vindextype@ vindex_op = @vindexload@((@vindextype@*)&index_op[0]);
- @vtype1@ zeros_f = _mm512_setzero_@vsuffix@();
- @vtype2@ zeros = @setzero@();
-
- while (num_remaining_elements > 0) {
- if (num_remaining_elements < @num_lanes@) {
- load_mask = avx512_get_partial_load_mask_@vsuffix@(
- num_remaining_elements, @num_lanes@);
- }
- @vtype1@ x1;
- @vtype2@ x2;
- if (stride_ip1 == 1) {
- x1 = avx512_masked_load_@vsuffix@(load_mask, ip1);
- }
- else {
- x1 = avx512_masked_gather_@vsuffix@(zeros_f, ip1, vindex_ip1, load_mask);
- }
- if (stride_ip2 == 1) {
- x2 = @vtype2_load@(load_mask, ip2);
- }
- else {
- x2 = @vtype2_gather@(zeros, load_mask, vindex_ip2, ip2, 4);
- }
-
- @vtype1@ out = _mm512_scalef_@vsuffix@(x1, _mm512_cvtepi32_@vsuffix@(x2));
-
- if (stride_op == 1) {
- _mm512_mask_storeu_@vsuffix@(op, load_mask, out);
- }
- else {
- /* scatter! */
- _mm512_mask_i32scatter_@vsuffix@(op, load_mask, vindex_op, out, @scale@);
- }
-
- ip1 += @num_lanes@*stride_ip1;
- ip2 += @num_lanes@*stride_ip2;
- op += @num_lanes@*stride_op;
- num_remaining_elements -= @num_lanes@;
- }
-}
-
-static NPY_INLINE NPY_GCC_TARGET_AVX512_SKX void
-AVX512_SKX_frexp_@TYPE@(char **args, npy_intp const *dimensions, npy_intp const *steps)
-{
- const npy_intp stride_ip1 = steps[0]/(npy_intp)sizeof(@type@);
- const npy_intp stride_op1 = steps[1]/(npy_intp)sizeof(@type@);
- const npy_intp stride_op2 = steps[2]/(npy_intp)sizeof(int);
- const npy_intp array_size = dimensions[0];
- npy_intp num_remaining_elements = array_size;
- @type@* ip1 = (@type@*) args[0];
- @type@* op1 = (@type@*) args[1];
- int* op2 = (int*) args[2];
-
- @mask@ load_mask = avx512_get_full_load_mask_@vsuffix@();
-
- /*
- * Note: while generally indices are npy_intp, we ensure that our maximum index
- * will fit in an int32 as a precondition for this function via
- * IS_BINARY_SMALL_STEPS_AND_NOMEMOVERLAP
- */
-
- npy_int32 index_ip1[@num_lanes@], index_op1[@num_lanes@], index_op2[@num_lanes@];
- for (npy_int32 ii = 0; ii < @num_lanes@; ii++) {
- index_ip1[ii] = ii*stride_ip1;
- index_op1[ii] = ii*stride_op1;
- index_op2[ii] = ii*stride_op2;
- }
- @vindextype@ vindex_ip1 = @vindexload@((@vindextype@*)&index_ip1[0]);
- @vindextype@ vindex_op1 = @vindexload@((@vindextype@*)&index_op1[0]);
- @vindextype@ vindex_op2 = @vindexload@((@vindextype@*)&index_op2[0]);
- @vtype1@ zeros_f = _mm512_setzero_@vsuffix@();
-
- while (num_remaining_elements > 0) {
- if (num_remaining_elements < @num_lanes@) {
- load_mask = avx512_get_partial_load_mask_@vsuffix@(
- num_remaining_elements, @num_lanes@);
- }
- @vtype1@ x1;
- if (stride_ip1 == 1) {
- x1 = avx512_masked_load_@vsuffix@(load_mask, ip1);
- }
- else {
- x1 = avx512_masked_gather_@vsuffix@(zeros_f, ip1, vindex_ip1, load_mask);
- }
-
- /*
- * The x86 instructions vpgetmant and vpgetexp do not conform
- * with NumPy's output for special floating points: NAN, +/-INF, +/-0.0
- * We mask these values with spmask to avoid invalid exceptions.
- */
- @mask@ spmask =_mm512_knot(_mm512_fpclass_@vsuffix@_mask(
- x1, 0b10011111));
- @vtype1@ out1 = _mm512_maskz_getmant_@vsuffix@(
- spmask, x1, _MM_MANT_NORM_p5_1, _MM_MANT_SIGN_src);
- out1 = _mm512_mask_mov_@vsuffix@(x1, spmask, out1);
- @vtype2@ out2 = _mm512_cvt@vsuffix@_epi32(
- _mm512_maskz_add_@vsuffix@(spmask, _mm512_set1_@vsuffix@(1.0),
- _mm512_maskz_getexp_@vsuffix@(spmask, x1)));
- if (stride_op1 == 1) {
- _mm512_mask_storeu_@vsuffix@(op1, load_mask, out1);
- }
- else {
- _mm512_mask_i32scatter_@vsuffix@(op1, load_mask, vindex_op1, out1, @scale@);
- }
- if (stride_op2 == 1) {
- @vtype2_store@(op2, load_mask, out2);
- }
- else {
- @vtype2_scatter@(op2, load_mask, vindex_op2, out2, 4);
- }
-
- ip1 += @num_lanes@*stride_ip1;
- op1 += @num_lanes@*stride_op1;
- op2 += @num_lanes@*stride_op2;
- num_remaining_elements -= @num_lanes@;
- }
-}
-#endif
-
/**begin repeat1
* #func = maximum, minimum#
* #vectorf = max, min#
@@ -2525,814 +1451,6 @@ static NPY_INLINE NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ void
/**end repeat**/
/**begin repeat
- * #ISA = FMA, AVX512F#
- * #isa = fma, avx512#
- * #vtype = __m256, __m512#
- * #vsize = 256, 512#
- * #BYTES = 32, 64#
- * #NUM_LANES = 8, 16#
- * #mask = __m256, __mmask16#
- * #vsub = , _mask#
- * #or_masks =_mm256_or_ps, _mm512_kor#
- * #and_masks =_mm256_and_ps, _mm512_kand#
- * #xor_masks =_mm256_xor_ps, _mm512_kxor#
- * #fmadd = _mm256_fmadd_ps, _mm512_fmadd_ps#
- * #mask_to_int = _mm256_movemask_ps, #
- * #full_mask= 0xFF, 0xFFFF#
- * #masked_store = _mm256_maskstore_ps, _mm512_mask_storeu_ps#
- * #cvtps_epi32 = _mm256_cvtps_epi32, #
- * #CHK = HAVE_ATTRIBUTE_TARGET_AVX2_WITH_INTRINSICS, HAVE_ATTRIBUTE_TARGET_AVX512F_WITH_INTRINSICS#
- */
-
-/*
- * Vectorized approximate sine/cosine algorithms: The following code is a
- * vectorized version of the algorithm presented here:
- * https://stackoverflow.com/questions/30463616/payne-hanek-algorithm-implementation-in-c/30465751#30465751
- * (1) Load data in ZMM/YMM registers and generate mask for elements that are
- * within range [-71476.0625f, 71476.0625f] for cosine and [-117435.992f,
- * 117435.992f] for sine.
- * (2) For elements within range, perform range reduction using Cody-Waite's
- * method: x* = x - y*PI/2, where y = rint(x*2/PI). x* \in [-PI/4, PI/4].
- * (3) Map cos(x) to (+/-)sine or (+/-)cosine of x* based on the quadrant k =
- * int(y).
- * (4) For elements outside that range, Cody-Waite reduction performs poorly
- * leading to catastrophic cancellation. We compute cosine by calling glibc in
- * a scalar fashion.
- * (5) Vectorized implementation has a max ULP of 1.49 and performs at least
- * 5-7x faster than scalar implementations when magnitude of all elements in
- * the array < 71476.0625f (117435.992f for sine). Worst case performance is
- * when all the elements are large leading to about 1-2% reduction in
- * performance.
- */
-
-#if defined @CHK@
-static NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ void
-@ISA@_sincos_FLOAT(npy_float * op,
- npy_float * ip,
- const npy_intp array_size,
- const npy_intp steps,
- NPY_TRIG_OP my_trig_op)
-{
- const npy_intp stride = steps/(npy_intp)sizeof(npy_float);
- const npy_int num_lanes = @NUM_LANES@;
- npy_float large_number = 71476.0625f;
- if (my_trig_op == npy_compute_sin) {
- large_number = 117435.992f;
- }
-
- /* Load up frequently used constants */
- @vtype@i zeros = _mm@vsize@_set1_epi32(0);
- @vtype@i ones = _mm@vsize@_set1_epi32(1);
- @vtype@i twos = _mm@vsize@_set1_epi32(2);
- @vtype@ two_over_pi = _mm@vsize@_set1_ps(NPY_TWO_O_PIf);
- @vtype@ codyw_c1 = _mm@vsize@_set1_ps(NPY_CODY_WAITE_PI_O_2_HIGHf);
- @vtype@ codyw_c2 = _mm@vsize@_set1_ps(NPY_CODY_WAITE_PI_O_2_MEDf);
- @vtype@ codyw_c3 = _mm@vsize@_set1_ps(NPY_CODY_WAITE_PI_O_2_LOWf);
- @vtype@ cos_invf0 = _mm@vsize@_set1_ps(NPY_COEFF_INVF0_COSINEf);
- @vtype@ cos_invf2 = _mm@vsize@_set1_ps(NPY_COEFF_INVF2_COSINEf);
- @vtype@ cos_invf4 = _mm@vsize@_set1_ps(NPY_COEFF_INVF4_COSINEf);
- @vtype@ cos_invf6 = _mm@vsize@_set1_ps(NPY_COEFF_INVF6_COSINEf);
- @vtype@ cos_invf8 = _mm@vsize@_set1_ps(NPY_COEFF_INVF8_COSINEf);
- @vtype@ sin_invf3 = _mm@vsize@_set1_ps(NPY_COEFF_INVF3_SINEf);
- @vtype@ sin_invf5 = _mm@vsize@_set1_ps(NPY_COEFF_INVF5_SINEf);
- @vtype@ sin_invf7 = _mm@vsize@_set1_ps(NPY_COEFF_INVF7_SINEf);
- @vtype@ sin_invf9 = _mm@vsize@_set1_ps(NPY_COEFF_INVF9_SINEf);
- @vtype@ cvt_magic = _mm@vsize@_set1_ps(NPY_RINT_CVT_MAGICf);
- @vtype@ zero_f = _mm@vsize@_set1_ps(0.0f);
- @vtype@ quadrant, reduced_x, reduced_x2, cos, sin;
- @vtype@i iquadrant;
- @mask@ nan_mask, glibc_mask, sine_mask, negate_mask;
- @mask@ load_mask = @isa@_get_full_load_mask_ps();
- npy_intp num_remaining_elements = array_size;
-
- /*
- * Note: while generally indices are npy_intp, we ensure that our maximum index
- * will fit in an int32 as a precondition for this function via
- * IS_OUTPUT_BLOCKABLE_UNARY
- */
- npy_int32 indexarr[16];
- for (npy_int32 ii = 0; ii < 16; ii++) {
- indexarr[ii] = ii*stride;
- }
- @vtype@i vindex = _mm@vsize@_loadu_si@vsize@((@vtype@i*)&indexarr[0]);
-
- while (num_remaining_elements > 0) {
-
- if (num_remaining_elements < num_lanes) {
- load_mask = @isa@_get_partial_load_mask_ps(num_remaining_elements,
- num_lanes);
- }
-
- @vtype@ x_in;
- if (stride == 1) {
- x_in = @isa@_masked_load_ps(load_mask, ip);
- }
- else {
- x_in = @isa@_masked_gather_ps(zero_f, ip, vindex, load_mask);
- }
-
- /*
- * For elements outside of this range, Cody-Waite's range reduction
- * becomes inaccurate and we will call glibc to compute cosine for
- * these numbers
- */
-
- glibc_mask = @isa@_in_range_mask(x_in, large_number,-large_number);
- glibc_mask = @and_masks@(load_mask, glibc_mask);
- nan_mask = _mm@vsize@_cmp_ps@vsub@(x_in, x_in, _CMP_NEQ_UQ);
- @vtype@ x = @isa@_set_masked_lanes_ps(x_in, zero_f, @or_masks@(nan_mask, glibc_mask));
- npy_int iglibc_mask = @mask_to_int@(glibc_mask);
-
- if (iglibc_mask != @full_mask@) {
- quadrant = _mm@vsize@_mul_ps(x, two_over_pi);
-
- /* round to nearest */
- quadrant = _mm@vsize@_add_ps(quadrant, cvt_magic);
- quadrant = _mm@vsize@_sub_ps(quadrant, cvt_magic);
-
- /* Cody-Waite's range reduction algorithm */
- reduced_x = @isa@_range_reduction(x, quadrant,
- codyw_c1, codyw_c2, codyw_c3);
- reduced_x2 = _mm@vsize@_mul_ps(reduced_x, reduced_x);
-
- /* compute cosine and sine */
- cos = @isa@_cosine(reduced_x2, cos_invf8, cos_invf6, cos_invf4,
- cos_invf2, cos_invf0);
- sin = @isa@_sine(reduced_x, reduced_x2, sin_invf9, sin_invf7,
- sin_invf5, sin_invf3, zero_f);
-
- iquadrant = _mm@vsize@_cvtps_epi32(quadrant);
- if (my_trig_op == npy_compute_cos) {
- iquadrant = _mm@vsize@_add_epi32(iquadrant, ones);
- }
-
- /* blend sin and cos based on the quadrant */
- sine_mask = @isa@_should_calculate_sine(iquadrant, ones, zeros);
- cos = @isa@_blend(cos, sin, sine_mask);
-
- /* multiply by -1 for appropriate elements */
- negate_mask = @isa@_should_negate(iquadrant, twos, twos);
- cos = @isa@_blend(cos, _mm@vsize@_sub_ps(zero_f, cos), negate_mask);
- cos = @isa@_set_masked_lanes_ps(cos, _mm@vsize@_set1_ps(NPY_NANF), nan_mask);
-
- @masked_store@(op, @cvtps_epi32@(load_mask), cos);
- }
-
- /* process elements using glibc for large elements */
- if (iglibc_mask != 0) {
- float NPY_DECL_ALIGNED(@BYTES@) ip_fback[@NUM_LANES@];
- _mm@vsize@_store_ps(ip_fback, x_in);
-
- if (my_trig_op == npy_compute_cos) {
- for (int ii = 0; ii < num_lanes; ++ii, iglibc_mask >>= 1) {
- if (iglibc_mask & 0x01) {
- op[ii] = npy_cosf(ip_fback[ii]);
- }
- }
- }
- else {
- for (int ii = 0; ii < num_lanes; ++ii, iglibc_mask >>= 1) {
- if (iglibc_mask & 0x01) {
- op[ii] = npy_sinf(ip_fback[ii]);
- }
- }
- }
- }
- ip += num_lanes*stride;
- op += num_lanes;
- num_remaining_elements -= num_lanes;
- }
-}
-
-/*
- * Vectorized implementation of exp using AVX2 and AVX512:
- * 1) if x >= xmax; return INF (overflow)
- * 2) if x <= xmin; return 0.0f (underflow)
- * 3) Range reduction (using Coyd-Waite):
- * a) y = x - k*ln(2); k = rint(x/ln(2)); y \in [0, ln(2)]
- * 4) Compute exp(y) = P/Q, ratio of 2 polynomials P and Q
- * b) P = 5th order and Q = 2nd order polynomials obtained from Remez's
- * algorithm (mini-max polynomial approximation)
- * 5) Compute exp(x) = exp(y) * 2^k
- * 6) Max ULP error measured across all 32-bit FP's = 2.52 (x = 0xc2781e37)
- * 7) Max relative error measured across all 32-bit FP's= 2.1264E-07 (for the
- * same x = 0xc2781e37)
- */
-
-static NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ void
-@ISA@_exp_FLOAT(npy_float * op,
- npy_float * ip,
- const npy_intp array_size,
- const npy_intp steps)
-{
- const npy_intp stride = steps/(npy_intp)sizeof(npy_float);
- const npy_int num_lanes = @BYTES@/(npy_intp)sizeof(npy_float);
- npy_float xmax = 88.72283935546875f;
- npy_float xmin = -103.97208404541015625f;
-
- /*
- * Note: while generally indices are npy_intp, we ensure that our maximum index
- * will fit in an int32 as a precondition for this function via
- * IS_OUTPUT_BLOCKABLE_UNARY
- */
- npy_int32 indexarr[16];
- for (npy_int32 ii = 0; ii < 16; ii++) {
- indexarr[ii] = ii*stride;
- }
-
- /* Load up frequently used constants */
- @vtype@ codyw_c1 = _mm@vsize@_set1_ps(NPY_CODY_WAITE_LOGE_2_HIGHf);
- @vtype@ codyw_c2 = _mm@vsize@_set1_ps(NPY_CODY_WAITE_LOGE_2_LOWf);
- @vtype@ exp_p0 = _mm@vsize@_set1_ps(NPY_COEFF_P0_EXPf);
- @vtype@ exp_p1 = _mm@vsize@_set1_ps(NPY_COEFF_P1_EXPf);
- @vtype@ exp_p2 = _mm@vsize@_set1_ps(NPY_COEFF_P2_EXPf);
- @vtype@ exp_p3 = _mm@vsize@_set1_ps(NPY_COEFF_P3_EXPf);
- @vtype@ exp_p4 = _mm@vsize@_set1_ps(NPY_COEFF_P4_EXPf);
- @vtype@ exp_p5 = _mm@vsize@_set1_ps(NPY_COEFF_P5_EXPf);
- @vtype@ exp_q0 = _mm@vsize@_set1_ps(NPY_COEFF_Q0_EXPf);
- @vtype@ exp_q1 = _mm@vsize@_set1_ps(NPY_COEFF_Q1_EXPf);
- @vtype@ exp_q2 = _mm@vsize@_set1_ps(NPY_COEFF_Q2_EXPf);
- @vtype@ cvt_magic = _mm@vsize@_set1_ps(NPY_RINT_CVT_MAGICf);
- @vtype@ log2e = _mm@vsize@_set1_ps(NPY_LOG2Ef);
- @vtype@ inf = _mm@vsize@_set1_ps(NPY_INFINITYF);
- @vtype@ zeros_f = _mm@vsize@_set1_ps(0.0f);
- @vtype@ poly, num_poly, denom_poly, quadrant;
- @vtype@i vindex = _mm@vsize@_loadu_si@vsize@((@vtype@i*)&indexarr[0]);
-
- @mask@ xmax_mask, xmin_mask, nan_mask, inf_mask;
- @mask@ overflow_mask = @isa@_get_partial_load_mask_ps(0, num_lanes);
- @mask@ load_mask = @isa@_get_full_load_mask_ps();
- npy_intp num_remaining_elements = array_size;
-
- while (num_remaining_elements > 0) {
-
- if (num_remaining_elements < num_lanes) {
- load_mask = @isa@_get_partial_load_mask_ps(num_remaining_elements,
- num_lanes);
- }
-
- @vtype@ x;
- if (stride == 1) {
- x = @isa@_masked_load_ps(load_mask, ip);
- }
- else {
- x = @isa@_masked_gather_ps(zeros_f, ip, vindex, load_mask);
- }
-
- nan_mask = _mm@vsize@_cmp_ps@vsub@(x, x, _CMP_NEQ_UQ);
- x = @isa@_set_masked_lanes_ps(x, zeros_f, nan_mask);
-
- xmax_mask = _mm@vsize@_cmp_ps@vsub@(x, _mm@vsize@_set1_ps(xmax), _CMP_GE_OQ);
- xmin_mask = _mm@vsize@_cmp_ps@vsub@(x, _mm@vsize@_set1_ps(xmin), _CMP_LE_OQ);
- inf_mask = _mm@vsize@_cmp_ps@vsub@(x, inf, _CMP_EQ_OQ);
- overflow_mask = @or_masks@(overflow_mask,
- @xor_masks@(xmax_mask, inf_mask));
-
- x = @isa@_set_masked_lanes_ps(x, zeros_f, @or_masks@(
- @or_masks@(nan_mask, xmin_mask), xmax_mask));
-
- quadrant = _mm@vsize@_mul_ps(x, log2e);
-
- /* round to nearest */
- quadrant = _mm@vsize@_add_ps(quadrant, cvt_magic);
- quadrant = _mm@vsize@_sub_ps(quadrant, cvt_magic);
-
- /* Cody-Waite's range reduction algorithm */
- x = @isa@_range_reduction(x, quadrant, codyw_c1, codyw_c2, zeros_f);
-
- num_poly = @fmadd@(exp_p5, x, exp_p4);
- num_poly = @fmadd@(num_poly, x, exp_p3);
- num_poly = @fmadd@(num_poly, x, exp_p2);
- num_poly = @fmadd@(num_poly, x, exp_p1);
- num_poly = @fmadd@(num_poly, x, exp_p0);
- denom_poly = @fmadd@(exp_q2, x, exp_q1);
- denom_poly = @fmadd@(denom_poly, x, exp_q0);
- poly = _mm@vsize@_div_ps(num_poly, denom_poly);
-
- /*
- * compute val = poly * 2^quadrant; which is same as adding the
- * exponent of quadrant to the exponent of poly. quadrant is an int,
- * so extracting exponent is simply extracting 8 bits.
- */
- poly = @isa@_scalef_ps(poly, quadrant);
-
- /*
- * elem > xmax; return inf
- * elem < xmin; return 0.0f
- * elem = +/- nan, return nan
- */
- poly = @isa@_set_masked_lanes_ps(poly, _mm@vsize@_set1_ps(NPY_NANF), nan_mask);
- poly = @isa@_set_masked_lanes_ps(poly, inf, xmax_mask);
- poly = @isa@_set_masked_lanes_ps(poly, zeros_f, xmin_mask);
-
- @masked_store@(op, @cvtps_epi32@(load_mask), poly);
-
- ip += num_lanes*stride;
- op += num_lanes;
- num_remaining_elements -= num_lanes;
- }
-
- if (@mask_to_int@(overflow_mask)) {
- npy_set_floatstatus_overflow();
- }
-}
-
-/*
- * Vectorized implementation of log using AVX2 and AVX512
- * 1) if x < 0.0f; return -NAN (invalid input)
- * 2) Range reduction: y = x/2^k;
- * a) y = normalized mantissa, k is the exponent (0.5 <= y < 1)
- * 3) Compute log(y) = P/Q, ratio of 2 polynomials P and Q
- * b) P = 5th order and Q = 5th order polynomials obtained from Remez's
- * algorithm (mini-max polynomial approximation)
- * 5) Compute log(x) = log(y) + k*ln(2)
- * 6) Max ULP error measured across all 32-bit FP's = 3.83 (x = 0x3f486945)
- * 7) Max relative error measured across all 32-bit FP's = 2.359E-07 (for same
- * x = 0x3f486945)
- */
-
-static NPY_GCC_OPT_3 NPY_GCC_TARGET_@ISA@ void
-@ISA@_log_FLOAT(npy_float * op,
- npy_float * ip,
- const npy_intp array_size,
- const npy_intp steps)
-{
- const npy_intp stride = steps/(npy_intp)sizeof(npy_float);
- const npy_int num_lanes = @BYTES@/(npy_intp)sizeof(npy_float);
-
- /*
- * Note: while generally indices are npy_intp, we ensure that our maximum index
- * will fit in an int32 as a precondition for this function via
- * IS_OUTPUT_BLOCKABLE_UNARY
- */
- npy_int32 indexarr[16];
- for (npy_int32 ii = 0; ii < 16; ii++) {
- indexarr[ii] = ii*stride;
- }
-
- /* Load up frequently used constants */
- @vtype@ log_p0 = _mm@vsize@_set1_ps(NPY_COEFF_P0_LOGf);
- @vtype@ log_p1 = _mm@vsize@_set1_ps(NPY_COEFF_P1_LOGf);
- @vtype@ log_p2 = _mm@vsize@_set1_ps(NPY_COEFF_P2_LOGf);
- @vtype@ log_p3 = _mm@vsize@_set1_ps(NPY_COEFF_P3_LOGf);
- @vtype@ log_p4 = _mm@vsize@_set1_ps(NPY_COEFF_P4_LOGf);
- @vtype@ log_p5 = _mm@vsize@_set1_ps(NPY_COEFF_P5_LOGf);
- @vtype@ log_q0 = _mm@vsize@_set1_ps(NPY_COEFF_Q0_LOGf);
- @vtype@ log_q1 = _mm@vsize@_set1_ps(NPY_COEFF_Q1_LOGf);
- @vtype@ log_q2 = _mm@vsize@_set1_ps(NPY_COEFF_Q2_LOGf);
- @vtype@ log_q3 = _mm@vsize@_set1_ps(NPY_COEFF_Q3_LOGf);
- @vtype@ log_q4 = _mm@vsize@_set1_ps(NPY_COEFF_Q4_LOGf);
- @vtype@ log_q5 = _mm@vsize@_set1_ps(NPY_COEFF_Q5_LOGf);
- @vtype@ loge2 = _mm@vsize@_set1_ps(NPY_LOGE2f);
- @vtype@ nan = _mm@vsize@_set1_ps(NPY_NANF);
- @vtype@ neg_nan = _mm@vsize@_set1_ps(-NPY_NANF);
- @vtype@ neg_inf = _mm@vsize@_set1_ps(-NPY_INFINITYF);
- @vtype@ inf = _mm@vsize@_set1_ps(NPY_INFINITYF);
- @vtype@ zeros_f = _mm@vsize@_set1_ps(0.0f);
- @vtype@ ones_f = _mm@vsize@_set1_ps(1.0f);
- @vtype@i vindex = _mm@vsize@_loadu_si@vsize@((@vtype@i*)indexarr);
- @vtype@ poly, num_poly, denom_poly, exponent;
-
- @mask@ inf_mask, nan_mask, sqrt2_mask, zero_mask, negx_mask;
- @mask@ invalid_mask = @isa@_get_partial_load_mask_ps(0, num_lanes);
- @mask@ divide_by_zero_mask = invalid_mask;
- @mask@ load_mask = @isa@_get_full_load_mask_ps();
- npy_intp num_remaining_elements = array_size;
-
- while (num_remaining_elements > 0) {
-
- if (num_remaining_elements < num_lanes) {
- load_mask = @isa@_get_partial_load_mask_ps(num_remaining_elements,
- num_lanes);
- }
-
- @vtype@ x_in;
- if (stride == 1) {
- x_in = @isa@_masked_load_ps(load_mask, ip);
- }
- else {
- x_in = @isa@_masked_gather_ps(zeros_f, ip, vindex, load_mask);
- }
-
- negx_mask = _mm@vsize@_cmp_ps@vsub@(x_in, zeros_f, _CMP_LT_OQ);
- zero_mask = _mm@vsize@_cmp_ps@vsub@(x_in, zeros_f, _CMP_EQ_OQ);
- inf_mask = _mm@vsize@_cmp_ps@vsub@(x_in, inf, _CMP_EQ_OQ);
- nan_mask = _mm@vsize@_cmp_ps@vsub@(x_in, x_in, _CMP_NEQ_UQ);
- divide_by_zero_mask = @or_masks@(divide_by_zero_mask,
- @and_masks@(zero_mask, load_mask));
- invalid_mask = @or_masks@(invalid_mask, negx_mask);
-
- @vtype@ x = @isa@_set_masked_lanes_ps(x_in, zeros_f, negx_mask);
-
- /* set x = normalized mantissa */
- exponent = @isa@_get_exponent(x);
- x = @isa@_get_mantissa(x);
-
- /* if x < sqrt(2) {exp = exp-1; x = 2*x} */
- sqrt2_mask = _mm@vsize@_cmp_ps@vsub@(x, _mm@vsize@_set1_ps(NPY_SQRT1_2f), _CMP_LE_OQ);
- x = @isa@_blend(x, _mm@vsize@_add_ps(x,x), sqrt2_mask);
- exponent = @isa@_blend(exponent,
- _mm@vsize@_sub_ps(exponent,ones_f), sqrt2_mask);
-
- /* x = x - 1 */
- x = _mm@vsize@_sub_ps(x, ones_f);
-
- /* Polynomial approximation for log(1+x) */
- num_poly = @fmadd@(log_p5, x, log_p4);
- num_poly = @fmadd@(num_poly, x, log_p3);
- num_poly = @fmadd@(num_poly, x, log_p2);
- num_poly = @fmadd@(num_poly, x, log_p1);
- num_poly = @fmadd@(num_poly, x, log_p0);
- denom_poly = @fmadd@(log_q5, x, log_q4);
- denom_poly = @fmadd@(denom_poly, x, log_q3);
- denom_poly = @fmadd@(denom_poly, x, log_q2);
- denom_poly = @fmadd@(denom_poly, x, log_q1);
- denom_poly = @fmadd@(denom_poly, x, log_q0);
- poly = _mm@vsize@_div_ps(num_poly, denom_poly);
- poly = @fmadd@(exponent, loge2, poly);
-
- /*
- * x < 0.0f; return -NAN
- * x = +/- NAN; return NAN
- * x = 0.0f; return -INF
- */
- poly = @isa@_set_masked_lanes_ps(poly, nan, nan_mask);
- poly = @isa@_set_masked_lanes_ps(poly, neg_nan, negx_mask);
- poly = @isa@_set_masked_lanes_ps(poly, neg_inf, zero_mask);
- poly = @isa@_set_masked_lanes_ps(poly, inf, inf_mask);
-
- @masked_store@(op, @cvtps_epi32@(load_mask), poly);
-
- ip += num_lanes*stride;
- op += num_lanes;
- num_remaining_elements -= num_lanes;
- }
-
- if (@mask_to_int@(invalid_mask)) {
- npy_set_floatstatus_invalid();
- }
- if (@mask_to_int@(divide_by_zero_mask)) {
- npy_set_floatstatus_divbyzero();
- }
-}
-#endif
-/**end repeat**/
-
-/*
- * Vectorized implementation of exp double using AVX512
- * Reference: Tang, P.T.P., "Table-driven implementation of the
- * exponential function in IEEE floating-point
- * arithmetic," ACM Transactions on Mathematical
- * Software, vol. 15, pp. 144-157, 1989.
- * 1) if x > mTH_max or x is INF; return INF (overflow)
- * 2) if x < mTH_min; return 0.0f (underflow)
- * 3) if abs(x) < mTH_nearzero; return 1.0f + x
- * 4) if x is Nan; return Nan
- * 5) Range reduction:
- * x = (32m + j)ln2 / 32 + r; r in [-ln2/64, ln2/64]
- * 6) exp(r) - 1 is approximated by a polynomial function p(r)
- * exp(x) = 2^m(2^(j/32) + 2^(j/32)p(r));
- */
-#if defined HAVE_ATTRIBUTE_TARGET_AVX512F_WITH_INTRINSICS
-#if !(defined(__clang__) && (__clang_major__ < 10 || (__clang_major__ == 10 && __clang_minor__ < 1)))
-static NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F void
-AVX512F_exp_DOUBLE(npy_double * op,
- npy_double * ip,
- const npy_intp array_size,
- const npy_intp steps)
-{
- npy_intp num_remaining_elements = array_size;
- const npy_intp stride = steps / (npy_intp)sizeof(npy_double);
- const npy_int num_lanes = 64 / (npy_intp)sizeof(npy_double);
- npy_int32 indexarr[8];
- for (npy_int32 ii = 0; ii < 8; ii++) {
- indexarr[ii] = ii*stride;
- }
-
- __m512d InvLn2N = _mm512_set1_pd(NPY_INV_LN2_MUL_32);
- __m512d mShift = _mm512_set1_pd(NPY_RINT_CVT_MAGIC);
- __m512d mNegL1 = _mm512_set1_pd(NPY_TANG_NEG_L1);
- __m512d mNegL2 = _mm512_set1_pd(NPY_TANG_NEG_L2);
- __m512i mMod = _mm512_set1_epi64(0x1f);
- __m512d mA1 = _mm512_set1_pd(NPY_TANG_A1);
- __m512d mA2 = _mm512_set1_pd(NPY_TANG_A2);
- __m512d mA3 = _mm512_set1_pd(NPY_TANG_A3);
- __m512d mA4 = _mm512_set1_pd(NPY_TANG_A4);
- __m512d mA5 = _mm512_set1_pd(NPY_TANG_A5);
- __m512d mTH_nearzero = _mm512_set1_pd(0x1p-54);
- __m512d mTH_max = _mm512_set1_pd(0x1.62e42fefa39efp+9);
- __m512d mTH_min = _mm512_set1_pd(-0x1.74910d52d3053p+9);
- __m512d mTH_inf = _mm512_set1_pd(NPY_INFINITY);
- __m512d zeros_d = _mm512_set1_pd(0.0f);
- __m512d ones_d = _mm512_set1_pd(1.0f);
- __m256i vindex = _mm256_loadu_si256((__m256i*)&indexarr[0]);
-
- __m512d mTable_top_0 = _mm512_loadu_pd(&(EXP_Table_top[8*0]));
- __m512d mTable_top_1 = _mm512_loadu_pd(&(EXP_Table_top[8*1]));
- __m512d mTable_top_2 = _mm512_loadu_pd(&(EXP_Table_top[8*2]));
- __m512d mTable_top_3 = _mm512_loadu_pd(&(EXP_Table_top[8*3]));
- __m512d mTable_tail_0 = _mm512_loadu_pd(&(EXP_Table_tail[8*0]));
- __m512d mTable_tail_1 = _mm512_loadu_pd(&(EXP_Table_tail[8*1]));
- __m512d mTable_tail_2 = _mm512_loadu_pd(&(EXP_Table_tail[8*2]));
- __m512d mTable_tail_3 = _mm512_loadu_pd(&(EXP_Table_tail[8*3]));
-
- __mmask8 overflow_mask = avx512_get_partial_load_mask_pd(0, num_lanes);
- __mmask8 load_mask = avx512_get_full_load_mask_pd();
- __mmask8 xmin_mask, xmax_mask, inf_mask, nan_mask, nearzero_mask;
-
- while (num_remaining_elements > 0) {
- if (num_remaining_elements < num_lanes) {
- load_mask = avx512_get_partial_load_mask_pd(num_remaining_elements,
- num_lanes);
- }
-
- __m512d x;
- if (1 == stride) {
- x = avx512_masked_load_pd(load_mask, ip);
- }
- else {
- x = avx512_masked_gather_pd(zeros_d, ip, vindex, load_mask);
- }
-
- nan_mask = _mm512_cmp_pd_mask(x, x, _CMP_NEQ_UQ);
- x = avx512_set_masked_lanes_pd(x, zeros_d, nan_mask);
- xmax_mask = _mm512_cmp_pd_mask(x, mTH_max, _CMP_GT_OQ);
- xmin_mask = _mm512_cmp_pd_mask(x, mTH_min, _CMP_LT_OQ);
- inf_mask = _mm512_cmp_pd_mask(x, mTH_inf, _CMP_EQ_OQ);
- __m512i x_abs = _mm512_and_epi64(_mm512_castpd_si512(x),
- _mm512_set1_epi64(0x7FFFFFFFFFFFFFFF));
- nearzero_mask = _mm512_cmp_pd_mask(_mm512_castsi512_pd(x_abs),
- mTH_nearzero, _CMP_LT_OQ);
- nearzero_mask = _mm512_kxor(nearzero_mask, nan_mask);
- overflow_mask = _mm512_kor(overflow_mask,
- _mm512_kxor(xmax_mask, inf_mask));
- x = avx512_set_masked_lanes_pd(x, zeros_d,
- _mm512_kor(_mm512_kor(nan_mask, xmin_mask),
- _mm512_kor(xmax_mask, nearzero_mask)));
-
- /* z = x * 32/ln2 */
- __m512d z = _mm512_mul_pd(x, InvLn2N);
-
- /* round to nearest */
- __m512d kd = _mm512_add_pd(z, mShift);
- __m512i ki = _mm512_castpd_si512(kd);
- kd = _mm512_sub_pd(kd, mShift);
-
- /* r = (x + kd*mNegL1) + kd*mNegL2 */
- __m512d r1 = _mm512_fmadd_pd(kd, mNegL1, x);
- __m512d r2 = _mm512_mul_pd(kd, mNegL2);
- __m512d r = _mm512_add_pd(r1,r2);
-
- /* Polynomial approximation for exp(r) - 1 */
- __m512d q = _mm512_fmadd_pd(mA5, r, mA4);
- q = _mm512_fmadd_pd(q, r, mA3);
- q = _mm512_fmadd_pd(q, r, mA2);
- q = _mm512_fmadd_pd(q, r, mA1);
- q = _mm512_mul_pd(q, r);
- __m512d p = _mm512_fmadd_pd(r, q, r2);;
- p = _mm512_add_pd(r1, p);
-
- /* Get 2^(j/32) from lookup table */
- __m512i j = _mm512_and_epi64(ki, mMod);
- __m512d top = avx512_permute_x4var_pd(mTable_top_0, mTable_top_1,
- mTable_top_2, mTable_top_3, j);
- __m512d tail = avx512_permute_x4var_pd(mTable_tail_0, mTable_tail_1,
- mTable_tail_2, mTable_tail_3, j);
-
- /*
- * s = top + tail;
- * exp(x) = 2^m * (top + (tail + s * p));
- */
- __m512d s = _mm512_add_pd(top, tail);
- __m512d res = _mm512_fmadd_pd(s, p, tail);
- res = _mm512_add_pd(res, top);
- res= _mm512_scalef_pd(res, _mm512_div_pd(kd, _mm512_set1_pd(32)));
-
- /* return special cases */
- res = avx512_set_masked_lanes_pd(res, _mm512_add_pd(x, ones_d),
- nearzero_mask);
- res = avx512_set_masked_lanes_pd(res, _mm512_set1_pd(NPY_NAN),
- nan_mask);
- res = avx512_set_masked_lanes_pd(res, mTH_inf, xmax_mask);
- res = avx512_set_masked_lanes_pd(res, zeros_d, xmin_mask);
-
- _mm512_mask_storeu_pd(op, load_mask, res);
-
- ip += num_lanes * stride;
- op += num_lanes;
- num_remaining_elements -= num_lanes;
- }
- if (overflow_mask) {
- npy_set_floatstatus_overflow();
- }
-}
-#endif
-#endif
-
-/*
- * Vectorized implementation of log double using AVX512
- * Reference:
- * [1] Tang, Ping Tak Peter. Table-lookup algorithms for elementary functions
- * and their error analysis. No. CONF-9106103-1. Argonne National Lab.,
- * IL (USA), 1991.
- * [2] Tang, Ping-Tak Peter. "Table-driven implementation of the logarithm
- * function in IEEE floating-point arithmetic." ACM Transactions on
- * Mathematical Software (TOMS) 16.4 (1990): 378-400.
- * [3] Muller, Jean-Michel. "Elementary functions: algorithms and
- * implementation." (2016).
- * 1) if x = 0; return -INF
- * 2) if x < 0; return NAN
- * 3) if x is INF; return INF
- * 4) if x is NAN; return NAN
- * 5) if x on (1.0 - 0x1p-4, 1.0 + 0x1.09p-4), calling npy_log()
- * 6) Range reduction:
- * log(x) = log(2^m * z)
- * = mln2 + log(z)
- * 7) log(z) = log(z / c_k) + log(c_k);
- * where c_k = 1 + k/64, k = 0,1,...,64
- * s.t. |x - c_k| <= 1/128 when x on[1,2].
- * 8) r = 2(x - c_k)/(x + c_k)
- * log(x/c_k) = log((1 + r/2) / (1 - r/2))
- * = p(r)
- * = 2((r/2) + 1/3*(r/2)^3 + 1/5*(r/2)^5 + ...)
- */
-#if defined HAVE_ATTRIBUTE_TARGET_AVX512F_WITH_INTRINSICS
-#if !(defined(__clang__) && (__clang_major__ < 10 || (__clang_major__ == 10 && __clang_minor__ < 1)))
-static NPY_GCC_OPT_3 NPY_GCC_TARGET_AVX512F void
-AVX512F_log_DOUBLE(npy_double * op,
- npy_double * ip,
- const npy_intp array_size,
- const npy_intp steps)
-{
- npy_intp num_remaining_elements = array_size;
- const npy_intp stride = steps / (npy_intp)sizeof(npy_double);
- const npy_int num_lanes = 64 / (npy_intp)sizeof(npy_double);
- npy_int32 indexarr[8];
- for (npy_int32 ii = 0; ii < 8; ii++) {
- indexarr[ii] = ii*stride;
- }
-
- __m512d zeros_d = _mm512_set1_pd(0.0f);
- __m512d ones_d = _mm512_set1_pd(1.0f);
- __m512d mInf = _mm512_set1_pd(NPY_INFINITY);
- __m512d mInv64 = (__m512d)(_mm512_set1_epi64(0x3f90000000000000));
- __m512d mNeg_nan = _mm512_set1_pd(-NPY_NAN);
- __m512d mNan = _mm512_set1_pd(NPY_NAN);
- __m512d mNeg_inf = _mm512_set1_pd(-NPY_INFINITY);
- __m512d mA1 = _mm512_set1_pd(NPY_TANG_LOG_A1);
- __m512d mA2 = _mm512_set1_pd(NPY_TANG_LOG_A2);
- __m512d mA3 = _mm512_set1_pd(NPY_TANG_LOG_A3);
- __m512d mA4 = _mm512_set1_pd(NPY_TANG_LOG_A4);
- __m512d mLN2HI = _mm512_set1_pd(NPY_TANG_LOG_LN2HI);
- __m512d mLN2LO = _mm512_set1_pd(NPY_TANG_LOG_LN2LO);
-
- __m512d mTo_glibc_min = _mm512_set1_pd(1.0 - 0x1p-4);
- __m512d mTo_glibc_max = _mm512_set1_pd(1.0 + 0x1.09p-4);
- __m256i vindex = _mm256_loadu_si256((__m256i*)&indexarr[0]);
-
- /* Load lookup table data */
- /**begin repeat
- * #i = 0, 1, 2, 3, 4, 5, 6, 7#
- */
-
- __m512d mLUT_TOP_@i@ = _mm512_loadu_pd(&(LOG_TABLE_TOP[8*@i@]));
- __m512d mLUT_TAIL_@i@ = _mm512_loadu_pd(&(LOG_TABLE_TAIL[8*@i@]));
-
- /**end repeat**/
-
- __mmask8 load_mask = avx512_get_full_load_mask_pd();
- __mmask8 invalid_mask = avx512_get_partial_load_mask_pd(0, num_lanes);
- __mmask8 divide_by_zero_mask = invalid_mask;
-
- __mmask8 inf_mask, nan_mask, zero_mask, negx_mask, denormal_mask,
- glibc_mask;
-
- __m512d x_in;
- while (num_remaining_elements > 0) {
- if (num_remaining_elements < num_lanes) {
- load_mask = avx512_get_partial_load_mask_pd(num_remaining_elements,
- num_lanes);
- }
-
- if (1 == stride) {
- x_in = avx512_masked_load_pd(load_mask, ip);
- }
- else {
- x_in = avx512_masked_gather_pd(zeros_d, ip, vindex, load_mask);
- }
-
- /* call glibc when x on [1.0 - 0x1p-4, 1.0 + 0x1.09p-4] */
- __mmask8 m1 = _mm512_cmp_pd_mask(x_in, mTo_glibc_max, _CMP_LT_OQ);
- __mmask8 m2 = _mm512_cmp_pd_mask(x_in, mTo_glibc_min, _CMP_GT_OQ);
- glibc_mask = m1 & m2;
-
- if (glibc_mask != 0xFF) {
- zero_mask = _mm512_cmp_pd_mask(x_in, zeros_d, _CMP_EQ_OQ);
- inf_mask = _mm512_cmp_pd_mask(x_in, mInf, _CMP_EQ_OQ);
- negx_mask = _mm512_cmp_pd_mask(x_in, zeros_d, _CMP_LT_OQ);
- nan_mask = _mm512_cmp_pd_mask(x_in, x_in, _CMP_NEQ_UQ);
-
- divide_by_zero_mask = divide_by_zero_mask | (zero_mask & load_mask);
- invalid_mask = invalid_mask | negx_mask;
-
- __m512d x = avx512_set_masked_lanes_pd(x_in, zeros_d, negx_mask);
- __m512i ix = (__m512i)x;
-
- /* Normalize x when it is denormal */
- __m512i top12 = _mm512_and_epi64(ix,
- _mm512_set1_epi64(0xfff0000000000000));
- denormal_mask = _mm512_cmp_epi64_mask(top12, _mm512_set1_epi64(0),
- _CMP_EQ_OQ);
- denormal_mask = (~zero_mask) & denormal_mask;
- ix = (__m512i)_mm512_mask_mul_pd(x, denormal_mask,
- x, _mm512_set1_pd(0x1p52));
- ix = _mm512_mask_sub_epi64(ix, denormal_mask,
- ix, _mm512_set1_epi64(52ULL << 52));
-
- /*
- * x = 2^k * z; where z in range [1,2]
- */
- __m512i tmp = _mm512_sub_epi64(ix,
- _mm512_set1_epi64(0x3ff0000000000000));
- __m512i i = _mm512_and_epi64(_mm512_srai_epi64(tmp, 52 - 6),
- _mm512_set1_epi64(0x3fULL));
- __m512i ik = _mm512_srai_epi64(tmp, 52);
- __m512d z = (__m512d)(_mm512_sub_epi64(ix, _mm512_and_epi64(tmp,
- _mm512_set1_epi64(0xfff0000000000000))));
- /* c = i/64 + 1 */
- __m256i i_32 = _mm512_cvtepi64_epi32(i);
- __m512d c = _mm512_fmadd_pd(_mm512_cvtepi32_pd(i_32), mInv64, ones_d);
-
- /* u = 2 * (z - c) / (z + c) */
- __m512d u = _mm512_div_pd(_mm512_sub_pd(z, c), _mm512_add_pd(z, c));
- u = _mm512_mul_pd(_mm512_set1_pd(2.0), u);
-
- /* v = u * u */
- __m512d v = _mm512_mul_pd(u,u);
-
- /* log(z/c) = u + u*v*(A1 + v*(A2 + v*(A3 + v*A4))) */
- __m512d res = _mm512_fmadd_pd(v, mA4, mA3);
- res = _mm512_fmadd_pd(v, res, mA2);
- res = _mm512_fmadd_pd(v, res, mA1);
- res = _mm512_mul_pd(v, res);
- res = _mm512_fmadd_pd(u, res, u);
-
- /* Load lookup table data */
- __m512d c_hi = avx512_permute_x8var_pd(mLUT_TOP_0, mLUT_TOP_1,
- mLUT_TOP_2, mLUT_TOP_3, mLUT_TOP_4, mLUT_TOP_5,
- mLUT_TOP_6, mLUT_TOP_7, i);
- __m512d c_lo = avx512_permute_x8var_pd(mLUT_TAIL_0, mLUT_TAIL_1,
- mLUT_TAIL_2, mLUT_TAIL_3, mLUT_TAIL_4, mLUT_TAIL_5,
- mLUT_TAIL_6, mLUT_TAIL_7, i);
-
- /*
- * log(x) = k * ln2_hi + c_hi +
- * k * ln2_lo + c_lo +
- * log(z/c)
- */
- __m256i ik_32 = _mm512_cvtepi64_epi32(ik);
- __m512d k = _mm512_cvtepi32_pd(ik_32);
- __m512d tt = _mm512_fmadd_pd(k, mLN2HI, c_hi);
- __m512d tt2 = _mm512_fmadd_pd(k, mLN2LO, c_lo);
- tt = _mm512_add_pd(tt, tt2);
- res = _mm512_add_pd(tt, res);
-
- /* return special cases */
- res = avx512_set_masked_lanes_pd(res, mNan, nan_mask);
- res = avx512_set_masked_lanes_pd(res, mNeg_nan, negx_mask);
- res = avx512_set_masked_lanes_pd(res, mNeg_inf, zero_mask);
- res = avx512_set_masked_lanes_pd(res, mInf, inf_mask);
-
- _mm512_mask_storeu_pd(op, load_mask, res);
- }
-
- /* call glibc's log func when x around 1.0f */
- if (glibc_mask != 0) {
- double NPY_DECL_ALIGNED(64) ip_fback[8];
- _mm512_store_pd(ip_fback, x_in);
-
- for (int ii = 0; ii < 8; ++ii, glibc_mask >>= 1) {
- if (glibc_mask & 0x01) {
- op[ii] = npy_log(ip_fback[ii]);
- }
- }
- }
- ip += num_lanes * stride;
- op += num_lanes;
- num_remaining_elements -= num_lanes;
- }
-
- if (invalid_mask) {
- npy_set_floatstatus_invalid();
- }
- if (divide_by_zero_mask) {
- npy_set_floatstatus_divbyzero();
- }
-}
-#endif
-#endif
-
-/**begin repeat
* #TYPE = CFLOAT, CDOUBLE#
* #type = npy_float, npy_double#
* #num_lanes = 16, 8#
@@ -3348,45 +1466,6 @@ AVX512F_log_DOUBLE(npy_double * op,
*/
/**begin repeat1
- * #func = add, subtract, multiply#
- * #vectorf = _mm512_add, _mm512_sub, avx512_cmul#
- */
-
-#if defined HAVE_ATTRIBUTE_TARGET_AVX512F_WITH_INTRINSICS && defined NPY_HAVE_SSE2_INTRINSICS
-static NPY_GCC_OPT_3 NPY_INLINE NPY_GCC_TARGET_AVX512F void
-AVX512F_@func@_@TYPE@(char **args, const npy_intp *dimensions, const npy_intp *steps)
-{
- const npy_intp array_size = dimensions[0];
- npy_intp num_remaining_elements = 2*array_size;
- @type@* ip1 = (@type@*) args[0];
- @type@* ip2 = (@type@*) args[1];
- @type@* op = (@type@*) args[2];
-
- @mask@ load_mask = avx512_get_full_load_mask_@vsuffix@();
-
- while (num_remaining_elements > 0) {
- if (num_remaining_elements < @num_lanes@) {
- load_mask = avx512_get_partial_load_mask_@vsuffix@(
- num_remaining_elements, @num_lanes@);
- }
- @vtype@ x1, x2;
- x1 = avx512_masked_load_@vsuffix@(load_mask, ip1);
- x2 = avx512_masked_load_@vsuffix@(load_mask, ip2);
-
- @vtype@ out = @vectorf@_@vsuffix@(x1, x2);
-
- _mm512_mask_storeu_@vsuffix@(op, load_mask, out);
-
- ip1 += @num_lanes@;
- ip2 += @num_lanes@;
- op += @num_lanes@;
- num_remaining_elements -= @num_lanes@;
- }
-}
-#endif
-/**end repeat1**/
-
-/**begin repeat1
* #func = square, conjugate#
* #vectorf = avx512_csquare, avx512_conjugate#
*/
@@ -3536,7 +1615,7 @@ AVX512F_absolute_@TYPE@(@type@ * op,
* you never know
*/
#if !@and@
-static NPY_INLINE @vtype@ byte_to_true(@vtype@ v)
+NPY_FINLINE @vtype@ byte_to_true(@vtype@ v)
{
const @vtype@ zero = @vpre@_setzero_@vsuf@();
const @vtype@ truemask = @vpre@_set1_epi8(1 == 1);
@@ -3648,86 +1727,5 @@ sse2_@kind@_BOOL(@type@ * op, @type@ * ip, const npy_intp n)
/**end repeat**/
#undef VECTOR_SIZE_BYTES
-#else /* NPY_HAVE_SSE2_INTRINSICS */
-
-/**begin repeat
- * #type = npy_float, npy_double#
- * #TYPE = FLOAT, DOUBLE#
- * #sfx = f32, f64#
- * #CHK = , _F64#
- */
-
-#if NPY_SIMD@CHK@
-
-/**begin repeat1
-* Arithmetic
-* # kind = add, subtract, multiply, divide#
-* # OP = +, -, *, /#
-* # VOP = add, sub, mul, div#
-*/
-
-static void
-simd_binary_@kind@_@TYPE@(@type@ * op, @type@ * ip1, @type@ * ip2, npy_intp n)
-{
- LOOP_BLOCK_ALIGN_VAR(op, @type@, NPY_SIMD_WIDTH) {
- op[i] = ip1[i] @OP@ ip2[i];
- }
- /* lots of specializations, to squeeze out max performance */
- if (ip1 == ip2) {
- LOOP_BLOCKED(@type@, NPY_SIMD_WIDTH) {
- npyv_@sfx@ a = npyv_load_@sfx@(&ip1[i]);
- npyv_@sfx@ c = npyv_@VOP@_@sfx@(a, a);
- npyv_store_@sfx@(&op[i], c);
- }
- }
- else {
- LOOP_BLOCKED(@type@, NPY_SIMD_WIDTH) {
- npyv_@sfx@ a = npyv_load_@sfx@(&ip1[i]);
- npyv_@sfx@ b = npyv_load_@sfx@(&ip2[i]);
- npyv_@sfx@ c = npyv_@VOP@_@sfx@(a, b);
- npyv_store_@sfx@(&op[i], c);
- }
- }
- LOOP_BLOCKED_END {
- op[i] = ip1[i] @OP@ ip2[i];
- }
-}
-
-static void
-simd_binary_scalar1_@kind@_@TYPE@(@type@ * op, @type@ * ip1, @type@ * ip2, npy_intp n)
-{
- const npyv_@sfx@ v1 = npyv_setall_@sfx@(ip1[0]);
- LOOP_BLOCK_ALIGN_VAR(op, @type@, NPY_SIMD_WIDTH) {
- op[i] = ip1[0] @OP@ ip2[i];
- }
- LOOP_BLOCKED(@type@, NPY_SIMD_WIDTH) {
- npyv_@sfx@ v2 = npyv_load_@sfx@(&ip2[i]);
- npyv_@sfx@ v3 = npyv_@VOP@_@sfx@(v1, v2);
- npyv_store_@sfx@(&op[i], v3);
- }
- LOOP_BLOCKED_END {
- op[i] = ip1[0] @OP@ ip2[i];
- }
-}
-
-static void
-simd_binary_scalar2_@kind@_@TYPE@(@type@ * op, @type@ * ip1, @type@ * ip2, npy_intp n)
-{
- const npyv_@sfx@ v2 = npyv_setall_@sfx@(ip2[0]);
- LOOP_BLOCK_ALIGN_VAR(op, @type@, NPY_SIMD_WIDTH) {
- op[i] = ip1[i] @OP@ ip2[0];
- }
- LOOP_BLOCKED(@type@, NPY_SIMD_WIDTH) {
- npyv_@sfx@ v1 = npyv_load_@sfx@(&ip1[i]);
- npyv_@sfx@ v3 = npyv_@VOP@_@sfx@(v1, v2);
- npyv_store_@sfx@(&op[i], v3);
- }
- LOOP_BLOCKED_END {
- op[i] = ip1[i] @OP@ ip2[0];
- }
-}
-/**end repeat1**/
-#endif /* NPY_SIMD@CHK@ */
-/**end repeat**/
-#endif
+#endif /* NPY_HAVE_SSE2_INTRINSICS */
#endif
diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c
index 1a035eb61..bed303a86 100644
--- a/numpy/core/src/umath/ufunc_object.c
+++ b/numpy/core/src/umath/ufunc_object.c
@@ -28,10 +28,11 @@
#define NPY_NO_DEPRECATED_API NPY_API_VERSION
#include "Python.h"
+#include "stddef.h"
#include "npy_config.h"
-
#include "npy_pycompat.h"
+#include "npy_argparse.h"
#include "numpy/arrayobject.h"
#include "numpy/ufuncobject.h"
@@ -40,13 +41,19 @@
#include "ufunc_type_resolution.h"
#include "reduction.h"
#include "mem_overlap.h"
+#include "npy_hashtable.h"
#include "ufunc_object.h"
#include "override.h"
#include "npy_import.h"
#include "extobj.h"
#include "common.h"
+#include "dtypemeta.h"
#include "numpyos.h"
+#include "dispatching.h"
+#include "convert_datatype.h"
+#include "legacy_array_method.h"
+#include "abstractdtypes.h"
/********** PRINTF DEBUG TRACING **************/
#define NPY_UF_DBG_TRACING 0
@@ -95,8 +102,15 @@ _get_wrap_prepare_args(ufunc_full_args full_args) {
/* ---------------------------------------------------------------- */
+static PyObject *
+prepare_input_arguments_for_outer(PyObject *args, PyUFuncObject *ufunc);
+
static int
-_does_loop_use_arrays(void *data);
+resolve_descriptors(int nop,
+ PyUFuncObject *ufunc, PyArrayMethodObject *ufuncimpl,
+ PyArrayObject *operands[], PyArray_Descr *dtypes[],
+ PyArray_DTypeMeta *signature[], NPY_CASTING casting);
+
/*UFUNC_API*/
NPY_NO_EXPORT int
@@ -270,7 +284,7 @@ _get_output_array_method(PyObject *obj, PyObject *method,
*/
static void
_find_array_prepare(ufunc_full_args args,
- PyObject **output_prep, int nin, int nout)
+ PyObject **output_prep, int nout)
{
int i;
PyObject *prep;
@@ -397,27 +411,19 @@ _ufunc_setup_flags(PyUFuncObject *ufunc, npy_uint32 op_in_flags,
* A NULL is placed in output_wrap for outputs that
* should just have PyArray_Return called.
*/
-static int
-_find_array_wrap(ufunc_full_args args, PyObject *kwds,
- PyObject **output_wrap, int nin, int nout)
+static void
+_find_array_wrap(ufunc_full_args args, npy_bool subok,
+ PyObject **output_wrap, int nin, int nout)
{
int i;
- PyObject *obj;
PyObject *wrap = NULL;
/*
* If a 'subok' parameter is passed and isn't True, don't wrap but put None
* into slots with out arguments which means return the out argument
*/
- if (kwds != NULL) {
- obj = PyDict_GetItemWithError(kwds, npy_um_str_subok);
- if (obj == NULL && PyErr_Occurred()) {
- return -1;
- }
- else if (obj != NULL && obj != Py_True) {
- /* skip search for wrap members */
- goto handle_out;
- }
+ if (!subok) {
+ goto handle_out;
}
/*
@@ -453,7 +459,6 @@ handle_out:
}
Py_XDECREF(wrap);
- return 0;
}
@@ -849,103 +854,12 @@ ufunc_get_name_cstr(PyUFuncObject *ufunc) {
return ufunc->name ? ufunc->name : "<unnamed ufunc>";
}
-/*
- * Helpers for keyword parsing
- */
-
-/*
- * Find key in a list of pointers to keyword names.
- * The list should end with NULL.
- *
- * Returns either the index into the list (pointing to the final key with NULL
- * if no match was found), or -1 on failure.
- */
-static npy_intp
-locate_key(PyObject **kwnames, PyObject *key)
-{
- PyObject **kwname = kwnames;
- while (*kwname != NULL && *kwname != key) {
- kwname++;
- }
- /* Slow fallback, just in case */
- if (*kwname == NULL) {
- int cmp = 0;
- kwname = kwnames;
- while (*kwname != NULL &&
- (cmp = PyObject_RichCompareBool(key, *kwname,
- Py_EQ)) == 0) {
- kwname++;
- }
- if (cmp < 0) {
- return -1;
- }
- }
- return kwname - kwnames;
-}
-
-/*
- * Parse keyword arguments, matching against kwnames
- *
- * Arguments beyond kwnames (the va_list) should contain converters and outputs
- * for each keyword name (where an output can be NULL to indicate the particular
- * keyword should be ignored).
- *
- * Returns 0 on success, -1 on failure with an error set.
- *
- * Note that the parser does not clean up on failure, i.e., already parsed keyword
- * values may hold new references, which the caller has to remove.
- *
- * TODO: ufunc is only used for the name in error messages; passing on the
- * name instead might be an option.
- *
- * TODO: instead of having this function ignore of keywords for which the
- * corresponding output is NULL, the calling routine should prepare the
- * correct list.
- */
-static int
-parse_ufunc_keywords(PyUFuncObject *ufunc, PyObject *kwds, PyObject **kwnames, ...)
-{
- va_list va;
- PyObject *key, *value;
- Py_ssize_t pos = 0;
- typedef int converter(PyObject *, void *);
-
- while (PyDict_Next(kwds, &pos, &key, &value)) {
- npy_intp i;
- converter *convert;
- void *output = NULL;
- npy_intp index = locate_key(kwnames, key);
- if (index < 0) {
- return -1;
- }
- if (kwnames[index]) {
- va_start(va, kwnames);
- for (i = 0; i <= index; i++) {
- convert = va_arg(va, converter *);
- output = va_arg(va, void *);
- }
- va_end(va);
- }
- if (output) {
- if (!convert(value, output)) {
- return -1;
- }
- }
- else {
- PyErr_Format(PyExc_TypeError,
- "'%S' is an invalid keyword to ufunc '%s'",
- key, ufunc_get_name_cstr(ufunc));
- return -1;
- }
- }
- return 0;
-}
/*
* Converters for use in parsing of keywords arguments.
*/
-NPY_NO_EXPORT int
-_subok_converter(PyObject *obj, int *subok)
+static int
+_subok_converter(PyObject *obj, npy_bool *subok)
{
if (PyBool_Check(obj)) {
*subok = (obj == Py_True);
@@ -958,7 +872,7 @@ _subok_converter(PyObject *obj, int *subok)
}
}
-NPY_NO_EXPORT int
+static int
_keepdims_converter(PyObject *obj, int *keepdims)
{
if (PyBool_Check(obj)) {
@@ -972,7 +886,7 @@ _keepdims_converter(PyObject *obj, int *keepdims)
}
}
-NPY_NO_EXPORT int
+static int
_wheremask_converter(PyObject *obj, PyArrayObject **wheremask)
{
/*
@@ -996,232 +910,124 @@ _wheremask_converter(PyObject *obj, PyArrayObject **wheremask)
}
}
-NPY_NO_EXPORT int
-_new_reference(PyObject *obj, PyObject **out)
-{
- Py_INCREF(obj);
- *out = obj;
- return NPY_SUCCEED;
-}
-
-NPY_NO_EXPORT int
-_borrowed_reference(PyObject *obj, PyObject **out)
-{
- *out = obj;
- return NPY_SUCCEED;
-}
/*
- * Parses the positional and keyword arguments for a generic ufunc call.
- * All returned arguments are new references (with optional ones NULL
- * if not present)
+ * Due to the array override, do the actual parameter conversion
+ * only in this step. This function takes the reference objects and
+ * parses them into the desired values.
+ * This function cleans up after itself and NULLs references on error,
+ * however, the caller has to ensure that `out_op[0:nargs]` and `out_whermeask`
+ * are NULL initialized.
*/
static int
-get_ufunc_arguments(PyUFuncObject *ufunc,
- PyObject *args, PyObject *kwds,
- PyArrayObject **out_op,
- NPY_ORDER *out_order,
- NPY_CASTING *out_casting,
- PyObject **out_extobj,
- PyObject **out_typetup, /* type: Tuple[np.dtype] */
- int *out_subok, /* bool */
- PyArrayObject **out_wheremask, /* PyArray of bool */
- PyObject **out_axes, /* type: List[Tuple[T]] */
- PyObject **out_axis, /* type: T */
- int *out_keepdims) /* bool */
+convert_ufunc_arguments(PyUFuncObject *ufunc,
+ ufunc_full_args full_args, PyArrayObject *out_op[],
+ PyArray_DTypeMeta *out_op_DTypes[],
+ npy_bool *force_legacy_promotion, npy_bool *allow_legacy_promotion,
+ PyObject *order_obj, NPY_ORDER *out_order,
+ PyObject *casting_obj, NPY_CASTING *out_casting,
+ PyObject *subok_obj, npy_bool *out_subok,
+ PyObject *where_obj, PyArrayObject **out_wheremask, /* PyArray of bool */
+ PyObject *keepdims_obj, int *out_keepdims)
{
- int i, nargs;
int nin = ufunc->nin;
int nout = ufunc->nout;
int nop = ufunc->nargs;
PyObject *obj;
- PyArray_Descr *dtype = NULL;
- /*
- * Initialize output objects so caller knows when outputs and optional
- * arguments are set (also means we can safely XDECREF on failure).
- */
- for (i = 0; i < nop; i++) {
- out_op[i] = NULL;
- }
- *out_extobj = NULL;
- *out_typetup = NULL;
- if (out_axes != NULL) {
- *out_axes = NULL;
- }
- if (out_axis != NULL) {
- *out_axis = NULL;
- }
- if (out_wheremask != NULL) {
- *out_wheremask = NULL;
- }
- /* Check number of arguments */
- nargs = PyTuple_Size(args);
- if ((nargs < nin) || (nargs > nop)) {
- PyErr_SetString(PyExc_ValueError, "invalid number of arguments");
- return -1;
- }
-
- /* Get input arguments */
- for (i = 0; i < nin; ++i) {
- obj = PyTuple_GET_ITEM(args, i);
+ /* Convert and fill in input arguments */
+ npy_bool all_scalar = NPY_TRUE;
+ npy_bool any_scalar = NPY_FALSE;
+ *allow_legacy_promotion = NPY_TRUE;
+ *force_legacy_promotion = NPY_FALSE;
+ for (int i = 0; i < nin; i++) {
+ obj = PyTuple_GET_ITEM(full_args.in, i);
if (PyArray_Check(obj)) {
- PyArrayObject *obj_a = (PyArrayObject *)obj;
- out_op[i] = (PyArrayObject *)PyArray_FromArray(obj_a, NULL, 0);
+ out_op[i] = (PyArrayObject *)obj;
+ Py_INCREF(out_op[i]);
}
else {
- out_op[i] = (PyArrayObject *)PyArray_FromAny(obj,
- NULL, 0, 0, 0, NULL);
- }
-
- if (out_op[i] == NULL) {
- goto fail;
+ /* Convert the input to an array and check for special cases */
+ out_op[i] = (PyArrayObject *)PyArray_FromAny(obj, NULL, 0, 0, 0, NULL);
+ if (out_op[i] == NULL) {
+ goto fail;
+ }
}
- }
+ out_op_DTypes[i] = NPY_DTYPE(PyArray_DESCR(out_op[i]));
+ Py_INCREF(out_op_DTypes[i]);
- /* Get positional output arguments */
- for (i = nin; i < nargs; ++i) {
- obj = PyTuple_GET_ITEM(args, i);
- if (_set_out_array(obj, out_op + i) < 0) {
- goto fail;
+ if (!NPY_DT_is_legacy(out_op_DTypes[i])) {
+ *allow_legacy_promotion = NPY_FALSE;
}
- }
-
- /*
- * If keywords are present, get keyword output and other arguments.
- * Raise an error if anything else is present in the keyword dictionary.
- */
- if (kwds) {
- PyObject *out_kwd = NULL;
- PyObject *sig = NULL;
- static PyObject *kwnames[13] = {NULL};
- if (kwnames[0] == NULL) {
- kwnames[0] = npy_um_str_out;
- kwnames[1] = npy_um_str_where;
- kwnames[2] = npy_um_str_axes;
- kwnames[3] = npy_um_str_axis;
- kwnames[4] = npy_um_str_keepdims;
- kwnames[5] = npy_um_str_casting;
- kwnames[6] = npy_um_str_order;
- kwnames[7] = npy_um_str_dtype;
- kwnames[8] = npy_um_str_subok;
- kwnames[9] = npy_um_str_signature;
- kwnames[10] = npy_um_str_sig;
- kwnames[11] = npy_um_str_extobj;
- kwnames[12] = NULL; /* sentinel */
+ if (PyArray_NDIM(out_op[i]) == 0) {
+ any_scalar = NPY_TRUE;
}
- /*
- * Parse using converters to calculate outputs
- * (NULL outputs are treated as indicating a keyword is not allowed).
- */
- if (parse_ufunc_keywords(
- ufunc, kwds, kwnames,
- _borrowed_reference, &out_kwd,
- _wheremask_converter, out_wheremask, /* new reference */
- _new_reference, out_axes,
- _new_reference, out_axis,
- _keepdims_converter, out_keepdims,
- PyArray_CastingConverter, out_casting,
- PyArray_OrderConverter, out_order,
- PyArray_DescrConverter2, &dtype, /* new reference */
- _subok_converter, out_subok,
- _new_reference, out_typetup,
- _borrowed_reference, &sig,
- _new_reference, out_extobj) < 0) {
- goto fail;
+ else {
+ all_scalar = NPY_FALSE;
+ continue;
}
/*
- * Check that outputs were not passed as positional as well,
- * and that they are either None or an array.
+ * TODO: we need to special case scalars here, if the input is a
+ * Python int, float, or complex, we have to use the "weak"
+ * DTypes: `PyArray_PyIntAbstractDType`, etc.
+ * This is to allow e.g. `float32(1.) + 1` to return `float32`.
+ * The correct array dtype can only be found after promotion for
+ * such a "weak scalar". We could avoid conversion here, but
+ * must convert it for use in the legacy promotion.
+ * There is still a small chance that this logic can instead
+ * happen inside the Python operators.
*/
- if (out_kwd) { /* borrowed reference */
- /*
- * Output arrays are generally specified as a tuple of arrays
- * and None, but may be a single array or None for ufuncs
- * with a single output.
- */
- if (nargs > nin) {
- PyErr_SetString(PyExc_ValueError,
- "cannot specify 'out' as both a "
- "positional and keyword argument");
- goto fail;
- }
- if (PyTuple_CheckExact(out_kwd)) {
- if (PyTuple_GET_SIZE(out_kwd) != nout) {
- PyErr_SetString(PyExc_ValueError,
- "The 'out' tuple must have exactly "
- "one entry per ufunc output");
- goto fail;
- }
- /* 'out' must be a tuple of arrays and Nones */
- for(i = 0; i < nout; ++i) {
- PyObject *val = PyTuple_GET_ITEM(out_kwd, i);
- if (_set_out_array(val, out_op+nin+i) < 0) {
- goto fail;
- }
- }
- }
- else if (nout == 1) {
- /* Can be an array if it only has one output */
- if (_set_out_array(out_kwd, out_op + nin) < 0) {
- goto fail;
- }
- }
- else {
- PyErr_SetString(PyExc_TypeError,
- nout > 1 ? "'out' must be a tuple of arrays" :
- "'out' must be an array or a tuple with "
- "a single array");
- goto fail;
- }
- }
+ }
+ if (*allow_legacy_promotion && (!all_scalar && any_scalar)) {
+ *force_legacy_promotion = should_use_min_scalar(nin, out_op, 0, NULL);
/*
- * Check we did not get both axis and axes, or multiple ways
- * to define a signature.
+ * TODO: if this is False, we end up in a "very slow" path that should
+ * be avoided. This makes `int_arr + 0.` ~40% slower.
*/
- if (out_axes != NULL && out_axis != NULL &&
- *out_axes != NULL && *out_axis != NULL) {
- PyErr_SetString(PyExc_TypeError,
- "cannot specify both 'axis' and 'axes'");
- goto fail;
- }
- if (sig) { /* borrowed reference */
- if (*out_typetup != NULL) {
- PyErr_SetString(PyExc_ValueError,
- "cannot specify both 'sig' and 'signature'");
+ }
+
+ /* Convert and fill in output arguments */
+ if (full_args.out != NULL) {
+ for (int i = 0; i < nout; i++) {
+ obj = PyTuple_GET_ITEM(full_args.out, i);
+ if (_set_out_array(obj, out_op + i + nin) < 0) {
goto fail;
}
- Py_INCREF(sig);
- *out_typetup = sig;
- }
- if (dtype) { /* new reference */
- if (*out_typetup != NULL) {
- PyErr_SetString(PyExc_RuntimeError,
- "cannot specify both 'signature' and 'dtype'");
- goto fail;
+ if (out_op[i] != NULL) {
+ out_op_DTypes[i + nin] = NPY_DTYPE(PyArray_DESCR(out_op[i]));
+ Py_INCREF(out_op_DTypes[i + nin]);
}
- /* Note: "N" uses the reference */
- *out_typetup = Py_BuildValue("(N)", dtype);
}
}
+
+ /*
+ * Convert most arguments manually here, since it is easier to handle
+ * the ufunc override if we first parse only to objects.
+ */
+ if (where_obj && !_wheremask_converter(where_obj, out_wheremask)) {
+ goto fail;
+ }
+ if (keepdims_obj && !_keepdims_converter(keepdims_obj, out_keepdims)) {
+ goto fail;
+ }
+ if (casting_obj && !PyArray_CastingConverter(casting_obj, out_casting)) {
+ goto fail;
+ }
+ if (order_obj && !PyArray_OrderConverter(order_obj, out_order)) {
+ goto fail;
+ }
+ if (subok_obj && !_subok_converter(subok_obj, out_subok)) {
+ goto fail;
+ }
return 0;
fail:
- Py_XDECREF(dtype);
- Py_XDECREF(*out_typetup);
- Py_XDECREF(*out_extobj);
if (out_wheremask != NULL) {
- Py_XDECREF(*out_wheremask);
+ Py_XSETREF(*out_wheremask, NULL);
}
- if (out_axes != NULL) {
- Py_XDECREF(*out_axes);
- }
- if (out_axis != NULL) {
- Py_XDECREF(*out_axis);
- }
- for (i = 0; i < nop; i++) {
- Py_XDECREF(out_op[i]);
+ for (int i = 0; i < nop; i++) {
+ Py_XSETREF(out_op[i], NULL);
}
return -1;
}
@@ -1235,34 +1041,49 @@ fail:
* -1 if there is an error.
*/
static int
-check_for_trivial_loop(PyUFuncObject *ufunc,
- PyArrayObject **op,
- PyArray_Descr **dtype,
- npy_intp buffersize)
+check_for_trivial_loop(PyArrayMethodObject *ufuncimpl,
+ PyArrayObject **op, PyArray_Descr **dtypes,
+ NPY_CASTING casting, npy_intp buffersize)
{
- npy_intp i, nin = ufunc->nin, nop = nin + ufunc->nout;
+ int i, nin = ufuncimpl->nin, nop = nin + ufuncimpl->nout;
for (i = 0; i < nop; ++i) {
/*
* If the dtype doesn't match, or the array isn't aligned,
* indicate that the trivial loop can't be done.
*/
- if (op[i] != NULL &&
- (!PyArray_ISALIGNED(op[i]) ||
- !PyArray_EquivTypes(dtype[i], PyArray_DESCR(op[i]))
- )) {
+ if (op[i] == NULL) {
+ continue;
+ }
+ int must_copy = !PyArray_ISALIGNED(op[i]);
+
+ if (dtypes[i] != PyArray_DESCR(op[i])) {
+ NPY_CASTING safety = PyArray_GetCastSafety(
+ PyArray_DESCR(op[i]), dtypes[i], NULL);
+ if (safety < 0) {
+ /* A proper error during a cast check should be rare */
+ return -1;
+ }
+ if (!(safety & _NPY_CAST_IS_VIEW)) {
+ must_copy = 1;
+ }
+
+ if (PyArray_MinCastSafety(safety, casting) != casting) {
+ return 0; /* the cast is not safe enough */
+ }
+ }
+ if (must_copy) {
/*
* If op[j] is a scalar or small one dimensional
* array input, make a copy to keep the opportunity
- * for a trivial loop.
+ * for a trivial loop. Outputs are not copied here.
*/
- if (i < nin && (PyArray_NDIM(op[i]) == 0 ||
- (PyArray_NDIM(op[i]) == 1 &&
- PyArray_DIM(op[i],0) <= buffersize))) {
+ if (i < nin && (PyArray_NDIM(op[i]) == 0
+ || (PyArray_NDIM(op[i]) == 1
+ && PyArray_DIM(op[i], 0) <= buffersize))) {
PyArrayObject *tmp;
- Py_INCREF(dtype[i]);
- tmp = (PyArrayObject *)
- PyArray_CastToType(op[i], dtype[i], 0);
+ Py_INCREF(dtypes[i]);
+ tmp = (PyArrayObject *)PyArray_CastToType(op[i], dtypes[i], 0);
if (tmp == NULL) {
return -1;
}
@@ -1278,65 +1099,6 @@ check_for_trivial_loop(PyUFuncObject *ufunc,
return 1;
}
-static void
-trivial_two_operand_loop(PyArrayObject **op,
- PyUFuncGenericFunction innerloop,
- void *innerloopdata)
-{
- char *data[2];
- npy_intp count[2], stride[2];
- int needs_api;
- NPY_BEGIN_THREADS_DEF;
-
- needs_api = PyDataType_REFCHK(PyArray_DESCR(op[0])) ||
- PyDataType_REFCHK(PyArray_DESCR(op[1]));
-
- PyArray_PREPARE_TRIVIAL_PAIR_ITERATION(op[0], op[1],
- count[0],
- data[0], data[1],
- stride[0], stride[1]);
- count[1] = count[0];
- NPY_UF_DBG_PRINT1("two operand loop count %d\n", (int)count[0]);
-
- if (!needs_api) {
- NPY_BEGIN_THREADS_THRESHOLDED(count[0]);
- }
-
- innerloop(data, count, stride, innerloopdata);
-
- NPY_END_THREADS;
-}
-
-static void
-trivial_three_operand_loop(PyArrayObject **op,
- PyUFuncGenericFunction innerloop,
- void *innerloopdata)
-{
- char *data[3];
- npy_intp count[3], stride[3];
- int needs_api;
- NPY_BEGIN_THREADS_DEF;
-
- needs_api = PyDataType_REFCHK(PyArray_DESCR(op[0])) ||
- PyDataType_REFCHK(PyArray_DESCR(op[1])) ||
- PyDataType_REFCHK(PyArray_DESCR(op[2]));
-
- PyArray_PREPARE_TRIVIAL_TRIPLE_ITERATION(op[0], op[1], op[2],
- count[0],
- data[0], data[1], data[2],
- stride[0], stride[1], stride[2]);
- count[1] = count[0];
- count[2] = count[0];
- NPY_UF_DBG_PRINT1("three operand loop count %d\n", (int)count[0]);
-
- if (!needs_api) {
- NPY_BEGIN_THREADS_THRESHOLDED(count[0]);
- }
-
- innerloop(data, count, stride, innerloopdata);
-
- NPY_END_THREADS;
-}
/*
* Calls the given __array_prepare__ function on the operand *op,
@@ -1410,366 +1172,277 @@ prepare_ufunc_output(PyUFuncObject *ufunc,
return 0;
}
+
+/*
+ * Check whether a trivial loop is possible and call the innerloop if it is.
+ * A trivial loop is defined as one where a single strided inner-loop call
+ * is possible.
+ *
+ * This function only supports a single output (due to the overlap check).
+ * It always accepts 0-D arrays and will broadcast them. The function
+ * cannot broadcast any other array (as it requires a single stride).
+ * The function accepts all 1-D arrays, and N-D arrays that are either all
+ * C- or all F-contiguous.
+ *
+ * Returns -2 if a trivial loop is not possible, 0 on success and -1 on error.
+ */
static int
-iterator_loop(PyUFuncObject *ufunc,
- PyArrayObject **op,
- PyArray_Descr **dtype,
- NPY_ORDER order,
- npy_intp buffersize,
- PyObject **arr_prep,
- ufunc_full_args full_args,
- PyUFuncGenericFunction innerloop,
- void *innerloopdata,
- npy_uint32 *op_flags)
+try_trivial_single_output_loop(PyArrayMethod_Context *context,
+ PyArrayObject *op[], NPY_ORDER order,
+ PyObject *arr_prep[], ufunc_full_args full_args,
+ int errormask, PyObject *extobj)
{
- npy_intp i, nin = ufunc->nin, nout = ufunc->nout;
- npy_intp nop = nin + nout;
- NpyIter *iter;
- char *baseptrs[NPY_MAXARGS];
+ int nin = context->method->nin;
+ int nop = nin + 1;
+ assert(context->method->nout == 1);
- NpyIter_IterNextFunc *iternext;
- char **dataptr;
- npy_intp *stride;
- npy_intp *count_ptr;
-
- PyArrayObject **op_it;
- npy_uint32 iter_flags;
+ /* The order of all N-D contiguous operands, can be fixed by `order` */
+ int operation_order = 0;
+ if (order == NPY_CORDER) {
+ operation_order = NPY_ARRAY_C_CONTIGUOUS;
+ }
+ else if (order == NPY_FORTRANORDER) {
+ operation_order = NPY_ARRAY_F_CONTIGUOUS;
+ }
- NPY_BEGIN_THREADS_DEF;
+ int operation_ndim = 0;
+ npy_intp *operation_shape = NULL;
+ npy_intp fixed_strides[NPY_MAXARGS];
- iter_flags = ufunc->iter_flags |
- NPY_ITER_EXTERNAL_LOOP |
- NPY_ITER_REFS_OK |
- NPY_ITER_ZEROSIZE_OK |
- NPY_ITER_BUFFERED |
- NPY_ITER_GROWINNER |
- NPY_ITER_DELAY_BUFALLOC |
- NPY_ITER_COPY_IF_OVERLAP;
-
- /* Call the __array_prepare__ functions for already existing output arrays.
- * Do this before creating the iterator, as the iterator may UPDATEIFCOPY
- * some of them.
- */
- for (i = 0; i < nout; ++i) {
- if (op[nin+i] == NULL) {
+ for (int iop = 0; iop < nop; iop++) {
+ if (op[iop] == NULL) {
+ /* The out argument may be NULL (and only that one); fill later */
+ assert(iop == nin);
continue;
}
- if (prepare_ufunc_output(ufunc, &op[nin+i],
- arr_prep[i], full_args, i) < 0) {
- return -1;
- }
- }
- /*
- * Allocate the iterator. Because the types of the inputs
- * were already checked, we use the casting rule 'unsafe' which
- * is faster to calculate.
- */
- iter = NpyIter_AdvancedNew(nop, op,
- iter_flags,
- order, NPY_UNSAFE_CASTING,
- op_flags, dtype,
- -1, NULL, NULL, buffersize);
- if (iter == NULL) {
- return -1;
- }
+ int op_ndim = PyArray_NDIM(op[iop]);
- /* Copy any allocated outputs */
- op_it = NpyIter_GetOperandArray(iter);
- for (i = 0; i < nout; ++i) {
- if (op[nin+i] == NULL) {
- op[nin+i] = op_it[nin+i];
- Py_INCREF(op[nin+i]);
+ /* Special case 0-D since we can handle broadcasting using a 0-stride */
+ if (op_ndim == 0) {
+ fixed_strides[iop] = 0;
+ continue;
+ }
- /* Call the __array_prepare__ functions for the new array */
- if (prepare_ufunc_output(ufunc, &op[nin+i],
- arr_prep[i], full_args, i) < 0) {
- NpyIter_Deallocate(iter);
- return -1;
- }
+ /* First non 0-D op: fix dimensions, shape (order is fixed later) */
+ if (operation_ndim == 0) {
+ operation_ndim = op_ndim;
+ operation_shape = PyArray_SHAPE(op[iop]);
+ }
+ else if (op_ndim != operation_ndim) {
+ return -2; /* dimension mismatch (except 0-d ops) */
+ }
+ else if (!PyArray_CompareLists(
+ operation_shape, PyArray_DIMS(op[iop]), op_ndim)) {
+ return -2; /* shape mismatch */
+ }
- /*
- * In case __array_prepare__ returned a different array, put the
- * results directly there, ignoring the array allocated by the
- * iterator.
- *
- * Here, we assume the user-provided __array_prepare__ behaves
- * sensibly and doesn't return an array overlapping in memory
- * with other operands --- the op[nin+i] array passed to it is newly
- * allocated and doesn't have any overlap.
- */
- baseptrs[nin+i] = PyArray_BYTES(op[nin+i]);
+ if (op_ndim == 1) {
+ fixed_strides[iop] = PyArray_STRIDES(op[iop])[0];
}
else {
- baseptrs[nin+i] = PyArray_BYTES(op_it[nin+i]);
+ fixed_strides[iop] = PyArray_ITEMSIZE(op[iop]); /* contiguous */
+
+ /* This op must match the operation order (and be contiguous) */
+ int op_order = (PyArray_FLAGS(op[iop]) &
+ (NPY_ARRAY_C_CONTIGUOUS|NPY_ARRAY_F_CONTIGUOUS));
+ if (op_order == 0) {
+ return -2; /* N-dimensional op must be contiguous */
+ }
+ else if (operation_order == 0) {
+ operation_order = op_order; /* op fixes order */
+ }
+ else if (operation_order != op_order) {
+ return -2;
+ }
}
}
- /* Only do the loop if the iteration size is non-zero */
- if (NpyIter_GetIterSize(iter) != 0) {
- /* Reset the iterator with the base pointers from possible __array_prepare__ */
- for (i = 0; i < nin; ++i) {
- baseptrs[i] = PyArray_BYTES(op_it[i]);
- }
- if (NpyIter_ResetBasePointers(iter, baseptrs, NULL) != NPY_SUCCEED) {
- NpyIter_Deallocate(iter);
+ if (op[nin] == NULL) {
+ Py_INCREF(context->descriptors[nin]);
+ op[nin] = (PyArrayObject *) PyArray_NewFromDescr(&PyArray_Type,
+ context->descriptors[nin], operation_ndim, operation_shape,
+ NULL, NULL, operation_order==NPY_ARRAY_F_CONTIGUOUS, NULL);
+ if (op[nin] == NULL) {
return -1;
}
-
- /* Get the variables needed for the loop */
- iternext = NpyIter_GetIterNext(iter, NULL);
- if (iternext == NULL) {
- NpyIter_Deallocate(iter);
- return -1;
+ fixed_strides[nin] = context->descriptors[nin]->elsize;
+ }
+ else {
+ /* If any input overlaps with the output, we use the full path. */
+ for (int iop = 0; iop < nin; iop++) {
+ if (!PyArray_EQUIVALENTLY_ITERABLE_OVERLAP_OK(
+ op[iop], op[nin],
+ PyArray_TRIVIALLY_ITERABLE_OP_READ,
+ PyArray_TRIVIALLY_ITERABLE_OP_NOREAD)) {
+ return -2;
+ }
+ }
+ /* Check self-overlap (non 1-D are contiguous, perfect overlap is OK) */
+ if (operation_ndim == 1 &&
+ PyArray_STRIDES(op[nin])[0] < PyArray_ITEMSIZE(op[nin]) &&
+ PyArray_STRIDES(op[nin])[0] != 0) {
+ return -2;
}
- dataptr = NpyIter_GetDataPtrArray(iter);
- stride = NpyIter_GetInnerStrideArray(iter);
- count_ptr = NpyIter_GetInnerLoopSizePtr(iter);
-
- NPY_BEGIN_THREADS_NDITER(iter);
-
- /* Execute the loop */
- do {
- NPY_UF_DBG_PRINT1("iterator loop count %d\n", (int)*count_ptr);
- innerloop(dataptr, count_ptr, stride, innerloopdata);
- } while (iternext(iter));
-
- NPY_END_THREADS;
}
- /*
- * Currently `innerloop` may leave an error set, in this case
- * NpyIter_Deallocate will always return an error as well.
- */
- if (NpyIter_Deallocate(iter) == NPY_FAIL) {
+
+ /* Call the __prepare_array__ if necessary */
+ if (prepare_ufunc_output((PyUFuncObject *)context->caller, &op[nin],
+ arr_prep[0], full_args, 0) < 0) {
return -1;
}
- return 0;
-}
-/*
- * ufunc - the ufunc to call
- * trivial_loop_ok - 1 if no alignment, data conversion, etc required
- * op - the operands (ufunc->nin + ufunc->nout of them)
- * dtypes - the dtype of each operand
- * order - the loop execution order/output memory order
- * buffersize - how big of a buffer to use
- * arr_prep - the __array_prepare__ functions for the outputs
- * full_args - the original input, output PyObject *
- * op_flags - per-operand flags, a combination of NPY_ITER_* constants
- */
-static int
-execute_legacy_ufunc_loop(PyUFuncObject *ufunc,
- int trivial_loop_ok,
- PyArrayObject **op,
- PyArray_Descr **dtypes,
- NPY_ORDER order,
- npy_intp buffersize,
- PyObject **arr_prep,
- ufunc_full_args full_args,
- npy_uint32 *op_flags)
-{
- npy_intp nin = ufunc->nin, nout = ufunc->nout;
- PyUFuncGenericFunction innerloop;
- void *innerloopdata;
- int needs_api = 0;
+ /*
+ * We can use the trivial (single inner-loop call) optimization
+ * and `fixed_strides` holds the strides for that call.
+ */
+ char *data[NPY_MAXARGS];
+ npy_intp count = PyArray_MultiplyList(operation_shape, operation_ndim);
+ NPY_BEGIN_THREADS_DEF;
- if (ufunc->legacy_inner_loop_selector(ufunc, dtypes,
- &innerloop, &innerloopdata, &needs_api) < 0) {
+ PyArrayMethod_StridedLoop *strided_loop;
+ NpyAuxData *auxdata = NULL;
+ NPY_ARRAYMETHOD_FLAGS flags = 0;
+ if (context->method->get_strided_loop(context,
+ 1, 0, fixed_strides,
+ &strided_loop, &auxdata, &flags) < 0) {
return -1;
}
- /* If the loop wants the arrays, provide them. */
- if (_does_loop_use_arrays(innerloopdata)) {
- innerloopdata = (void*)op;
- }
-
- /* First check for the trivial cases that don't need an iterator */
- if (trivial_loop_ok) {
- if (nin == 1 && nout == 1) {
- if (op[1] == NULL &&
- (order == NPY_ANYORDER || order == NPY_KEEPORDER) &&
- PyArray_TRIVIALLY_ITERABLE(op[0])) {
- Py_INCREF(dtypes[1]);
- op[1] = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type,
- dtypes[1],
- PyArray_NDIM(op[0]),
- PyArray_DIMS(op[0]),
- NULL, NULL,
- PyArray_ISFORTRAN(op[0]) ?
- NPY_ARRAY_F_CONTIGUOUS : 0,
- NULL);
- if (op[1] == NULL) {
- return -1;
- }
-
- /* Call the __prepare_array__ if necessary */
- if (prepare_ufunc_output(ufunc, &op[1],
- arr_prep[0], full_args, 0) < 0) {
- return -1;
- }
-
- NPY_UF_DBG_PRINT("trivial 1 input with allocated output\n");
- trivial_two_operand_loop(op, innerloop, innerloopdata);
-
- return 0;
- }
- else if (op[1] != NULL &&
- PyArray_NDIM(op[1]) >= PyArray_NDIM(op[0]) &&
- PyArray_TRIVIALLY_ITERABLE_PAIR(op[0], op[1],
- PyArray_TRIVIALLY_ITERABLE_OP_READ,
- PyArray_TRIVIALLY_ITERABLE_OP_NOREAD)) {
-
- /* Call the __prepare_array__ if necessary */
- if (prepare_ufunc_output(ufunc, &op[1],
- arr_prep[0], full_args, 0) < 0) {
- return -1;
- }
-
- NPY_UF_DBG_PRINT("trivial 1 input\n");
- trivial_two_operand_loop(op, innerloop, innerloopdata);
-
- return 0;
- }
- }
- else if (nin == 2 && nout == 1) {
- if (op[2] == NULL &&
- (order == NPY_ANYORDER || order == NPY_KEEPORDER) &&
- PyArray_TRIVIALLY_ITERABLE_PAIR(op[0], op[1],
- PyArray_TRIVIALLY_ITERABLE_OP_READ,
- PyArray_TRIVIALLY_ITERABLE_OP_READ)) {
- PyArrayObject *tmp;
- /*
- * Have to choose the input with more dimensions to clone, as
- * one of them could be a scalar.
- */
- if (PyArray_NDIM(op[0]) >= PyArray_NDIM(op[1])) {
- tmp = op[0];
- }
- else {
- tmp = op[1];
- }
- Py_INCREF(dtypes[2]);
- op[2] = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type,
- dtypes[2],
- PyArray_NDIM(tmp),
- PyArray_DIMS(tmp),
- NULL, NULL,
- PyArray_ISFORTRAN(tmp) ?
- NPY_ARRAY_F_CONTIGUOUS : 0,
- NULL);
- if (op[2] == NULL) {
- return -1;
- }
-
- /* Call the __prepare_array__ if necessary */
- if (prepare_ufunc_output(ufunc, &op[2],
- arr_prep[0], full_args, 0) < 0) {
- return -1;
- }
+ for (int iop=0; iop < nop; iop++) {
+ data[iop] = PyArray_BYTES(op[iop]);
+ }
- NPY_UF_DBG_PRINT("trivial 2 input with allocated output\n");
- trivial_three_operand_loop(op, innerloop, innerloopdata);
+ if (!(flags & NPY_METH_NO_FLOATINGPOINT_ERRORS)) {
+ npy_clear_floatstatus_barrier((char *)context);
+ }
+ if (!(flags & NPY_METH_REQUIRES_PYAPI)) {
+ NPY_BEGIN_THREADS_THRESHOLDED(count);
+ }
- return 0;
- }
- else if (op[2] != NULL &&
- PyArray_NDIM(op[2]) >= PyArray_NDIM(op[0]) &&
- PyArray_NDIM(op[2]) >= PyArray_NDIM(op[1]) &&
- PyArray_TRIVIALLY_ITERABLE_TRIPLE(op[0], op[1], op[2],
- PyArray_TRIVIALLY_ITERABLE_OP_READ,
- PyArray_TRIVIALLY_ITERABLE_OP_READ,
- PyArray_TRIVIALLY_ITERABLE_OP_NOREAD)) {
-
- /* Call the __prepare_array__ if necessary */
- if (prepare_ufunc_output(ufunc, &op[2],
- arr_prep[0], full_args, 0) < 0) {
- return -1;
- }
+ int res = strided_loop(context, data, &count, fixed_strides, auxdata);
- NPY_UF_DBG_PRINT("trivial 2 input\n");
- trivial_three_operand_loop(op, innerloop, innerloopdata);
+ NPY_END_THREADS;
+ NPY_AUXDATA_FREE(auxdata);
- return 0;
- }
- }
+ if (res == 0 && !(flags & NPY_METH_NO_FLOATINGPOINT_ERRORS)) {
+ /* NOTE: We could check float errors even when `res < 0` */
+ const char *name = ufunc_get_name_cstr((PyUFuncObject *)context->caller);
+ res = _check_ufunc_fperr(errormask, extobj, name);
}
+ return res;
+}
- /*
- * If no trivial loop matched, an iterator is required to
- * resolve broadcasting, etc
- */
- NPY_UF_DBG_PRINT("iterator loop\n");
- if (iterator_loop(ufunc, op, dtypes, order,
- buffersize, arr_prep, full_args,
- innerloop, innerloopdata, op_flags) < 0) {
+/*
+ * Check casting: It would be nice to just move this into the iterator
+ * or pass in the full cast information. But this can special case
+ * the logical functions and prints a better error message.
+ */
+static NPY_INLINE int
+validate_casting(PyArrayMethodObject *method, PyUFuncObject *ufunc,
+ PyArrayObject *ops[], PyArray_Descr *descriptors[],
+ NPY_CASTING casting)
+{
+ if (method->resolve_descriptors == &wrapped_legacy_resolve_descriptors) {
+ /*
+ * In this case the legacy type resolution was definitely called
+ * and we do not need to check (astropy/pyerfa relied on this).
+ */
+ return 0;
+ }
+ if (PyUFunc_ValidateCasting(ufunc, casting, ops, descriptors) < 0) {
return -1;
}
-
return 0;
}
+
/*
- * nin - number of inputs
- * nout - number of outputs
- * wheremask - if not NULL, the 'where=' parameter to the ufunc.
- * op - the operands (nin + nout of them)
- * order - the loop execution order/output memory order
- * buffersize - how big of a buffer to use
- * arr_prep - the __array_prepare__ functions for the outputs
- * innerloop - the inner loop function
- * innerloopdata - data to pass to the inner loop
+ * The ufunc loop implementation for both normal ufunc calls and masked calls
+ * when the iterator has to be used.
+ *
+ * See `PyUFunc_GenericFunctionInternal` for more information (where this is
+ * called from).
*/
static int
-execute_fancy_ufunc_loop(PyUFuncObject *ufunc,
- PyArrayObject *wheremask,
- PyArrayObject **op,
- PyArray_Descr **dtypes,
- NPY_ORDER order,
- npy_intp buffersize,
- PyObject **arr_prep,
- ufunc_full_args full_args,
- npy_uint32 *op_flags)
+execute_ufunc_loop(PyArrayMethod_Context *context, int masked,
+ PyArrayObject **op, NPY_ORDER order, npy_intp buffersize,
+ NPY_CASTING casting,
+ PyObject **arr_prep, ufunc_full_args full_args,
+ npy_uint32 *op_flags, int errormask, PyObject *extobj)
{
- int i, nin = ufunc->nin, nout = ufunc->nout;
+ PyUFuncObject *ufunc = (PyUFuncObject *)context->caller;
+ int nin = context->method->nin, nout = context->method->nout;
int nop = nin + nout;
- NpyIter *iter;
- int needs_api;
-
- NpyIter_IterNextFunc *iternext;
- char **dataptr;
- npy_intp *strides;
- npy_intp *countptr;
- PyArrayObject **op_it;
- npy_uint32 iter_flags;
-
- for (i = nin; i < nop; ++i) {
- op_flags[i] |= (op[i] != NULL ? NPY_ITER_READWRITE : NPY_ITER_WRITEONLY);
+ if (validate_casting(context->method,
+ ufunc, op, context->descriptors, casting) < 0) {
+ return -1;
}
- if (wheremask != NULL) {
- op_flags[nop] = NPY_ITER_READONLY | NPY_ITER_ARRAYMASK;
+ if (masked) {
+ assert(PyArray_TYPE(op[nop]) == NPY_BOOL);
+ if (ufunc->_always_null_previously_masked_innerloop_selector != NULL) {
+ if (PyErr_WarnFormat(PyExc_UserWarning, 1,
+ "The ufunc %s has a custom masked-inner-loop-selector."
+ "NumPy assumes that this is NEVER used. If you do make "
+ "use of this please notify the NumPy developers to discuss "
+ "future solutions. (See NEP 41 and 43)\n"
+ "NumPy will continue, but ignore the custom loop selector. "
+ "This should only affect performance.",
+ ufunc_get_name_cstr(ufunc)) < 0) {
+ return -1;
+ }
+ }
+
+ /*
+ * NOTE: In the masked version, we consider the output read-write,
+ * this gives a best-effort of preserving the input, but does
+ * not always work. It could allow the operand to be copied
+ * due to copy-if-overlap, but only if it was passed in.
+ * In that case `__array_prepare__` is called before it happens.
+ */
+ for (int i = nin; i < nop; ++i) {
+ op_flags[i] |= (op[i] != NULL ? NPY_ITER_READWRITE : NPY_ITER_WRITEONLY);
+ }
+ op_flags[nop] = NPY_ITER_READONLY | NPY_ITER_ARRAYMASK; /* mask */
}
NPY_UF_DBG_PRINT("Making iterator\n");
- iter_flags = ufunc->iter_flags |
+ npy_uint32 iter_flags = ufunc->iter_flags |
NPY_ITER_EXTERNAL_LOOP |
NPY_ITER_REFS_OK |
NPY_ITER_ZEROSIZE_OK |
NPY_ITER_BUFFERED |
NPY_ITER_GROWINNER |
+ NPY_ITER_DELAY_BUFALLOC |
NPY_ITER_COPY_IF_OVERLAP;
/*
+ * Call the __array_prepare__ functions for already existing output arrays.
+ * Do this before creating the iterator, as the iterator may UPDATEIFCOPY
+ * some of them.
+ */
+ for (int i = 0; i < nout; i++) {
+ if (op[nin+i] == NULL) {
+ continue;
+ }
+ if (prepare_ufunc_output(ufunc, &op[nin+i],
+ arr_prep[i], full_args, i) < 0) {
+ return -1;
+ }
+ }
+
+ /*
* Allocate the iterator. Because the types of the inputs
* were already checked, we use the casting rule 'unsafe' which
* is faster to calculate.
*/
- iter = NpyIter_AdvancedNew(nop + ((wheremask != NULL) ? 1 : 0), op,
+ NpyIter *iter = NpyIter_AdvancedNew(nop + masked, op,
iter_flags,
order, NPY_UNSAFE_CASTING,
- op_flags, dtypes,
+ op_flags, context->descriptors,
-1, NULL, NULL, buffersize);
if (iter == NULL) {
return -1;
@@ -1777,225 +1450,132 @@ execute_fancy_ufunc_loop(PyUFuncObject *ufunc,
NPY_UF_DBG_PRINT("Made iterator\n");
- needs_api = NpyIter_IterationNeedsAPI(iter);
+ /* Call the __array_prepare__ functions for newly allocated arrays */
+ PyArrayObject **op_it = NpyIter_GetOperandArray(iter);
+ char *baseptrs[NPY_MAXARGS];
- /* Call the __array_prepare__ functions where necessary */
- op_it = NpyIter_GetOperandArray(iter);
- for (i = nin; i < nop; ++i) {
- PyArrayObject *op_tmp, *orig_op_tmp;
+ for (int i = 0; i < nout; ++i) {
+ if (op[nin + i] == NULL) {
+ op[nin + i] = op_it[nin + i];
+ Py_INCREF(op[nin + i]);
- /*
- * The array can be allocated by the iterator -- it is placed in op[i]
- * and returned to the caller, and this needs an extra incref.
- */
- if (op[i] == NULL) {
- op_tmp = op_it[i];
- Py_INCREF(op_tmp);
+ /* Call the __array_prepare__ functions for the new array */
+ if (prepare_ufunc_output(ufunc,
+ &op[nin + i], arr_prep[i], full_args, i) < 0) {
+ NpyIter_Deallocate(iter);
+ return -1;
+ }
+
+ /*
+ * In case __array_prepare__ returned a different array, put the
+ * results directly there, ignoring the array allocated by the
+ * iterator.
+ *
+ * Here, we assume the user-provided __array_prepare__ behaves
+ * sensibly and doesn't return an array overlapping in memory
+ * with other operands --- the op[nin+i] array passed to it is newly
+ * allocated and doesn't have any overlap.
+ */
+ baseptrs[nin + i] = PyArray_BYTES(op[nin + i]);
}
else {
- op_tmp = op[i];
+ baseptrs[nin + i] = PyArray_BYTES(op_it[nin + i]);
}
-
- /* prepare_ufunc_output may decref & replace the pointer */
- orig_op_tmp = op_tmp;
- Py_INCREF(op_tmp);
-
- if (prepare_ufunc_output(ufunc, &op_tmp,
- arr_prep[i], full_args, i) < 0) {
- NpyIter_Deallocate(iter);
- return -1;
- }
-
- /* Validate that the prepare_ufunc_output didn't mess with pointers */
- if (PyArray_BYTES(op_tmp) != PyArray_BYTES(orig_op_tmp)) {
- PyErr_SetString(PyExc_ValueError,
- "The __array_prepare__ functions modified the data "
- "pointer addresses in an invalid fashion");
- Py_DECREF(op_tmp);
- NpyIter_Deallocate(iter);
+ }
+ /* Only do the loop if the iteration size is non-zero */
+ npy_intp full_size = NpyIter_GetIterSize(iter);
+ if (full_size == 0) {
+ if (!NpyIter_Deallocate(iter)) {
return -1;
}
-
- /*
- * Put the updated operand back and undo the DECREF above. If
- * COPY_IF_OVERLAP made a temporary copy, the output will be copied
- * by UPDATEIFCOPY even if op[i] was changed by prepare_ufunc_output.
- */
- op[i] = op_tmp;
- Py_DECREF(op_tmp);
+ return 0;
}
- /* Only do the loop if the iteration size is non-zero */
- if (NpyIter_GetIterSize(iter) != 0) {
- PyUFunc_MaskedStridedInnerLoopFunc *innerloop;
- NpyAuxData *innerloopdata;
- npy_intp fixed_strides[2*NPY_MAXARGS];
- PyArray_Descr **iter_dtypes;
- NPY_BEGIN_THREADS_DEF;
+ /*
+ * Reset the iterator with the base pointers possibly modified by
+ * `__array_prepare__`.
+ */
+ for (int i = 0; i < nin; i++) {
+ baseptrs[i] = PyArray_BYTES(op_it[i]);
+ }
+ if (masked) {
+ baseptrs[nop] = PyArray_BYTES(op_it[nop]);
+ }
+ if (NpyIter_ResetBasePointers(iter, baseptrs, NULL) != NPY_SUCCEED) {
+ NpyIter_Deallocate(iter);
+ return -1;
+ }
- /*
- * Get the inner loop, with the possibility of specialization
- * based on the fixed strides.
- */
- NpyIter_GetInnerFixedStrideArray(iter, fixed_strides);
- iter_dtypes = NpyIter_GetDescrArray(iter);
- if (ufunc->masked_inner_loop_selector(ufunc, dtypes,
- wheremask != NULL ? iter_dtypes[nop]
- : iter_dtypes[nop + nin],
- fixed_strides,
- wheremask != NULL ? fixed_strides[nop]
- : fixed_strides[nop + nin],
- &innerloop, &innerloopdata, &needs_api) < 0) {
+ /*
+ * Get the inner loop, with the possibility of specialization
+ * based on the fixed strides.
+ */
+ PyArrayMethod_StridedLoop *strided_loop;
+ NpyAuxData *auxdata;
+ npy_intp fixed_strides[NPY_MAXARGS];
+
+ NpyIter_GetInnerFixedStrideArray(iter, fixed_strides);
+ NPY_ARRAYMETHOD_FLAGS flags = 0;
+ if (masked) {
+ if (PyArrayMethod_GetMaskedStridedLoop(context,
+ 1, fixed_strides, &strided_loop, &auxdata, &flags) < 0) {
NpyIter_Deallocate(iter);
return -1;
}
-
- /* Get the variables needed for the loop */
- iternext = NpyIter_GetIterNext(iter, NULL);
- if (iternext == NULL) {
+ }
+ else {
+ if (context->method->get_strided_loop(context,
+ 1, 0, fixed_strides, &strided_loop, &auxdata, &flags) < 0) {
NpyIter_Deallocate(iter);
return -1;
}
- dataptr = NpyIter_GetDataPtrArray(iter);
- strides = NpyIter_GetInnerStrideArray(iter);
- countptr = NpyIter_GetInnerLoopSizePtr(iter);
-
- NPY_BEGIN_THREADS_NDITER(iter);
-
- NPY_UF_DBG_PRINT("Actual inner loop:\n");
- /* Execute the loop */
- do {
- NPY_UF_DBG_PRINT1("iterator loop count %d\n", (int)*countptr);
- innerloop(dataptr, strides,
- dataptr[nop], strides[nop],
- *countptr, innerloopdata);
- } while (iternext(iter));
-
- NPY_END_THREADS;
-
- NPY_AUXDATA_FREE(innerloopdata);
}
- return NpyIter_Deallocate(iter);
-}
-
-static npy_bool
-tuple_all_none(PyObject *tup) {
- npy_intp i;
- for (i = 0; i < PyTuple_GET_SIZE(tup); ++i) {
- if (PyTuple_GET_ITEM(tup, i) != Py_None) {
- return NPY_FALSE;
- }
+ /* Get the variables needed for the loop */
+ NpyIter_IterNextFunc *iternext = NpyIter_GetIterNext(iter, NULL);
+ if (iternext == NULL) {
+ NPY_AUXDATA_FREE(auxdata);
+ NpyIter_Deallocate(iter);
+ return -1;
}
- return NPY_TRUE;
-}
-
-/*
- * Convert positional args and the out kwarg into an input and output tuple.
- *
- * If the output tuple would be all None, return NULL instead.
- *
- * This duplicates logic in many places, so further refactoring is needed:
- * - get_ufunc_arguments
- * - PyUFunc_WithOverride
- * - normalize___call___args
- */
-static int
-make_full_arg_tuple(
- ufunc_full_args *full_args,
- npy_intp nin, npy_intp nout,
- PyObject *args, PyObject *kwds)
-{
- PyObject *out_kwd = NULL;
- npy_intp nargs = PyTuple_GET_SIZE(args);
- npy_intp i;
-
- /* This should have been checked by the caller */
- assert(nin <= nargs && nargs <= nin + nout);
+ char **dataptr = NpyIter_GetDataPtrArray(iter);
+ npy_intp *strides = NpyIter_GetInnerStrideArray(iter);
+ npy_intp *countptr = NpyIter_GetInnerLoopSizePtr(iter);
+ int needs_api = NpyIter_IterationNeedsAPI(iter);
- /* Initialize so we can XDECREF safely */
- full_args->in = NULL;
- full_args->out = NULL;
-
- /* Get the input arguments*/
- full_args->in = PyTuple_GetSlice(args, 0, nin);
- if (full_args->in == NULL) {
- goto fail;
- }
+ NPY_BEGIN_THREADS_DEF;
- /* Look for output keyword arguments */
- if (kwds) {
- out_kwd = PyDict_GetItemWithError(kwds, npy_um_str_out);
- if (out_kwd == NULL && PyErr_Occurred()) {
- goto fail;
- }
+ if (!(flags & NPY_METH_NO_FLOATINGPOINT_ERRORS)) {
+ npy_clear_floatstatus_barrier((char *)context);
}
- else {
- out_kwd = NULL;
+ if (!needs_api && !(flags & NPY_METH_REQUIRES_PYAPI)) {
+ NPY_BEGIN_THREADS_THRESHOLDED(full_size);
}
- if (out_kwd != NULL) {
- assert(nargs == nin);
- if (out_kwd == Py_None) {
- return 0;
- }
- else if (PyTuple_Check(out_kwd)) {
- assert(PyTuple_GET_SIZE(out_kwd) == nout);
- if (tuple_all_none(out_kwd)) {
- return 0;
- }
- Py_INCREF(out_kwd);
- full_args->out = out_kwd;
- return 0;
- }
- else {
- /* A single argument x is promoted to (x, None, None ...) */
- full_args->out = PyTuple_New(nout);
- if (full_args->out == NULL) {
- goto fail;
- }
- Py_INCREF(out_kwd);
- PyTuple_SET_ITEM(full_args->out, 0, out_kwd);
- for (i = 1; i < nout; ++i) {
- Py_INCREF(Py_None);
- PyTuple_SET_ITEM(full_args->out, i, Py_None);
- }
- return 0;
- }
- }
+ NPY_UF_DBG_PRINT("Actual inner loop:\n");
+ /* Execute the loop */
+ int res;
+ do {
+ NPY_UF_DBG_PRINT1("iterator loop count %d\n", (int)*countptr);
+ res = strided_loop(context, dataptr, countptr, strides, auxdata);
+ } while (res == 0 && iternext(iter));
- /* No outputs in kwargs; if also none in args, we're done */
- if (nargs == nin) {
- return 0;
- }
- /* copy across positional output arguments, adding trailing Nones */
- full_args->out = PyTuple_New(nout);
- if (full_args->out == NULL) {
- goto fail;
- }
- for (i = nin; i < nargs; ++i) {
- PyObject *item = PyTuple_GET_ITEM(args, i);
- Py_INCREF(item);
- PyTuple_SET_ITEM(full_args->out, i - nin, item);
- }
- for (i = nargs; i < nin + nout; ++i) {
- Py_INCREF(Py_None);
- PyTuple_SET_ITEM(full_args->out, i - nin, Py_None);
- }
+ NPY_END_THREADS;
+ NPY_AUXDATA_FREE(auxdata);
- /* don't return a tuple full of None */
- if (tuple_all_none(full_args->out)) {
- Py_DECREF(full_args->out);
- full_args->out = NULL;
+ if (res == 0 && !(flags & NPY_METH_NO_FLOATINGPOINT_ERRORS)) {
+ /* NOTE: We could check float errors even when `res < 0` */
+ const char *name = ufunc_get_name_cstr((PyUFuncObject *)context->caller);
+ res = _check_ufunc_fperr(errormask, extobj, name);
}
- return 0;
-fail:
- Py_XDECREF(full_args->in);
- Py_XDECREF(full_args->out);
- return -1;
+ if (!NpyIter_Deallocate(iter)) {
+ return -1;
+ }
+ return res;
}
+
/*
* Validate that operands have enough dimensions, accounting for
* possible flexible dimensions that may be absent.
@@ -2484,18 +2064,18 @@ _initialize_variable_parts(PyUFuncObject *ufunc,
}
static int
-PyUFunc_GeneralizedFunction(PyUFuncObject *ufunc,
- PyObject *args, PyObject *kwds,
- PyArrayObject **op)
+PyUFunc_GeneralizedFunctionInternal(PyUFuncObject *ufunc,
+ PyArrayMethodObject *ufuncimpl, PyArray_Descr *operation_descrs[],
+ PyArrayObject *op[], PyObject *extobj,
+ NPY_CASTING casting, NPY_ORDER order,
+ PyObject *axis, PyObject *axes, int keepdims)
{
int nin, nout;
int i, j, idim, nop;
const char *ufunc_name;
- int retval, subok = 1;
+ int retval;
int needs_api = 0;
- PyArray_Descr *dtypes[NPY_MAXARGS];
-
/* Use remapped axes for generalized ufunc */
int broadcast_ndim, iter_ndim;
int op_core_num_dims[NPY_MAXARGS];
@@ -2512,13 +2092,12 @@ PyUFunc_GeneralizedFunction(PyUFuncObject *ufunc,
/* These parameters come from extobj= or from a TLS global */
int buffersize = 0, errormask = 0;
- /* The selected inner loop */
- PyUFuncGenericFunction innerloop = NULL;
- void *innerloopdata = NULL;
/* The dimensions which get passed to the inner loop */
npy_intp inner_dimensions[NPY_MAXDIMS+1];
/* The strides which get passed to the inner loop */
npy_intp *inner_strides = NULL;
+ /* Auxiliary data allocated by the ufuncimpl (ArrayMethod) */
+ NpyAuxData *auxdata = NULL;
/* The sizes of the core dimensions (# entries is ufunc->core_num_dim_ix) */
npy_intp *core_dim_sizes = inner_dimensions + 1;
@@ -2526,22 +2105,6 @@ PyUFunc_GeneralizedFunction(PyUFuncObject *ufunc,
/* swapping around of axes */
int *remap_axis_memory = NULL;
int **remap_axis = NULL;
- /* The __array_prepare__ function to call for each output */
- PyObject *arr_prep[NPY_MAXARGS];
- /* The separated input and output arguments, parsed from args and kwds */
- ufunc_full_args full_args = {NULL, NULL};
-
- NPY_ORDER order = NPY_KEEPORDER;
- /* Use the default assignment casting rule */
- NPY_CASTING casting = NPY_DEFAULT_ASSIGN_CASTING;
- /* other possible keyword arguments */
- PyObject *extobj, *type_tup, *axes, *axis;
- int keepdims = -1;
-
- if (ufunc == NULL) {
- PyErr_SetString(PyExc_ValueError, "function not supported");
- return -1;
- }
nin = ufunc->nin;
nout = ufunc->nout;
@@ -2551,11 +2114,11 @@ PyUFunc_GeneralizedFunction(PyUFuncObject *ufunc,
NPY_UF_DBG_PRINT1("\nEvaluating ufunc %s\n", ufunc_name);
- /* Initialize all dtypes and __array_prepare__ call-backs to NULL */
- for (i = 0; i < nop; ++i) {
- dtypes[i] = NULL;
- arr_prep[i] = NULL;
+ if (validate_casting(ufuncimpl,
+ ufunc, op, operation_descrs, casting) < 0) {
+ return -1;
}
+
/* Initialize possibly variable parts to the values from the ufunc */
retval = _initialize_variable_parts(ufunc, op_core_num_dims,
core_dim_sizes, core_dim_flags);
@@ -2563,18 +2126,6 @@ PyUFunc_GeneralizedFunction(PyUFuncObject *ufunc,
goto fail;
}
- NPY_UF_DBG_PRINT("Getting arguments\n");
-
- /*
- * Get all the arguments.
- */
- retval = get_ufunc_arguments(ufunc, args, kwds,
- op, &order, &casting, &extobj,
- &type_tup, &subok, NULL, &axes, &axis, &keepdims);
- if (retval < 0) {
- NPY_UF_DBG_PRINT("Failure in getting arguments\n");
- return retval;
- }
/*
* If keepdims was passed in (and thus changed from the initial value
* on top), check the gufunc is suitable, i.e., that its inputs share
@@ -2634,6 +2185,8 @@ PyUFunc_GeneralizedFunction(PyUFuncObject *ufunc,
/* Possibly remap axes. */
if (axes != NULL || axis != NULL) {
+ assert(!(axes != NULL && axis != NULL));
+
remap_axis = PyArray_malloc(sizeof(remap_axis[0]) * nop);
remap_axis_memory = PyArray_malloc(sizeof(remap_axis_memory[0]) *
nop * NPY_MAXDIMS);
@@ -2771,12 +2324,6 @@ PyUFunc_GeneralizedFunction(PyUFuncObject *ufunc,
NPY_UF_DBG_PRINT("Finding inner loop\n");
-
- retval = ufunc->type_resolver(ufunc, casting,
- op, type_tup, dtypes);
- if (retval < 0) {
- goto fail;
- }
/*
* We don't write to all elements, and the iterator may make
* UPDATEIFCOPY temporary copies. The output arrays (unless they are
@@ -2789,49 +2336,11 @@ PyUFunc_GeneralizedFunction(PyUFuncObject *ufunc,
NPY_ITER_WRITEONLY |
NPY_UFUNC_DEFAULT_OUTPUT_FLAGS,
op_flags);
- /* For the generalized ufunc, we get the loop right away too */
- retval = ufunc->legacy_inner_loop_selector(ufunc, dtypes,
- &innerloop, &innerloopdata, &needs_api);
- if (retval < 0) {
- goto fail;
- }
-
-#if NPY_UF_DBG_TRACING
- printf("input types:\n");
- for (i = 0; i < nin; ++i) {
- PyObject_Print((PyObject *)dtypes[i], stdout, 0);
- printf(" ");
- }
- printf("\noutput types:\n");
- for (i = nin; i < nop; ++i) {
- PyObject_Print((PyObject *)dtypes[i], stdout, 0);
- printf(" ");
- }
- printf("\n");
-#endif
-
- if (subok) {
- if (make_full_arg_tuple(&full_args, nin, nout, args, kwds) < 0) {
- goto fail;
- }
-
- /*
- * Get the appropriate __array_prepare__ function to call
- * for each output
- */
- _find_array_prepare(full_args, arr_prep, nin, nout);
- }
-
- /* If the loop wants the arrays, provide them */
- if (_does_loop_use_arrays(innerloopdata)) {
- innerloopdata = (void*)op;
- }
/*
* Set up the iterator per-op flags. For generalized ufuncs, we
* can't do buffering, so must COPY or UPDATEIFCOPY.
*/
-
iter_flags = ufunc->iter_flags |
NPY_ITER_MULTI_INDEX |
NPY_ITER_REFS_OK |
@@ -2841,7 +2350,7 @@ PyUFunc_GeneralizedFunction(PyUFuncObject *ufunc,
/* Create the iterator */
iter = NpyIter_AdvancedNew(nop, op, iter_flags,
order, NPY_UNSAFE_CASTING, op_flags,
- dtypes, iter_ndim,
+ operation_descrs, iter_ndim,
op_axes, iter_shape, 0);
if (iter == NULL) {
retval = -1;
@@ -2851,7 +2360,7 @@ PyUFunc_GeneralizedFunction(PyUFuncObject *ufunc,
/* Fill in any allocated outputs */
{
PyArrayObject **operands = NpyIter_GetOperandArray(iter);
- for (i = 0; i < nop; ++i) {
+ for (i = nin; i < nop; ++i) {
if (op[i] == NULL) {
op[i] = operands[i];
Py_INCREF(op[i]);
@@ -2940,21 +2449,34 @@ PyUFunc_GeneralizedFunction(PyUFuncObject *ufunc,
/*
* The first nop strides are for the inner loop (but only can
- * copy them after removing the core axes)
+ * copy them after removing the core axes). The strides will not change
+ * if the iterator is not buffered (they are effectively fixed).
+ * Supporting buffering would make sense, but probably would have to be
+ * done in the inner-loop itself (not the iterator).
*/
+ assert(!NpyIter_IsBuffered(iter));
memcpy(inner_strides, NpyIter_GetInnerStrideArray(iter),
NPY_SIZEOF_INTP * nop);
-#if 0
- printf("strides: ");
- for (i = 0; i < nop+core_dim_ixs_size; ++i) {
- printf("%d ", (int)inner_strides[i]);
+ /* Final preparation of the arraymethod call */
+ PyArrayMethod_Context context = {
+ .caller = (PyObject *)ufunc,
+ .method = ufuncimpl,
+ .descriptors = operation_descrs,
+ };
+ PyArrayMethod_StridedLoop *strided_loop;
+ NPY_ARRAYMETHOD_FLAGS flags = 0;
+
+ if (ufuncimpl->get_strided_loop(&context, 1, 0, inner_strides,
+ &strided_loop, &auxdata, &flags) < 0) {
+ goto fail;
+ }
+ needs_api = (flags & NPY_METH_REQUIRES_PYAPI) != 0;
+ needs_api |= NpyIter_IterationNeedsAPI(iter);
+ if (!(flags & NPY_METH_NO_FLOATINGPOINT_ERRORS)) {
+ /* Start with the floating-point exception flags cleared */
+ npy_clear_floatstatus_barrier((char*)&iter);
}
- printf("\n");
-#endif
-
- /* Start with the floating-point exception flags cleared */
- npy_clear_floatstatus_barrier((char*)&iter);
NPY_UF_DBG_PRINT("Executing inner loop\n");
@@ -2974,70 +2496,31 @@ PyUFunc_GeneralizedFunction(PyUFuncObject *ufunc,
dataptr = NpyIter_GetDataPtrArray(iter);
count_ptr = NpyIter_GetInnerLoopSizePtr(iter);
- if (!needs_api && !NpyIter_IterationNeedsAPI(iter)) {
+ if (!needs_api) {
NPY_BEGIN_THREADS_THRESHOLDED(total_problem_size);
}
do {
inner_dimensions[0] = *count_ptr;
- innerloop(dataptr, inner_dimensions, inner_strides, innerloopdata);
- } while (iternext(iter));
+ retval = strided_loop(&context,
+ dataptr, inner_dimensions, inner_strides, auxdata);
+ } while (retval == 0 && iternext(iter));
if (!needs_api && !NpyIter_IterationNeedsAPI(iter)) {
NPY_END_THREADS;
}
- } else {
- /**
- * For each output operand, check if it has non-zero size,
- * and assign the identity if it does. For example, a dot
- * product of two zero-length arrays will be a scalar,
- * which has size one.
- */
- npy_bool reorderable;
- PyObject *identity = _get_identity(ufunc, &reorderable);
- if (identity == NULL) {
- retval = -1;
- goto fail;
- }
-
- for (i = nin; i < nop; ++i) {
- if (PyArray_SIZE(op[i]) != 0) {
- if (identity == Py_None) {
- PyErr_Format(PyExc_ValueError,
- "ufunc %s ",
- ufunc_name);
- Py_DECREF(identity);
- retval = -1;
- goto fail;
- }
- PyArray_FillWithScalar(op[i], identity);
- }
- }
- Py_DECREF(identity);
}
- /* Check whether any errors occurred during the loop */
- if (PyErr_Occurred() ||
- _check_ufunc_fperr(errormask, extobj, ufunc_name) < 0) {
- retval = -1;
- goto fail;
+ if (retval == 0 && !(flags & NPY_METH_NO_FLOATINGPOINT_ERRORS)) {
+ /* NOTE: We could check float errors even when `res < 0` */
+ retval = _check_ufunc_fperr(errormask, extobj, ufunc_name);
}
PyArray_free(inner_strides);
+ NPY_AUXDATA_FREE(auxdata);
if (NpyIter_Deallocate(iter) < 0) {
retval = -1;
}
- /* The caller takes ownership of all the references in op */
- for (i = 0; i < nop; ++i) {
- Py_XDECREF(dtypes[i]);
- Py_XDECREF(arr_prep[i]);
- }
- Py_XDECREF(type_tup);
- Py_XDECREF(extobj);
- Py_XDECREF(axes);
- Py_XDECREF(axis);
- Py_XDECREF(full_args.in);
- Py_XDECREF(full_args.out);
PyArray_free(remap_axis_memory);
PyArray_free(remap_axis);
@@ -3048,110 +2531,37 @@ PyUFunc_GeneralizedFunction(PyUFuncObject *ufunc,
fail:
NPY_UF_DBG_PRINT1("Returning failure code %d\n", retval);
PyArray_free(inner_strides);
+ NPY_AUXDATA_FREE(auxdata);
NpyIter_Deallocate(iter);
- for (i = 0; i < nop; ++i) {
- Py_XDECREF(op[i]);
- op[i] = NULL;
- Py_XDECREF(dtypes[i]);
- Py_XDECREF(arr_prep[i]);
- }
- Py_XDECREF(type_tup);
- Py_XDECREF(extobj);
- Py_XDECREF(axes);
- Py_XDECREF(axis);
- Py_XDECREF(full_args.in);
- Py_XDECREF(full_args.out);
PyArray_free(remap_axis_memory);
PyArray_free(remap_axis);
return retval;
}
-/*
- * This generic function is called with the ufunc object, the arguments to it,
- * and an array of (pointers to) PyArrayObjects which are NULL.
- *
- * 'op' is an array of at least NPY_MAXARGS PyArrayObject *.
- */
+
static int
-PyUFunc_GenericFunction_int(PyUFuncObject *ufunc,
- PyObject *args, PyObject *kwds, PyArrayObject **op)
+PyUFunc_GenericFunctionInternal(PyUFuncObject *ufunc,
+ PyArrayMethodObject *ufuncimpl, PyArray_Descr *operation_descrs[],
+ PyArrayObject *op[], PyObject *extobj,
+ NPY_CASTING casting, NPY_ORDER order,
+ PyObject *output_array_prepare[], ufunc_full_args full_args,
+ PyArrayObject *wheremask)
{
- int nin, nout;
- int i, nop;
- const char *ufunc_name;
- int retval = -1, subok = 1;
- npy_uint32 op_flags[NPY_MAXARGS];
- npy_intp default_op_out_flags;
+ int nin = ufunc->nin, nout = ufunc->nout, nop = nin + nout;
- PyArray_Descr *dtypes[NPY_MAXARGS];
+ const char *ufunc_name = ufunc_get_name_cstr(ufunc);
+
+ npy_intp default_op_out_flags;
+ npy_uint32 op_flags[NPY_MAXARGS];
/* These parameters come from extobj= or from a TLS global */
int buffersize = 0, errormask = 0;
- /* The mask provided in the 'where=' parameter */
- PyArrayObject *wheremask = NULL;
-
- /* The __array_prepare__ function to call for each output */
- PyObject *arr_prep[NPY_MAXARGS];
- /*
- * This is either args, or args with the out= parameter from
- * kwds added appropriately.
- */
- ufunc_full_args full_args = {NULL, NULL};
-
- int trivial_loop_ok = 0;
-
- NPY_ORDER order = NPY_KEEPORDER;
- /* Use the default assignment casting rule */
- NPY_CASTING casting = NPY_DEFAULT_ASSIGN_CASTING;
- PyObject *extobj, *type_tup;
-
- if (ufunc == NULL) {
- PyErr_SetString(PyExc_ValueError, "function not supported");
- return -1;
- }
-
- if (ufunc->core_enabled) {
- return PyUFunc_GeneralizedFunction(ufunc, args, kwds, op);
- }
-
- nin = ufunc->nin;
- nout = ufunc->nout;
- nop = nin + nout;
-
- ufunc_name = ufunc_get_name_cstr(ufunc);
-
NPY_UF_DBG_PRINT1("\nEvaluating ufunc %s\n", ufunc_name);
- /* Initialize all the dtypes and __array_prepare__ callbacks to NULL */
- for (i = 0; i < nop; ++i) {
- dtypes[i] = NULL;
- arr_prep[i] = NULL;
- }
-
- NPY_UF_DBG_PRINT("Getting arguments\n");
-
- /* Get all the arguments */
- retval = get_ufunc_arguments(ufunc, args, kwds,
- op, &order, &casting, &extobj,
- &type_tup, &subok, &wheremask, NULL, NULL, NULL);
- if (retval < 0) {
- NPY_UF_DBG_PRINT("Failure in getting arguments\n");
- return retval;
- }
-
/* Get the buffersize and errormask */
if (_get_bufsize_errmask(extobj, ufunc_name, &buffersize, &errormask) < 0) {
- retval = -1;
- goto fail;
- }
-
- NPY_UF_DBG_PRINT("Finding inner loop\n");
-
- retval = ufunc->type_resolver(ufunc, casting,
- op, type_tup, dtypes);
- if (retval < 0) {
- goto fail;
+ return -1;
}
if (wheremask != NULL) {
@@ -3170,35 +2580,16 @@ PyUFunc_GenericFunction_int(PyUFuncObject *ufunc,
default_op_out_flags, op_flags);
}
-#if NPY_UF_DBG_TRACING
- printf("input types:\n");
- for (i = 0; i < nin; ++i) {
- PyObject_Print((PyObject *)dtypes[i], stdout, 0);
- printf(" ");
- }
- printf("\noutput types:\n");
- for (i = nin; i < nop; ++i) {
- PyObject_Print((PyObject *)dtypes[i], stdout, 0);
- printf(" ");
- }
- printf("\n");
-#endif
-
- if (subok) {
- if (make_full_arg_tuple(&full_args, nin, nout, args, kwds) < 0) {
- goto fail;
- }
- /*
- * Get the appropriate __array_prepare__ function to call
- * for each output
- */
- _find_array_prepare(full_args, arr_prep, nin, nout);
- }
-
+ /* Final preparation of the arraymethod call */
+ PyArrayMethod_Context context = {
+ .caller = (PyObject *)ufunc,
+ .method = ufuncimpl,
+ .descriptors = operation_descrs,
+ };
/* Do the ufunc loop */
if (wheremask != NULL) {
- NPY_UF_DBG_PRINT("Executing fancy inner loop\n");
+ NPY_UF_DBG_PRINT("Executing masked inner loop\n");
if (nop + 1 > NPY_MAXARGS) {
PyErr_SetString(PyExc_ValueError,
@@ -3206,102 +2597,56 @@ PyUFunc_GenericFunction_int(PyUFuncObject *ufunc,
return -1;
}
op[nop] = wheremask;
- dtypes[nop] = NULL;
-
- /* Set up the flags */
+ operation_descrs[nop] = NULL;
- npy_clear_floatstatus_barrier((char*)&ufunc);
- retval = execute_fancy_ufunc_loop(ufunc, wheremask,
- op, dtypes, order,
- buffersize, arr_prep, full_args, op_flags);
+ return execute_ufunc_loop(&context, 1,
+ op, order, buffersize, casting,
+ output_array_prepare, full_args, op_flags,
+ errormask, extobj);
}
else {
- NPY_UF_DBG_PRINT("Executing legacy inner loop\n");
+ NPY_UF_DBG_PRINT("Executing normal inner loop\n");
/*
* This checks whether a trivial loop is ok, making copies of
- * scalar and one dimensional operands if that will help.
- * Since it requires dtypes, it can only be called after
- * ufunc->type_resolver
+ * scalar and one dimensional operands if that should help.
*/
- trivial_loop_ok = check_for_trivial_loop(ufunc, op, dtypes, buffersize);
- if (trivial_loop_ok < 0) {
- goto fail;
+ int trivial_ok = check_for_trivial_loop(ufuncimpl,
+ op, operation_descrs, casting, buffersize);
+ if (trivial_ok < 0) {
+ return -1;
+ }
+ if (trivial_ok && context.method->nout == 1) {
+ /* Try to handle everything without using the (heavy) iterator */
+ int retval = try_trivial_single_output_loop(&context,
+ op, order, output_array_prepare, full_args,
+ errormask, extobj);
+ if (retval != -2) {
+ return retval;
+ }
}
- /* check_for_trivial_loop on half-floats can overflow */
- npy_clear_floatstatus_barrier((char*)&ufunc);
-
- retval = execute_legacy_ufunc_loop(ufunc, trivial_loop_ok,
- op, dtypes, order,
- buffersize, arr_prep, full_args, op_flags);
- }
- if (retval < 0) {
- goto fail;
- }
-
- /*
- * Check whether any errors occurred during the loop. The loops should
- * indicate this in retval, but since the inner-loop currently does not
- * report errors, this does not happen in all branches (at this time).
- */
- if (PyErr_Occurred() ||
- _check_ufunc_fperr(errormask, extobj, ufunc_name) < 0) {
- retval = -1;
- goto fail;
- }
-
-
- /* The caller takes ownership of all the references in op */
- for (i = 0; i < nop; ++i) {
- Py_XDECREF(dtypes[i]);
- Py_XDECREF(arr_prep[i]);
+ return execute_ufunc_loop(&context, 0,
+ op, order, buffersize, casting,
+ output_array_prepare, full_args, op_flags,
+ errormask, extobj);
}
- Py_XDECREF(type_tup);
- Py_XDECREF(extobj);
- Py_XDECREF(full_args.in);
- Py_XDECREF(full_args.out);
- Py_XDECREF(wheremask);
-
- NPY_UF_DBG_PRINT("Returning success code 0\n");
-
- return 0;
-
-fail:
- NPY_UF_DBG_PRINT1("Returning failure code %d\n", retval);
- for (i = 0; i < nop; ++i) {
- Py_XDECREF(op[i]);
- op[i] = NULL;
- Py_XDECREF(dtypes[i]);
- Py_XDECREF(arr_prep[i]);
- }
- Py_XDECREF(type_tup);
- Py_XDECREF(extobj);
- Py_XDECREF(full_args.in);
- Py_XDECREF(full_args.out);
- Py_XDECREF(wheremask);
-
- return retval;
}
/*UFUNC_API*/
NPY_NO_EXPORT int
-PyUFunc_GenericFunction(PyUFuncObject *ufunc,
- PyObject *args, PyObject *kwds, PyArrayObject **op)
+PyUFunc_GenericFunction(PyUFuncObject *NPY_UNUSED(ufunc),
+ PyObject *NPY_UNUSED(args), PyObject *NPY_UNUSED(kwds),
+ PyArrayObject **NPY_UNUSED(op))
{
- /* NumPy 1.19, 2020-01-24 */
- if (DEPRECATE(
- "PyUFunc_GenericFunction() C-API function is deprecated "
- "and expected to be removed rapidly. If you are using it (i.e. see "
- "this warning/error), please notify the NumPy developers. "
- "As of now it is expected that any use case is served better by "
- "the direct use of `PyObject_Call(ufunc, args, kwargs)`. "
- "PyUFunc_GenericFunction function has slightly different "
- "untested behaviour.") < 0) {
- return -1;
- }
- return PyUFunc_GenericFunction_int(ufunc, args, kwds, op);
+ /* NumPy 1.21, 2020-03-29 */
+ PyErr_SetString(PyExc_RuntimeError,
+ "The `PyUFunc_GenericFunction()` C-API function has been disabled. "
+ "Please use `PyObject_Call(ufunc, args, kwargs)`, which has "
+ "identical behaviour but allows subclass and `__array_ufunc__` "
+ "override handling and only returns the normal ufunc result.");
+ return -1;
}
@@ -3520,6 +2865,10 @@ reduce_loop(NpyIter *iter, char **dataptrs, npy_intp const *strides,
innerloop(dataptrs_copy, &count,
strides_copy, innerloopdata);
+ if (needs_api && PyErr_Occurred()) {
+ goto finish_loop;
+ }
+
/* Jump to the faster loop when skipping is done */
if (skip_first_count == 0) {
if (iternext(iter)) {
@@ -3531,6 +2880,11 @@ reduce_loop(NpyIter *iter, char **dataptrs, npy_intp const *strides,
}
} while (iternext(iter));
}
+
+ if (needs_api && PyErr_Occurred()) {
+ goto finish_loop;
+ }
+
do {
/* Turn the two items into three for the inner loop */
dataptrs_copy[0] = dataptrs[0];
@@ -3569,7 +2923,7 @@ reduce_loop(NpyIter *iter, char **dataptrs, npy_intp const *strides,
n = 1;
}
}
- } while (iternext(iter));
+ } while (!(needs_api && PyErr_Occurred()) && iternext(iter));
finish_loop:
NPY_END_THREADS;
@@ -3608,13 +2962,9 @@ PyUFunc_Reduce(PyUFuncObject *ufunc, PyArrayObject *arr, PyArrayObject *out,
const char *ufunc_name = ufunc_get_name_cstr(ufunc);
/* These parameters come from a TLS global */
int buffersize = 0, errormask = 0;
- static PyObject *NoValue = NULL;
NPY_UF_DBG_PRINT1("\nEvaluating ufunc %s.reduce\n", ufunc_name);
- npy_cache_import("numpy", "_NoValue", &NoValue);
- if (NoValue == NULL) return NULL;
-
ndim = PyArray_NDIM(arr);
/* Create an array of flags for reduction */
@@ -3640,7 +2990,7 @@ PyUFunc_Reduce(PyUFuncObject *ufunc, PyArrayObject *arr, PyArrayObject *out,
}
/* Get the initial value */
- if (initial == NULL || initial == NoValue) {
+ if (initial == NULL) {
initial = identity;
/*
@@ -3689,7 +3039,7 @@ PyUFunc_Accumulate(PyUFuncObject *ufunc, PyArrayObject *arr, PyArrayObject *out,
int idim, ndim, otype_final;
int needs_api, need_outer_iterator;
- NpyIter *iter = NULL, *iter_inner = NULL;
+ NpyIter *iter = NULL;
/* The selected inner loop */
PyUFuncGenericFunction innerloop = NULL;
@@ -3882,6 +3232,7 @@ PyUFunc_Accumulate(PyUFuncObject *ufunc, PyArrayObject *arr, PyArrayObject *out,
goto fail;
}
dataptr = NpyIter_GetDataPtrArray(iter);
+ needs_api = NpyIter_IterationNeedsAPI(iter);
/* Execute the loop with just the outer iterator */
@@ -3932,7 +3283,7 @@ PyUFunc_Accumulate(PyUFuncObject *ufunc, PyArrayObject *arr, PyArrayObject *out,
innerloop(dataptr_copy, &count_m1,
stride_copy, innerloopdata);
}
- } while (iternext(iter));
+ } while (!(needs_api && PyErr_Occurred()) && iternext(iter));
NPY_END_THREADS;
}
@@ -4014,9 +3365,6 @@ finish:
if (!NpyIter_Deallocate(iter)) {
res = -1;
}
- if (!NpyIter_Deallocate(iter_inner)) {
- res = -1;
- }
if (res < 0) {
Py_DECREF(out);
return NULL;
@@ -4029,7 +3377,6 @@ fail:
Py_XDECREF(op_dtypes[0]);
NpyIter_Deallocate(iter);
- NpyIter_Deallocate(iter_inner);
return NULL;
}
@@ -4263,6 +3610,7 @@ PyUFunc_Reduceat(PyUFuncObject *ufunc, PyArrayObject *arr, PyArrayObject *ind,
npy_intp stride0_ind = PyArray_STRIDE(op[0], axis);
int itemsize = op_dtypes[0]->elsize;
+ int needs_api = NpyIter_IterationNeedsAPI(iter);
/* Get the variables needed for the loop */
iternext = NpyIter_GetIterNext(iter, NULL);
@@ -4327,7 +3675,7 @@ PyUFunc_Reduceat(PyUFuncObject *ufunc, PyArrayObject *arr, PyArrayObject *ind,
stride_copy, innerloopdata);
}
}
- } while (iternext(iter));
+ } while (!(needs_api && PyErr_Occurred()) && iternext(iter));
NPY_END_THREADS;
}
@@ -4417,32 +3765,105 @@ fail:
}
+static npy_bool
+tuple_all_none(PyObject *tup) {
+ npy_intp i;
+ for (i = 0; i < PyTuple_GET_SIZE(tup); ++i) {
+ if (PyTuple_GET_ITEM(tup, i) != Py_None) {
+ return NPY_FALSE;
+ }
+ }
+ return NPY_TRUE;
+}
+
+
+static int
+_set_full_args_out(int nout, PyObject *out_obj, ufunc_full_args *full_args)
+{
+ if (PyTuple_CheckExact(out_obj)) {
+ if (PyTuple_GET_SIZE(out_obj) != nout) {
+ PyErr_SetString(PyExc_ValueError,
+ "The 'out' tuple must have exactly "
+ "one entry per ufunc output");
+ return -1;
+ }
+ if (tuple_all_none(out_obj)) {
+ return 0;
+ }
+ else {
+ Py_INCREF(out_obj);
+ full_args->out = out_obj;
+ }
+ }
+ else if (nout == 1) {
+ if (out_obj == Py_None) {
+ return 0;
+ }
+ /* Can be an array if it only has one output */
+ full_args->out = PyTuple_Pack(1, out_obj);
+ if (full_args->out == NULL) {
+ return -1;
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ nout > 1 ? "'out' must be a tuple of arrays" :
+ "'out' must be an array or a tuple with "
+ "a single array");
+ return -1;
+ }
+ return 0;
+}
+
+
+/*
+ * Convert function which replaces np._NoValue with NULL.
+ * As a converter returns 0 on error and 1 on success.
+ */
+static int
+_not_NoValue(PyObject *obj, PyObject **out)
+{
+ static PyObject *NoValue = NULL;
+ npy_cache_import("numpy", "_NoValue", &NoValue);
+ if (NoValue == NULL) {
+ return 0;
+ }
+ if (obj == NoValue) {
+ *out = NULL;
+ }
+ else {
+ *out = obj;
+ }
+ return 1;
+}
+
+
+/* forward declaration */
+static PyArray_DTypeMeta * _get_dtype(PyObject *dtype_obj);
+
/*
* This code handles reduce, reduceat, and accumulate
* (accumulate and reduce are special cases of the more general reduceat
* but they are handled separately for speed)
*/
static PyObject *
-PyUFunc_GenericReduction(PyUFuncObject *ufunc, PyObject *args,
- PyObject *kwds, int operation)
+PyUFunc_GenericReduction(PyUFuncObject *ufunc,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames, int operation)
{
int i, naxes=0, ndim;
int axes[NPY_MAXDIMS];
- PyObject *axes_in = NULL;
+
+ ufunc_full_args full_args = {NULL, NULL};
+ PyObject *axes_obj = NULL;
PyArrayObject *mp = NULL, *wheremask = NULL, *ret = NULL;
- PyObject *op;
- PyObject *obj_ind;
+ PyObject *op = NULL;
PyArrayObject *indices = NULL;
PyArray_Descr *otype = NULL;
PyArrayObject *out = NULL;
int keepdims = 0;
PyObject *initial = NULL;
- static char *reduce_kwlist[] = {
- "array", "axis", "dtype", "out", "keepdims", "initial", "where", NULL};
- static char *accumulate_kwlist[] = {
- "array", "axis", "dtype", "out", NULL};
- static char *reduceat_kwlist[] = {
- "array", "indices", "axis", "dtype", "out", NULL};
+ npy_bool out_is_passed_by_position;
+
static char *_reduce_type[] = {"reduce", "accumulate", "reduceat", NULL};
@@ -4468,62 +3889,137 @@ PyUFunc_GenericReduction(PyUFuncObject *ufunc, PyObject *args,
_reduce_type[operation]);
return NULL;
}
- /* if there is a tuple of 1 for `out` in kwds, unpack it */
- if (kwds != NULL) {
- PyObject *out_obj = PyDict_GetItemWithError(kwds, npy_um_str_out);
- if (out_obj == NULL && PyErr_Occurred()){
- return NULL;
- }
- else if (out_obj != NULL && PyTuple_CheckExact(out_obj)) {
- if (PyTuple_GET_SIZE(out_obj) != 1) {
- PyErr_SetString(PyExc_ValueError,
- "The 'out' tuple must have exactly one entry");
- return NULL;
- }
- out_obj = PyTuple_GET_ITEM(out_obj, 0);
- PyDict_SetItem(kwds, npy_um_str_out, out_obj);
- }
- }
+ /*
+ * Perform argument parsing, but start by only extracting. This is
+ * just to preserve the behaviour that __array_ufunc__ did not perform
+ * any checks on arguments, and we could change this or change it for
+ * certain parameters.
+ */
+ PyObject *otype_obj = NULL, *out_obj = NULL, *indices_obj = NULL;
+ PyObject *keepdims_obj = NULL, *wheremask_obj = NULL;
if (operation == UFUNC_REDUCEAT) {
- PyArray_Descr *indtype;
- indtype = PyArray_DescrFromType(NPY_INTP);
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "OO|OO&O&:reduceat", reduceat_kwlist,
- &op,
- &obj_ind,
- &axes_in,
- PyArray_DescrConverter2, &otype,
- PyArray_OutputConverter, &out)) {
+ NPY_PREPARE_ARGPARSER;
+
+ if (npy_parse_arguments("reduceat", args, len_args, kwnames,
+ "array", NULL, &op,
+ "indices", NULL, &indices_obj,
+ "|axis", NULL, &axes_obj,
+ "|dtype", NULL, &otype_obj,
+ "|out", NULL, &out_obj,
+ NULL, NULL, NULL) < 0) {
goto fail;
}
- indices = (PyArrayObject *)PyArray_FromAny(obj_ind, indtype,
- 1, 1, NPY_ARRAY_CARRAY, NULL);
- if (indices == NULL) {
+ /* Prepare inputs for PyUfunc_CheckOverride */
+ full_args.in = PyTuple_Pack(2, op, indices_obj);
+ if (full_args.in == NULL) {
goto fail;
}
+ out_is_passed_by_position = len_args >= 5;
}
else if (operation == UFUNC_ACCUMULATE) {
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OO&O&:accumulate",
- accumulate_kwlist,
- &op,
- &axes_in,
- PyArray_DescrConverter2, &otype,
- PyArray_OutputConverter, &out)) {
+ NPY_PREPARE_ARGPARSER;
+
+ if (npy_parse_arguments("accumulate", args, len_args, kwnames,
+ "array", NULL, &op,
+ "|axis", NULL, &axes_obj,
+ "|dtype", NULL, &otype_obj,
+ "|out", NULL, &out_obj,
+ NULL, NULL, NULL) < 0) {
+ goto fail;
+ }
+ /* Prepare input for PyUfunc_CheckOverride */
+ full_args.in = PyTuple_Pack(1, op);
+ if (full_args.in == NULL) {
goto fail;
}
+ out_is_passed_by_position = len_args >= 4;
}
else {
- if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|OO&O&iOO&:reduce",
- reduce_kwlist,
- &op,
- &axes_in,
- PyArray_DescrConverter2, &otype,
- PyArray_OutputConverter, &out,
- &keepdims, &initial,
- _wheremask_converter, &wheremask)) {
+ NPY_PREPARE_ARGPARSER;
+
+ if (npy_parse_arguments("reduce", args, len_args, kwnames,
+ "array", NULL, &op,
+ "|axis", NULL, &axes_obj,
+ "|dtype", NULL, &otype_obj,
+ "|out", NULL, &out_obj,
+ "|keepdims", NULL, &keepdims_obj,
+ "|initial", &_not_NoValue, &initial,
+ "|where", NULL, &wheremask_obj,
+ NULL, NULL, NULL) < 0) {
+ goto fail;
+ }
+ /* Prepare input for PyUfunc_CheckOverride */
+ full_args.in = PyTuple_Pack(1, op);
+ if (full_args.in == NULL) {
+ goto fail;
+ }
+ out_is_passed_by_position = len_args >= 4;
+ }
+
+ /* Normalize output for PyUFunc_CheckOverride and conversion. */
+ if (out_is_passed_by_position) {
+ /* in this branch, out is always wrapped in a tuple. */
+ if (out_obj != Py_None) {
+ full_args.out = PyTuple_Pack(1, out_obj);
+ if (full_args.out == NULL) {
+ goto fail;
+ }
+ }
+ }
+ else if (out_obj) {
+ if (_set_full_args_out(1, out_obj, &full_args) < 0) {
+ goto fail;
+ }
+ /* Ensure that out_obj is the array, not the tuple: */
+ if (full_args.out != NULL) {
+ out_obj = PyTuple_GET_ITEM(full_args.out, 0);
+ }
+ }
+
+ /* We now have all the information required to check for Overrides */
+ PyObject *override = NULL;
+ int errval = PyUFunc_CheckOverride(ufunc, _reduce_type[operation],
+ full_args.in, full_args.out, args, len_args, kwnames, &override);
+ if (errval) {
+ return NULL;
+ }
+ else if (override) {
+ Py_XDECREF(full_args.in);
+ Py_XDECREF(full_args.out);
+ return override;
+ }
+
+ /* Finish parsing of all parameters (no matter which reduce-like) */
+ if (indices_obj) {
+ PyArray_Descr *indtype = PyArray_DescrFromType(NPY_INTP);
+
+ indices = (PyArrayObject *)PyArray_FromAny(indices_obj,
+ indtype, 1, 1, NPY_ARRAY_CARRAY, NULL);
+ if (indices == NULL) {
+ goto fail;
+ }
+ }
+ if (otype_obj && otype_obj != Py_None) {
+ /* Use `_get_dtype` because `dtype` is a DType and not the instance */
+ PyArray_DTypeMeta *dtype = _get_dtype(otype_obj);
+ if (dtype == NULL) {
goto fail;
}
+ otype = dtype->singleton;
+ Py_INCREF(otype);
+ Py_DECREF(dtype);
+ }
+ if (out_obj && !PyArray_OutputConverter(out_obj, &out)) {
+ goto fail;
+ }
+ if (keepdims_obj && !PyArray_PythonPyIntFromInt(keepdims_obj, &keepdims)) {
+ goto fail;
+ }
+ if (wheremask_obj && !_wheremask_converter(wheremask_obj, &wheremask)) {
+ goto fail;
}
+
/* Ensure input is an array */
mp = (PyArrayObject *)PyArray_FromAny(op, NULL, 0, 0, 0, NULL);
if (mp == NULL) {
@@ -4542,7 +4038,7 @@ PyUFunc_GenericReduction(PyUFuncObject *ufunc, PyObject *args,
}
/* Convert the 'axis' parameter into a list of axes */
- if (axes_in == NULL) {
+ if (axes_obj == NULL) {
/* apply defaults */
if (ndim == 0) {
naxes = 0;
@@ -4552,22 +4048,22 @@ PyUFunc_GenericReduction(PyUFuncObject *ufunc, PyObject *args,
axes[0] = 0;
}
}
- else if (axes_in == Py_None) {
+ else if (axes_obj == Py_None) {
/* Convert 'None' into all the axes */
naxes = ndim;
for (i = 0; i < naxes; ++i) {
axes[i] = i;
}
}
- else if (PyTuple_Check(axes_in)) {
- naxes = PyTuple_Size(axes_in);
+ else if (PyTuple_Check(axes_obj)) {
+ naxes = PyTuple_Size(axes_obj);
if (naxes < 0 || naxes > NPY_MAXDIMS) {
PyErr_SetString(PyExc_ValueError,
"too many values for 'axis'");
goto fail;
}
for (i = 0; i < naxes; ++i) {
- PyObject *tmp = PyTuple_GET_ITEM(axes_in, i);
+ PyObject *tmp = PyTuple_GET_ITEM(axes_obj, i);
int axis = PyArray_PyIntAsInt(tmp);
if (error_converting(axis)) {
goto fail;
@@ -4580,7 +4076,7 @@ PyUFunc_GenericReduction(PyUFuncObject *ufunc, PyObject *args,
}
else {
/* Try to interpret axis as an integer */
- int axis = PyArray_PyIntAsInt(axes_in);
+ int axis = PyArray_PyIntAsInt(axes_obj);
/* TODO: PyNumber_Index would be good to use here */
if (error_converting(axis)) {
goto fail;
@@ -4617,8 +4113,8 @@ PyUFunc_GenericReduction(PyUFuncObject *ufunc, PyObject *args,
*/
int typenum = PyArray_TYPE(mp);
if ((PyTypeNum_ISBOOL(typenum) || PyTypeNum_ISINTEGER(typenum))
- && ((strcmp(ufunc->name,"add") == 0)
- || (strcmp(ufunc->name,"multiply") == 0))) {
+ && ((strcmp(ufunc->name, "add") == 0)
+ || (strcmp(ufunc->name, "multiply") == 0))) {
if (PyTypeNum_ISBOOL(typenum)) {
typenum = NPY_LONG;
}
@@ -4664,13 +4160,15 @@ PyUFunc_GenericReduction(PyUFuncObject *ufunc, PyObject *args,
"reduceat does not allow multiple axes");
goto fail;
}
- ret = (PyArrayObject *)PyUFunc_Reduceat(ufunc, mp, indices, out,
- axes[0], otype->type_num);
- Py_DECREF(indices);
+ ret = (PyArrayObject *)PyUFunc_Reduceat(ufunc,
+ mp, indices, out, axes[0], otype->type_num);
+ Py_SETREF(indices, NULL);
break;
}
Py_DECREF(mp);
Py_DECREF(otype);
+ Py_XDECREF(full_args.in);
+ Py_XDECREF(full_args.out);
if (ret == NULL) {
return NULL;
@@ -4706,110 +4204,805 @@ fail:
Py_XDECREF(otype);
Py_XDECREF(mp);
Py_XDECREF(wheremask);
+ Py_XDECREF(indices);
+ Py_XDECREF(full_args.in);
+ Py_XDECREF(full_args.out);
return NULL;
}
-static PyObject *
-ufunc_generic_call(PyUFuncObject *ufunc, PyObject *args, PyObject *kwds)
+/*
+ * Perform a basic check on `dtype`, `sig`, and `signature` since only one
+ * may be set. If `sig` is used, writes it into `out_signature` (which should
+ * be set to `signature_obj` so that following code only requires to handle
+ * `signature_obj`).
+ *
+ * Does NOT incref the output! This only copies the borrowed references
+ * gotten during the argument parsing.
+ *
+ * This function does not do any normalization of the input dtype tuples,
+ * this happens after the array-ufunc override check currently.
+ */
+static int
+_check_and_copy_sig_to_signature(
+ PyObject *sig_obj, PyObject *signature_obj, PyObject *dtype,
+ PyObject **out_signature)
{
- int i;
- PyArrayObject *mps[NPY_MAXARGS];
- PyObject *retobj[NPY_MAXARGS];
- PyObject *wraparr[NPY_MAXARGS];
- PyObject *override = NULL;
- ufunc_full_args full_args = {NULL, NULL};
- int errval;
+ *out_signature = NULL;
+ if (signature_obj != NULL) {
+ *out_signature = signature_obj;
+ }
- errval = PyUFunc_CheckOverride(ufunc, "__call__", args, kwds, &override);
- if (errval) {
- return NULL;
+ if (sig_obj != NULL) {
+ if (*out_signature != NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "cannot specify both 'sig' and 'signature'");
+ *out_signature = NULL;
+ return -1;
+ }
+ *out_signature = sig_obj;
}
- else if (override) {
- return override;
+
+ if (dtype != NULL) {
+ if (*out_signature != NULL) {
+ PyErr_SetString(PyExc_TypeError,
+ "cannot specify both 'signature' and 'dtype'");
+ return -1;
+ }
+ /* dtype needs to be converted, delay after the override check */
}
+ return 0;
+}
- errval = PyUFunc_GenericFunction_int(ufunc, args, kwds, mps);
- if (errval < 0) {
- return NULL;
+
+/*
+ * Note: This function currently lets DType classes pass, but in general
+ * the class (not the descriptor instance) is the preferred input, so the
+ * parsing should eventually be adapted to prefer classes and possible
+ * deprecated instances. (Users should not notice that much, since `np.float64`
+ * or "float64" usually denotes the DType class rather than the instance.)
+ */
+static PyArray_DTypeMeta *
+_get_dtype(PyObject *dtype_obj) {
+ if (PyObject_TypeCheck(dtype_obj, &PyArrayDTypeMeta_Type)) {
+ Py_INCREF(dtype_obj);
+ return (PyArray_DTypeMeta *)dtype_obj;
+ }
+ else {
+ PyArray_Descr *descr = NULL;
+ if (!PyArray_DescrConverter(dtype_obj, &descr)) {
+ return NULL;
+ }
+ PyArray_DTypeMeta *out = NPY_DTYPE(descr);
+ if (NPY_UNLIKELY(!NPY_DT_is_legacy(out))) {
+ /* TODO: this path was unreachable when added. */
+ PyErr_SetString(PyExc_TypeError,
+ "Cannot pass a new user DType instance to the `dtype` or "
+ "`signature` arguments of ufuncs. Pass the DType class "
+ "instead.");
+ Py_DECREF(descr);
+ return NULL;
+ }
+ else if (NPY_UNLIKELY(out->singleton != descr)) {
+ /* This does not warn about `metadata`, but units is important. */
+ if (!PyArray_EquivTypes(out->singleton, descr)) {
+ PyErr_Format(PyExc_TypeError,
+ "The `dtype` and `signature` arguments to "
+ "ufuncs only select the general DType and not details "
+ "such as the byte order or time unit (with rare "
+ "exceptions see release notes). To avoid this warning "
+ "please use the scalar types `np.float64`, or string "
+ "notation.\n"
+ "In rare cases where the time unit was preserved, "
+ "either cast the inputs or provide an output array. "
+ "In the future NumPy may transition to allow providing "
+ "`dtype=` to denote the outputs `dtype` as well");
+ Py_DECREF(descr);
+ return NULL;
+ }
+ }
+ Py_INCREF(out);
+ Py_DECREF(descr);
+ return out;
}
+}
- /* Free the input references */
- for (i = 0; i < ufunc->nin; i++) {
- Py_XDECREF(mps[i]);
+
+/*
+ * Finish conversion parsing of the DType signature. NumPy always only
+ * honored the type number for passed in descriptors/dtypes.
+ * The `dtype` argument is interpreted as the first output DType (not
+ * descriptor).
+ * Unlike the dtype of an `out` array, it influences loop selection!
+ *
+ * It is the callers responsibility to clean `signature` and NULL it before
+ * calling.
+ */
+static int
+_get_fixed_signature(PyUFuncObject *ufunc,
+ PyObject *dtype_obj, PyObject *signature_obj,
+ PyArray_DTypeMeta **signature)
+{
+ if (dtype_obj == NULL && signature_obj == NULL) {
+ return 0;
}
- /*
- * Use __array_wrap__ on all outputs
- * if present on one of the input arguments.
- * If present for multiple inputs:
- * use __array_wrap__ of input object with largest
- * __array_priority__ (default = 0.0)
- *
- * Exception: we should not wrap outputs for items already
- * passed in as output-arguments. These items should either
- * be left unwrapped or wrapped by calling their own __array_wrap__
- * routine.
- *
- * For each output argument, wrap will be either
- * NULL --- call PyArray_Return() -- default if no output arguments given
- * None --- array-object passed in don't call PyArray_Return
- * method --- the __array_wrap__ method to call.
- */
- if (make_full_arg_tuple(&full_args, ufunc->nin, ufunc->nout, args, kwds) < 0) {
- goto fail;
+ int nin = ufunc->nin, nout = ufunc->nout, nop = nin + nout;
+
+ if (dtype_obj != NULL) {
+ if (dtype_obj == Py_None) {
+ /* If `dtype=None` is passed, no need to do anything */
+ return 0;
+ }
+ if (nout == 0) {
+ /* This may be allowed (NumPy does not do this)? */
+ PyErr_SetString(PyExc_TypeError,
+ "Cannot provide `dtype` when a ufunc has no outputs");
+ return -1;
+ }
+ PyArray_DTypeMeta *dtype = _get_dtype(dtype_obj);
+ if (dtype == NULL) {
+ return -1;
+ }
+ for (int i = nin; i < nop; i++) {
+ Py_INCREF(dtype);
+ signature[i] = dtype;
+ }
+ Py_DECREF(dtype);
+ return 0;
}
- if (_find_array_wrap(full_args, kwds, wraparr, ufunc->nin, ufunc->nout) < 0) {
- goto fail;
+
+ assert(signature_obj != NULL);
+ /* Fill in specified_types from the tuple or string (signature_obj) */
+ if (PyTuple_Check(signature_obj)) {
+ Py_ssize_t n = PyTuple_GET_SIZE(signature_obj);
+ if (n == 1 && nop != 1) {
+ /*
+ * Special handling, because we deprecate this path. The path
+ * probably mainly existed since the `dtype=obj` was passed through
+ * as `(obj,)` and parsed later.
+ */
+ if (PyTuple_GET_ITEM(signature_obj, 0) == Py_None) {
+ PyErr_SetString(PyExc_TypeError,
+ "a single item type tuple cannot contain None.");
+ return -1;
+ }
+ if (DEPRECATE("The use of a length 1 tuple for the ufunc "
+ "`signature` is deprecated. Use `dtype` or fill the"
+ "tuple with `None`s.") < 0) {
+ return -1;
+ }
+ /* Use the same logic as for `dtype=` */
+ return _get_fixed_signature(ufunc,
+ PyTuple_GET_ITEM(signature_obj, 0), NULL, signature);
+ }
+ if (n != nop) {
+ PyErr_Format(PyExc_ValueError,
+ "a type-tuple must be specified of length %d for ufunc '%s'",
+ nop, ufunc_get_name_cstr(ufunc));
+ return -1;
+ }
+ for (int i = 0; i < nop; ++i) {
+ PyObject *item = PyTuple_GET_ITEM(signature_obj, i);
+ if (item == Py_None) {
+ continue;
+ }
+ else {
+ signature[i] = _get_dtype(item);
+ if (signature[i] == NULL) {
+ return -1;
+ }
+ else if (i < nin && NPY_DT_is_abstract(signature[i])) {
+ /*
+ * We reject abstract input signatures for now. These
+ * can probably be defined by finding the common DType with
+ * the actual input and using the result of this for the
+ * promotion.
+ */
+ PyErr_SetString(PyExc_TypeError,
+ "Input DTypes to the signature must not be "
+ "abstract. The behaviour may be defined in the "
+ "future.");
+ return -1;
+ }
+ }
+ }
+ }
+ else if (PyBytes_Check(signature_obj) || PyUnicode_Check(signature_obj)) {
+ PyObject *str_object = NULL;
+
+ if (PyBytes_Check(signature_obj)) {
+ str_object = PyUnicode_FromEncodedObject(signature_obj, NULL, NULL);
+ if (str_object == NULL) {
+ return -1;
+ }
+ }
+ else {
+ Py_INCREF(signature_obj);
+ str_object = signature_obj;
+ }
+
+ Py_ssize_t length;
+ const char *str = PyUnicode_AsUTF8AndSize(str_object, &length);
+ if (str == NULL) {
+ Py_DECREF(str_object);
+ return -1;
+ }
+
+ if (length != 1 && (length != nin+nout + 2 ||
+ str[nin] != '-' || str[nin+1] != '>')) {
+ PyErr_Format(PyExc_ValueError,
+ "a type-string for %s, %d typecode(s) before and %d after "
+ "the -> sign", ufunc_get_name_cstr(ufunc), nin, nout);
+ Py_DECREF(str_object);
+ return -1;
+ }
+ if (length == 1 && nin+nout != 1) {
+ Py_DECREF(str_object);
+ if (DEPRECATE("The use of a length 1 string for the ufunc "
+ "`signature` is deprecated. Use `dtype` attribute or "
+ "pass a tuple with `None`s.") < 0) {
+ return -1;
+ }
+ /* `signature="l"` is the same as `dtype="l"` */
+ return _get_fixed_signature(ufunc, str_object, NULL, signature);
+ }
+ else {
+ for (int i = 0; i < nin+nout; ++i) {
+ npy_intp istr = i < nin ? i : i+2;
+ PyArray_Descr *descr = PyArray_DescrFromType(str[istr]);
+ if (descr == NULL) {
+ Py_DECREF(str_object);
+ return -1;
+ }
+ signature[i] = NPY_DTYPE(descr);
+ Py_INCREF(signature[i]);
+ Py_DECREF(descr);
+ }
+ Py_DECREF(str_object);
+ }
+ }
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "the signature object to ufunc must be a string or a tuple.");
+ return -1;
}
+ return 0;
+}
+
+
+/*
+ * Fill in the actual descriptors used for the operation. This function
+ * supports falling back to the legacy `ufunc->type_resolver`.
+ *
+ * We guarantee the array-method that all passed in descriptors are of the
+ * correct DType instance (i.e. a string can just fetch the length, it doesn't
+ * need to "cast" to string first).
+ */
+static int
+resolve_descriptors(int nop,
+ PyUFuncObject *ufunc, PyArrayMethodObject *ufuncimpl,
+ PyArrayObject *operands[], PyArray_Descr *dtypes[],
+ PyArray_DTypeMeta *signature[], NPY_CASTING casting)
+{
+ int retval = -1;
+ PyArray_Descr *original_dtypes[NPY_MAXARGS];
+
+ for (int i = 0; i < nop; ++i) {
+ if (operands[i] == NULL) {
+ original_dtypes[i] = NULL;
+ }
+ else {
+ /*
+ * The dtype may mismatch the signature, in which case we need
+ * to make it fit before calling the resolution.
+ */
+ PyArray_Descr *descr = PyArray_DTYPE(operands[i]);
+ original_dtypes[i] = PyArray_CastDescrToDType(descr, signature[i]);
+ if (original_dtypes[i] == NULL) {
+ nop = i; /* only this much is initialized */
+ goto finish;
+ }
+ }
+ }
+
+ NPY_UF_DBG_PRINT("Resolving the descriptors\n");
+
+ if (ufuncimpl->resolve_descriptors != &wrapped_legacy_resolve_descriptors) {
+ /* The default: use the `ufuncimpl` as nature intended it */
+ NPY_CASTING safety = ufuncimpl->resolve_descriptors(ufuncimpl,
+ signature, original_dtypes, dtypes);
+ if (safety < 0) {
+ goto finish;
+ }
+ if (NPY_UNLIKELY(PyArray_MinCastSafety(safety, casting) != casting)) {
+ /* TODO: Currently impossible to reach (specialized unsafe loop) */
+ PyErr_Format(PyExc_TypeError,
+ "The ufunc implementation for %s with the given dtype "
+ "signature is not possible under the casting rule %s",
+ ufunc_get_name_cstr(ufunc), npy_casting_to_string(casting));
+ goto finish;
+ }
+ retval = 0;
+ }
+ else {
+ /*
+ * Fall-back to legacy resolver using `operands`, used exclusively
+ * for datetime64/timedelta64 and custom ufuncs (in pyerfa/astropy).
+ */
+ retval = ufunc->type_resolver(ufunc, casting, operands, NULL, dtypes);
+ }
+
+ finish:
+ for (int i = 0; i < nop; i++) {
+ Py_XDECREF(original_dtypes[i]);
+ }
+ return retval;
+}
+
+
+/**
+ * Wraps all outputs and returns the result (which may be NULL on error).
+ *
+ * Use __array_wrap__ on all outputs
+ * if present on one of the input arguments.
+ * If present for multiple inputs:
+ * use __array_wrap__ of input object with largest
+ * __array_priority__ (default = 0.0)
+ *
+ * Exception: we should not wrap outputs for items already
+ * passed in as output-arguments. These items should either
+ * be left unwrapped or wrapped by calling their own __array_wrap__
+ * routine.
+ *
+ * For each output argument, wrap will be either
+ * NULL --- call PyArray_Return() -- default if no output arguments given
+ * None --- array-object passed in don't call PyArray_Return
+ * method --- the __array_wrap__ method to call.
+ *
+ * @param ufunc
+ * @param full_args Original inputs and outputs
+ * @param subok Whether subclasses are allowed
+ * @param result_arrays The ufunc result(s). REFERENCES ARE STOLEN!
+ */
+static PyObject *
+replace_with_wrapped_result_and_return(PyUFuncObject *ufunc,
+ ufunc_full_args full_args, npy_bool subok,
+ PyArrayObject *result_arrays[])
+{
+ PyObject *retobj[NPY_MAXARGS];
+ PyObject *wraparr[NPY_MAXARGS];
+ _find_array_wrap(full_args, subok, wraparr, ufunc->nin, ufunc->nout);
/* wrap outputs */
- for (i = 0; i < ufunc->nout; i++) {
- int j = ufunc->nin+i;
+ for (int i = 0; i < ufunc->nout; i++) {
_ufunc_context context;
- PyObject *wrapped;
context.ufunc = ufunc;
context.args = full_args;
context.out_i = i;
- wrapped = _apply_array_wrap(wraparr[i], mps[j], &context);
- mps[j] = NULL; /* Prevent fail double-freeing this */
- if (wrapped == NULL) {
- for (j = 0; j < i; j++) {
- Py_DECREF(retobj[j]);
+ retobj[i] = _apply_array_wrap(wraparr[i], result_arrays[i], &context);
+ result_arrays[i] = NULL; /* Was DECREF'ed and (probably) wrapped */
+ if (retobj[i] == NULL) {
+ goto fail;
+ }
+ }
+
+ if (ufunc->nout == 1) {
+ return retobj[0];
+ }
+ else {
+ PyObject *result = PyTuple_New(ufunc->nout);
+ if (result == NULL) {
+ return NULL;
+ }
+ for (int i = 0; i < ufunc->nout; i++) {
+ PyTuple_SET_ITEM(result, i, retobj[i]);
+ }
+ return result;
+ }
+
+ fail:
+ for (int i = 0; i < ufunc->nout; i++) {
+ if (result_arrays[i] != NULL) {
+ Py_DECREF(result_arrays[i]);
+ }
+ else {
+ Py_XDECREF(retobj[i]);
+ }
+ }
+ return NULL;
+}
+
+
+/*
+ * Main ufunc call implementation.
+ *
+ * This implementation makes use of the "fastcall" way of passing keyword
+ * arguments and is called directly from `ufunc_generic_vectorcall` when
+ * Python has `tp_vectorcall` (Python 3.8+).
+ * If `tp_vectorcall` is not available, the dictionary `kwargs` are unpacked in
+ * `ufunc_generic_call` with fairly little overhead.
+ */
+static PyObject *
+ufunc_generic_fastcall(PyUFuncObject *ufunc,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames,
+ npy_bool outer)
+{
+ int errval;
+ int nin = ufunc->nin, nout = ufunc->nout, nop = ufunc->nargs;
+
+ /* All following variables are cleared in the `fail` error path */
+ ufunc_full_args full_args;
+ PyArrayObject *wheremask = NULL;
+
+ PyArray_DTypeMeta *signature[NPY_MAXARGS];
+ PyArrayObject *operands[NPY_MAXARGS];
+ PyArray_DTypeMeta *operand_DTypes[NPY_MAXARGS];
+ PyArray_Descr *operation_descrs[NPY_MAXARGS];
+ PyObject *output_array_prepare[NPY_MAXARGS];
+ /* Initialize all arrays (we usually only need a small part) */
+ memset(signature, 0, nop * sizeof(*signature));
+ memset(operands, 0, nop * sizeof(*operands));
+ memset(operand_DTypes, 0, nop * sizeof(*operation_descrs));
+ memset(operation_descrs, 0, nop * sizeof(*operation_descrs));
+ memset(output_array_prepare, 0, nout * sizeof(*output_array_prepare));
+
+ /*
+ * Note that the input (and possibly output) arguments are passed in as
+ * positional arguments. We extract these first and check for `out`
+ * passed by keyword later.
+ * Outputs and inputs are stored in `full_args.in` and `full_args.out`
+ * as tuples (or NULL when no outputs are passed).
+ */
+
+ /* Check number of arguments */
+ if (NPY_UNLIKELY((len_args < nin) || (len_args > nop))) {
+ PyErr_Format(PyExc_TypeError,
+ "%s() takes from %d to %d positional arguments but "
+ "%zd were given",
+ ufunc_get_name_cstr(ufunc) , nin, nop, len_args);
+ return NULL;
+ }
+
+ /* Fetch input arguments. */
+ full_args.in = PyArray_TupleFromItems(ufunc->nin, args, 0);
+ if (full_args.in == NULL) {
+ return NULL;
+ }
+
+ /*
+ * If there are more arguments, they define the out args. Otherwise
+ * full_args.out is NULL for now, and the `out` kwarg may still be passed.
+ */
+ npy_bool out_is_passed_by_position = len_args > nin;
+ if (out_is_passed_by_position) {
+ npy_bool all_none = NPY_TRUE;
+
+ full_args.out = PyTuple_New(nout);
+ if (full_args.out == NULL) {
+ goto fail;
+ }
+ for (int i = nin; i < nop; i++) {
+ PyObject *tmp;
+ if (i < (int)len_args) {
+ tmp = args[i];
+ if (tmp != Py_None) {
+ all_none = NPY_FALSE;
+ }
+ }
+ else {
+ tmp = Py_None;
}
+ Py_INCREF(tmp);
+ PyTuple_SET_ITEM(full_args.out, i-nin, tmp);
+ }
+ if (all_none) {
+ Py_SETREF(full_args.out, NULL);
+ }
+ }
+ else {
+ full_args.out = NULL;
+ }
+
+ /*
+ * We have now extracted (but not converted) the input arguments.
+ * To simplify overrides, extract all other arguments (as objects only)
+ */
+ PyObject *out_obj = NULL, *where_obj = NULL;
+ PyObject *axes_obj = NULL, *axis_obj = NULL;
+ PyObject *keepdims_obj = NULL, *casting_obj = NULL, *order_obj = NULL;
+ PyObject *subok_obj = NULL, *signature_obj = NULL, *sig_obj = NULL;
+ PyObject *dtype_obj = NULL, *extobj = NULL;
+
+ /* Skip parsing if there are no keyword arguments, nothing left to do */
+ if (kwnames != NULL) {
+ if (!ufunc->core_enabled) {
+ NPY_PREPARE_ARGPARSER;
+
+ if (npy_parse_arguments(ufunc->name, args + len_args, 0, kwnames,
+ "$out", NULL, &out_obj,
+ "$where", NULL, &where_obj,
+ "$casting", NULL, &casting_obj,
+ "$order", NULL, &order_obj,
+ "$subok", NULL, &subok_obj,
+ "$dtype", NULL, &dtype_obj,
+ "$signature", NULL, &signature_obj,
+ "$sig", NULL, &sig_obj,
+ "$extobj", NULL, &extobj,
+ NULL, NULL, NULL) < 0) {
+ goto fail;
+ }
+ }
+ else {
+ NPY_PREPARE_ARGPARSER;
+
+ if (npy_parse_arguments(ufunc->name, args + len_args, 0, kwnames,
+ "$out", NULL, &out_obj,
+ "$axes", NULL, &axes_obj,
+ "$axis", NULL, &axis_obj,
+ "$keepdims", NULL, &keepdims_obj,
+ "$casting", NULL, &casting_obj,
+ "$order", NULL, &order_obj,
+ "$subok", NULL, &subok_obj,
+ "$dtype", NULL, &dtype_obj,
+ "$signature", NULL, &signature_obj,
+ "$sig", NULL, &sig_obj,
+ "$extobj", NULL, &extobj,
+ NULL, NULL, NULL) < 0) {
+ goto fail;
+ }
+ if (NPY_UNLIKELY((axes_obj != NULL) && (axis_obj != NULL))) {
+ PyErr_SetString(PyExc_TypeError,
+ "cannot specify both 'axis' and 'axes'");
+ goto fail;
+ }
+ }
+
+ /* Handle `out` arguments passed by keyword */
+ if (out_obj != NULL) {
+ if (out_is_passed_by_position) {
+ PyErr_SetString(PyExc_TypeError,
+ "cannot specify 'out' as both a "
+ "positional and keyword argument");
+ goto fail;
+ }
+ if (_set_full_args_out(nout, out_obj, &full_args) < 0) {
+ goto fail;
+ }
+ }
+ /*
+ * Only one of signature, sig, and dtype should be passed. If `sig`
+ * was passed, this puts it into `signature_obj` instead (these
+ * are borrowed references).
+ */
+ if (_check_and_copy_sig_to_signature(
+ sig_obj, signature_obj, dtype_obj, &signature_obj) < 0) {
goto fail;
}
+ }
- retobj[i] = wrapped;
+ char *method;
+ if (!outer) {
+ method = "__call__";
+ }
+ else {
+ method = "outer";
+ }
+ /* We now have all the information required to check for Overrides */
+ PyObject *override = NULL;
+ errval = PyUFunc_CheckOverride(ufunc, method,
+ full_args.in, full_args.out,
+ args, len_args, kwnames, &override);
+ if (errval) {
+ goto fail;
+ }
+ else if (override) {
+ Py_DECREF(full_args.in);
+ Py_XDECREF(full_args.out);
+ return override;
}
- Py_XDECREF(full_args.in);
- Py_XDECREF(full_args.out);
+ if (outer) {
+ /* Outer uses special preparation of inputs (expand dims) */
+ PyObject *new_in = prepare_input_arguments_for_outer(full_args.in, ufunc);
+ if (new_in == NULL) {
+ goto fail;
+ }
+ Py_SETREF(full_args.in, new_in);
+ }
- if (ufunc->nout == 1) {
- return retobj[0];
+ /*
+ * Parse the passed `dtype` or `signature` into an array containing
+ * PyArray_DTypeMeta and/or None.
+ */
+ if (_get_fixed_signature(ufunc,
+ dtype_obj, signature_obj, signature) < 0) {
+ goto fail;
+ }
+
+ NPY_ORDER order = NPY_KEEPORDER;
+ NPY_CASTING casting = NPY_DEFAULT_ASSIGN_CASTING;
+ npy_bool subok = NPY_TRUE;
+ int keepdims = -1; /* We need to know if it was passed */
+ npy_bool force_legacy_promotion;
+ npy_bool allow_legacy_promotion;
+ if (convert_ufunc_arguments(ufunc,
+ /* extract operand related information: */
+ full_args, operands,
+ operand_DTypes, &force_legacy_promotion, &allow_legacy_promotion,
+ /* extract general information: */
+ order_obj, &order,
+ casting_obj, &casting,
+ subok_obj, &subok,
+ where_obj, &wheremask,
+ keepdims_obj, &keepdims) < 0) {
+ goto fail;
+ }
+
+ /*
+ * Note that part of the promotion is to the complete the signature
+ * (until here it only represents the fixed part and is usually NULLs).
+ *
+ * After promotion, we could push the following logic into the ArrayMethod
+ * in the future. For now, we do it here. The type resolution step can
+ * be shared between the ufunc and gufunc code.
+ */
+ PyArrayMethodObject *ufuncimpl = promote_and_get_ufuncimpl(ufunc,
+ operands, signature,
+ operand_DTypes, force_legacy_promotion, allow_legacy_promotion);
+ if (ufuncimpl == NULL) {
+ goto fail;
+ }
+
+ /* Find the correct descriptors for the operation */
+ if (resolve_descriptors(nop, ufunc, ufuncimpl,
+ operands, operation_descrs, signature, casting) < 0) {
+ goto fail;
+ }
+
+ if (subok) {
+ _find_array_prepare(full_args, output_array_prepare, nout);
+ }
+
+ /*
+ * Do the final preparations and call the inner-loop.
+ */
+ if (!ufunc->core_enabled) {
+ errval = PyUFunc_GenericFunctionInternal(ufunc, ufuncimpl,
+ operation_descrs, operands, extobj, casting, order,
+ output_array_prepare, full_args, /* for __array_prepare__ */
+ wheremask);
}
else {
- PyTupleObject *ret;
+ errval = PyUFunc_GeneralizedFunctionInternal(ufunc, ufuncimpl,
+ operation_descrs, operands, extobj, casting, order,
+ /* GUFuncs never (ever) called __array_prepare__! */
+ axis_obj, axes_obj, keepdims);
+ }
+ if (errval < 0) {
+ goto fail;
+ }
- ret = (PyTupleObject *)PyTuple_New(ufunc->nout);
- for (i = 0; i < ufunc->nout; i++) {
- PyTuple_SET_ITEM(ret, i, retobj[i]);
+ /*
+ * Clear all variables which are not needed any further.
+ * (From here on, we cannot `goto fail` any more.)
+ */
+ Py_XDECREF(wheremask);
+ for (int i = 0; i < nop; i++) {
+ Py_XDECREF(operand_DTypes[i]);
+ Py_DECREF(operation_descrs[i]);
+ if (i < nin) {
+ Py_DECREF(operands[i]);
+ }
+ else {
+ Py_XDECREF(output_array_prepare[i-nin]);
}
- return (PyObject *)ret;
}
+ /* The following steals the references to the outputs: */
+ PyObject *result = replace_with_wrapped_result_and_return(ufunc,
+ full_args, subok, operands+nin);
+ Py_XDECREF(full_args.in);
+ Py_XDECREF(full_args.out);
+
+ return result;
fail:
Py_XDECREF(full_args.in);
Py_XDECREF(full_args.out);
- for (i = ufunc->nin; i < ufunc->nargs; i++) {
- Py_XDECREF(mps[i]);
+ Py_XDECREF(wheremask);
+ for (int i = 0; i < ufunc->nargs; i++) {
+ Py_XDECREF(operands[i]);
+ Py_XDECREF(operand_DTypes[i]);
+ Py_XDECREF(operation_descrs[i]);
+ if (i < nout) {
+ Py_XDECREF(output_array_prepare[i]);
+ }
}
return NULL;
}
+
+/*
+ * TODO: The implementation below can be replaced with PyVectorcall_Call
+ * when available (should be Python 3.8+).
+ */
+static PyObject *
+ufunc_generic_call(
+ PyUFuncObject *ufunc, PyObject *args, PyObject *kwds)
+{
+ Py_ssize_t len_args = PyTuple_GET_SIZE(args);
+ /*
+ * Wrapper for tp_call to tp_fastcall, to support both on older versions
+ * of Python. (and generally simplifying support of both versions in the
+ * same codebase.
+ */
+ if (kwds == NULL) {
+ return ufunc_generic_fastcall(ufunc,
+ PySequence_Fast_ITEMS(args), len_args, NULL, NPY_FALSE);
+ }
+
+ PyObject *new_args[NPY_MAXARGS];
+ Py_ssize_t len_kwds = PyDict_Size(kwds);
+
+ if (NPY_UNLIKELY(len_args + len_kwds > NPY_MAXARGS)) {
+ /*
+ * We do not have enough scratch-space, so we have to abort;
+ * In practice this error should not be seen by users.
+ */
+ PyErr_Format(PyExc_ValueError,
+ "%s() takes from %d to %d positional arguments but "
+ "%zd were given",
+ ufunc_get_name_cstr(ufunc) , ufunc->nin, ufunc->nargs, len_args);
+ return NULL;
+ }
+
+ /* Copy args into the scratch space */
+ for (Py_ssize_t i = 0; i < len_args; i++) {
+ new_args[i] = PyTuple_GET_ITEM(args, i);
+ }
+
+ PyObject *kwnames = PyTuple_New(len_kwds);
+
+ PyObject *key, *value;
+ Py_ssize_t pos = 0;
+ Py_ssize_t i = 0;
+ while (PyDict_Next(kwds, &pos, &key, &value)) {
+ Py_INCREF(key);
+ PyTuple_SET_ITEM(kwnames, i, key);
+ new_args[i + len_args] = value;
+ i++;
+ }
+
+ PyObject *res = ufunc_generic_fastcall(ufunc,
+ new_args, len_args, kwnames, NPY_FALSE);
+ Py_DECREF(kwnames);
+ return res;
+}
+
+
+#if PY_VERSION_HEX >= 0x03080000
+/*
+ * Implement vectorcallfunc which should be defined with Python 3.8+.
+ * In principle this could be backported, but the speed gain seems moderate
+ * since ufunc calls often do not have keyword arguments and always have
+ * a large overhead. The only user would potentially be cython probably.
+ */
+static PyObject *
+ufunc_generic_vectorcall(PyObject *ufunc,
+ PyObject *const *args, size_t len_args, PyObject *kwnames)
+{
+ /*
+ * Unlike METH_FASTCALL, `len_args` may have a flag to signal that
+ * args[-1] may be (temporarily) used. So normalize it here.
+ */
+ return ufunc_generic_fastcall((PyUFuncObject *)ufunc,
+ args, PyVectorcall_NARGS(len_args), kwnames, NPY_FALSE);
+}
+#endif /* PY_VERSION_HEX >= 0x03080000 */
+
+
NPY_NO_EXPORT PyObject *
ufunc_geterr(PyObject *NPY_UNUSED(dummy), PyObject *args)
{
@@ -4842,6 +5035,7 @@ ufunc_geterr(PyObject *NPY_UNUSED(dummy), PyObject *args)
return res;
}
+
NPY_NO_EXPORT PyObject *
ufunc_seterr(PyObject *NPY_UNUSED(dummy), PyObject *args)
{
@@ -4983,14 +5177,40 @@ PyUFunc_FromFuncAndDataAndSignatureAndIdentity(PyUFuncGenericFunction *func, voi
ufunc->core_dim_flags = NULL;
ufunc->userloops = NULL;
ufunc->ptr = NULL;
+#if PY_VERSION_HEX >= 0x03080000
+ ufunc->vectorcall = &ufunc_generic_vectorcall;
+#else
ufunc->reserved2 = NULL;
+#endif
ufunc->reserved1 = 0;
ufunc->iter_flags = 0;
/* Type resolution and inner loop selection functions */
ufunc->type_resolver = &PyUFunc_DefaultTypeResolver;
ufunc->legacy_inner_loop_selector = &PyUFunc_DefaultLegacyInnerLoopSelector;
- ufunc->masked_inner_loop_selector = &PyUFunc_DefaultMaskedInnerLoopSelector;
+ ufunc->_always_null_previously_masked_innerloop_selector = NULL;
+
+ ufunc->op_flags = NULL;
+ ufunc->_loops = NULL;
+ if (nin + nout != 0) {
+ ufunc->_dispatch_cache = PyArrayIdentityHash_New(nin + nout);
+ if (ufunc->_dispatch_cache == NULL) {
+ Py_DECREF(ufunc);
+ return NULL;
+ }
+ }
+ else {
+ /*
+ * Work around a test that seems to do this right now, it should not
+ * be a valid ufunc at all though, so. TODO: Remove...
+ */
+ ufunc->_dispatch_cache = NULL;
+ }
+ ufunc->_loops = PyList_New(0);
+ if (ufunc->_loops == NULL) {
+ Py_DECREF(ufunc);
+ return NULL;
+ }
if (name == NULL) {
ufunc->name = "?";
@@ -5013,47 +5233,42 @@ PyUFunc_FromFuncAndDataAndSignatureAndIdentity(PyUFuncGenericFunction *func, voi
return NULL;
}
}
+
+ char *curr_types = ufunc->types;
+ for (int i = 0; i < ntypes * (nin + nout); i += nin + nout) {
+ /*
+ * Add all legacy wrapping loops here. This is normally not necessary,
+ * but makes sense. It could also help/be needed to avoid issues with
+ * ambiguous loops such as: `OO->?` and `OO->O` where in theory the
+ * wrong loop could be picked if only the second one is added.
+ */
+ PyObject *info;
+ PyArray_DTypeMeta *op_dtypes[NPY_MAXARGS];
+ for (int arg = 0; arg < nin + nout; arg++) {
+ op_dtypes[arg] = PyArray_DTypeFromTypeNum(curr_types[arg]);
+ /* These DTypes are immortal and adding INCREFs: so borrow it */
+ Py_DECREF(op_dtypes[arg]);
+ }
+ curr_types += nin + nout;
+
+ info = add_and_return_legacy_wrapping_ufunc_loop(ufunc, op_dtypes, 1);
+ if (info == NULL) {
+ return NULL;
+ }
+ }
return (PyObject *)ufunc;
}
-/* Specify that the loop specified by the given index should use the array of
- * input and arrays as the data pointer to the loop.
- */
+
/*UFUNC_API*/
NPY_NO_EXPORT int
-PyUFunc_SetUsesArraysAsData(void **data, size_t i)
+PyUFunc_SetUsesArraysAsData(void **NPY_UNUSED(data), size_t NPY_UNUSED(i))
{
- /* NumPy 1.19, 2020-01-24 */
- if (DEPRECATE(
- "PyUFunc_SetUsesArraysAsData() C-API function is deprecated "
- "and expected to be removed rapidly. If you are using it (i.e. see "
- "this warning/error), please notify the NumPy developers. "
- "It is currently assumed that this function is simply unused and "
- "its removal will facilitate the implementation of better "
- "approaches.") < 0) {
- return -1;
- }
- data[i] = (void*)PyUFunc_SetUsesArraysAsData;
- return 0;
-}
-
-/*
- * Return 1 if the given data pointer for the loop specifies that it needs the
- * arrays as the data pointer.
- *
- * NOTE: This is easier to specify with the type_resolver
- * in the ufunc object.
- *
- * TODO: Remove this, since this is already basically broken
- * with the addition of the masked inner loops and
- * not worth fixing since the new loop selection functions
- * have access to the full dtypes and can dynamically allocate
- * arbitrary auxiliary data.
- */
-static int
-_does_loop_use_arrays(void *data)
-{
- return (data == PyUFunc_SetUsesArraysAsData);
+ /* NumPy 1.21, 201-03-29 */
+ PyErr_SetString(PyExc_RuntimeError,
+ "PyUFunc_SetUsesArraysAsData() C-API function has been "
+ "disabled. It was initially deprecated in NumPy 1.19.");
+ return -1;
}
@@ -5164,6 +5379,7 @@ PyUFunc_RegisterLoopForDescr(PyUFuncObject *ufunc,
arg_typenums = PyArray_malloc(ufunc->nargs * sizeof(int));
if (arg_typenums == NULL) {
+ Py_DECREF(key);
PyErr_NoMemory();
return -1;
}
@@ -5209,7 +5425,12 @@ PyUFunc_RegisterLoopForDescr(PyUFuncObject *ufunc,
if (cmp == 0 && current != NULL && current->arg_dtypes == NULL) {
current->arg_dtypes = PyArray_malloc(ufunc->nargs *
sizeof(PyArray_Descr*));
- if (arg_dtypes != NULL) {
+ if (current->arg_dtypes == NULL) {
+ PyErr_NoMemory();
+ result = -1;
+ goto done;
+ }
+ else if (arg_dtypes != NULL) {
for (i = 0; i < ufunc->nargs; i++) {
current->arg_dtypes[i] = arg_dtypes[i];
Py_INCREF(current->arg_dtypes[i]);
@@ -5250,6 +5471,8 @@ PyUFunc_RegisterLoopForType(PyUFuncObject *ufunc,
PyArray_Descr *descr;
PyUFunc_Loop1d *funcdata;
PyObject *key, *cobj;
+ PyArray_DTypeMeta *signature[NPY_MAXARGS];
+ PyObject *signature_tuple = NULL;
int i;
int *newtypes=NULL;
@@ -5278,13 +5501,67 @@ PyUFunc_RegisterLoopForType(PyUFuncObject *ufunc,
if (arg_types != NULL) {
for (i = 0; i < ufunc->nargs; i++) {
newtypes[i] = arg_types[i];
+ signature[i] = PyArray_DTypeFromTypeNum(arg_types[i]);
+ Py_DECREF(signature[i]); /* DType can't be deleted... */
}
}
else {
for (i = 0; i < ufunc->nargs; i++) {
newtypes[i] = usertype;
+ signature[i] = PyArray_DTypeFromTypeNum(usertype);
+ Py_DECREF(signature[i]); /* DType can't be deleted... */
+ }
+ }
+
+ signature_tuple = PyArray_TupleFromItems(
+ ufunc->nargs, (PyObject **)signature, 0);
+ if (signature_tuple == NULL) {
+ goto fail;
+ }
+ /*
+ * We add the loop to the list of all loops and promoters. If the
+ * equivalent loop was already added, skip this.
+ * Note that even then the ufunc is still modified: The legacy ArrayMethod
+ * already looks up the inner-loop from the ufunc (and this is replaced
+ * below!).
+ * If the existing one is not a legacy ArrayMethod, we raise currently:
+ * A new-style loop should not be replaced by an old-style one.
+ */
+ int add_new_loop = 1;
+ for (Py_ssize_t j = 0; j < PyList_GET_SIZE(ufunc->_loops); j++) {
+ PyObject *item = PyList_GET_ITEM(ufunc->_loops, j);
+ PyObject *existing_tuple = PyTuple_GET_ITEM(item, 0);
+
+ int cmp = PyObject_RichCompareBool(existing_tuple, signature_tuple, Py_EQ);
+ if (cmp < 0) {
+ goto fail;
+ }
+ if (!cmp) {
+ continue;
+ }
+ PyObject *registered = PyTuple_GET_ITEM(item, 1);
+ if (!PyObject_TypeCheck(registered, &PyArrayMethod_Type) || (
+ (PyArrayMethodObject *)registered)->get_strided_loop !=
+ &get_wrapped_legacy_ufunc_loop) {
+ PyErr_Format(PyExc_TypeError,
+ "A non-compatible loop was already registered for "
+ "ufunc %s and DTypes %S.",
+ ufunc_get_name_cstr(ufunc), signature_tuple);
+ goto fail;
+ }
+ /* The loop was already added */
+ add_new_loop = 0;
+ break;
+ }
+ if (add_new_loop) {
+ PyObject *info = add_and_return_legacy_wrapping_ufunc_loop(
+ ufunc, signature, 0);
+ if (info == NULL) {
+ goto fail;
}
}
+ /* Clearing sets it to NULL for the error paths */
+ Py_CLEAR(signature_tuple);
funcdata->func = function;
funcdata->arg_types = newtypes;
@@ -5296,6 +5573,7 @@ PyUFunc_RegisterLoopForType(PyUFuncObject *ufunc,
/* Get entry for this user-defined type*/
cobj = PyDict_GetItemWithError(ufunc->userloops, key);
if (cobj == NULL && PyErr_Occurred()) {
+ Py_DECREF(key);
return 0;
}
/* If it's not there, then make one and return. */
@@ -5358,6 +5636,7 @@ PyUFunc_RegisterLoopForType(PyUFuncObject *ufunc,
fail:
Py_DECREF(key);
+ Py_XDECREF(signature_tuple);
PyArray_free(funcdata);
PyArray_free(newtypes);
if (!PyErr_Occurred()) PyErr_NoMemory();
@@ -5383,8 +5662,10 @@ ufunc_dealloc(PyUFuncObject *ufunc)
if (ufunc->identity == PyUFunc_IdentityValue) {
Py_DECREF(ufunc->identity_value);
}
- if (ufunc->obj != NULL) {
- Py_DECREF(ufunc->obj);
+ Py_XDECREF(ufunc->obj);
+ Py_XDECREF(ufunc->_loops);
+ if (ufunc->_dispatch_cache != NULL) {
+ PyArrayIdentityHash_Dealloc(ufunc->_dispatch_cache);
}
PyObject_GC_Del(ufunc);
}
@@ -5417,24 +5698,9 @@ ufunc_traverse(PyUFuncObject *self, visitproc visit, void *arg)
* The result has dimensions a.ndim + b.ndim
*/
static PyObject *
-ufunc_outer(PyUFuncObject *ufunc, PyObject *args, PyObject *kwds)
+ufunc_outer(PyUFuncObject *ufunc,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
- int errval;
- PyObject *override = NULL;
- PyObject *ret;
- PyArrayObject *ap1 = NULL, *ap2 = NULL, *ap_new = NULL;
- PyObject *new_args, *tmp;
- static PyObject *_numpy_matrix;
-
-
- errval = PyUFunc_CheckOverride(ufunc, "outer", args, kwds, &override);
- if (errval) {
- return NULL;
- }
- else if (override) {
- return override;
- }
-
if (ufunc->core_enabled) {
PyErr_Format(PyExc_TypeError,
"method outer is not allowed in ufunc with non-trivial"\
@@ -5449,20 +5715,22 @@ ufunc_outer(PyUFuncObject *ufunc, PyObject *args, PyObject *kwds)
return NULL;
}
- if (PySequence_Length(args) != 2) {
+ if (len_args != 2) {
PyErr_SetString(PyExc_TypeError, "exactly two arguments expected");
return NULL;
}
- tmp = PySequence_GetItem(args, 0);
- if (tmp == NULL) {
- return NULL;
- }
+ return ufunc_generic_fastcall(ufunc, args, len_args, kwnames, NPY_TRUE);
+}
- npy_cache_import(
- "numpy",
- "matrix",
- &_numpy_matrix);
+
+static PyObject *
+prepare_input_arguments_for_outer(PyObject *args, PyUFuncObject *ufunc)
+{
+ PyArrayObject *ap1 = NULL;
+ PyObject *tmp;
+ static PyObject *_numpy_matrix;
+ npy_cache_import("numpy", "matrix", &_numpy_matrix);
const char *matrix_deprecation_msg = (
"%s.outer() was passed a numpy matrix as %s argument. "
@@ -5471,6 +5739,8 @@ ufunc_outer(PyUFuncObject *ufunc, PyObject *args, PyObject *kwds)
"array to retain the old behaviour. You can use `matrix.A` "
"to achieve this.");
+ tmp = PyTuple_GET_ITEM(args, 0);
+
if (PyObject_IsInstance(tmp, _numpy_matrix)) {
/* DEPRECATED 2020-05-13, NumPy 1.20 */
if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
@@ -5482,14 +5752,12 @@ ufunc_outer(PyUFuncObject *ufunc, PyObject *args, PyObject *kwds)
else {
ap1 = (PyArrayObject *) PyArray_FROM_O(tmp);
}
- Py_DECREF(tmp);
if (ap1 == NULL) {
return NULL;
}
- tmp = PySequence_GetItem(args, 1);
- if (tmp == NULL) {
- return NULL;
- }
+
+ PyArrayObject *ap2 = NULL;
+ tmp = PyTuple_GET_ITEM(args, 1);
if (PyObject_IsInstance(tmp, _numpy_matrix)) {
/* DEPRECATED 2020-05-13, NumPy 1.20 */
if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1,
@@ -5502,7 +5770,6 @@ ufunc_outer(PyUFuncObject *ufunc, PyObject *args, PyObject *kwds)
else {
ap2 = (PyArrayObject *) PyArray_FROM_O(tmp);
}
- Py_DECREF(tmp);
if (ap2 == NULL) {
Py_DECREF(ap1);
return NULL;
@@ -5518,7 +5785,7 @@ ufunc_outer(PyUFuncObject *ufunc, PyObject *args, PyObject *kwds)
"maximum supported dimension for an ndarray is %d, but "
"`%s.outer()` result would have %d.",
NPY_MAXDIMS, ufunc->name, newdims.len);
- return NPY_FAIL;
+ goto fail;
}
if (newdims.ptr == NULL) {
goto fail;
@@ -5528,6 +5795,7 @@ ufunc_outer(PyUFuncObject *ufunc, PyObject *args, PyObject *kwds)
newshape[i] = 1;
}
+ PyArrayObject *ap_new;
ap_new = (PyArrayObject *)PyArray_Newshape(ap1, &newdims, NPY_CORDER);
if (ap_new == NULL) {
goto fail;
@@ -5543,71 +5811,42 @@ ufunc_outer(PyUFuncObject *ufunc, PyObject *args, PyObject *kwds)
"To work around this issue, please convert the inputs to "
"numpy arrays.",
ufunc->name, Py_TYPE(ap_new)->tp_name);
+ Py_DECREF(ap_new);
goto fail;
}
- new_args = Py_BuildValue("(OO)", ap_new, ap2);
Py_DECREF(ap1);
- Py_DECREF(ap2);
- Py_DECREF(ap_new);
- ret = ufunc_generic_call(ufunc, new_args, kwds);
- Py_DECREF(new_args);
- return ret;
+ return Py_BuildValue("(NN)", ap_new, ap2);
fail:
Py_XDECREF(ap1);
Py_XDECREF(ap2);
- Py_XDECREF(ap_new);
return NULL;
}
static PyObject *
-ufunc_reduce(PyUFuncObject *ufunc, PyObject *args, PyObject *kwds)
+ufunc_reduce(PyUFuncObject *ufunc,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
- int errval;
- PyObject *override = NULL;
-
- errval = PyUFunc_CheckOverride(ufunc, "reduce", args, kwds, &override);
- if (errval) {
- return NULL;
- }
- else if (override) {
- return override;
- }
- return PyUFunc_GenericReduction(ufunc, args, kwds, UFUNC_REDUCE);
+ return PyUFunc_GenericReduction(
+ ufunc, args, len_args, kwnames, UFUNC_REDUCE);
}
static PyObject *
-ufunc_accumulate(PyUFuncObject *ufunc, PyObject *args, PyObject *kwds)
+ufunc_accumulate(PyUFuncObject *ufunc,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
- int errval;
- PyObject *override = NULL;
-
- errval = PyUFunc_CheckOverride(ufunc, "accumulate", args, kwds, &override);
- if (errval) {
- return NULL;
- }
- else if (override) {
- return override;
- }
- return PyUFunc_GenericReduction(ufunc, args, kwds, UFUNC_ACCUMULATE);
+ return PyUFunc_GenericReduction(
+ ufunc, args, len_args, kwnames, UFUNC_ACCUMULATE);
}
static PyObject *
-ufunc_reduceat(PyUFuncObject *ufunc, PyObject *args, PyObject *kwds)
+ufunc_reduceat(PyUFuncObject *ufunc,
+ PyObject *const *args, Py_ssize_t len_args, PyObject *kwnames)
{
- int errval;
- PyObject *override = NULL;
-
- errval = PyUFunc_CheckOverride(ufunc, "reduceat", args, kwds, &override);
- if (errval) {
- return NULL;
- }
- else if (override) {
- return override;
- }
- return PyUFunc_GenericReduction(ufunc, args, kwds, UFUNC_REDUCEAT);
+ return PyUFunc_GenericReduction(
+ ufunc, args, len_args, kwnames, UFUNC_REDUCEAT);
}
/* Helper for ufunc_at, below */
@@ -5664,14 +5903,6 @@ ufunc_at(PyUFuncObject *ufunc, PyObject *args)
char * err_msg = NULL;
NPY_BEGIN_THREADS_DEF;
- errval = PyUFunc_CheckOverride(ufunc, "at", args, NULL, &override);
- if (errval) {
- return NULL;
- }
- else if (override) {
- return override;
- }
-
if (ufunc->nin > 2) {
PyErr_SetString(PyExc_ValueError,
"Only unary and binary ufuncs supported at this time");
@@ -5693,6 +5924,15 @@ ufunc_at(PyUFuncObject *ufunc, PyObject *args)
"second operand needed for ufunc");
return NULL;
}
+ errval = PyUFunc_CheckOverride(ufunc, "at",
+ args, NULL, NULL, 0, NULL, &override);
+
+ if (errval) {
+ return NULL;
+ }
+ else if (override) {
+ return override;
+ }
if (!PyArray_Check(op1)) {
PyErr_SetString(PyExc_TypeError,
@@ -5945,16 +6185,16 @@ fail:
static struct PyMethodDef ufunc_methods[] = {
{"reduce",
(PyCFunction)ufunc_reduce,
- METH_VARARGS | METH_KEYWORDS, NULL },
+ METH_FASTCALL | METH_KEYWORDS, NULL },
{"accumulate",
(PyCFunction)ufunc_accumulate,
- METH_VARARGS | METH_KEYWORDS, NULL },
+ METH_FASTCALL | METH_KEYWORDS, NULL },
{"reduceat",
(PyCFunction)ufunc_reduceat,
- METH_VARARGS | METH_KEYWORDS, NULL },
+ METH_FASTCALL | METH_KEYWORDS, NULL },
{"outer",
(PyCFunction)ufunc_outer,
- METH_VARARGS | METH_KEYWORDS, NULL},
+ METH_FASTCALL | METH_KEYWORDS, NULL},
{"at",
(PyCFunction)ufunc_at,
METH_VARARGS, NULL},
@@ -5980,7 +6220,7 @@ _typecharfromnum(int num) {
static PyObject *
-ufunc_get_doc(PyUFuncObject *ufunc)
+ufunc_get_doc(PyUFuncObject *ufunc, void *NPY_UNUSED(ignored))
{
static PyObject *_sig_formatter;
PyObject *doc;
@@ -6012,31 +6252,31 @@ ufunc_get_doc(PyUFuncObject *ufunc)
static PyObject *
-ufunc_get_nin(PyUFuncObject *ufunc)
+ufunc_get_nin(PyUFuncObject *ufunc, void *NPY_UNUSED(ignored))
{
return PyLong_FromLong(ufunc->nin);
}
static PyObject *
-ufunc_get_nout(PyUFuncObject *ufunc)
+ufunc_get_nout(PyUFuncObject *ufunc, void *NPY_UNUSED(ignored))
{
return PyLong_FromLong(ufunc->nout);
}
static PyObject *
-ufunc_get_nargs(PyUFuncObject *ufunc)
+ufunc_get_nargs(PyUFuncObject *ufunc, void *NPY_UNUSED(ignored))
{
return PyLong_FromLong(ufunc->nargs);
}
static PyObject *
-ufunc_get_ntypes(PyUFuncObject *ufunc)
+ufunc_get_ntypes(PyUFuncObject *ufunc, void *NPY_UNUSED(ignored))
{
return PyLong_FromLong(ufunc->ntypes);
}
static PyObject *
-ufunc_get_types(PyUFuncObject *ufunc)
+ufunc_get_types(PyUFuncObject *ufunc, void *NPY_UNUSED(ignored))
{
/* return a list with types grouped input->output */
PyObject *list;
@@ -6070,20 +6310,20 @@ ufunc_get_types(PyUFuncObject *ufunc)
}
static PyObject *
-ufunc_get_name(PyUFuncObject *ufunc)
+ufunc_get_name(PyUFuncObject *ufunc, void *NPY_UNUSED(ignored))
{
return PyUnicode_FromString(ufunc->name);
}
static PyObject *
-ufunc_get_identity(PyUFuncObject *ufunc)
+ufunc_get_identity(PyUFuncObject *ufunc, void *NPY_UNUSED(ignored))
{
npy_bool reorderable;
return _get_identity(ufunc, &reorderable);
}
static PyObject *
-ufunc_get_signature(PyUFuncObject *ufunc)
+ufunc_get_signature(PyUFuncObject *ufunc, void *NPY_UNUSED(ignored))
{
if (!ufunc->core_enabled) {
Py_RETURN_NONE;
@@ -6141,10 +6381,17 @@ NPY_NO_EXPORT PyTypeObject PyUFunc_Type = {
.tp_repr = (reprfunc)ufunc_repr,
.tp_call = (ternaryfunc)ufunc_generic_call,
.tp_str = (reprfunc)ufunc_repr,
- .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
+ .tp_flags = Py_TPFLAGS_DEFAULT |
+#if PY_VERSION_HEX >= 0x03080000
+ _Py_TPFLAGS_HAVE_VECTORCALL |
+#endif
+ Py_TPFLAGS_HAVE_GC,
.tp_traverse = (traverseproc)ufunc_traverse,
.tp_methods = ufunc_methods,
.tp_getset = ufunc_getset,
+#if PY_VERSION_HEX >= 0x03080000
+ .tp_vectorcall_offset = offsetof(PyUFuncObject, vectorcall),
+#endif
};
/* End of code for ufunc objects */
diff --git a/numpy/core/src/umath/ufunc_object.h b/numpy/core/src/umath/ufunc_object.h
index f5de9f9b7..6d4fed7c0 100644
--- a/numpy/core/src/umath/ufunc_object.h
+++ b/numpy/core/src/umath/ufunc_object.h
@@ -13,22 +13,8 @@ NPY_NO_EXPORT const char*
ufunc_get_name_cstr(PyUFuncObject *ufunc);
/* strings from umathmodule.c that are interned on umath import */
-NPY_VISIBILITY_HIDDEN extern PyObject *npy_um_str_out;
-NPY_VISIBILITY_HIDDEN extern PyObject *npy_um_str_where;
-NPY_VISIBILITY_HIDDEN extern PyObject *npy_um_str_axes;
-NPY_VISIBILITY_HIDDEN extern PyObject *npy_um_str_axis;
-NPY_VISIBILITY_HIDDEN extern PyObject *npy_um_str_keepdims;
-NPY_VISIBILITY_HIDDEN extern PyObject *npy_um_str_casting;
-NPY_VISIBILITY_HIDDEN extern PyObject *npy_um_str_order;
-NPY_VISIBILITY_HIDDEN extern PyObject *npy_um_str_dtype;
-NPY_VISIBILITY_HIDDEN extern PyObject *npy_um_str_subok;
-NPY_VISIBILITY_HIDDEN extern PyObject *npy_um_str_signature;
-NPY_VISIBILITY_HIDDEN extern PyObject *npy_um_str_sig;
-NPY_VISIBILITY_HIDDEN extern PyObject *npy_um_str_extobj;
NPY_VISIBILITY_HIDDEN extern PyObject *npy_um_str_array_prepare;
NPY_VISIBILITY_HIDDEN extern PyObject *npy_um_str_array_wrap;
-NPY_VISIBILITY_HIDDEN extern PyObject *npy_um_str_array_finalize;
-NPY_VISIBILITY_HIDDEN extern PyObject *npy_um_str_ufunc;
NPY_VISIBILITY_HIDDEN extern PyObject *npy_um_str_pyvals_name;
#endif
diff --git a/numpy/core/src/umath/ufunc_type_resolution.c b/numpy/core/src/umath/ufunc_type_resolution.c
index 3abeb2c5a..a7d536656 100644
--- a/numpy/core/src/umath/ufunc_type_resolution.c
+++ b/numpy/core/src/umath/ufunc_type_resolution.c
@@ -1,4 +1,16 @@
/*
+ * NOTE: The type resolution defined in this file is considered legacy.
+ *
+ * The new mechanism separates type resolution and promotion into two
+ * distinct steps, as per NEP 43.
+ * Further, the functions in this file rely on the operands rather than
+ * only the DTypes/descriptors. They are still called and at this point
+ * vital (NumPy ~1.21), but should hopefully become largely irrelevant very
+ * quickly.
+ *
+ * At that point, this file should be deletable in its entirety.
+ *
+ *
* This file implements type resolution for NumPy element-wise ufuncs.
* This mechanism is still backwards-compatible with the pre-existing
* legacy mechanism, so performs much slower than is necessary.
@@ -12,6 +24,11 @@
#define _MULTIARRAYMODULE
#define NPY_NO_DEPRECATED_API NPY_API_VERSION
+// printif debug tracing
+#ifndef NPY_UF_DBG_TRACING
+ #define NPY_UF_DBG_TRACING 0
+#endif
+
#include <stdbool.h>
#include "Python.h"
@@ -84,14 +101,11 @@ raise_binary_type_reso_error(PyUFuncObject *ufunc, PyArrayObject **operands) {
/** Helper function to raise UFuncNoLoopError
* Always returns -1 to indicate the exception was raised, for convenience
*/
-static int
+NPY_NO_EXPORT int
raise_no_loop_found_error(
- PyUFuncObject *ufunc, PyArray_Descr **dtypes)
+ PyUFuncObject *ufunc, PyObject **dtypes)
{
static PyObject *exc_type = NULL;
- PyObject *exc_value;
- PyObject *dtypes_tup;
- npy_intp i;
npy_cache_import(
"numpy.core._exceptions", "_UFuncNoLoopError",
@@ -100,20 +114,14 @@ raise_no_loop_found_error(
return -1;
}
- /* convert dtypes to a tuple */
- dtypes_tup = PyTuple_New(ufunc->nargs);
+ PyObject *dtypes_tup = PyArray_TupleFromItems(ufunc->nargs, dtypes, 1);
if (dtypes_tup == NULL) {
return -1;
}
- for (i = 0; i < ufunc->nargs; ++i) {
- Py_INCREF(dtypes[i]);
- PyTuple_SET_ITEM(dtypes_tup, i, (PyObject *)dtypes[i]);
- }
-
/* produce an error object */
- exc_value = PyTuple_Pack(2, ufunc, dtypes_tup);
+ PyObject *exc_value = PyTuple_Pack(2, ufunc, dtypes_tup);
Py_DECREF(dtypes_tup);
- if (exc_value == NULL){
+ if (exc_value == NULL) {
return -1;
}
PyErr_SetObject(exc_type, exc_value);
@@ -122,6 +130,7 @@ raise_no_loop_found_error(
return -1;
}
+
static int
raise_casting_error(
PyObject *exc_type,
@@ -279,7 +288,7 @@ PyUFunc_DefaultTypeResolver(PyUFuncObject *ufunc,
} else {
/* Find the specified ufunc inner loop, and fill in the dtypes */
retval = type_tuple_type_resolver(ufunc, type_tup,
- operands, casting, any_object, out_dtypes);
+ operands, input_casting, casting, any_object, out_dtypes);
}
return retval;
@@ -324,39 +333,72 @@ PyUFunc_SimpleBinaryComparisonTypeResolver(PyUFuncObject *ufunc,
}
if (type_tup == NULL) {
- /* Input types are the result type */
- out_dtypes[0] = PyArray_ResultType(2, operands, 0, NULL);
- if (out_dtypes[0] == NULL) {
- return -1;
+ /*
+ * DEPRECATED NumPy 1.20, 2020-12.
+ * This check is required to avoid the FutureWarning that
+ * ResultType will give for number->string promotions.
+ * (We never supported flexible dtypes here.)
+ */
+ if (!PyArray_ISFLEXIBLE(operands[0]) &&
+ !PyArray_ISFLEXIBLE(operands[1])) {
+ out_dtypes[0] = PyArray_ResultType(2, operands, 0, NULL);
+ if (out_dtypes[0] == NULL) {
+ return -1;
+ }
+ out_dtypes[1] = out_dtypes[0];
+ Py_INCREF(out_dtypes[1]);
+ }
+ else {
+ /* Not doing anything will lead to a loop no found error. */
+ out_dtypes[0] = PyArray_DESCR(operands[0]);
+ Py_INCREF(out_dtypes[0]);
+ out_dtypes[1] = PyArray_DESCR(operands[1]);
+ Py_INCREF(out_dtypes[1]);
}
- out_dtypes[1] = out_dtypes[0];
- Py_INCREF(out_dtypes[1]);
}
else {
- PyObject *item;
- PyArray_Descr *dtype = NULL;
-
+ PyArray_Descr *descr;
/*
- * If the type tuple isn't a single-element tuple, let the
- * default type resolution handle this one.
+ * DEPRECATED 2021-03, NumPy 1.20
+ *
+ * If the type tuple was originally a single element (probably),
+ * issue a deprecation warning, but otherwise accept it. Since the
+ * result dtype is always boolean, this is not actually valid unless it
+ * is `object` (but if there is an object input we already deferred).
+ *
+ * TODO: Once this deprecation is gone, the special case for
+ * `PyUFunc_SimpleBinaryComparisonTypeResolver` in dispatching.c
+ * can be removed.
*/
- if (!PyTuple_Check(type_tup) || PyTuple_GET_SIZE(type_tup) != 1) {
+ if (PyTuple_Check(type_tup) && PyTuple_GET_SIZE(type_tup) == 3 &&
+ PyTuple_GET_ITEM(type_tup, 0) == Py_None &&
+ PyTuple_GET_ITEM(type_tup, 1) == Py_None &&
+ PyArray_DescrCheck(PyTuple_GET_ITEM(type_tup, 2))) {
+ descr = (PyArray_Descr *)PyTuple_GET_ITEM(type_tup, 2);
+ if (descr->type_num == NPY_OBJECT) {
+ if (DEPRECATE_FUTUREWARNING(
+ "using `dtype=object` (or equivalent signature) will "
+ "return object arrays in the future also when the "
+ "inputs do not already have `object` dtype.") < 0) {
+ return -1;
+ }
+ }
+ else if (descr->type_num != NPY_BOOL) {
+ if (DEPRECATE(
+ "using `dtype=` in comparisons is only useful for "
+ "`dtype=object` (and will do nothing for bool). "
+ "This operation will fail in the future.") < 0) {
+ return -1;
+ }
+ }
+ }
+ else {
+ /* Usually a failure, but let the the default version handle it */
return PyUFunc_DefaultTypeResolver(ufunc, casting,
operands, type_tup, out_dtypes);
}
- item = PyTuple_GET_ITEM(type_tup, 0);
-
- if (item == Py_None) {
- PyErr_SetString(PyExc_ValueError,
- "require data type in the type tuple");
- return -1;
- }
- else if (!PyArray_DescrConverter(item, &dtype)) {
- return -1;
- }
-
- out_dtypes[0] = ensure_dtype_nbo(dtype);
+ out_dtypes[0] = ensure_dtype_nbo(descr);
if (out_dtypes[0] == NULL) {
return -1;
}
@@ -483,6 +525,35 @@ PyUFunc_SimpleUniformOperationTypeResolver(
out_dtypes[0] = ensure_dtype_nbo(PyArray_DESCR(operands[0]));
}
else {
+ int iop;
+ npy_bool has_flexible = 0;
+ npy_bool has_object = 0;
+ for (iop = 0; iop < ufunc->nin; iop++) {
+ if (PyArray_ISOBJECT(operands[iop])) {
+ has_object = 1;
+ }
+ if (PyArray_ISFLEXIBLE(operands[iop])) {
+ has_flexible = 1;
+ }
+ }
+ if (NPY_UNLIKELY(has_flexible && !has_object)) {
+ /*
+ * DEPRECATED NumPy 1.20, 2020-12.
+ * This check is required to avoid the FutureWarning that
+ * ResultType will give for number->string promotions.
+ * (We never supported flexible dtypes here.)
+ */
+ for (iop = 0; iop < ufunc->nin; iop++) {
+ out_dtypes[iop] = PyArray_DESCR(operands[iop]);
+ Py_INCREF(out_dtypes[iop]);
+ }
+ raise_no_loop_found_error(ufunc, (PyObject **)out_dtypes);
+ for (iop = 0; iop < ufunc->nin; iop++) {
+ Py_DECREF(out_dtypes[iop]);
+ out_dtypes[iop] = NULL;
+ }
+ return -1;
+ }
out_dtypes[0] = PyArray_ResultType(ufunc->nin, operands, 0, NULL);
}
if (out_dtypes[0] == NULL) {
@@ -490,34 +561,52 @@ PyUFunc_SimpleUniformOperationTypeResolver(
}
}
else {
- PyObject *item;
- PyArray_Descr *dtype = NULL;
-
/*
- * If the type tuple isn't a single-element tuple, let the
- * default type resolution handle this one.
+ * This is a fast-path, since all descriptors will be identical, mainly
+ * when only a single descriptor was passed (which would set the out
+ * one in the tuple), there is no need to check all loops.
+ * Note that this also allows (None, None, float64) to resolve to
+ * (float64, float64, float64), even when the inputs do not match,
+ * i.e. fixing the output part of the signature can fix all of them.
+ * This is necessary to support `nextafter(1., inf, dtype=float32)`,
+ * where it is "clear" we want to cast 1. and inf to float32.
*/
- if (!PyTuple_Check(type_tup) || PyTuple_GET_SIZE(type_tup) != 1) {
+ PyArray_Descr *descr = NULL;
+ if (PyTuple_CheckExact(type_tup) &&
+ PyTuple_GET_SIZE(type_tup) == nop) {
+ for (int i = 0; i < nop; i++) {
+ PyObject *item = PyTuple_GET_ITEM(type_tup, i);
+ if (item == Py_None) {
+ if (i < ufunc->nin) {
+ continue;
+ }
+ /* All outputs must be set (this could be relaxed) */
+ descr = NULL;
+ break;
+ }
+ if (!PyArray_DescrCheck(item)) {
+ /* Defer to default resolver (will raise an error there) */
+ descr = NULL;
+ break;
+ }
+ if (descr != NULL && descr != (PyArray_Descr *)item) {
+ /* Descriptor mismatch: try with default (probable error) */
+ descr = NULL;
+ break;
+ }
+ descr = (PyArray_Descr *)item;
+ }
+ }
+ if (descr == NULL) {
+ /* in all bad/unlikely cases, use the default type resolver: */
return PyUFunc_DefaultTypeResolver(ufunc, casting,
operands, type_tup, out_dtypes);
}
-
- item = PyTuple_GET_ITEM(type_tup, 0);
-
- if (item == Py_None) {
- PyErr_SetString(PyExc_ValueError,
- "require data type in the type tuple");
- return -1;
- }
- else if (!PyArray_DescrConverter(item, &dtype)) {
- return -1;
- }
-
- out_dtypes[0] = ensure_dtype_nbo(dtype);
- Py_DECREF(dtype);
- if (out_dtypes[0] == NULL) {
- return -1;
+ else if (descr->type_num == PyArray_DESCR(operands[0])->type_num) {
+ /* Prefer the input descriptor if it matches (preserve metadata) */
+ descr = PyArray_DESCR(operands[0]);
}
+ out_dtypes[0] = ensure_dtype_nbo(descr);
}
/* All types are the same - copy the first one to the rest */
@@ -1423,139 +1512,10 @@ PyUFunc_DefaultLegacyInnerLoopSelector(PyUFuncObject *ufunc,
types += nargs;
}
- return raise_no_loop_found_error(ufunc, dtypes);
-}
-
-typedef struct {
- NpyAuxData base;
- PyUFuncGenericFunction unmasked_innerloop;
- void *unmasked_innerloopdata;
- int nargs;
-} _ufunc_masker_data;
-
-static NpyAuxData *
-ufunc_masker_data_clone(NpyAuxData *data)
-{
- _ufunc_masker_data *n;
-
- /* Allocate a new one */
- n = (_ufunc_masker_data *)PyArray_malloc(sizeof(_ufunc_masker_data));
- if (n == NULL) {
- return NULL;
- }
-
- /* Copy the data (unmasked data doesn't have object semantics) */
- memcpy(n, data, sizeof(_ufunc_masker_data));
-
- return (NpyAuxData *)n;
-}
-
-/*
- * This function wraps a regular unmasked ufunc inner loop as a
- * masked ufunc inner loop, only calling the function for
- * elements where the mask is True.
- */
-static void
-unmasked_ufunc_loop_as_masked(
- char **dataptrs, npy_intp *strides,
- char *mask, npy_intp mask_stride,
- npy_intp loopsize,
- NpyAuxData *innerloopdata)
-{
- _ufunc_masker_data *data;
- int iargs, nargs;
- PyUFuncGenericFunction unmasked_innerloop;
- void *unmasked_innerloopdata;
- npy_intp subloopsize;
-
- /* Put the aux data into local variables */
- data = (_ufunc_masker_data *)innerloopdata;
- unmasked_innerloop = data->unmasked_innerloop;
- unmasked_innerloopdata = data->unmasked_innerloopdata;
- nargs = data->nargs;
-
- /* Process the data as runs of unmasked values */
- do {
- /* Skip masked values */
- mask = npy_memchr(mask, 0, mask_stride, loopsize, &subloopsize, 1);
- for (iargs = 0; iargs < nargs; ++iargs) {
- dataptrs[iargs] += subloopsize * strides[iargs];
- }
- loopsize -= subloopsize;
- /*
- * Process unmasked values (assumes unmasked loop doesn't
- * mess with the 'args' pointer values)
- */
- mask = npy_memchr(mask, 0, mask_stride, loopsize, &subloopsize, 0);
- unmasked_innerloop(dataptrs, &subloopsize, strides,
- unmasked_innerloopdata);
- for (iargs = 0; iargs < nargs; ++iargs) {
- dataptrs[iargs] += subloopsize * strides[iargs];
- }
- loopsize -= subloopsize;
- } while (loopsize > 0);
+ return raise_no_loop_found_error(ufunc, (PyObject **)dtypes);
}
-/*
- * This function wraps a legacy inner loop so it becomes masked.
- *
- * Returns 0 on success, -1 on error.
- */
-NPY_NO_EXPORT int
-PyUFunc_DefaultMaskedInnerLoopSelector(PyUFuncObject *ufunc,
- PyArray_Descr **dtypes,
- PyArray_Descr *mask_dtype,
- npy_intp *NPY_UNUSED(fixed_strides),
- npy_intp NPY_UNUSED(fixed_mask_stride),
- PyUFunc_MaskedStridedInnerLoopFunc **out_innerloop,
- NpyAuxData **out_innerloopdata,
- int *out_needs_api)
-{
- int retcode;
- _ufunc_masker_data *data;
-
- if (ufunc->legacy_inner_loop_selector == NULL) {
- PyErr_SetString(PyExc_RuntimeError,
- "the ufunc default masked inner loop selector doesn't "
- "yet support wrapping the new inner loop selector, it "
- "still only wraps the legacy inner loop selector");
- return -1;
- }
-
- if (mask_dtype->type_num != NPY_BOOL) {
- PyErr_SetString(PyExc_ValueError,
- "only boolean masks are supported in ufunc inner loops "
- "presently");
- return -1;
- }
-
- /* Create a new NpyAuxData object for the masker data */
- data = (_ufunc_masker_data *)PyArray_malloc(sizeof(_ufunc_masker_data));
- if (data == NULL) {
- PyErr_NoMemory();
- return -1;
- }
- memset(data, 0, sizeof(_ufunc_masker_data));
- data->base.free = (NpyAuxData_FreeFunc *)&PyArray_free;
- data->base.clone = &ufunc_masker_data_clone;
- data->nargs = ufunc->nin + ufunc->nout;
-
- /* Get the unmasked ufunc inner loop */
- retcode = ufunc->legacy_inner_loop_selector(ufunc, dtypes,
- &data->unmasked_innerloop, &data->unmasked_innerloopdata,
- out_needs_api);
- if (retcode < 0) {
- PyArray_free(data);
- return retcode;
- }
-
- /* Return the loop function + aux data */
- *out_innerloop = &unmasked_ufunc_loop_as_masked;
- *out_innerloopdata = (NpyAuxData *)data;
- return 0;
-}
-
static int
ufunc_loop_matches(PyUFuncObject *self,
PyArrayObject **op,
@@ -1589,6 +1549,9 @@ ufunc_loop_matches(PyUFuncObject *self,
if (types[i] == NPY_OBJECT && !any_object && self->ntypes > 1) {
return 0;
}
+ if (types[i] == NPY_NOTYPE) {
+ continue; /* Matched by being explicitly specified. */
+ }
/*
* If type num is NPY_VOID and struct dtypes have been passed in,
@@ -1638,6 +1601,9 @@ ufunc_loop_matches(PyUFuncObject *self,
* outputs.
*/
for (i = nin; i < nop; ++i) {
+ if (types[i] == NPY_NOTYPE) {
+ continue; /* Matched by being explicitly specified. */
+ }
if (op[i] != NULL) {
PyArray_Descr *tmp = PyArray_DescrFromType(types[i]);
if (tmp == NULL) {
@@ -1656,7 +1622,6 @@ ufunc_loop_matches(PyUFuncObject *self,
Py_DECREF(tmp);
}
}
-
return 1;
}
@@ -1797,12 +1762,15 @@ type_tuple_userloop_type_resolver(PyUFuncObject *self,
int n_specified,
int *specified_types,
PyArrayObject **op,
+ NPY_CASTING input_casting,
NPY_CASTING casting,
int any_object,
int use_min_scalar,
PyArray_Descr **out_dtype)
{
int i, j, nin = self->nin, nop = nin + self->nout;
+ assert(n_specified == nop);
+ int types[NPY_MAXARGS];
/* Use this to try to avoid repeating the same userdef loop search */
int last_userdef = -1;
@@ -1835,28 +1803,31 @@ type_tuple_userloop_type_resolver(PyUFuncObject *self,
return -1;
}
for (; funcdata != NULL; funcdata = funcdata->next) {
- int *types = funcdata->arg_types;
- int matched = 1;
-
- if (n_specified == nop) {
- for (j = 0; j < nop; ++j) {
- if (types[j] != specified_types[j] &&
- specified_types[j] != NPY_NOTYPE) {
- matched = 0;
- break;
- }
+ int *orig_types = funcdata->arg_types;
+
+ /*
+ * Copy the types into an int array for matching
+ * (Mostly duplicated in `type_tuple_type_resolver`)
+ */
+ for (j = 0; j < nop; ++j) {
+ if (specified_types[j] == NPY_NOTYPE) {
+ types[j] = orig_types[j];
+ continue;
}
- } else {
- if (types[nin] != specified_types[0]) {
- matched = 0;
+ if (orig_types[j] != specified_types[j]) {
+ break;
}
+ /* indicate that we do not have to check this type anymore. */
+ types[j] = NPY_NOTYPE;
}
- if (!matched) {
+
+ if (j != nop) {
+ /* no match */
continue;
}
switch (ufunc_loop_matches(self, op,
- casting, casting,
+ input_casting, casting,
any_object, use_min_scalar,
types, NULL,
&no_castable_output, &err_src_typecode,
@@ -1864,7 +1835,19 @@ type_tuple_userloop_type_resolver(PyUFuncObject *self,
/* It works */
case 1:
set_ufunc_loop_data_types(self, op,
- out_dtype, types, NULL);
+ out_dtype, orig_types, NULL);
+ /*
+ * In principle, we only need to validate the
+ * NPY_NOTYPE ones
+ */
+ if (PyUFunc_ValidateCasting(self,
+ casting, op, out_dtype) < 0) {
+ for (j = 0; j < self->nargs; j++) {
+ Py_DECREF(out_dtype[j]);
+ out_dtype[j] = NULL;
+ }
+ return -1;
+ }
return 1;
/* Didn't match */
case 0:
@@ -1997,6 +1980,94 @@ linear_search_type_resolver(PyUFuncObject *self,
return -1;
}
+
+static int
+type_tuple_type_resolver_core(PyUFuncObject *self,
+ PyArrayObject **op,
+ NPY_CASTING input_casting, NPY_CASTING casting,
+ int specified_types[],
+ int any_object,
+ int no_castable_output, int use_min_scalar,
+ PyArray_Descr **out_dtype)
+{
+ int i, j;
+ int nop = self->nargs;
+ int types[NPY_MAXARGS];
+
+ /* For making a better error message on coercion error */
+ char err_dst_typecode = '-', err_src_typecode = '-';
+
+ /* If the ufunc has userloops, search for them. */
+ if (self->userloops) {
+ switch (type_tuple_userloop_type_resolver(self,
+ nop, specified_types,
+ op, input_casting, casting,
+ any_object, use_min_scalar,
+ out_dtype)) {
+ /* Error */
+ case -1:
+ return -1;
+ /* Found matching loop */
+ case 1:
+ return 0;
+ }
+ }
+
+ for (i = 0; i < self->ntypes; ++i) {
+ char *orig_types = self->types + i*self->nargs;
+
+ /*
+ * Check specified types and copy into an int array for matching
+ * (Mostly duplicated in `type_tuple_userloop_type_resolver`)
+ */
+ for (j = 0; j < nop; ++j) {
+ if (specified_types[j] == NPY_NOTYPE) {
+ types[j] = orig_types[j];
+ continue;
+ }
+ if (orig_types[j] != specified_types[j]) {
+ break;
+ }
+ /* indicate that we do not have to check this type anymore. */
+ types[j] = NPY_NOTYPE;
+ }
+ if (j < nop) {
+ /* no match */
+ continue;
+ }
+
+ switch (ufunc_loop_matches(self, op,
+ input_casting, casting,
+ any_object, use_min_scalar,
+ types, NULL,
+ &no_castable_output, &err_src_typecode,
+ &err_dst_typecode)) {
+ case -1:
+ /* Error */
+ return -1;
+ case 0:
+ /* Cannot cast inputs */
+ continue;
+ case 1:
+ /* Success, fill also the NPY_NOTYPE (cast from char to int) */
+ for (j = 0; j < nop; j++) {
+ types[j] = orig_types[j];
+ }
+ set_ufunc_loop_data_types(self, op, out_dtype, types, NULL);
+ /* In principle, we only need to validate the NPY_NOTYPE ones */
+ if (PyUFunc_ValidateCasting(self, casting, op, out_dtype) < 0) {
+ for (j = 0; j < self->nargs; j++) {
+ Py_DECREF(out_dtype[j]);
+ out_dtype[j] = NULL;
+ }
+ return -1;
+ }
+ return 0;
+ }
+ }
+ return -2;
+}
+
/*
* Does a linear search for the inner loop of the ufunc specified by type_tup.
*
@@ -2007,176 +2078,101 @@ NPY_NO_EXPORT int
type_tuple_type_resolver(PyUFuncObject *self,
PyObject *type_tup,
PyArrayObject **op,
+ NPY_CASTING input_casting,
NPY_CASTING casting,
int any_object,
PyArray_Descr **out_dtype)
{
- npy_intp i, j, n, nin = self->nin, nop = nin + self->nout;
- int n_specified = 0;
- int specified_types[NPY_MAXARGS], types[NPY_MAXARGS];
+ int nin = self->nin, nop = nin + self->nout;
+ int specified_types[NPY_MAXARGS];
const char *ufunc_name;
- int no_castable_output, use_min_scalar;
-
- /* For making a better error message on coercion error */
- char err_dst_typecode = '-', err_src_typecode = '-';
+ int no_castable_output = 0, use_min_scalar;
ufunc_name = ufunc_get_name_cstr(self);
use_min_scalar = should_use_min_scalar(nin, op, 0, NULL);
/* Fill in specified_types from the tuple or string */
- if (PyTuple_Check(type_tup)) {
- int nonecount = 0;
- n = PyTuple_GET_SIZE(type_tup);
- if (n != 1 && n != nop) {
- PyErr_Format(PyExc_ValueError,
- "a type-tuple must be specified "
- "of length 1 or %d for ufunc '%s'", (int)nop,
- ufunc_get_name_cstr(self));
+ const char *bad_type_tup_msg = (
+ "Only NumPy must call `ufunc->type_resolver()` explicitly. "
+ "NumPy ensures that a type-tuple is normalized now to be a tuple "
+ "only containing None or descriptors. If anything else is passed "
+ "(you are seeing this message), the `type_resolver()` was called "
+ "directly by a third party. "
+ "This is unexpected, please inform the NumPy developers about it. "
+ "Also note that `type_resolver` will be phased out, since it must "
+ "be replaced.");
+
+ if (PyTuple_CheckExact(type_tup)) {
+ Py_ssize_t n = PyTuple_GET_SIZE(type_tup);
+ if (n != nop) {
+ PyErr_SetString(PyExc_RuntimeError, bad_type_tup_msg);
return -1;
}
-
- for (i = 0; i < n; ++i) {
+ for (int i = 0; i < nop; ++i) {
PyObject *item = PyTuple_GET_ITEM(type_tup, i);
if (item == Py_None) {
specified_types[i] = NPY_NOTYPE;
- ++nonecount;
}
else {
- PyArray_Descr *dtype = NULL;
- if (!PyArray_DescrConverter(item, &dtype)) {
+ if (!PyArray_DescrCheck(item)) {
+ PyErr_SetString(PyExc_RuntimeError, bad_type_tup_msg);
return -1;
}
- specified_types[i] = dtype->type_num;
- Py_DECREF(dtype);
+ specified_types[i] = ((PyArray_Descr *)item)->type_num;
}
}
-
- if (nonecount == n) {
- PyErr_SetString(PyExc_ValueError,
- "the type-tuple provided to the ufunc "
- "must specify at least one none-None dtype");
- return -1;
- }
-
- n_specified = n;
}
- else if (PyBytes_Check(type_tup) || PyUnicode_Check(type_tup)) {
- Py_ssize_t length;
- char *str;
- PyObject *str_obj = NULL;
-
- if (PyUnicode_Check(type_tup)) {
- str_obj = PyUnicode_AsASCIIString(type_tup);
- if (str_obj == NULL) {
- return -1;
- }
- type_tup = str_obj;
- }
-
- if (PyBytes_AsStringAndSize(type_tup, &str, &length) < 0) {
- Py_XDECREF(str_obj);
- return -1;
- }
- if (length != 1 && (length != nop + 2 ||
- str[nin] != '-' || str[nin+1] != '>')) {
- PyErr_Format(PyExc_ValueError,
- "a type-string for %s, " \
- "requires 1 typecode, or "
- "%d typecode(s) before " \
- "and %d after the -> sign",
- ufunc_get_name_cstr(self),
- self->nin, self->nout);
- Py_XDECREF(str_obj);
- return -1;
- }
- if (length == 1) {
- PyArray_Descr *dtype;
- n_specified = 1;
- dtype = PyArray_DescrFromType(str[0]);
- if (dtype == NULL) {
- Py_XDECREF(str_obj);
- return -1;
- }
- specified_types[0] = dtype->type_num;
- Py_DECREF(dtype);
- }
- else {
- PyArray_Descr *dtype;
- n_specified = (int)nop;
+ else {
+ PyErr_SetString(PyExc_RuntimeError, bad_type_tup_msg);
+ return -1;
+ }
- for (i = 0; i < nop; ++i) {
- npy_intp istr = i < nin ? i : i+2;
+ int res = type_tuple_type_resolver_core(self,
+ op, input_casting, casting, specified_types, any_object,
+ no_castable_output, use_min_scalar, out_dtype);
- dtype = PyArray_DescrFromType(str[istr]);
- if (dtype == NULL) {
- Py_XDECREF(str_obj);
- return -1;
- }
- specified_types[i] = dtype->type_num;
- Py_DECREF(dtype);
- }
- }
- Py_XDECREF(str_obj);
+ if (res != -2) {
+ return res;
}
- /* If the ufunc has userloops, search for them. */
- if (self->userloops) {
- switch (type_tuple_userloop_type_resolver(self,
- n_specified, specified_types,
- op, casting,
- any_object, use_min_scalar,
- out_dtype)) {
- /* Error */
- case -1:
- return -1;
- /* Found matching loop */
- case 1:
- return 0;
+ /*
+ * When the user passes `dtype=dtype`, it gets translated to
+ * `signature=(None,)*nin + (dtype,)*nout`. If the signature matches that
+ * exactly (could be relaxed but that is not necessary for backcompat),
+ * we also try `signature=(dtype,)*(nin+nout)`.
+ * This used to be the main meaning for `dtype=dtype`, but some calls broke
+ * the expectation, and changing it allows for `dtype=dtype` to be useful
+ * for ufuncs like `np.ldexp` in the future while also normalizing it to
+ * a `signature` early on.
+ */
+ int homogeneous_type = NPY_NOTYPE;
+ if (self->nout > 0) {
+ homogeneous_type = specified_types[nin];
+ for (int i = nin+1; i < nop; i++) {
+ if (specified_types[i] != homogeneous_type) {
+ homogeneous_type = NPY_NOTYPE;
+ break;
+ }
}
}
-
- for (i = 0; i < self->ntypes; ++i) {
- char *orig_types = self->types + i*self->nargs;
-
- /* Copy the types into an int array for matching */
- for (j = 0; j < nop; ++j) {
- types[j] = orig_types[j];
- }
-
- if (n_specified == nop) {
- for (j = 0; j < nop; ++j) {
- if (types[j] != specified_types[j] &&
- specified_types[j] != NPY_NOTYPE) {
- break;
- }
- }
- if (j < nop) {
- /* no match */
- continue;
+ if (homogeneous_type != NPY_NOTYPE) {
+ for (int i = 0; i < nin; i++) {
+ if (specified_types[i] != NPY_NOTYPE) {
+ homogeneous_type = NPY_NOTYPE;
+ break;
}
+ specified_types[i] = homogeneous_type;
}
- else if (types[nin] != specified_types[0]) {
- /* no match */
- continue;
- }
+ }
+ if (homogeneous_type != NPY_NOTYPE) {
+ /* Try again with the homogeneous specified types. */
+ res = type_tuple_type_resolver_core(self,
+ op, input_casting, casting, specified_types, any_object,
+ no_castable_output, use_min_scalar, out_dtype);
- switch (ufunc_loop_matches(self, op,
- casting, casting,
- any_object, use_min_scalar,
- types, NULL,
- &no_castable_output, &err_src_typecode,
- &err_dst_typecode)) {
- case -1:
- /* Error */
- return -1;
- case 0:
- /* Cannot cast inputs */
- continue;
- case 1:
- /* Success */
- set_ufunc_loop_data_types(self, op, out_dtype, types, NULL);
- return 0;
+ if (res != -2) {
+ return res;
}
}
diff --git a/numpy/core/src/umath/ufunc_type_resolution.h b/numpy/core/src/umath/ufunc_type_resolution.h
index 1d6ad3358..dd88a081a 100644
--- a/numpy/core/src/umath/ufunc_type_resolution.h
+++ b/numpy/core/src/umath/ufunc_type_resolution.h
@@ -123,6 +123,7 @@ NPY_NO_EXPORT int
type_tuple_type_resolver(PyUFuncObject *self,
PyObject *type_tup,
PyArrayObject **op,
+ NPY_CASTING input_casting,
NPY_CASTING casting,
int any_object,
PyArray_Descr **out_dtype);
@@ -135,14 +136,6 @@ PyUFunc_DefaultLegacyInnerLoopSelector(PyUFuncObject *ufunc,
int *out_needs_api);
NPY_NO_EXPORT int
-PyUFunc_DefaultMaskedInnerLoopSelector(PyUFuncObject *ufunc,
- PyArray_Descr **dtypes,
- PyArray_Descr *mask_dtypes,
- npy_intp *NPY_UNUSED(fixed_strides),
- npy_intp NPY_UNUSED(fixed_mask_stride),
- PyUFunc_MaskedStridedInnerLoopFunc
- **out_innerloop,
- NpyAuxData **out_innerloopdata,
- int *out_needs_api);
+raise_no_loop_found_error(PyUFuncObject *ufunc, PyObject **dtypes);
#endif
diff --git a/numpy/core/src/umath/umathmodule.c b/numpy/core/src/umath/umathmodule.c
index 474db0245..6a718889b 100644
--- a/numpy/core/src/umath/umathmodule.c
+++ b/numpy/core/src/umath/umathmodule.c
@@ -216,45 +216,26 @@ add_newdoc_ufunc(PyObject *NPY_UNUSED(dummy), PyObject *args)
*****************************************************************************
*/
-NPY_VISIBILITY_HIDDEN PyObject *npy_um_str_out = NULL;
-NPY_VISIBILITY_HIDDEN PyObject *npy_um_str_where = NULL;
-NPY_VISIBILITY_HIDDEN PyObject *npy_um_str_axes = NULL;
-NPY_VISIBILITY_HIDDEN PyObject *npy_um_str_axis = NULL;
-NPY_VISIBILITY_HIDDEN PyObject *npy_um_str_keepdims = NULL;
-NPY_VISIBILITY_HIDDEN PyObject *npy_um_str_casting = NULL;
-NPY_VISIBILITY_HIDDEN PyObject *npy_um_str_order = NULL;
-NPY_VISIBILITY_HIDDEN PyObject *npy_um_str_dtype = NULL;
-NPY_VISIBILITY_HIDDEN PyObject *npy_um_str_subok = NULL;
-NPY_VISIBILITY_HIDDEN PyObject *npy_um_str_signature = NULL;
-NPY_VISIBILITY_HIDDEN PyObject *npy_um_str_sig = NULL;
-NPY_VISIBILITY_HIDDEN PyObject *npy_um_str_extobj = NULL;
NPY_VISIBILITY_HIDDEN PyObject *npy_um_str_array_prepare = NULL;
NPY_VISIBILITY_HIDDEN PyObject *npy_um_str_array_wrap = NULL;
-NPY_VISIBILITY_HIDDEN PyObject *npy_um_str_array_finalize = NULL;
-NPY_VISIBILITY_HIDDEN PyObject *npy_um_str_ufunc = NULL;
NPY_VISIBILITY_HIDDEN PyObject *npy_um_str_pyvals_name = NULL;
/* intern some strings used in ufuncs, returns 0 on success */
static int
intern_strings(void)
{
- if (!(npy_um_str_out = PyUnicode_InternFromString("out"))) return -1;
- if (!(npy_um_str_where = PyUnicode_InternFromString("where"))) return -1;
- if (!(npy_um_str_axes = PyUnicode_InternFromString("axes"))) return -1;
- if (!(npy_um_str_axis = PyUnicode_InternFromString("axis"))) return -1;
- if (!(npy_um_str_keepdims = PyUnicode_InternFromString("keepdims"))) return -1;
- if (!(npy_um_str_casting = PyUnicode_InternFromString("casting"))) return -1;
- if (!(npy_um_str_order = PyUnicode_InternFromString("order"))) return -1;
- if (!(npy_um_str_dtype = PyUnicode_InternFromString("dtype"))) return -1;
- if (!(npy_um_str_subok = PyUnicode_InternFromString("subok"))) return -1;
- if (!(npy_um_str_signature = PyUnicode_InternFromString("signature"))) return -1;
- if (!(npy_um_str_sig = PyUnicode_InternFromString("sig"))) return -1;
- if (!(npy_um_str_extobj = PyUnicode_InternFromString("extobj"))) return -1;
- if (!(npy_um_str_array_prepare = PyUnicode_InternFromString("__array_prepare__"))) return -1;
- if (!(npy_um_str_array_wrap = PyUnicode_InternFromString("__array_wrap__"))) return -1;
- if (!(npy_um_str_array_finalize = PyUnicode_InternFromString("__array_finalize__"))) return -1;
- if (!(npy_um_str_ufunc = PyUnicode_InternFromString("__array_ufunc__"))) return -1;
- if (!(npy_um_str_pyvals_name = PyUnicode_InternFromString(UFUNC_PYVALS_NAME))) return -1;
+ npy_um_str_array_prepare = PyUnicode_InternFromString("__array_prepare__");
+ if (npy_um_str_array_prepare == NULL) {
+ return -1;
+ }
+ npy_um_str_array_wrap = PyUnicode_InternFromString("__array_wrap__");
+ if (npy_um_str_array_wrap == NULL) {
+ return -1;
+ }
+ npy_um_str_pyvals_name = PyUnicode_InternFromString(UFUNC_PYVALS_NAME);
+ if (npy_um_str_pyvals_name == NULL) {
+ return -1;
+ }
return 0;
}
diff --git a/numpy/core/tests/data/generate_umath_validation_data.cpp b/numpy/core/tests/data/generate_umath_validation_data.cpp
new file mode 100644
index 000000000..9d97ff4ab
--- /dev/null
+++ b/numpy/core/tests/data/generate_umath_validation_data.cpp
@@ -0,0 +1,157 @@
+#include<math.h>
+#include<stdio.h>
+#include<iostream>
+#include<algorithm>
+#include<vector>
+#include<random>
+#include<fstream>
+#include<time.h>
+
+struct ufunc {
+ std::string name;
+ double (*f32func) (double);
+ long double (*f64func) (long double);
+ float f32ulp;
+ float f64ulp;
+};
+
+template<typename T>
+T RandomFloat(T a, T b) {
+ T random = ((T) rand()) / (T) RAND_MAX;
+ T diff = b - a;
+ T r = random * diff;
+ return a + r;
+}
+
+template<typename T>
+void append_random_array(std::vector<T>& arr, T min, T max, size_t N)
+{
+ for (size_t ii = 0; ii < N; ++ii)
+ arr.emplace_back(RandomFloat<T>(min, max));
+}
+
+template<typename T1, typename T2>
+std::vector<T1> computeTrueVal(const std::vector<T1>& in, T2(*mathfunc)(T2)) {
+ std::vector<T1> out;
+ for (T1 elem : in) {
+ T2 elem_d = (T2) elem;
+ T1 out_elem = (T1) mathfunc(elem_d);
+ out.emplace_back(out_elem);
+ }
+ return out;
+}
+
+/*
+ * FP range:
+ * [-inf, -maxflt, -1., -minflt, -minden, 0., minden, minflt, 1., maxflt, inf]
+ */
+
+#define MINDEN std::numeric_limits<T>::denorm_min()
+#define MINFLT std::numeric_limits<T>::min()
+#define MAXFLT std::numeric_limits<T>::max()
+#define INF std::numeric_limits<T>::infinity()
+#define qNAN std::numeric_limits<T>::quiet_NaN()
+#define sNAN std::numeric_limits<T>::signaling_NaN()
+
+template<typename T>
+std::vector<T> generate_input_vector(std::string func) {
+ std::vector<T> input = {MINDEN, -MINDEN, MINFLT, -MINFLT, MAXFLT, -MAXFLT,
+ INF, -INF, qNAN, sNAN, -1.0, 1.0, 0.0, -0.0};
+
+ // [-1.0, 1.0]
+ if ((func == "arcsin") || (func == "arccos") || (func == "arctanh")){
+ append_random_array<T>(input, -1.0, 1.0, 700);
+ }
+ // (0.0, INF]
+ else if ((func == "log2") || (func == "log10")) {
+ append_random_array<T>(input, 0.0, 1.0, 200);
+ append_random_array<T>(input, MINDEN, MINFLT, 200);
+ append_random_array<T>(input, MINFLT, 1.0, 200);
+ append_random_array<T>(input, 1.0, MAXFLT, 200);
+ }
+ // (-1.0, INF]
+ else if (func == "log1p") {
+ append_random_array<T>(input, -1.0, 1.0, 200);
+ append_random_array<T>(input, -MINFLT, -MINDEN, 100);
+ append_random_array<T>(input, -1.0, -MINFLT, 100);
+ append_random_array<T>(input, MINDEN, MINFLT, 100);
+ append_random_array<T>(input, MINFLT, 1.0, 100);
+ append_random_array<T>(input, 1.0, MAXFLT, 100);
+ }
+ // [1.0, INF]
+ else if (func == "arccosh") {
+ append_random_array<T>(input, 1.0, 2.0, 400);
+ append_random_array<T>(input, 2.0, MAXFLT, 300);
+ }
+ // [-INF, INF]
+ else {
+ append_random_array<T>(input, -1.0, 1.0, 100);
+ append_random_array<T>(input, MINDEN, MINFLT, 100);
+ append_random_array<T>(input, -MINFLT, -MINDEN, 100);
+ append_random_array<T>(input, MINFLT, 1.0, 100);
+ append_random_array<T>(input, -1.0, -MINFLT, 100);
+ append_random_array<T>(input, 1.0, MAXFLT, 100);
+ append_random_array<T>(input, -MAXFLT, -100.0, 100);
+ }
+
+ std::random_shuffle(input.begin(), input.end());
+ return input;
+}
+
+int main() {
+ srand (42);
+ std::vector<struct ufunc> umathfunc = {
+ {"sin",sin,sin,2.37,3.3},
+ {"cos",cos,cos,2.36,3.38},
+ {"tan",tan,tan,3.91,3.93},
+ {"arcsin",asin,asin,3.12,2.55},
+ {"arccos",acos,acos,2.1,1.67},
+ {"arctan",atan,atan,2.3,2.52},
+ {"sinh",sinh,sinh,1.55,1.89},
+ {"cosh",cosh,cosh,2.48,1.97},
+ {"tanh",tanh,tanh,1.38,1.19},
+ {"arcsinh",asinh,asinh,1.01,1.48},
+ {"arccosh",acosh,acosh,1.16,1.05},
+ {"arctanh",atanh,atanh,1.45,1.46},
+ {"cbrt",cbrt,cbrt,1.94,1.82},
+ //{"exp",exp,exp,3.76,1.53},
+ {"exp2",exp2,exp2,1.01,1.04},
+ {"expm1",expm1,expm1,2.62,2.1},
+ //{"log",log,log,1.84,1.67},
+ {"log10",log10,log10,3.5,1.92},
+ {"log1p",log1p,log1p,1.96,1.93},
+ {"log2",log2,log2,2.12,1.84},
+ };
+
+ for (int ii = 0; ii < umathfunc.size(); ++ii) {
+ // ignore sin/cos
+ if ((umathfunc[ii].name != "sin") && (umathfunc[ii].name != "cos")) {
+ std::string fileName = "umath-validation-set-" + umathfunc[ii].name + ".csv";
+ std::ofstream txtOut;
+ txtOut.open (fileName, std::ofstream::trunc);
+ txtOut << "dtype,input,output,ulperrortol" << std::endl;
+
+ // Single Precision
+ auto f32in = generate_input_vector<float>(umathfunc[ii].name);
+ auto f32out = computeTrueVal<float, double>(f32in, umathfunc[ii].f32func);
+ for (int jj = 0; jj < f32in.size(); ++jj) {
+ txtOut << "np.float32" << std::hex <<
+ ",0x" << *reinterpret_cast<uint32_t*>(&f32in[jj]) <<
+ ",0x" << *reinterpret_cast<uint32_t*>(&f32out[jj]) <<
+ "," << ceil(umathfunc[ii].f32ulp) << std::endl;
+ }
+
+ // Double Precision
+ auto f64in = generate_input_vector<double>(umathfunc[ii].name);
+ auto f64out = computeTrueVal<double, long double>(f64in, umathfunc[ii].f64func);
+ for (int jj = 0; jj < f64in.size(); ++jj) {
+ txtOut << "np.float64" << std::hex <<
+ ",0x" << *reinterpret_cast<uint64_t*>(&f64in[jj]) <<
+ ",0x" << *reinterpret_cast<uint64_t*>(&f64out[jj]) <<
+ "," << ceil(umathfunc[ii].f64ulp) << std::endl;
+ }
+ txtOut.close();
+ }
+ }
+ return 0;
+}
diff --git a/numpy/core/tests/data/umath-validation-set-README b/numpy/core/tests/data/umath-validation-set-README.txt
index 6561ca3b5..cfc9e4145 100644
--- a/numpy/core/tests/data/umath-validation-set-README
+++ b/numpy/core/tests/data/umath-validation-set-README.txt
@@ -1,5 +1,5 @@
Steps to validate transcendental functions:
-1) Add a file 'umath-validation-set-<ufuncname>', where ufuncname is name of
+1) Add a file 'umath-validation-set-<ufuncname>.txt', where ufuncname is name of
the function in NumPy you want to validate
2) The file should contain 4 columns: dtype,input,expected output,ulperror
a. dtype: one of np.float16, np.float32, np.float64
@@ -11,5 +11,5 @@ Steps to validate transcendental functions:
d. ulperror: expected maximum ulp error of the function. This
should be same across all rows of the same dtype. Otherwise, the function is
tested for the maximum ulp error among all entries of that dtype.
-3) Add file umath-validation-set-<ufuncname> to the test file test_umath_accuracy.py
+3) Add file umath-validation-set-<ufuncname>.txt to the test file test_umath_accuracy.py
which will then validate your ufunc.
diff --git a/numpy/core/tests/data/umath-validation-set-arccos.csv b/numpy/core/tests/data/umath-validation-set-arccos.csv
new file mode 100644
index 000000000..6697ae956
--- /dev/null
+++ b/numpy/core/tests/data/umath-validation-set-arccos.csv
@@ -0,0 +1,1429 @@
+dtype,input,output,ulperrortol
+np.float32,0xbddd7f50,0x3fd6eec2,3
+np.float32,0xbe32a20c,0x3fdf8182,3
+np.float32,0xbf607c09,0x4028f84f,3
+np.float32,0x3f25d906,0x3f5db544,3
+np.float32,0x3f01cec8,0x3f84febf,3
+np.float32,0x3f1d5c6e,0x3f68a735,3
+np.float32,0xbf0cab89,0x4009c36d,3
+np.float32,0xbf176b40,0x400d0941,3
+np.float32,0x3f3248b2,0x3f4ce6d4,3
+np.float32,0x3f390b48,0x3f434e0d,3
+np.float32,0xbe261698,0x3fddea43,3
+np.float32,0x3f0e1154,0x3f7b848b,3
+np.float32,0xbf379a3c,0x4017b764,3
+np.float32,0xbeda6f2c,0x4000bd62,3
+np.float32,0xbf6a0c3f,0x402e5d5a,3
+np.float32,0x3ef1d700,0x3f8a17b7,3
+np.float32,0xbf6f4f65,0x4031d30d,3
+np.float32,0x3f2c9eee,0x3f54adfd,3
+np.float32,0x3f3cfb18,0x3f3d8a1e,3
+np.float32,0x3ba80800,0x3fc867d2,3
+np.float32,0x3e723b08,0x3faa7e4d,3
+np.float32,0xbf65820f,0x402bb054,3
+np.float32,0xbee64e7a,0x40026410,3
+np.float32,0x3cb15140,0x3fc64a87,3
+np.float32,0x3f193660,0x3f6ddf2a,3
+np.float32,0xbf0e5b52,0x400a44f7,3
+np.float32,0x3ed55f14,0x3f920a4b,3
+np.float32,0x3dd11a80,0x3fbbf85c,3
+np.float32,0xbf4f5c4b,0x4020f4f9,3
+np.float32,0x3f787532,0x3e792e87,3
+np.float32,0x3f40e6ac,0x3f37a74f,3
+np.float32,0x3f1c1318,0x3f6a47b6,3
+np.float32,0xbe3c48d8,0x3fe0bb70,3
+np.float32,0xbe94d4bc,0x3feed08e,3
+np.float32,0xbe5c3688,0x3fe4ce26,3
+np.float32,0xbf6fe026,0x403239cb,3
+np.float32,0x3ea5983c,0x3f9ee7bf,3
+np.float32,0x3f1471e6,0x3f73c5bb,3
+np.float32,0x3f0e2622,0x3f7b6b87,3
+np.float32,0xbf597180,0x40257ad1,3
+np.float32,0xbeb5321c,0x3ff75d34,3
+np.float32,0x3f5afcd2,0x3f0b6012,3
+np.float32,0xbef2ff88,0x40042e14,3
+np.float32,0xbedc747e,0x400104f5,3
+np.float32,0xbee0c2f4,0x40019dfc,3
+np.float32,0xbf152cd8,0x400c57dc,3
+np.float32,0xbf6cf9e2,0x40303bbe,3
+np.float32,0x3ed9cd74,0x3f90d1a1,3
+np.float32,0xbf754406,0x4036767f,3
+np.float32,0x3f59c5c2,0x3f0db42f,3
+np.float32,0x3f2eefd8,0x3f518684,3
+np.float32,0xbf156bf9,0x400c6b49,3
+np.float32,0xbd550790,0x3fcfb8dc,3
+np.float32,0x3ede58fc,0x3f8f8f77,3
+np.float32,0xbf00ac19,0x40063c4b,3
+np.float32,0x3f4d25ba,0x3f24280e,3
+np.float32,0xbe9568be,0x3feef73c,3
+np.float32,0x3f67d154,0x3ee05547,3
+np.float32,0x3f617226,0x3efcb4f4,3
+np.float32,0xbf3ab41a,0x4018d6cc,3
+np.float32,0xbf3186fe,0x401592cd,3
+np.float32,0x3de3ba50,0x3fbacca9,3
+np.float32,0x3e789f98,0x3fa9ab97,3
+np.float32,0x3f016e08,0x3f8536d8,3
+np.float32,0x3e8b618c,0x3fa5c571,3
+np.float32,0x3eff97bc,0x3f8628a9,3
+np.float32,0xbf6729f0,0x402ca32f,3
+np.float32,0xbebec146,0x3ff9eddc,3
+np.float32,0x3ddb2e60,0x3fbb563a,3
+np.float32,0x3caa8e40,0x3fc66595,3
+np.float32,0xbf5973f2,0x40257bfa,3
+np.float32,0xbdd82c70,0x3fd69916,3
+np.float32,0xbedf4c82,0x400169ef,3
+np.float32,0x3ef8f22c,0x3f881184,3
+np.float32,0xbf1d74d4,0x400eedc9,3
+np.float32,0x3f2e10a6,0x3f52b790,3
+np.float32,0xbf08ecc0,0x4008a628,3
+np.float32,0x3ecb7db4,0x3f94be9f,3
+np.float32,0xbf052ded,0x40078bfc,3
+np.float32,0x3f2ee78a,0x3f5191e4,3
+np.float32,0xbf56f4e1,0x40245194,3
+np.float32,0x3f600a3e,0x3f014a25,3
+np.float32,0x3f3836f8,0x3f44808b,3
+np.float32,0x3ecabfbc,0x3f94f25c,3
+np.float32,0x3c70f500,0x3fc72dec,3
+np.float32,0x3f17c444,0x3f6fabf0,3
+np.float32,0xbf4c22a5,0x401f9a09,3
+np.float32,0xbe4205dc,0x3fe1765a,3
+np.float32,0x3ea49138,0x3f9f2d36,3
+np.float32,0xbece0082,0x3ffe106b,3
+np.float32,0xbe387578,0x3fe03eef,3
+np.float32,0xbf2b6466,0x40137a30,3
+np.float32,0xbe9dadb2,0x3ff12204,3
+np.float32,0xbf56b3f2,0x402433bb,3
+np.float32,0xbdf9b4d8,0x3fd8b51f,3
+np.float32,0x3f58a596,0x3f0fd4b4,3
+np.float32,0xbedf5748,0x40016b6e,3
+np.float32,0x3f446442,0x3f32476f,3
+np.float32,0x3f5be886,0x3f099658,3
+np.float32,0x3ea1e44c,0x3f9fe1de,3
+np.float32,0xbf11e9b8,0x400b585f,3
+np.float32,0xbf231f8f,0x4010befb,3
+np.float32,0xbf4395ea,0x401c2dd0,3
+np.float32,0x3e9e7784,0x3fa0c8a6,3
+np.float32,0xbe255184,0x3fddd14c,3
+np.float32,0x3f70d25e,0x3eb13148,3
+np.float32,0x3f220cdc,0x3f62a722,3
+np.float32,0xbd027bf0,0x3fcd23e7,3
+np.float32,0x3e4ef8b8,0x3faf02d2,3
+np.float32,0xbf76fc6b,0x40380728,3
+np.float32,0xbf57e761,0x4024c1cd,3
+np.float32,0x3ed4fc20,0x3f922580,3
+np.float32,0xbf09b64a,0x4008e1db,3
+np.float32,0x3f21ca62,0x3f62fcf5,3
+np.float32,0xbe55f610,0x3fe40170,3
+np.float32,0xbc0def80,0x3fca2bbb,3
+np.float32,0xbebc8764,0x3ff9547b,3
+np.float32,0x3ec1b200,0x3f9766d1,3
+np.float32,0xbf4ee44e,0x4020c1ee,3
+np.float32,0xbea85852,0x3ff3f22a,3
+np.float32,0xbf195c0c,0x400da3d3,3
+np.float32,0xbf754b5d,0x40367ce8,3
+np.float32,0xbdcbfe50,0x3fd5d52b,3
+np.float32,0xbf1adb87,0x400e1be3,3
+np.float32,0xbf6f8491,0x4031f898,3
+np.float32,0xbf6f9ae7,0x4032086e,3
+np.float32,0xbf52b3f0,0x40226790,3
+np.float32,0xbf698452,0x402e09f4,3
+np.float32,0xbf43dc9a,0x401c493a,3
+np.float32,0xbf165f7f,0x400cb664,3
+np.float32,0x3e635468,0x3fac682f,3
+np.float32,0xbe8cf2b6,0x3fecc28a,3
+np.float32,0x7f7fffff,0x7fc00000,3
+np.float32,0xbf4c6513,0x401fb597,3
+np.float32,0xbf02b8f8,0x4006d47e,3
+np.float32,0x3ed3759c,0x3f9290c8,3
+np.float32,0xbf2a7a5f,0x40132b98,3
+np.float32,0xbae65000,0x3fc9496f,3
+np.float32,0x3f65f5ea,0x3ee8ef07,3
+np.float32,0xbe7712fc,0x3fe84106,3
+np.float32,0xbb9ff700,0x3fc9afd2,3
+np.float32,0x3d8d87a0,0x3fc03592,3
+np.float32,0xbefc921c,0x40058c23,3
+np.float32,0xbf286566,0x401279d8,3
+np.float32,0x3f53857e,0x3f192eaf,3
+np.float32,0xbee9b0f4,0x4002dd90,3
+np.float32,0x3f4041f8,0x3f38a14a,3
+np.float32,0x3f54ea96,0x3f16b02d,3
+np.float32,0x3ea50ef8,0x3f9f0c01,3
+np.float32,0xbeaad2dc,0x3ff49a4a,3
+np.float32,0xbec428c8,0x3ffb636f,3
+np.float32,0xbda46178,0x3fd358c7,3
+np.float32,0xbefacfc4,0x40054b7f,3
+np.float32,0xbf7068f9,0x40329c85,3
+np.float32,0x3f70b850,0x3eb1caa7,3
+np.float32,0x7fa00000,0x7fe00000,3
+np.float32,0x80000000,0x3fc90fdb,3
+np.float32,0x3f68d5c8,0x3edb7cf3,3
+np.float32,0x3d9443d0,0x3fbfc98a,3
+np.float32,0xff7fffff,0x7fc00000,3
+np.float32,0xbeee7ba8,0x40038a5e,3
+np.float32,0xbf0aaaba,0x40092a73,3
+np.float32,0x3f36a4e8,0x3f46c0ee,3
+np.float32,0x3ed268e4,0x3f92da82,3
+np.float32,0xbee6002c,0x4002591b,3
+np.float32,0xbe8f2752,0x3fed5576,3
+np.float32,0x3f525912,0x3f1b40e0,3
+np.float32,0xbe8e151e,0x3fed0e16,3
+np.float32,0x1,0x3fc90fdb,3
+np.float32,0x3ee23b84,0x3f8e7ae1,3
+np.float32,0xbf5961ca,0x40257361,3
+np.float32,0x3f6bbca0,0x3ecd14cd,3
+np.float32,0x3e27b230,0x3fb4014d,3
+np.float32,0xbf183bb8,0x400d49fc,3
+np.float32,0x3f57759c,0x3f120b68,3
+np.float32,0xbd6994c0,0x3fd05d84,3
+np.float32,0xbf1dd684,0x400f0cc8,3
+np.float32,0xbececc1c,0x3ffe480a,3
+np.float32,0xbf48855f,0x401e206d,3
+np.float32,0x3f28c922,0x3f59d382,3
+np.float32,0xbf65c094,0x402bd3b0,3
+np.float32,0x3f657d42,0x3eeb11dd,3
+np.float32,0xbed32d4e,0x3fff7b15,3
+np.float32,0xbf31af02,0x4015a0b1,3
+np.float32,0x3d89eb00,0x3fc06f7f,3
+np.float32,0x3dac2830,0x3fbe4a17,3
+np.float32,0x3f7f7cb6,0x3d81a7df,3
+np.float32,0xbedbb570,0x4000ea82,3
+np.float32,0x3db37830,0x3fbdd4a8,3
+np.float32,0xbf376f48,0x4017a7fd,3
+np.float32,0x3f319f12,0x3f4dd2c9,3
+np.float32,0x7fc00000,0x7fc00000,3
+np.float32,0x3f1b4f70,0x3f6b3e31,3
+np.float32,0x3e33c880,0x3fb278d1,3
+np.float32,0x3f2796e0,0x3f5b69bd,3
+np.float32,0x3f4915d6,0x3f2ad4d0,3
+np.float32,0x3e4db120,0x3faf2ca0,3
+np.float32,0x3ef03dd4,0x3f8a8ba9,3
+np.float32,0x3e96ca88,0x3fa2cbf7,3
+np.float32,0xbeb136ce,0x3ff64d2b,3
+np.float32,0xbf2f3938,0x4014c75e,3
+np.float32,0x3f769dde,0x3e8b0d76,3
+np.float32,0x3f67cec8,0x3ee06148,3
+np.float32,0x3f0a1ade,0x3f80204e,3
+np.float32,0x3e4b9718,0x3faf7144,3
+np.float32,0x3cccb480,0x3fc5dcf3,3
+np.float32,0x3caeb740,0x3fc654f0,3
+np.float32,0x3f684e0e,0x3ede0678,3
+np.float32,0x3f0ba93c,0x3f7e6663,3
+np.float32,0xbf12bbc4,0x400b985e,3
+np.float32,0xbf2a8e1a,0x40133235,3
+np.float32,0x3f42029c,0x3f35f5c5,3
+np.float32,0x3eed1728,0x3f8b6f9c,3
+np.float32,0xbe5779ac,0x3fe432fd,3
+np.float32,0x3f6ed8b8,0x3ebc7e4b,3
+np.float32,0x3eea25b0,0x3f8c43c7,3
+np.float32,0x3f1988a4,0x3f6d786b,3
+np.float32,0xbe751674,0x3fe7ff8a,3
+np.float32,0xbe9f7418,0x3ff1997d,3
+np.float32,0x3dca11d0,0x3fbc6979,3
+np.float32,0x3f795226,0x3e6a6cab,3
+np.float32,0xbea780e0,0x3ff3b926,3
+np.float32,0xbed92770,0x4000901e,3
+np.float32,0xbf3e9f8c,0x401a49f8,3
+np.float32,0x3f0f7054,0x3f79ddb2,3
+np.float32,0x3a99d400,0x3fc8e966,3
+np.float32,0xbef082b0,0x4003d3c6,3
+np.float32,0xbf0d0790,0x4009defb,3
+np.float32,0xbf1649da,0x400cafb4,3
+np.float32,0xbea5aca8,0x3ff33d5c,3
+np.float32,0xbf4e1843,0x40206ba1,3
+np.float32,0xbe3d7d5c,0x3fe0e2ad,3
+np.float32,0xbf0e802d,0x400a500e,3
+np.float32,0xbf0de8f0,0x400a2295,3
+np.float32,0xbf3016ba,0x4015137e,3
+np.float32,0x3f36b1ea,0x3f46ae5d,3
+np.float32,0xbd27f170,0x3fce4fc7,3
+np.float32,0x3e96ec54,0x3fa2c31f,3
+np.float32,0x3eb4dfdc,0x3f9ad87d,3
+np.float32,0x3f5cac6c,0x3f0815cc,3
+np.float32,0xbf0489aa,0x40075bf1,3
+np.float32,0x3df010c0,0x3fba05f5,3
+np.float32,0xbf229f4a,0x4010956a,3
+np.float32,0x3f75e474,0x3e905a99,3
+np.float32,0xbcece6a0,0x3fccc397,3
+np.float32,0xbdb41528,0x3fd454e7,3
+np.float32,0x3ec8b2f8,0x3f958118,3
+np.float32,0x3f5eaa70,0x3f041a1d,3
+np.float32,0xbf32e1cc,0x40160b91,3
+np.float32,0xbe8e6026,0x3fed219c,3
+np.float32,0x3e6b3160,0x3fab65e3,3
+np.float32,0x3e6d7460,0x3fab1b81,3
+np.float32,0xbf13fbde,0x400bfa3b,3
+np.float32,0xbe8235ec,0x3fe9f9e3,3
+np.float32,0x3d71c4a0,0x3fc18096,3
+np.float32,0x3eb769d0,0x3f9a2aa0,3
+np.float32,0xbf68cb3b,0x402d99e4,3
+np.float32,0xbd917610,0x3fd22932,3
+np.float32,0x3d3cba60,0x3fc3297f,3
+np.float32,0xbf383cbe,0x4017f1cc,3
+np.float32,0xbeee96d0,0x40038e34,3
+np.float32,0x3ec89cb4,0x3f958725,3
+np.float32,0x3ebf92d8,0x3f97f95f,3
+np.float32,0x3f30f3da,0x3f4ec021,3
+np.float32,0xbd26b560,0x3fce45e4,3
+np.float32,0xbec0eb12,0x3ffa8330,3
+np.float32,0x3f6d592a,0x3ec4a6c1,3
+np.float32,0x3ea6d39c,0x3f9e9463,3
+np.float32,0x3e884184,0x3fa6951e,3
+np.float32,0x3ea566c4,0x3f9ef4d1,3
+np.float32,0x3f0c8f4c,0x3f7d5380,3
+np.float32,0x3f28e1ba,0x3f59b2cb,3
+np.float32,0x3f798538,0x3e66e1c3,3
+np.float32,0xbe2889b8,0x3fde39b8,3
+np.float32,0x3f3da05e,0x3f3c949c,3
+np.float32,0x3f24d700,0x3f5f073e,3
+np.float32,0xbe5b5768,0x3fe4b198,3
+np.float32,0xbed3b03a,0x3fff9f05,3
+np.float32,0x3e8a1c4c,0x3fa619eb,3
+np.float32,0xbf075d24,0x40083030,3
+np.float32,0x3f765648,0x3e8d1f52,3
+np.float32,0xbf70fc5e,0x403308bb,3
+np.float32,0x3f557ae8,0x3f15ab76,3
+np.float32,0x3f02f7ea,0x3f84521c,3
+np.float32,0x3f7ebbde,0x3dcbc5c5,3
+np.float32,0xbefbdfc6,0x40057285,3
+np.float32,0x3ec687ac,0x3f9617d9,3
+np.float32,0x3e4831c8,0x3fafe01b,3
+np.float32,0x3e25cde0,0x3fb43ea8,3
+np.float32,0x3e4f2ab8,0x3faefc70,3
+np.float32,0x3ea60ae4,0x3f9ec973,3
+np.float32,0xbf1ed55f,0x400f5dde,3
+np.float32,0xbf5ad4aa,0x40262479,3
+np.float32,0x3e8b3594,0x3fa5d0de,3
+np.float32,0x3f3a77aa,0x3f413c80,3
+np.float32,0xbf07512b,0x40082ca9,3
+np.float32,0x3f33d990,0x3f4ab5e5,3
+np.float32,0x3f521556,0x3f1bb78f,3
+np.float32,0xbecf6036,0x3ffe7086,3
+np.float32,0x3db91bd0,0x3fbd7a11,3
+np.float32,0x3ef63a74,0x3f88d839,3
+np.float32,0xbf2f1116,0x4014b99c,3
+np.float32,0xbf17fdc0,0x400d36b9,3
+np.float32,0xbe87df2c,0x3feb7117,3
+np.float32,0x80800000,0x3fc90fdb,3
+np.float32,0x3ee24c1c,0x3f8e7641,3
+np.float32,0x3f688dce,0x3edcd644,3
+np.float32,0xbf0f4e1c,0x400a8e1b,3
+np.float32,0x0,0x3fc90fdb,3
+np.float32,0x3f786eba,0x3e7999d4,3
+np.float32,0xbf404f80,0x401aeca8,3
+np.float32,0xbe9ffb6a,0x3ff1bd18,3
+np.float32,0x3f146bfc,0x3f73ccfd,3
+np.float32,0xbe47d630,0x3fe233ee,3
+np.float32,0xbe95847c,0x3feefe7c,3
+np.float32,0xbf135df0,0x400bc9e5,3
+np.float32,0x3ea19f3c,0x3f9ff411,3
+np.float32,0x3f235e20,0x3f60f247,3
+np.float32,0xbec789ec,0x3ffc4def,3
+np.float32,0x3f04b656,0x3f834db6,3
+np.float32,0x3dfaf440,0x3fb95679,3
+np.float32,0xbe4a7f28,0x3fe28abe,3
+np.float32,0x3ed4850c,0x3f92463b,3
+np.float32,0x3ec4ba5c,0x3f9694dd,3
+np.float32,0xbce24ca0,0x3fcc992b,3
+np.float32,0xbf5b7c6e,0x402675a0,3
+np.float32,0xbea3ce2a,0x3ff2bf04,3
+np.float32,0x3db02c60,0x3fbe0998,3
+np.float32,0x3c47b780,0x3fc78069,3
+np.float32,0x3ed33b20,0x3f92a0d5,3
+np.float32,0xbf4556d7,0x401cdcde,3
+np.float32,0xbe1b6e28,0x3fdc90ec,3
+np.float32,0xbf3289b7,0x4015ecd0,3
+np.float32,0x3df3f240,0x3fb9c76d,3
+np.float32,0x3eefa7d0,0x3f8ab61d,3
+np.float32,0xbe945838,0x3feeb006,3
+np.float32,0xbf0b1386,0x400949a3,3
+np.float32,0x3f77e546,0x3e812cc1,3
+np.float32,0x3e804ba0,0x3fa8a480,3
+np.float32,0x3f43dcea,0x3f331a06,3
+np.float32,0x3eb87450,0x3f99e33c,3
+np.float32,0x3e5f4898,0x3facecea,3
+np.float32,0x3f646640,0x3eeff10e,3
+np.float32,0x3f1aa832,0x3f6c1051,3
+np.float32,0xbebf6bfa,0x3ffa1bdc,3
+np.float32,0xbb77f300,0x3fc98bd4,3
+np.float32,0x3f3587fe,0x3f485645,3
+np.float32,0x3ef85f34,0x3f883b8c,3
+np.float32,0x3f50e584,0x3f1dc82c,3
+np.float32,0x3f1d30a8,0x3f68deb0,3
+np.float32,0x3ee75a78,0x3f8d0c86,3
+np.float32,0x3f2c023a,0x3f5581e1,3
+np.float32,0xbf074e34,0x40082bca,3
+np.float32,0xbead71f0,0x3ff54c6d,3
+np.float32,0xbf39ed88,0x40188e69,3
+np.float32,0x3f5d2fe6,0x3f07118b,3
+np.float32,0xbf1f79f8,0x400f9267,3
+np.float32,0x3e900c58,0x3fa48e99,3
+np.float32,0xbf759cb2,0x4036c47b,3
+np.float32,0x3f63329c,0x3ef5359c,3
+np.float32,0xbf5d6755,0x40276709,3
+np.float32,0x3f2ce31c,0x3f54519a,3
+np.float32,0x7f800000,0x7fc00000,3
+np.float32,0x3f1bf50e,0x3f6a6d9a,3
+np.float32,0x3f258334,0x3f5e25d8,3
+np.float32,0xbf661a3f,0x402c06ac,3
+np.float32,0x3d1654c0,0x3fc45cef,3
+np.float32,0xbef14a36,0x4003f009,3
+np.float32,0xbf356051,0x4016ec3a,3
+np.float32,0x3f6ccc42,0x3ec79193,3
+np.float32,0xbf2fe3d6,0x401501f9,3
+np.float32,0x3deedc80,0x3fba195b,3
+np.float32,0x3f2e5a28,0x3f52533e,3
+np.float32,0x3e6b68b8,0x3fab5ec8,3
+np.float32,0x3e458240,0x3fb037b7,3
+np.float32,0xbf24bab0,0x401144cb,3
+np.float32,0x3f600f4c,0x3f013fb2,3
+np.float32,0x3f021a04,0x3f84d316,3
+np.float32,0x3f741732,0x3e9cc948,3
+np.float32,0x3f0788aa,0x3f81a5b0,3
+np.float32,0x3f28802c,0x3f5a347c,3
+np.float32,0x3c9eb400,0x3fc69500,3
+np.float32,0x3e5d11e8,0x3fad357a,3
+np.float32,0x3d921250,0x3fbfecb9,3
+np.float32,0x3f354866,0x3f48b066,3
+np.float32,0xbf72cf43,0x40346d84,3
+np.float32,0x3eecdbb8,0x3f8b805f,3
+np.float32,0xbee585d0,0x400247fd,3
+np.float32,0x3e3607a8,0x3fb22fc6,3
+np.float32,0xbf0cb7d6,0x4009c71c,3
+np.float32,0xbf56b230,0x402432ec,3
+np.float32,0xbf4ced02,0x401fee29,3
+np.float32,0xbf3a325c,0x4018a776,3
+np.float32,0x3ecae8bc,0x3f94e732,3
+np.float32,0xbe48c7e8,0x3fe252bd,3
+np.float32,0xbe175d7c,0x3fdc0d5b,3
+np.float32,0x3ea78dac,0x3f9e632d,3
+np.float32,0xbe7434a8,0x3fe7e279,3
+np.float32,0x3f1f9e02,0x3f65c7b9,3
+np.float32,0xbe150f2c,0x3fdbc2c2,3
+np.float32,0x3ee13480,0x3f8ec423,3
+np.float32,0x3ecb7d54,0x3f94beb9,3
+np.float32,0x3f1cef42,0x3f693181,3
+np.float32,0xbf1ec06a,0x400f5730,3
+np.float32,0xbe112acc,0x3fdb44e8,3
+np.float32,0xbe77b024,0x3fe85545,3
+np.float32,0x3ec86fe0,0x3f959353,3
+np.float32,0x3f36b326,0x3f46ac9a,3
+np.float32,0x3e581a70,0x3fadd829,3
+np.float32,0xbf032c0c,0x4006f5f9,3
+np.float32,0xbf43b1fd,0x401c38b1,3
+np.float32,0x3f3701b4,0x3f463c5c,3
+np.float32,0x3f1a995a,0x3f6c22f1,3
+np.float32,0xbf05de0b,0x4007bf97,3
+np.float32,0x3d4bd960,0x3fc2b063,3
+np.float32,0x3f0e1618,0x3f7b7ed0,3
+np.float32,0x3edfd420,0x3f8f2628,3
+np.float32,0xbf6662fe,0x402c3047,3
+np.float32,0x3ec0690c,0x3f97bf9b,3
+np.float32,0xbeaf4146,0x3ff5c7a0,3
+np.float32,0x3f5e7764,0x3f04816d,3
+np.float32,0xbedd192c,0x40011bc5,3
+np.float32,0x3eb76350,0x3f9a2c5e,3
+np.float32,0xbed8108c,0x400069a5,3
+np.float32,0xbe59f31c,0x3fe48401,3
+np.float32,0xbea3e1e6,0x3ff2c439,3
+np.float32,0x3e26d1f8,0x3fb41db5,3
+np.float32,0x3f3a0a7c,0x3f41dba5,3
+np.float32,0x3ebae068,0x3f993ce4,3
+np.float32,0x3f2d8e30,0x3f536942,3
+np.float32,0xbe838bbe,0x3fea5247,3
+np.float32,0x3ebe4420,0x3f98538f,3
+np.float32,0xbcc59b80,0x3fcc265c,3
+np.float32,0x3eebb5c8,0x3f8bd334,3
+np.float32,0xbafc3400,0x3fc94ee8,3
+np.float32,0xbf63ddc1,0x402ac683,3
+np.float32,0xbeabdf80,0x3ff4e18f,3
+np.float32,0x3ea863f0,0x3f9e2a78,3
+np.float32,0x3f45b292,0x3f303bc1,3
+np.float32,0xbe68aa60,0x3fe666bf,3
+np.float32,0x3eb9de18,0x3f998239,3
+np.float32,0xbf719d85,0x4033815e,3
+np.float32,0x3edef9a8,0x3f8f62db,3
+np.float32,0xbd7781c0,0x3fd0cd1e,3
+np.float32,0x3f0b3b90,0x3f7ee92a,3
+np.float32,0xbe3eb3b4,0x3fe10a27,3
+np.float32,0xbf31a4c4,0x40159d23,3
+np.float32,0x3e929434,0x3fa3e5b0,3
+np.float32,0xbeb1a90e,0x3ff66b9e,3
+np.float32,0xbeba9b5e,0x3ff8d048,3
+np.float32,0xbf272a84,0x4012119e,3
+np.float32,0x3f1ebbd0,0x3f66e889,3
+np.float32,0x3ed3cdc8,0x3f927893,3
+np.float32,0xbf50dfce,0x40219b58,3
+np.float32,0x3f0c02de,0x3f7dfb62,3
+np.float32,0xbf694de3,0x402de8d2,3
+np.float32,0xbeaeb13e,0x3ff5a14f,3
+np.float32,0xbf61aa7a,0x40299702,3
+np.float32,0xbf13d159,0x400bed35,3
+np.float32,0xbeecd034,0x40034e0b,3
+np.float32,0xbe50c2e8,0x3fe35761,3
+np.float32,0x3f714406,0x3eae8e57,3
+np.float32,0xbf1ca486,0x400eabd8,3
+np.float32,0x3f5858cc,0x3f106497,3
+np.float32,0x3f670288,0x3ee41c84,3
+np.float32,0xbf20bd2c,0x400ff9f5,3
+np.float32,0xbe29afd8,0x3fde5eff,3
+np.float32,0xbf635e6a,0x402a80f3,3
+np.float32,0x3e82b7b0,0x3fa80446,3
+np.float32,0x3e982e7c,0x3fa26ece,3
+np.float32,0x3d9f0e00,0x3fbf1c6a,3
+np.float32,0x3e8299b4,0x3fa80c07,3
+np.float32,0xbf0529c1,0x40078ac3,3
+np.float32,0xbf403b8a,0x401ae519,3
+np.float32,0xbe57e09c,0x3fe44027,3
+np.float32,0x3ea1c8f4,0x3f9fe913,3
+np.float32,0xbe216a94,0x3fdd52d0,3
+np.float32,0x3f59c442,0x3f0db709,3
+np.float32,0xbd636260,0x3fd02bdd,3
+np.float32,0xbdbbc788,0x3fd4d08d,3
+np.float32,0x3dd19560,0x3fbbf0a3,3
+np.float32,0x3f060ad4,0x3f828641,3
+np.float32,0x3b102e00,0x3fc8c7c4,3
+np.float32,0x3f42b3b8,0x3f34e5a6,3
+np.float32,0x3f0255ac,0x3f84b071,3
+np.float32,0xbf014898,0x40066996,3
+np.float32,0x3e004dc0,0x3fb8fb51,3
+np.float32,0xbf594ff8,0x40256af2,3
+np.float32,0x3efafddc,0x3f877b80,3
+np.float32,0xbf5f0780,0x40283899,3
+np.float32,0x3ee95e54,0x3f8c7bcc,3
+np.float32,0x3eba2f0c,0x3f996c80,3
+np.float32,0x3f37721c,0x3f459b68,3
+np.float32,0x3e2be780,0x3fb378bf,3
+np.float32,0x3e550270,0x3fae3d69,3
+np.float32,0x3e0f9500,0x3fb70e0a,3
+np.float32,0xbf51974a,0x4021eaf4,3
+np.float32,0x3f393832,0x3f430d05,3
+np.float32,0x3f3df16a,0x3f3c1bd8,3
+np.float32,0xbd662340,0x3fd041ed,3
+np.float32,0x3f7e8418,0x3ddc9fce,3
+np.float32,0xbf392734,0x40184672,3
+np.float32,0x3ee3b278,0x3f8e124e,3
+np.float32,0x3eed4808,0x3f8b61d2,3
+np.float32,0xbf6fccbd,0x40322beb,3
+np.float32,0x3e3ecdd0,0x3fb1123b,3
+np.float32,0x3f4419e0,0x3f32bb45,3
+np.float32,0x3f595e00,0x3f0e7914,3
+np.float32,0xbe8c1486,0x3fec88c6,3
+np.float32,0xbf800000,0x40490fdb,3
+np.float32,0xbdaf5020,0x3fd4084d,3
+np.float32,0xbf407660,0x401afb63,3
+np.float32,0x3f0c3aa8,0x3f7db8b8,3
+np.float32,0xbcdb5980,0x3fcc7d5b,3
+np.float32,0x3f4738d4,0x3f2dd1ed,3
+np.float32,0x3f4d7064,0x3f23ab14,3
+np.float32,0xbeb1d576,0x3ff67774,3
+np.float32,0xbf507166,0x40216bb3,3
+np.float32,0x3e86484c,0x3fa71813,3
+np.float32,0x3f09123e,0x3f80bd35,3
+np.float32,0xbe9abe0e,0x3ff05cb2,3
+np.float32,0x3f3019dc,0x3f4fed21,3
+np.float32,0xbe99e00e,0x3ff0227d,3
+np.float32,0xbf155ec5,0x400c6739,3
+np.float32,0x3f5857ba,0x3f106698,3
+np.float32,0x3edf619c,0x3f8f45fb,3
+np.float32,0xbf5ab76a,0x40261664,3
+np.float32,0x3e54b5a8,0x3fae4738,3
+np.float32,0xbee92772,0x4002ca40,3
+np.float32,0x3f2fd610,0x3f504a7a,3
+np.float32,0xbf38521c,0x4017f97e,3
+np.float32,0xff800000,0x7fc00000,3
+np.float32,0x3e2da348,0x3fb34077,3
+np.float32,0x3f2f85fa,0x3f50b894,3
+np.float32,0x3e88f9c8,0x3fa66551,3
+np.float32,0xbf61e570,0x4029b648,3
+np.float32,0xbeab362c,0x3ff4b4a1,3
+np.float32,0x3ec6c310,0x3f9607bd,3
+np.float32,0x3f0d7bda,0x3f7c3810,3
+np.float32,0xbeba5d36,0x3ff8bf99,3
+np.float32,0x3f4b0554,0x3f27adda,3
+np.float32,0x3f60f5dc,0x3efebfb3,3
+np.float32,0x3f36ce2c,0x3f468603,3
+np.float32,0xbe70afac,0x3fe76e8e,3
+np.float32,0x3f673350,0x3ee339b5,3
+np.float32,0xbe124cf0,0x3fdb698c,3
+np.float32,0xbf1243dc,0x400b73d0,3
+np.float32,0x3f3c8850,0x3f3e3407,3
+np.float32,0x3ea02f24,0x3fa05500,3
+np.float32,0xbeffed34,0x400607db,3
+np.float32,0x3f5c75c2,0x3f08817c,3
+np.float32,0x3f4b2fbe,0x3f27682d,3
+np.float32,0x3ee47c34,0x3f8dd9f9,3
+np.float32,0x3f50d48c,0x3f1de584,3
+np.float32,0x3f12dc5e,0x3f75b628,3
+np.float32,0xbefe7e4a,0x4005d2f4,3
+np.float32,0xbec2e846,0x3ffb0cbc,3
+np.float32,0xbedc3036,0x4000fb80,3
+np.float32,0xbf48aedc,0x401e311f,3
+np.float32,0x3f6e032e,0x3ec11363,3
+np.float32,0xbf60de15,0x40292b72,3
+np.float32,0x3f06585e,0x3f8258ba,3
+np.float32,0x3ef49b98,0x3f894e66,3
+np.float32,0x3cc5fe00,0x3fc5f7cf,3
+np.float32,0xbf7525c5,0x40365c2c,3
+np.float32,0x3f64f9f8,0x3eed5fb2,3
+np.float32,0x3e8849c0,0x3fa692fb,3
+np.float32,0x3e50c878,0x3faec79e,3
+np.float32,0x3ed61530,0x3f91d831,3
+np.float32,0xbf54872e,0x40233724,3
+np.float32,0xbf52ee7f,0x4022815e,3
+np.float32,0xbe708c24,0x3fe769fc,3
+np.float32,0xbf26fc54,0x40120260,3
+np.float32,0x3f226e8a,0x3f6228db,3
+np.float32,0xbef30406,0x40042eb8,3
+np.float32,0x3f5d996c,0x3f063f5f,3
+np.float32,0xbf425f9c,0x401bb618,3
+np.float32,0x3e4bb260,0x3faf6dc9,3
+np.float32,0xbe52d5a4,0x3fe39b29,3
+np.float32,0xbe169cf0,0x3fdbf505,3
+np.float32,0xbedfc422,0x40017a8e,3
+np.float32,0x3d8ffef0,0x3fc00e05,3
+np.float32,0xbf12bdab,0x400b98f2,3
+np.float32,0x3f295d0a,0x3f590e88,3
+np.float32,0x3f49d8e4,0x3f2998aa,3
+np.float32,0xbef914f4,0x40050c12,3
+np.float32,0xbf4ea2b5,0x4020a61e,3
+np.float32,0xbf3a89e5,0x4018c762,3
+np.float32,0x3e8707b4,0x3fa6e67a,3
+np.float32,0x3ac55400,0x3fc8de86,3
+np.float32,0x800000,0x3fc90fdb,3
+np.float32,0xbeb9762c,0x3ff8819b,3
+np.float32,0xbebbe23c,0x3ff92815,3
+np.float32,0xbf598c88,0x402587a1,3
+np.float32,0x3e95d864,0x3fa30b4a,3
+np.float32,0x3f7f6f40,0x3d882486,3
+np.float32,0xbf53658c,0x4022b604,3
+np.float32,0xbf2a35f2,0x401314ad,3
+np.float32,0x3eb14380,0x3f9bcf28,3
+np.float32,0x3f0e0c64,0x3f7b8a7a,3
+np.float32,0x3d349920,0x3fc36a9a,3
+np.float32,0xbec2092c,0x3ffad071,3
+np.float32,0xbe1d08e8,0x3fdcc4e0,3
+np.float32,0xbf008968,0x40063243,3
+np.float32,0xbefad582,0x40054c51,3
+np.float32,0xbe52d010,0x3fe39a72,3
+np.float32,0x3f4afdac,0x3f27ba6b,3
+np.float32,0x3f6c483c,0x3eca4408,3
+np.float32,0xbef3cb68,0x40044b0c,3
+np.float32,0x3e94687c,0x3fa36b6f,3
+np.float32,0xbf64ae5c,0x402b39bb,3
+np.float32,0xbf0022b4,0x40061497,3
+np.float32,0x80000001,0x3fc90fdb,3
+np.float32,0x3f25bcd0,0x3f5dda4b,3
+np.float32,0x3ed91b40,0x3f9102d7,3
+np.float32,0x3f800000,0x0,3
+np.float32,0xbebc6aca,0x3ff94cca,3
+np.float32,0x3f239e9a,0x3f609e7d,3
+np.float32,0xbf7312be,0x4034a305,3
+np.float32,0x3efd16d0,0x3f86e148,3
+np.float32,0x3f52753a,0x3f1b0f72,3
+np.float32,0xbde58960,0x3fd7702c,3
+np.float32,0x3ef88580,0x3f883099,3
+np.float32,0x3eebaefc,0x3f8bd51e,3
+np.float32,0x3e877d2c,0x3fa6c807,3
+np.float32,0x3f1a0324,0x3f6cdf32,3
+np.float32,0xbedfe20a,0x40017eb6,3
+np.float32,0x3f205a3c,0x3f64d69d,3
+np.float32,0xbeed5b7c,0x400361b0,3
+np.float32,0xbf69ba10,0x402e2ad0,3
+np.float32,0x3c4fe200,0x3fc77014,3
+np.float32,0x3f043310,0x3f839a69,3
+np.float32,0xbeaf359a,0x3ff5c485,3
+np.float32,0x3db3f110,0x3fbdcd12,3
+np.float32,0x3e24af88,0x3fb462ed,3
+np.float32,0xbf34e858,0x4016c1c8,3
+np.float32,0x3f3334f2,0x3f4b9cd0,3
+np.float32,0xbf145882,0x400c16a2,3
+np.float32,0xbf541c38,0x40230748,3
+np.float32,0x3eba7e10,0x3f99574b,3
+np.float32,0xbe34c6e0,0x3fdfc731,3
+np.float32,0xbe957abe,0x3feefbf0,3
+np.float32,0xbf595a59,0x40256fdb,3
+np.float32,0xbdedc7b8,0x3fd7f4f0,3
+np.float32,0xbf627c02,0x402a06a9,3
+np.float32,0x3f339b78,0x3f4b0d18,3
+np.float32,0xbf2df6d2,0x40145929,3
+np.float32,0x3f617726,0x3efc9fd8,3
+np.float32,0xbee3a8fc,0x40020561,3
+np.float32,0x3efe9f68,0x3f867043,3
+np.float32,0xbf2c3e76,0x4013c3ba,3
+np.float32,0xbf218f28,0x40103d84,3
+np.float32,0xbf1ea847,0x400f4f7f,3
+np.float32,0x3ded9160,0x3fba2e31,3
+np.float32,0x3bce1b00,0x3fc841bf,3
+np.float32,0xbe90566e,0x3feda46a,3
+np.float32,0xbf5ea2ba,0x4028056b,3
+np.float32,0x3f538e62,0x3f191ee6,3
+np.float32,0xbf59e054,0x4025af74,3
+np.float32,0xbe8c98ba,0x3fecab24,3
+np.float32,0x3ee7bdb0,0x3f8cf0b7,3
+np.float32,0xbf2eb828,0x40149b2b,3
+np.float32,0xbe5eb904,0x3fe52068,3
+np.float32,0xbf16b422,0x400cd08d,3
+np.float32,0x3f1ab9b4,0x3f6bfa58,3
+np.float32,0x3dc23040,0x3fbce82a,3
+np.float32,0xbf29d9e7,0x4012f5e5,3
+np.float32,0xbf38f30a,0x40183393,3
+np.float32,0x3e88e798,0x3fa66a09,3
+np.float32,0x3f1d07e6,0x3f69124f,3
+np.float32,0xbe1d3d34,0x3fdccb7e,3
+np.float32,0xbf1715be,0x400ceec2,3
+np.float32,0x3f7a0eac,0x3e5d11f7,3
+np.float32,0xbe764924,0x3fe82707,3
+np.float32,0xbf01a1f8,0x4006837c,3
+np.float32,0x3f2be730,0x3f55a661,3
+np.float32,0xbf7bb070,0x403d4ce5,3
+np.float32,0xbd602110,0x3fd011c9,3
+np.float32,0x3f5d080c,0x3f07609d,3
+np.float32,0xbda20400,0x3fd332d1,3
+np.float32,0x3f1c62da,0x3f69e308,3
+np.float32,0xbf2c6916,0x4013d223,3
+np.float32,0xbf44f8fd,0x401cb816,3
+np.float32,0x3f4da392,0x3f235539,3
+np.float32,0x3e9e8aa0,0x3fa0c3a0,3
+np.float32,0x3e9633c4,0x3fa2f366,3
+np.float32,0xbf0422ab,0x40073ddd,3
+np.float32,0x3f518386,0x3f1cb603,3
+np.float32,0x3f24307a,0x3f5fe096,3
+np.float32,0xbdfb4220,0x3fd8ce24,3
+np.float32,0x3f179d28,0x3f6fdc7d,3
+np.float32,0xbecc2df0,0x3ffd911e,3
+np.float32,0x3f3dff0c,0x3f3c0782,3
+np.float32,0xbf58c4d8,0x4025295b,3
+np.float32,0xbdcf8438,0x3fd60dd3,3
+np.float32,0xbeeaf1b2,0x40030aa7,3
+np.float32,0xbf298a28,0x4012db45,3
+np.float32,0x3f6c4dec,0x3eca2678,3
+np.float32,0x3f4d1ac8,0x3f243a59,3
+np.float32,0x3f62cdfa,0x3ef6e8f8,3
+np.float32,0xbee8acce,0x4002b909,3
+np.float32,0xbd5f2af0,0x3fd00a15,3
+np.float32,0x3f5fde8e,0x3f01a453,3
+np.float32,0x3e95233c,0x3fa33aa4,3
+np.float32,0x3ecd2a60,0x3f9449be,3
+np.float32,0x3f10aa86,0x3f78619d,3
+np.float32,0x3f3888e8,0x3f440a70,3
+np.float32,0x3eeb5bfc,0x3f8bec7d,3
+np.float32,0xbe12d654,0x3fdb7ae6,3
+np.float32,0x3eca3110,0x3f951931,3
+np.float32,0xbe2d1b7c,0x3fdece05,3
+np.float32,0xbf29e9db,0x4012fb3a,3
+np.float32,0xbf0c50b8,0x4009a845,3
+np.float32,0xbed9f0e4,0x4000abef,3
+np.float64,0x3fd078ec5ba0f1d8,0x3ff4f7c00595a4d3,2
+np.float64,0xbfdbc39743b7872e,0x400027f85bce43b2,2
+np.float64,0xbfacd2707c39a4e0,0x3ffa08ae1075d766,2
+np.float64,0xbfc956890f32ad14,0x3ffc52308e7285fd,2
+np.float64,0xbf939c2298273840,0x3ff9706d18e6ea6b,2
+np.float64,0xbfe0d7048961ae09,0x4000fff4406bd395,2
+np.float64,0xbfe9d19b86f3a337,0x4004139bc683a69f,2
+np.float64,0x3fd35c7f90a6b900,0x3ff437220e9123f8,2
+np.float64,0x3fdddca171bbb944,0x3ff15da61e61ec08,2
+np.float64,0x3feb300de9f6601c,0x3fe1c6fadb68cdca,2
+np.float64,0xbfef1815327e302a,0x400739808fc6f964,2
+np.float64,0xbfe332d78e6665af,0x4001b6c4ef922f7c,2
+np.float64,0xbfedbf4dfb7b7e9c,0x40061cefed62a58b,2
+np.float64,0xbfd8dcc7e3b1b990,0x3fff84307713c2c3,2
+np.float64,0xbfedaf161c7b5e2c,0x400612027c1b2b25,2
+np.float64,0xbfed9bde897b37bd,0x4006053f05bd7d26,2
+np.float64,0xbfe081ebc26103d8,0x4000e70755eb66e0,2
+np.float64,0xbfe0366f9c606cdf,0x4000d11212f29afd,2
+np.float64,0xbfc7c115212f822c,0x3ffc1e8c9d58f7db,2
+np.float64,0x3fd8dd9a78b1bb34,0x3ff2bf8d0f4c9376,2
+np.float64,0xbfe54eff466a9dfe,0x4002655950b611f4,2
+np.float64,0xbfe4aad987e955b3,0x40022efb19882518,2
+np.float64,0x3f70231ca0204600,0x3ff911d834e7abf4,2
+np.float64,0x3fede01d047bc03a,0x3fd773cecbd8561b,2
+np.float64,0xbfd6a00d48ad401a,0x3ffee9fd7051633f,2
+np.float64,0x3fd44f3d50a89e7c,0x3ff3f74dd0fc9c91,2
+np.float64,0x3fe540f0d0ea81e2,0x3feb055a7c7d43d6,2
+np.float64,0xbf3ba2e200374800,0x3ff923b582650c6c,2
+np.float64,0x3fe93b2d3f72765a,0x3fe532fa15331072,2
+np.float64,0x3fee8ce5a17d19cc,0x3fd35666eefbe336,2
+np.float64,0x3fe55d5f8feabac0,0x3feadf3dcfe251d4,2
+np.float64,0xbfd1d2ede8a3a5dc,0x3ffda600041ac884,2
+np.float64,0xbfee41186e7c8231,0x40067a625cc6f64d,2
+np.float64,0x3fe521a8b9ea4352,0x3feb2f1a6c8084e5,2
+np.float64,0x3fc65378ef2ca6f0,0x3ff653dfe81ee9f2,2
+np.float64,0x3fdaba0fbcb57420,0x3ff23d630995c6ba,2
+np.float64,0xbfe6b7441d6d6e88,0x4002e182539a2994,2
+np.float64,0x3fda00b6dcb4016c,0x3ff2703d516f28e7,2
+np.float64,0xbfe8699f01f0d33e,0x400382326920ea9e,2
+np.float64,0xbfef5889367eb112,0x4007832af5983793,2
+np.float64,0x3fefb57c8aff6afa,0x3fc14700ab38dcef,2
+np.float64,0xbfda0dfdaab41bfc,0x3fffd75b6fd497f6,2
+np.float64,0xbfb059c36620b388,0x3ffa27c528b97a42,2
+np.float64,0xbfdd450ab1ba8a16,0x40005dcac6ab50fd,2
+np.float64,0xbfe54d6156ea9ac2,0x400264ce9f3f0fb9,2
+np.float64,0xbfe076e94760edd2,0x4000e3d1374884da,2
+np.float64,0xbfc063286720c650,0x3ffb2fd1d6bff0ef,2
+np.float64,0xbfe24680f2e48d02,0x40016ddfbb5bcc0e,2
+np.float64,0xbfdc9351d2b926a4,0x400044e3756fb765,2
+np.float64,0x3fefb173d8ff62e8,0x3fc1bd5626f80850,2
+np.float64,0x3fe77c117a6ef822,0x3fe7e57089bad2ec,2
+np.float64,0xbfddbcebf7bb79d8,0x40006eadb60406b3,2
+np.float64,0xbfecf6625ff9ecc5,0x40059e6c6961a6db,2
+np.float64,0x3fdc8950b8b912a0,0x3ff1bcfb2e27795b,2
+np.float64,0xbfeb2fa517765f4a,0x4004b00aee3e6888,2
+np.float64,0x3fd0efc88da1df90,0x3ff4d8f7cbd8248a,2
+np.float64,0xbfe6641a2becc834,0x4002c43362c1bd0f,2
+np.float64,0xbfe28aec0fe515d8,0x400182c91d4df039,2
+np.float64,0xbfd5ede8d0abdbd2,0x3ffeba7baef05ae8,2
+np.float64,0xbfbd99702a3b32e0,0x3ffafca21c1053f1,2
+np.float64,0x3f96f043f82de080,0x3ff8c6384d5eb610,2
+np.float64,0xbfe5badbc9eb75b8,0x400289c8cd5873d1,2
+np.float64,0x3fe5c6bf95eb8d80,0x3fea5093e9a3e43e,2
+np.float64,0x3fb1955486232ab0,0x3ff8086d4c3e71d5,2
+np.float64,0xbfea145f397428be,0x4004302237a35871,2
+np.float64,0xbfdabe685db57cd0,0x400003e2e29725fb,2
+np.float64,0xbfefc79758ff8f2f,0x400831814e23bfc8,2
+np.float64,0x3fd7edb66cafdb6c,0x3ff3006c5123bfaf,2
+np.float64,0xbfeaf7644bf5eec8,0x400495a7963ce4ed,2
+np.float64,0x3fdf838d78bf071c,0x3ff0e527eed73800,2
+np.float64,0xbfd1a0165ba3402c,0x3ffd98c5ab76d375,2
+np.float64,0x3fd75b67a9aeb6d0,0x3ff327c8d80b17cf,2
+np.float64,0x3fc2aa9647255530,0x3ff6ca854b157df1,2
+np.float64,0xbfe0957fd4612b00,0x4000ecbf3932becd,2
+np.float64,0x3fda1792c0b42f24,0x3ff269fbb2360487,2
+np.float64,0x3fd480706ca900e0,0x3ff3ea53a6aa3ae8,2
+np.float64,0xbfd0780ed9a0f01e,0x3ffd4bfd544c7d47,2
+np.float64,0x3feeec0cd77dd81a,0x3fd0a8a241fdb441,2
+np.float64,0x3fcfa933e93f5268,0x3ff5223478621a6b,2
+np.float64,0x3fdad2481fb5a490,0x3ff236b86c6b2b49,2
+np.float64,0x3fe03b129de07626,0x3ff09f21fb868451,2
+np.float64,0xbfc01212cd202424,0x3ffb259a07159ae9,2
+np.float64,0x3febdb912df7b722,0x3fe0768e20dac8c9,2
+np.float64,0xbfbf2148763e4290,0x3ffb154c361ce5bf,2
+np.float64,0xbfb1a7eb1e234fd8,0x3ffa3cb37ac4a176,2
+np.float64,0xbfe26ad1ec64d5a4,0x400178f480ecce8d,2
+np.float64,0x3fe6d1cd1b6da39a,0x3fe8dc20ec4dad3b,2
+np.float64,0xbfede0e53dfbc1ca,0x4006340d3bdd7c97,2
+np.float64,0xbfe8fd1bd9f1fa38,0x4003bc3477f93f40,2
+np.float64,0xbfe329d0f26653a2,0x4001b3f345af5648,2
+np.float64,0xbfe4bb20eee97642,0x40023451404d6d08,2
+np.float64,0x3fb574832e2ae900,0x3ff7ca4bed0c7110,2
+np.float64,0xbfdf3c098fbe7814,0x4000a525bb72d659,2
+np.float64,0x3fa453e6d428a7c0,0x3ff87f512bb9b0c6,2
+np.float64,0x3faaec888435d920,0x3ff84a7d9e4def63,2
+np.float64,0xbfcdc240df3b8480,0x3ffce30ece754e7f,2
+np.float64,0xbf8c3220f0386440,0x3ff95a600ae6e157,2
+np.float64,0x3fe806076c700c0e,0x3fe71784a96c76eb,2
+np.float64,0x3fedf9b0e17bf362,0x3fd6e35fc0a7b6c3,2
+np.float64,0xbfe1b48422636908,0x400141bd8ed251bc,2
+np.float64,0xbfe82e2817705c50,0x40036b5a5556d021,2
+np.float64,0xbfc8ef8ff931df20,0x3ffc450ffae7ce58,2
+np.float64,0xbfe919fa94f233f5,0x4003c7cce4697fe8,2
+np.float64,0xbfc3ace4a72759c8,0x3ffb9a197bb22651,2
+np.float64,0x3fe479f71ee8f3ee,0x3fec0bd2f59097aa,2
+np.float64,0xbfeeb54a967d6a95,0x4006da12c83649c5,2
+np.float64,0x3fe5e74ea8ebce9e,0x3fea2407cef0f08c,2
+np.float64,0x3fb382baf2270570,0x3ff7e98213b921ba,2
+np.float64,0xbfdd86fd3cbb0dfa,0x40006712952ddbcf,2
+np.float64,0xbfd250eb52a4a1d6,0x3ffdc6d56253b1cd,2
+np.float64,0x3fea30c4ed74618a,0x3fe3962deba4f30e,2
+np.float64,0x3fc895963d312b30,0x3ff60a5d52fcbccc,2
+np.float64,0x3fe9cc4f6273989e,0x3fe442740942c80f,2
+np.float64,0xbfe8769f5cf0ed3f,0x4003873b4cb5bfce,2
+np.float64,0xbfe382f3726705e7,0x4001cfeb3204d110,2
+np.float64,0x3fbfe9a9163fd350,0x3ff7220bd2b97c8f,2
+np.float64,0xbfca6162bb34c2c4,0x3ffc743f939358f1,2
+np.float64,0x3fe127a014e24f40,0x3ff0147c4bafbc39,2
+np.float64,0x3fee9cdd2a7d39ba,0x3fd2e9ef45ab122f,2
+np.float64,0x3fa9ffb97c33ff80,0x3ff851e69fa3542c,2
+np.float64,0x3fd378f393a6f1e8,0x3ff42faafa77de56,2
+np.float64,0xbfe4df1e1669be3c,0x400240284df1c321,2
+np.float64,0x3fed0ed79bfa1db0,0x3fdba89060aa96fb,2
+np.float64,0x3fdef2ee52bde5dc,0x3ff10e942244f4f1,2
+np.float64,0xbfdab38f3ab5671e,0x40000264d8d5b49b,2
+np.float64,0x3fbe95a96e3d2b50,0x3ff73774cb59ce2d,2
+np.float64,0xbfe945653af28aca,0x4003d9657bf129c2,2
+np.float64,0xbfb18f3f2a231e80,0x3ffa3b27cba23f50,2
+np.float64,0xbfef50bf22fea17e,0x40077998a850082c,2
+np.float64,0xbfc52b8c212a5718,0x3ffbca8d6560a2da,2
+np.float64,0x7ff8000000000000,0x7ff8000000000000,2
+np.float64,0x3fc1e3a02d23c740,0x3ff6e3a5fcac12a4,2
+np.float64,0xbfeb5e4ea5f6bc9d,0x4004c65abef9426f,2
+np.float64,0xbfe425b132684b62,0x400203c29608b00d,2
+np.float64,0xbfbfa1c19e3f4380,0x3ffb1d6367711158,2
+np.float64,0x3fbba2776e3744f0,0x3ff766f6df586fad,2
+np.float64,0xbfb5d0951e2ba128,0x3ffa7f712480b25e,2
+np.float64,0xbfe949fdab7293fb,0x4003db4530a18507,2
+np.float64,0xbfcf13519b3e26a4,0x3ffd0e6f0a6c38ee,2
+np.float64,0x3f91e6d72823cdc0,0x3ff8da5f08909b6e,2
+np.float64,0x3f78a2e360314600,0x3ff909586727caef,2
+np.float64,0xbfe1ae7e8fe35cfd,0x40013fef082caaa3,2
+np.float64,0x3fe97a6dd1f2f4dc,0x3fe4cb4b99863478,2
+np.float64,0xbfcc1e1e69383c3c,0x3ffcad250a949843,2
+np.float64,0x3faccb797c399700,0x3ff83b8066b49330,2
+np.float64,0x3fe7a2647a6f44c8,0x3fe7acceae6ec425,2
+np.float64,0xbfec3bfcf0f877fa,0x4005366af5a7175b,2
+np.float64,0xbfe2310b94646217,0x400167588fceb228,2
+np.float64,0x3feb167372762ce6,0x3fe1f74c0288fad8,2
+np.float64,0xbfb722b4ee2e4568,0x3ffa94a81b94dfca,2
+np.float64,0x3fc58da9712b1b50,0x3ff66cf8f072aa14,2
+np.float64,0xbfe7fff9d6effff4,0x400359d01b8141de,2
+np.float64,0xbfd56691c5aacd24,0x3ffe9686697797e8,2
+np.float64,0x3fe3ab0557e7560a,0x3fed1593959ef8e8,2
+np.float64,0x3fdd458995ba8b14,0x3ff1883d6f22a322,2
+np.float64,0x3fe7bbed2cef77da,0x3fe786d618094cda,2
+np.float64,0x3fa31a30c4263460,0x3ff88920b936fd79,2
+np.float64,0x8010000000000000,0x3ff921fb54442d18,2
+np.float64,0xbfdc5effbdb8be00,0x40003d95fe0dff11,2
+np.float64,0x3febfdad7e77fb5a,0x3fe030b5297dbbdd,2
+np.float64,0x3fe4f3f3b2e9e7e8,0x3feb6bc59eeb2be2,2
+np.float64,0xbfe44469fd6888d4,0x40020daa5488f97a,2
+np.float64,0xbfe19fddb0e33fbc,0x40013b8c902b167b,2
+np.float64,0x3fa36ad17c26d5a0,0x3ff8869b3e828134,2
+np.float64,0x3fcf23e6c93e47d0,0x3ff5336491a65d1e,2
+np.float64,0xffefffffffffffff,0x7ff8000000000000,2
+np.float64,0xbfe375f4cee6ebea,0x4001cbd2ba42e8b5,2
+np.float64,0xbfaef1215c3de240,0x3ffa19ab02081189,2
+np.float64,0xbfec39c59c78738b,0x4005353dc38e3d78,2
+np.float64,0x7ff4000000000000,0x7ffc000000000000,2
+np.float64,0xbfec09bb7b781377,0x40051c0a5754cb3a,2
+np.float64,0x3fe8301f2870603e,0x3fe6d783c5ef0944,2
+np.float64,0xbfed418c987a8319,0x4005cbae1b8693d1,2
+np.float64,0xbfdc16e7adb82dd0,0x4000338b634eaf03,2
+np.float64,0x3fd5d361bdaba6c4,0x3ff390899300a54c,2
+np.float64,0xbff0000000000000,0x400921fb54442d18,2
+np.float64,0x3fd5946232ab28c4,0x3ff3a14767813f29,2
+np.float64,0x3fe833e5fef067cc,0x3fe6d1be720edf2d,2
+np.float64,0x3fedf746a67bee8e,0x3fd6f127fdcadb7b,2
+np.float64,0x3fd90353d3b206a8,0x3ff2b54f7d369ba9,2
+np.float64,0x3fec4b4b72f89696,0x3fdf1b38d2e93532,2
+np.float64,0xbfe9c67596f38ceb,0x40040ee5f524ce03,2
+np.float64,0x3fd350d91aa6a1b4,0x3ff43a303c0da27f,2
+np.float64,0x3fd062603ba0c4c0,0x3ff4fd9514b935d8,2
+np.float64,0xbfe24c075f64980e,0x40016f8e9f2663b3,2
+np.float64,0x3fdaa546eeb54a8c,0x3ff2431a88fef1d5,2
+np.float64,0x3fe92b8151f25702,0x3fe54c67e005cbf9,2
+np.float64,0xbfe1be8b8a637d17,0x400144c078f67c6e,2
+np.float64,0xbfe468a1d7e8d144,0x40021964b118cbf4,2
+np.float64,0xbfdc6de4fab8dbca,0x40003fa9e27893d8,2
+np.float64,0xbfe3c2788ae784f1,0x4001e407ba3aa956,2
+np.float64,0xbfe2bf1542e57e2a,0x400192d4a9072016,2
+np.float64,0xbfe6982f4c6d305e,0x4002d681b1991bbb,2
+np.float64,0x3fdbceb1c4b79d64,0x3ff1f0f117b9d354,2
+np.float64,0x3fdb3705e7b66e0c,0x3ff21af01ca27ace,2
+np.float64,0x3fe3e6358ee7cc6c,0x3fecca4585053983,2
+np.float64,0xbfe16d6a9a62dad5,0x40012c7988aee247,2
+np.float64,0xbfce66e4413ccdc8,0x3ffcf83b08043a0c,2
+np.float64,0xbfeb6cd46876d9a9,0x4004cd61733bfb79,2
+np.float64,0xbfdb1cdd64b639ba,0x400010e6cf087cb7,2
+np.float64,0xbfe09e4e30e13c9c,0x4000ef5277c47721,2
+np.float64,0xbfee88dd127d11ba,0x4006b3cd443643ac,2
+np.float64,0xbf911e06c8223c00,0x3ff966744064fb05,2
+np.float64,0xbfe8f22bc471e458,0x4003b7d5513af295,2
+np.float64,0x3fe3d7329567ae66,0x3fecdd6c241f83ee,2
+np.float64,0x3fc8a9404b315280,0x3ff607dc175edf3f,2
+np.float64,0x3fe7eb80ad6fd702,0x3fe73f8fdb3e6a6c,2
+np.float64,0x3fef0931e37e1264,0x3fcf7fde80a3c5ab,2
+np.float64,0x3fe2ed3c3fe5da78,0x3fee038334cd1860,2
+np.float64,0x3fe251fdb8e4a3fc,0x3feec26dc636ac31,2
+np.float64,0x3feb239436764728,0x3fe1de9462455da7,2
+np.float64,0xbfe63fd7eeec7fb0,0x4002b78cfa3d2fa6,2
+np.float64,0x3fdd639cb5bac738,0x3ff17fc7d92b3eee,2
+np.float64,0x3fd0a7a13fa14f44,0x3ff4eba95c559c84,2
+np.float64,0x3fe804362d70086c,0x3fe71a44cd91ffa4,2
+np.float64,0xbfe0fecf6e61fd9f,0x40010bac8edbdc4f,2
+np.float64,0x3fcb74acfd36e958,0x3ff5ac84437f1b7c,2
+np.float64,0x3fe55053e1eaa0a8,0x3feaf0bf76304c30,2
+np.float64,0x3fc06b508d20d6a0,0x3ff7131da17f3902,2
+np.float64,0x3fdd78750fbaf0ec,0x3ff179e97fbf7f65,2
+np.float64,0x3fe44cb946689972,0x3fec46859b5da6be,2
+np.float64,0xbfeb165a7ff62cb5,0x4004a41c9cc9589e,2
+np.float64,0x3fe01ffb2b603ff6,0x3ff0aed52bf1c3c1,2
+np.float64,0x3f983c60a83078c0,0x3ff8c107805715ab,2
+np.float64,0x3fd8b5ff13b16c00,0x3ff2ca4a837a476a,2
+np.float64,0x3fc80510a1300a20,0x3ff61cc3b4af470b,2
+np.float64,0xbfd3935b06a726b6,0x3ffe1b3a2066f473,2
+np.float64,0xbfdd4a1f31ba943e,0x40005e81979ed445,2
+np.float64,0xbfa76afdd42ed600,0x3ff9dd63ffba72d2,2
+np.float64,0x3fe7e06d496fc0da,0x3fe7503773566707,2
+np.float64,0xbfea5fbfe874bf80,0x40045106af6c538f,2
+np.float64,0x3fee000c487c0018,0x3fd6bef1f8779d88,2
+np.float64,0xbfb39f4ee2273ea0,0x3ffa5c3f2b3888ab,2
+np.float64,0x3feb9247b0772490,0x3fe1092d2905efce,2
+np.float64,0x3fdaa39b4cb54738,0x3ff243901da0da17,2
+np.float64,0x3fcd5b2b493ab658,0x3ff56e262e65b67d,2
+np.float64,0x3fcf82512f3f04a0,0x3ff52738847c55f2,2
+np.float64,0x3fe2af5e0c655ebc,0x3fee4ffab0c82348,2
+np.float64,0xbfec0055d0f800ac,0x4005172d325933e8,2
+np.float64,0x3fe71da9336e3b52,0x3fe86f2e12f6e303,2
+np.float64,0x3fbefab0723df560,0x3ff731188ac716ec,2
+np.float64,0xbfe11dca28623b94,0x400114d3d4ad370d,2
+np.float64,0x3fbcbda8ca397b50,0x3ff755281078abd4,2
+np.float64,0x3fe687c7126d0f8e,0x3fe945099a7855cc,2
+np.float64,0xbfecde510579bca2,0x400590606e244591,2
+np.float64,0xbfd72de681ae5bce,0x3fff0ff797ad1755,2
+np.float64,0xbfe7c0f7386f81ee,0x40034226e0805309,2
+np.float64,0x3fd8d55619b1aaac,0x3ff2c1cb3267b14e,2
+np.float64,0x3fecd7a2ad79af46,0x3fdcabbffeaa279e,2
+np.float64,0x3fee7fb1a8fcff64,0x3fd3ae620286fe19,2
+np.float64,0xbfc5f3a3592be748,0x3ffbe3ed204d9842,2
+np.float64,0x3fec9e5527793caa,0x3fddb00bc8687e4b,2
+np.float64,0x3fc35dc70f26bb90,0x3ff6b3ded7191e33,2
+np.float64,0x3fda91c07ab52380,0x3ff24878848fec8f,2
+np.float64,0xbfe12cde1fe259bc,0x4001194ab99d5134,2
+np.float64,0xbfd35ab736a6b56e,0x3ffe0c5ce8356d16,2
+np.float64,0x3fc9c94123339280,0x3ff5e3239f3ad795,2
+np.float64,0xbfe72f54926e5ea9,0x40030c95d1d02b56,2
+np.float64,0xbfee283186fc5063,0x40066786bd0feb79,2
+np.float64,0xbfe7b383f56f6708,0x40033d23ef0e903d,2
+np.float64,0x3fd6037327ac06e8,0x3ff383bf2f311ddb,2
+np.float64,0x3fe0e344b561c68a,0x3ff03cd90fd4ba65,2
+np.float64,0xbfef0ff54b7e1feb,0x400730fa5fce381e,2
+np.float64,0x3fd269929da4d324,0x3ff476b230136d32,2
+np.float64,0xbfbc5fb9f638bf70,0x3ffae8e63a4e3234,2
+np.float64,0xbfe2e8bc84e5d179,0x40019fb5874f4310,2
+np.float64,0xbfd7017413ae02e8,0x3fff040d843c1531,2
+np.float64,0x3fefd362fa7fa6c6,0x3fbababc3ddbb21d,2
+np.float64,0x3fecb62ed3f96c5e,0x3fdd44ba77ccff94,2
+np.float64,0xbfb16fad5222df58,0x3ffa392d7f02b522,2
+np.float64,0x3fbcf4abc639e950,0x3ff751b23c40e27f,2
+np.float64,0x3fe128adbce2515c,0x3ff013dc91db04b5,2
+np.float64,0x3fa5dd9d842bbb40,0x3ff87300c88d512f,2
+np.float64,0xbfe61efcaf6c3dfa,0x4002ac27117f87c9,2
+np.float64,0x3feffe1233fffc24,0x3f9638d3796a4954,2
+np.float64,0xbfe78548b66f0a92,0x40032c0447b7bfe2,2
+np.float64,0x3fe7bd38416f7a70,0x3fe784e86d6546b6,2
+np.float64,0x3fe0d6bc5961ad78,0x3ff0443899e747ac,2
+np.float64,0xbfd0bb6e47a176dc,0x3ffd5d6dff390d41,2
+np.float64,0xbfec1d16b8f83a2e,0x40052620378d3b78,2
+np.float64,0x3fe9bbec20f377d8,0x3fe45e167c7a3871,2
+np.float64,0xbfeed81d9dfdb03b,0x4006f9dec2db7310,2
+np.float64,0xbfe1e35179e3c6a3,0x40014fd1b1186ac0,2
+np.float64,0xbfc9c7e605338fcc,0x3ffc60a6bd1a7126,2
+np.float64,0x3feec92810fd9250,0x3fd1afde414ab338,2
+np.float64,0xbfeb9f1d90773e3b,0x4004e606b773f5b0,2
+np.float64,0x3fcbabdf6b3757c0,0x3ff5a573866404af,2
+np.float64,0x3fe9f4e1fff3e9c4,0x3fe3fd7b6712dd7b,2
+np.float64,0xbfe6c0175ded802e,0x4002e4a4dc12f3fe,2
+np.float64,0xbfeefc96f37df92e,0x40071d367cd721ff,2
+np.float64,0xbfeaab58dc7556b2,0x400472ce37e31e50,2
+np.float64,0xbfc62668772c4cd0,0x3ffbea5e6c92010a,2
+np.float64,0x3fafe055fc3fc0a0,0x3ff822ce6502519a,2
+np.float64,0x3fd7b648ffaf6c90,0x3ff30f5a42f11418,2
+np.float64,0xbfe934fe827269fd,0x4003d2b9fed9e6ad,2
+np.float64,0xbfe6d691f2edad24,0x4002eca6a4b1797b,2
+np.float64,0x3fc7e62ced2fcc58,0x3ff620b1f44398b7,2
+np.float64,0xbfc89be9f33137d4,0x3ffc3a67a497f59c,2
+np.float64,0xbfe7793d536ef27a,0x40032794bf14dd64,2
+np.float64,0x3fde55a02dbcab40,0x3ff13b5f82d223e4,2
+np.float64,0xbfc8eabd7b31d57c,0x3ffc4472a81cb6d0,2
+np.float64,0x3fddcb5468bb96a8,0x3ff162899c381f2e,2
+np.float64,0xbfec7554d8f8eaaa,0x40055550e18ec463,2
+np.float64,0x3fd0b6e8b6a16dd0,0x3ff4e7b4781a50e3,2
+np.float64,0x3fedaae01b7b55c0,0x3fd8964916cdf53d,2
+np.float64,0x3fe0870f8a610e20,0x3ff072e7db95c2a2,2
+np.float64,0xbfec3e3ce2787c7a,0x4005379d0f6be873,2
+np.float64,0xbfe65502586caa04,0x4002beecff89147f,2
+np.float64,0xbfe0df39a961be74,0x4001025e36d1c061,2
+np.float64,0xbfb5d8edbe2bb1d8,0x3ffa7ff72b7d6a2b,2
+np.float64,0xbfde89574bbd12ae,0x40008ba4cd74544d,2
+np.float64,0xbfe72938f0ee5272,0x40030a5efd1acb6d,2
+np.float64,0xbfcd500d133aa01c,0x3ffcd462f9104689,2
+np.float64,0x3fe0350766606a0e,0x3ff0a2a3664e2c14,2
+np.float64,0xbfc892fb573125f8,0x3ffc3944641cc69d,2
+np.float64,0xbfba7dc7c634fb90,0x3ffaca9a6a0ffe61,2
+np.float64,0xbfeac94478759289,0x40048068a8b83e45,2
+np.float64,0xbfe8f60c1af1ec18,0x4003b961995b6e51,2
+np.float64,0x3fea1c0817743810,0x3fe3ba28c1643cf7,2
+np.float64,0xbfe42a0fefe85420,0x4002052aadd77f01,2
+np.float64,0x3fd2c61c56a58c38,0x3ff45e84cb9a7fa9,2
+np.float64,0xbfd83fb7cdb07f70,0x3fff59ab4790074c,2
+np.float64,0x3fd95e630fb2bcc8,0x3ff29c8bee1335ad,2
+np.float64,0x3feee88f387dd11e,0x3fd0c3ad3ded4094,2
+np.float64,0x3fe061291160c252,0x3ff0890010199bbc,2
+np.float64,0xbfdc7db3b5b8fb68,0x400041dea3759443,2
+np.float64,0x3fee23b320fc4766,0x3fd5ee73d7aa5c56,2
+np.float64,0xbfdc25c590b84b8c,0x4000359cf98a00b4,2
+np.float64,0xbfd63cbfd2ac7980,0x3ffecf7b9cf99b3c,2
+np.float64,0xbfbeb3c29a3d6788,0x3ffb0e66ecc0fc3b,2
+np.float64,0xbfd2f57fd6a5eb00,0x3ffdf1d7c79e1532,2
+np.float64,0xbfab3eda9c367db0,0x3ff9fc0c875f42e9,2
+np.float64,0xbfe12df1c6e25be4,0x4001199c673e698c,2
+np.float64,0x3fef8ab23a7f1564,0x3fc5aff358c59f1c,2
+np.float64,0x3fe562f50feac5ea,0x3fead7bce205f7d9,2
+np.float64,0x3fdc41adbeb8835c,0x3ff1d0f71341b8f2,2
+np.float64,0x3fe2748967e4e912,0x3fee9837f970ff9e,2
+np.float64,0xbfdaa89d57b5513a,0x400000e3889ba4cf,2
+np.float64,0x3fdf2a137dbe5428,0x3ff0fecfbecbbf86,2
+np.float64,0xbfea1fdcd2f43fba,0x4004351974b32163,2
+np.float64,0xbfe34a93a3e69528,0x4001be323946a3e0,2
+np.float64,0x3fe929bacff25376,0x3fe54f47bd7f4cf2,2
+np.float64,0xbfd667fbd6accff8,0x3ffedb04032b3a1a,2
+np.float64,0xbfeb695796f6d2af,0x4004cbb08ec6f525,2
+np.float64,0x3fd204df2ea409c0,0x3ff490f51e6670f5,2
+np.float64,0xbfd89a2757b1344e,0x3fff722127b988c4,2
+np.float64,0xbfd0787187a0f0e4,0x3ffd4c16dbe94f32,2
+np.float64,0x3fd44239bfa88474,0x3ff3fabbfb24b1fa,2
+np.float64,0xbfeb0b3489f61669,0x40049ee33d811d33,2
+np.float64,0x3fdcf04eaab9e09c,0x3ff1a02a29996c4e,2
+np.float64,0x3fd4c51e4fa98a3c,0x3ff3d8302c68fc9a,2
+np.float64,0x3fd1346645a268cc,0x3ff4c72b4970ecaf,2
+np.float64,0x3fd6a89d09ad513c,0x3ff357af6520afac,2
+np.float64,0xbfba0f469a341e90,0x3ffac3a8f41bed23,2
+np.float64,0xbfe13f8ddce27f1c,0x40011ed557719fd6,2
+np.float64,0x3fd43e5e26a87cbc,0x3ff3fbc040fc30dc,2
+np.float64,0x3fe838125a707024,0x3fe6cb5c987248f3,2
+np.float64,0x3fe128c30c625186,0x3ff013cff238dd1b,2
+np.float64,0xbfcd4718833a8e30,0x3ffcd33c96bde6f9,2
+np.float64,0x3fe43fcd08e87f9a,0x3fec573997456ec1,2
+np.float64,0xbfe9a29104734522,0x4003ffd502a1b57f,2
+np.float64,0xbfe4709d7968e13b,0x40021bfc5cd55af4,2
+np.float64,0x3fd21c3925a43874,0x3ff48adf48556cbb,2
+np.float64,0x3fe9a521b2734a44,0x3fe4844fc054e839,2
+np.float64,0xbfdfa6a912bf4d52,0x4000b4730ad8521e,2
+np.float64,0x3fe3740702e6e80e,0x3fed5b106283b6ed,2
+np.float64,0x3fd0a3aa36a14754,0x3ff4ecb02a5e3f49,2
+np.float64,0x3fdcb903d0b97208,0x3ff1afa5d692c5b9,2
+np.float64,0xbfe7d67839efacf0,0x40034a3146abf6f2,2
+np.float64,0x3f9981c6d8330380,0x3ff8bbf1853d7b90,2
+np.float64,0xbfe9d4191673a832,0x400414a9ab453c5d,2
+np.float64,0x3fef0a1e5c7e143c,0x3fcf70b02a54c415,2
+np.float64,0xbfd996dee6b32dbe,0x3fffb6cf707ad8e4,2
+np.float64,0x3fe19bef17e337de,0x3fef9e70d4fcedae,2
+np.float64,0x3fe34a59716694b2,0x3fed8f6d5cfba474,2
+np.float64,0x3fdf27e27cbe4fc4,0x3ff0ff70500e0c7c,2
+np.float64,0xbfe19df87fe33bf1,0x40013afb401de24c,2
+np.float64,0xbfbdfd97ba3bfb30,0x3ffb02ef8c225e57,2
+np.float64,0xbfe3d3417267a683,0x4001e95ed240b0f8,2
+np.float64,0x3fe566498b6acc94,0x3fead342957d4910,2
+np.float64,0x3ff0000000000000,0x0,2
+np.float64,0x3feb329bd8766538,0x3fe1c2225aafe3b4,2
+np.float64,0xbfc19ca703233950,0x3ffb575b5df057b9,2
+np.float64,0x3fe755027d6eaa04,0x3fe81eb99c262e00,2
+np.float64,0xbfe6c2b8306d8570,0x4002e594199f9eec,2
+np.float64,0x3fd69438e6ad2870,0x3ff35d2275ae891d,2
+np.float64,0x3fda3e7285b47ce4,0x3ff25f5573dd47ae,2
+np.float64,0x3fe7928a166f2514,0x3fe7c4490ef4b9a9,2
+np.float64,0xbfd4eb71b9a9d6e4,0x3ffe75e8ccb74be1,2
+np.float64,0xbfcc3a07f1387410,0x3ffcb0b8af914a5b,2
+np.float64,0xbfe6e80225edd004,0x4002f2e26eae8999,2
+np.float64,0xbfb347728a268ee8,0x3ffa56bd526a12db,2
+np.float64,0x3fe5140ead6a281e,0x3feb4132c9140a1c,2
+np.float64,0xbfc147f125228fe4,0x3ffb4cab18b9050f,2
+np.float64,0xbfcb9145b537228c,0x3ffc9b1b6227a8c9,2
+np.float64,0xbfda84ef4bb509de,0x3ffff7f8a674e17d,2
+np.float64,0x3fd2eb6bbfa5d6d8,0x3ff454c225529d7e,2
+np.float64,0x3fe18c95f1e3192c,0x3fefb0cf0efba75a,2
+np.float64,0x3fe78606efef0c0e,0x3fe7d6c3a092d64c,2
+np.float64,0x3fbad5119a35aa20,0x3ff773dffe3ce660,2
+np.float64,0x3fd0cf5903a19eb4,0x3ff4e15fd21fdb42,2
+np.float64,0xbfd85ce90bb0b9d2,0x3fff618ee848e974,2
+np.float64,0x3fe90e11b9f21c24,0x3fe57be62f606f4a,2
+np.float64,0x3fd7a2040faf4408,0x3ff314ce85457ec2,2
+np.float64,0xbfd73fba69ae7f74,0x3fff14bff3504811,2
+np.float64,0x3fa04b4bd42096a0,0x3ff89f9b52f521a2,2
+np.float64,0xbfd7219ce5ae433a,0x3fff0cac0b45cc18,2
+np.float64,0xbfe0cf4661e19e8d,0x4000fdadb14e3c22,2
+np.float64,0x3fd07469fea0e8d4,0x3ff4f8eaa9b2394a,2
+np.float64,0x3f9b05c5d8360b80,0x3ff8b5e10672db5c,2
+np.float64,0x3fe4c25b916984b8,0x3febad29bd0e25e2,2
+np.float64,0xbfde8b4891bd1692,0x40008beb88d5c409,2
+np.float64,0xbfe199a7efe33350,0x400139b089aee21c,2
+np.float64,0x3fecdad25cf9b5a4,0x3fdc9d062867e8c3,2
+np.float64,0xbfe979b277f2f365,0x4003eedb061e25a4,2
+np.float64,0x3fc8c7311f318e60,0x3ff6040b9aeaad9d,2
+np.float64,0x3fd2b605b8a56c0c,0x3ff462b9a955c224,2
+np.float64,0x3fc073b6ad20e770,0x3ff7120e9f2fd63c,2
+np.float64,0xbfec60ede678c1dc,0x40054a3863e24dc2,2
+np.float64,0x3fe225171be44a2e,0x3feef910dca420ea,2
+np.float64,0xbfd7529762aea52e,0x3fff19d00661f650,2
+np.float64,0xbfd781783daf02f0,0x3fff2667b90be461,2
+np.float64,0x3fe3f6ec6d67edd8,0x3fecb4e814a2e33a,2
+np.float64,0x3fece6702df9cce0,0x3fdc6719d92a50d2,2
+np.float64,0xbfb5c602ce2b8c08,0x3ffa7ec761ba856a,2
+np.float64,0xbfd61f0153ac3e02,0x3ffec78e3b1a6c4d,2
+np.float64,0xbfec3462b2f868c5,0x400532630bbd7050,2
+np.float64,0xbfdd248485ba490a,0x400059391c07c1bb,2
+np.float64,0xbfd424921fa84924,0x3ffe416a85d1dcdf,2
+np.float64,0x3fbb23a932364750,0x3ff76eef79209f7f,2
+np.float64,0x3fca248b0f344918,0x3ff5d77c5c1b4e5e,2
+np.float64,0xbfe69af4a4ed35ea,0x4002d77c2e4fbd4e,2
+np.float64,0x3fdafe3cdcb5fc78,0x3ff22a9be6efbbf2,2
+np.float64,0xbfebba3377f77467,0x4004f3836e1fe71a,2
+np.float64,0xbfe650fae06ca1f6,0x4002bd851406377c,2
+np.float64,0x3fda630007b4c600,0x3ff2554f1832bd94,2
+np.float64,0xbfda8107d9b50210,0x3ffff6e6209659f3,2
+np.float64,0x3fea759a02f4eb34,0x3fe31d1a632c9aae,2
+np.float64,0x3fbf88149e3f1030,0x3ff728313aa12ccb,2
+np.float64,0x3f7196d2a0232e00,0x3ff910647e1914c1,2
+np.float64,0x3feeae51d17d5ca4,0x3fd2709698d31f6f,2
+np.float64,0xbfd73cd663ae79ac,0x3fff13f96300b55a,2
+np.float64,0x3fd4fc5f06a9f8c0,0x3ff3c99359854b97,2
+np.float64,0x3fb29f5d6e253ec0,0x3ff7f7c20e396b20,2
+np.float64,0xbfd757c82aaeaf90,0x3fff1b34c6141e98,2
+np.float64,0x3fc56fd4cf2adfa8,0x3ff670c145122909,2
+np.float64,0x3fc609a2f52c1348,0x3ff65d3ef3cade2c,2
+np.float64,0xbfe1de631163bcc6,0x40014e5528fadb73,2
+np.float64,0xbfe7eb4a726fd695,0x40035202f49d95c4,2
+np.float64,0xbfc9223771324470,0x3ffc4b84d5e263b9,2
+np.float64,0x3fee91a8a87d2352,0x3fd3364befde8de6,2
+np.float64,0x3fbc9784fe392f10,0x3ff7578e29f6a1b2,2
+np.float64,0xbfec627c2c78c4f8,0x40054b0ff2cb9c55,2
+np.float64,0xbfb8b406a6316810,0x3ffaadd97062fb8c,2
+np.float64,0xbfecf98384f9f307,0x4005a043d9110d79,2
+np.float64,0xbfe5834bab6b0698,0x400276f114aebee4,2
+np.float64,0xbfd90f391eb21e72,0x3fff91e26a8f48f3,2
+np.float64,0xbfee288ce2fc511a,0x400667cb09aa04b3,2
+np.float64,0x3fd5aa5e32ab54bc,0x3ff39b7080a52214,2
+np.float64,0xbfee7ef907fcfdf2,0x4006ab96a8eba4c5,2
+np.float64,0x3fd6097973ac12f4,0x3ff3822486978bd1,2
+np.float64,0xbfe02d14b8e05a2a,0x4000ce5be53047b1,2
+np.float64,0xbf9c629a6838c540,0x3ff993897728c3f9,2
+np.float64,0xbfee2024667c4049,0x40066188782fb1f0,2
+np.float64,0xbfa42a88fc285510,0x3ff9c35a4bbce104,2
+np.float64,0x3fa407af5c280f60,0x3ff881b360d8eea1,2
+np.float64,0x3fed0ba42cfa1748,0x3fdbb7d55609175f,2
+np.float64,0xbfdd0b5844ba16b0,0x400055b0bb59ebb2,2
+np.float64,0x3fd88d97e6b11b30,0x3ff2d53c1ecb8f8c,2
+np.float64,0xbfeb7a915ef6f523,0x4004d410812eb84c,2
+np.float64,0xbfb5f979ca2bf2f0,0x3ffa8201d73cd4ca,2
+np.float64,0x3fb3b65dd6276cc0,0x3ff7e64576199505,2
+np.float64,0x3fcd47a7793a8f50,0x3ff570a7b672f160,2
+np.float64,0xbfa41dd30c283ba0,0x3ff9c2f488127eb3,2
+np.float64,0x3fe4b1ea1f6963d4,0x3febc2bed7760427,2
+np.float64,0xbfdd0f81d2ba1f04,0x400056463724b768,2
+np.float64,0x3fd15d93f7a2bb28,0x3ff4bc7a24eacfd7,2
+np.float64,0xbfe3213af8e64276,0x4001b14579dfded3,2
+np.float64,0x3fd90dfbeab21bf8,0x3ff2b26a6c2c3bb3,2
+np.float64,0xbfd02d54bca05aaa,0x3ffd38ab3886b203,2
+np.float64,0x3fc218dcad2431b8,0x3ff6dced56d5b417,2
+np.float64,0x3fea5edf71f4bdbe,0x3fe3455ee09f27e6,2
+np.float64,0x3fa74319042e8640,0x3ff867d224545438,2
+np.float64,0x3fd970ad92b2e15c,0x3ff2979084815dc1,2
+np.float64,0x3fce0a4bf73c1498,0x3ff557a4df32df3e,2
+np.float64,0x3fef5c8e10feb91c,0x3fc99ca0eeaaebe4,2
+np.float64,0xbfedae997ffb5d33,0x400611af18f407ab,2
+np.float64,0xbfbcf07d6239e0f8,0x3ffaf201177a2d36,2
+np.float64,0xbfc3c52541278a4c,0x3ffb9d2af0408e4a,2
+np.float64,0x3fe4ef44e4e9de8a,0x3feb71f7331255e5,2
+np.float64,0xbfccd9f5f539b3ec,0x3ffcc53a99339592,2
+np.float64,0xbfda32c745b4658e,0x3fffe16e8727ef89,2
+np.float64,0xbfef54932a7ea926,0x40077e4605e61ca1,2
+np.float64,0x3fe9d4ae3573a95c,0x3fe4344a069a3fd0,2
+np.float64,0x3fda567e73b4acfc,0x3ff258bd77a663c7,2
+np.float64,0xbfd5bcac5eab7958,0x3ffead6379c19c52,2
+np.float64,0xbfee5e56f97cbcae,0x40069131fc54018d,2
+np.float64,0x3fc2d4413925a880,0x3ff6c54163816298,2
+np.float64,0xbfe9ddf6e873bbee,0x400418d8c722f7c5,2
+np.float64,0x3fdaf2a683b5e54c,0x3ff22dcda599d69c,2
+np.float64,0xbfca69789f34d2f0,0x3ffc7547ff10b1a6,2
+np.float64,0x3fed076f62fa0ede,0x3fdbcbda03c1d72a,2
+np.float64,0xbfcb38326f367064,0x3ffc8fb55dadeae5,2
+np.float64,0x3fe1938705e3270e,0x3fefa88130c5adda,2
+np.float64,0x3feaffae3b75ff5c,0x3fe221e3da537c7e,2
+np.float64,0x3fefc94acb7f9296,0x3fbd9a360ace67b4,2
+np.float64,0xbfe8bddeb0f17bbe,0x4003a316685c767e,2
+np.float64,0x3fbe10fbee3c21f0,0x3ff73fceb10650f5,2
+np.float64,0x3fde9126c1bd224c,0x3ff12a742f734d0a,2
+np.float64,0xbfe9686c91f2d0d9,0x4003e7bc6ee77906,2
+np.float64,0xbfb1ba4892237490,0x3ffa3dda064c2509,2
+np.float64,0xbfe2879100e50f22,0x400181c1a5b16f0f,2
+np.float64,0x3fd1cd40b6a39a80,0x3ff49f70e3064e95,2
+np.float64,0xbfc965869132cb0c,0x3ffc5419f3b43701,2
+np.float64,0x3fea7a6f2874f4de,0x3fe31480fb2dd862,2
+np.float64,0x3fc3bc56892778b0,0x3ff6a7e8fa0e8b0e,2
+np.float64,0x3fec1ed451f83da8,0x3fdfd78e564b8ad7,2
+np.float64,0x3feb77d16df6efa2,0x3fe13d083344e45e,2
+np.float64,0xbfe822e7c67045d0,0x400367104a830cf6,2
+np.float64,0x8000000000000001,0x3ff921fb54442d18,2
+np.float64,0xbfd4900918a92012,0x3ffe5dc0e19737b4,2
+np.float64,0x3fed184187fa3084,0x3fdb7b7a39f234f4,2
+np.float64,0x3fecef846179df08,0x3fdc3cb2228c3682,2
+np.float64,0xbfe2d2aed165a55e,0x400198e21c5b861b,2
+np.float64,0x7ff0000000000000,0x7ff8000000000000,2
+np.float64,0xbfee9409a07d2813,0x4006bd358232d073,2
+np.float64,0xbfecedc2baf9db86,0x4005995df566fc21,2
+np.float64,0x3fe6d857396db0ae,0x3fe8d2cb8794aa99,2
+np.float64,0xbf9a579e7834af40,0x3ff98b5cc8021e1c,2
+np.float64,0x3fc664fefb2cca00,0x3ff651a664ccf8fa,2
+np.float64,0xbfe8a7aa0e714f54,0x40039a5b4df938a0,2
+np.float64,0xbfdf27d380be4fa8,0x4000a241074dbae6,2
+np.float64,0x3fe00ddf55e01bbe,0x3ff0b94eb1ea1851,2
+np.float64,0x3feb47edbff68fdc,0x3fe199822d075959,2
+np.float64,0x3fb4993822293270,0x3ff7d80c838186d0,2
+np.float64,0xbfca2cd1473459a4,0x3ffc6d88c8de3d0d,2
+np.float64,0xbfea7d9c7674fb39,0x40045e4559e9e52d,2
+np.float64,0x3fe0dce425e1b9c8,0x3ff04099cab23289,2
+np.float64,0x3fd6bb7e97ad76fc,0x3ff352a30434499c,2
+np.float64,0x3fd4a4f16da949e4,0x3ff3e0b07432c9aa,2
+np.float64,0x8000000000000000,0x3ff921fb54442d18,2
+np.float64,0x3fe688f5b56d11ec,0x3fe9435f63264375,2
+np.float64,0xbfdf5a427ebeb484,0x4000a97a6c5d4abc,2
+np.float64,0xbfd1f3483fa3e690,0x3ffdae6c8a299383,2
+np.float64,0xbfeac920db759242,0x4004805862be51ec,2
+np.float64,0x3fef5bc711feb78e,0x3fc9ac40fba5b93b,2
+np.float64,0x3fe4bd9e12e97b3c,0x3febb363c787d381,2
+np.float64,0x3fef6a59ab7ed4b4,0x3fc880f1324eafce,2
+np.float64,0x3fc07a362120f470,0x3ff7113cf2c672b3,2
+np.float64,0xbfe4d6dbe2e9adb8,0x40023d6f6bea44b7,2
+np.float64,0xbfec2d6a15785ad4,0x40052eb425cc37a2,2
+np.float64,0x3fc90dae05321b60,0x3ff5fb10015d2934,2
+np.float64,0xbfa9239f74324740,0x3ff9eb2d057068ea,2
+np.float64,0xbfeb4fc8baf69f92,0x4004bf5e17fb08a4,2
+np.float64,0x0,0x3ff921fb54442d18,2
+np.float64,0x3faaf1884c35e320,0x3ff84a5591dbe1f3,2
+np.float64,0xbfed842561fb084b,0x4005f5c0a19116ce,2
+np.float64,0xbfc64850c32c90a0,0x3ffbeeac2ee70f9a,2
+np.float64,0x3fd7d879f5afb0f4,0x3ff306254c453436,2
+np.float64,0xbfdabaa586b5754c,0x4000035e6ac83a2b,2
+np.float64,0xbfebfeefa977fddf,0x4005167446fb9faf,2
+np.float64,0xbfe9383462727069,0x4003d407aa6a1577,2
+np.float64,0x3fe108dfb6e211c0,0x3ff026ac924b281d,2
+np.float64,0xbf85096df02a12c0,0x3ff94c0e60a22ede,2
+np.float64,0xbfe3121cd566243a,0x4001ac8f90db5882,2
+np.float64,0xbfd227f62aa44fec,0x3ffdbc26bb175dcc,2
+np.float64,0x3fd931af2cb26360,0x3ff2a8b62dfe003c,2
+np.float64,0xbfd9b794e3b36f2a,0x3fffbfbc89ec013d,2
+np.float64,0x3fc89b2e6f313660,0x3ff609a6e67f15f2,2
+np.float64,0x3fc0b14a8f216298,0x3ff70a4b6905aad2,2
+np.float64,0xbfeda11a657b4235,0x400608b3f9fff574,2
+np.float64,0xbfed2ee9ec7a5dd4,0x4005c040b7c02390,2
+np.float64,0xbfef7819d8fef034,0x4007ac6bf75cf09d,2
+np.float64,0xbfcc4720fb388e40,0x3ffcb2666a00b336,2
+np.float64,0xbfe05dec4be0bbd8,0x4000dc8a25ca3760,2
+np.float64,0x3fb093416e212680,0x3ff81897b6d8b374,2
+np.float64,0xbfc6ab89332d5714,0x3ffbfb4559d143e7,2
+np.float64,0x3fc51948512a3290,0x3ff67bb9df662c0a,2
+np.float64,0x3fed4d94177a9b28,0x3fda76c92f0c0132,2
+np.float64,0x3fdd195fbeba32c0,0x3ff194a5586dd18e,2
+np.float64,0x3fe3f82799e7f050,0x3fecb354c2faf55c,2
+np.float64,0x3fecac2169f95842,0x3fdd7222296cb7a7,2
+np.float64,0x3fe3d3f36fe7a7e6,0x3fece18f45e30dd7,2
+np.float64,0x3fe31ff63d663fec,0x3fedc46c77d30c6a,2
+np.float64,0xbfe3120c83e62419,0x4001ac8a7c4aa742,2
+np.float64,0x3fe7c1a7976f8350,0x3fe77e4a9307c9f8,2
+np.float64,0x3fe226fe9de44dfe,0x3feef6c0f3cb00fa,2
+np.float64,0x3fd5c933baab9268,0x3ff3933e8a37de42,2
+np.float64,0x3feaa98496f5530a,0x3fe2c003832ebf21,2
+np.float64,0xbfc6f80a2f2df014,0x3ffc04fd54cb1317,2
+np.float64,0x3fde5e18d0bcbc30,0x3ff138f7b32a2ca3,2
+np.float64,0xbfe30c8dd566191c,0x4001aad4af935a78,2
+np.float64,0x3fbe8d196e3d1a30,0x3ff737fec8149ecc,2
+np.float64,0x3feaee6731f5dcce,0x3fe241fa42cce22d,2
+np.float64,0x3fef9cc46cff3988,0x3fc3f17b708dbdbb,2
+np.float64,0xbfdb181bdeb63038,0x4000103ecf405602,2
+np.float64,0xbfc58de0ed2b1bc0,0x3ffbd704c14e15cd,2
+np.float64,0xbfee05d5507c0bab,0x40064e480faba6d8,2
+np.float64,0x3fe27d0ffa64fa20,0x3fee8dc71ef79f2c,2
+np.float64,0xbfe4f7ad4c69ef5a,0x400248456cd09a07,2
+np.float64,0xbfe4843e91e9087d,0x4002225f3e139c84,2
+np.float64,0x3fe7158b9c6e2b18,0x3fe87ae845c5ba96,2
+np.float64,0xbfea64316074c863,0x400452fd2bc23a44,2
+np.float64,0xbfc9f3ae4133e75c,0x3ffc663d482afa42,2
+np.float64,0xbfd5e18513abc30a,0x3ffeb72fc76d7071,2
+np.float64,0xbfd52f6438aa5ec8,0x3ffe87e5b18041e5,2
+np.float64,0xbfea970650f52e0d,0x400469a4a6758154,2
+np.float64,0xbfe44321b7e88644,0x40020d404a2141b1,2
+np.float64,0x3fdf5a39bbbeb474,0x3ff0f10453059dbd,2
+np.float64,0xbfa1d4069423a810,0x3ff9b0a2eacd2ce2,2
+np.float64,0xbfc36d16a326da2c,0x3ffb92077d41d26a,2
+np.float64,0x1,0x3ff921fb54442d18,2
+np.float64,0x3feb232a79764654,0x3fe1df5beeb249d0,2
+np.float64,0xbfed2003d5fa4008,0x4005b737c2727583,2
+np.float64,0x3fd5b093a3ab6128,0x3ff399ca2db1d96d,2
+np.float64,0x3fca692c3d34d258,0x3ff5ceb86b79223e,2
+np.float64,0x3fd6bbdf89ad77c0,0x3ff3528916df652d,2
+np.float64,0xbfefdadd46ffb5bb,0x40085ee735e19f19,2
+np.float64,0x3feb69fb2676d3f6,0x3fe157ee0c15691e,2
+np.float64,0x3fe44c931f689926,0x3fec46b6f5e3f265,2
+np.float64,0xbfc43ddbcb287bb8,0x3ffbac71d268d74d,2
+np.float64,0x3fe6e16d43edc2da,0x3fe8c5cf0f0daa66,2
+np.float64,0x3fe489efc76913e0,0x3febf704ca1ac2a6,2
+np.float64,0xbfe590aadceb2156,0x40027b764205cf78,2
+np.float64,0xbf782e8aa0305d00,0x3ff93a29e81928ab,2
+np.float64,0x3fedcb80cffb9702,0x3fd7e5d1f98a418b,2
+np.float64,0x3fe075858060eb0c,0x3ff07d23ab46b60f,2
+np.float64,0x3fe62a68296c54d0,0x3fe9c77f7068043b,2
+np.float64,0x3feff16a3c7fe2d4,0x3fae8e8a739cc67a,2
+np.float64,0xbfd6ed93e3addb28,0x3ffefebab206fa99,2
+np.float64,0x3fe40d8ccf681b1a,0x3fec97e9cd29966d,2
+np.float64,0x3fd6408210ac8104,0x3ff3737a7d374107,2
+np.float64,0x3fec8023b8f90048,0x3fde35ebfb2b3afd,2
+np.float64,0xbfe13babd4627758,0x40011dae5c07c56b,2
+np.float64,0xbfd2183e61a4307c,0x3ffdb80dd747cfbe,2
+np.float64,0x3feae8eb1d75d1d6,0x3fe24c1f6e42ae77,2
+np.float64,0xbfea559b9c74ab37,0x40044c8e5e123b20,2
+np.float64,0xbfd12c9d57a2593a,0x3ffd7ac6222f561c,2
+np.float64,0x3fe32eb697e65d6e,0x3fedb202693875b6,2
+np.float64,0xbfde0808c3bc1012,0x4000794bd8616ea3,2
+np.float64,0x3fe14958a06292b2,0x3ff0007b40ac648a,2
+np.float64,0x3fe3d388a6e7a712,0x3fece21751a6dd7c,2
+np.float64,0x3fe7ad7897ef5af2,0x3fe79c5b3da302a7,2
+np.float64,0x3fec75527e78eaa4,0x3fde655de0cf0508,2
+np.float64,0x3fea920d4c75241a,0x3fe2ea48f031d908,2
+np.float64,0x7fefffffffffffff,0x7ff8000000000000,2
+np.float64,0xbfc17a68cb22f4d0,0x3ffb530925f41aa0,2
+np.float64,0xbfe1c93166e39263,0x400147f3cb435dec,2
+np.float64,0x3feb97c402f72f88,0x3fe0fe5b561bf869,2
+np.float64,0x3fb58ff5162b1ff0,0x3ff7c8933fa969dc,2
+np.float64,0x3fe68e2beded1c58,0x3fe93c075283703b,2
+np.float64,0xbf94564cc828aca0,0x3ff97355e5ee35db,2
+np.float64,0x3fd31061c9a620c4,0x3ff44b150ec96998,2
+np.float64,0xbfc7d0c89f2fa190,0x3ffc208bf4eddc4d,2
+np.float64,0x3fe5736f1d6ae6de,0x3feac18f84992d1e,2
+np.float64,0x3fdb62e480b6c5c8,0x3ff20ecfdc4afe7c,2
+np.float64,0xbfc417228b282e44,0x3ffba78afea35979,2
+np.float64,0x3f8f5ba1303eb780,0x3ff8e343714630ff,2
+np.float64,0x3fe8e99126f1d322,0x3fe5b6511d4c0798,2
+np.float64,0xbfe2ec08a1e5d812,0x4001a0bb28a85875,2
+np.float64,0x3fea3b46cf74768e,0x3fe383dceaa74296,2
+np.float64,0xbfe008b5ed60116c,0x4000c3d62c275d40,2
+np.float64,0xbfcd9f8a4b3b3f14,0x3ffcde98d6484202,2
+np.float64,0xbfdb5fb112b6bf62,0x40001a22137ef1c9,2
+np.float64,0xbfe9079565f20f2b,0x4003c0670c92e401,2
+np.float64,0xbfce250dc53c4a1c,0x3ffcefc2b3dc3332,2
+np.float64,0x3fe9ba85d373750c,0x3fe4607131b28773,2
+np.float64,0x10000000000000,0x3ff921fb54442d18,2
+np.float64,0xbfeb9ef42c773de8,0x4004e5f239203ad8,2
+np.float64,0xbfd6bf457dad7e8a,0x3ffef2563d87b18d,2
+np.float64,0x3fe4de9aa5e9bd36,0x3feb87f97defb04a,2
+np.float64,0x3fedb4f67cfb69ec,0x3fd8603c465bffac,2
+np.float64,0x3fe7b6d9506f6db2,0x3fe78e670c7bdb67,2
+np.float64,0x3fe071717460e2e2,0x3ff07f84472d9cc5,2
+np.float64,0xbfed2e79dbfa5cf4,0x4005bffc6f9ad24f,2
+np.float64,0x3febb8adc377715c,0x3fe0bcebfbd45900,2
+np.float64,0xbfee2cffd87c5a00,0x40066b20a037c478,2
+np.float64,0x3fef7e358d7efc6c,0x3fc6d0ba71a542a8,2
+np.float64,0xbfef027eef7e04fe,0x400723291cb00a7a,2
+np.float64,0x3fac96da34392dc0,0x3ff83d260a936c6a,2
+np.float64,0x3fe9dba94a73b752,0x3fe428736b94885e,2
+np.float64,0x3fed37581efa6eb0,0x3fdae49dcadf1d90,2
+np.float64,0xbfe6e61037edcc20,0x4002f23031b8d522,2
+np.float64,0xbfdea7204dbd4e40,0x40008fe1f37918b7,2
+np.float64,0x3feb9f8edb773f1e,0x3fe0eef20bd4387b,2
+np.float64,0x3feeb0b6ed7d616e,0x3fd25fb3b7a525d6,2
+np.float64,0xbfd7ce9061af9d20,0x3fff3b25d531aa2b,2
+np.float64,0xbfc806b509300d6c,0x3ffc2768743a8360,2
+np.float64,0xbfa283882c250710,0x3ff9b61fda28914a,2
+np.float64,0x3fdec70050bd8e00,0x3ff11b1d769b578f,2
+np.float64,0xbfc858a44930b148,0x3ffc31d6758b4721,2
+np.float64,0x3fdc321150b86424,0x3ff1d5504c3c91e4,2
+np.float64,0x3fd9416870b282d0,0x3ff2a46f3a850f5b,2
+np.float64,0x3fdd756968baead4,0x3ff17ac510a5573f,2
+np.float64,0xbfedfd632cfbfac6,0x400648345a2f89b0,2
+np.float64,0x3fd6874285ad0e84,0x3ff36098ebff763f,2
+np.float64,0x3fe6daacc9edb55a,0x3fe8cf75fae1e35f,2
+np.float64,0x3fe53f19766a7e32,0x3feb07d0e97cd55b,2
+np.float64,0x3fd13cc36ca27988,0x3ff4c4ff801b1faa,2
+np.float64,0x3fe4f21cbce9e43a,0x3feb6e34a72ef529,2
+np.float64,0xbfc21c1cc9243838,0x3ffb67726394ca89,2
+np.float64,0x3fe947a3f2728f48,0x3fe51eae4660e23c,2
+np.float64,0xbfce78cd653cf19c,0x3ffcfa89194b3f5e,2
+np.float64,0x3fe756f049eeade0,0x3fe81be7f2d399e2,2
+np.float64,0xbfcc727cf138e4f8,0x3ffcb7f547841bb0,2
+np.float64,0xbfc2d8d58f25b1ac,0x3ffb7f496cc72458,2
+np.float64,0xbfcfd0e4653fa1c8,0x3ffd26e1309bc80b,2
+np.float64,0xbfe2126c106424d8,0x40015e0e01db6a4a,2
+np.float64,0x3fe580e4306b01c8,0x3feaaf683ce51aa5,2
+np.float64,0x3fcea8a1b93d5140,0x3ff543456c0d28c7,2
+np.float64,0xfff0000000000000,0x7ff8000000000000,2
+np.float64,0xbfd9d5da72b3abb4,0x3fffc8013113f968,2
+np.float64,0xbfe1fdfcea63fbfa,0x400157def2e4808d,2
+np.float64,0xbfc0022e0720045c,0x3ffb239963e7cbf2,2
diff --git a/numpy/core/tests/data/umath-validation-set-arccosh.csv b/numpy/core/tests/data/umath-validation-set-arccosh.csv
new file mode 100644
index 000000000..0defe50be
--- /dev/null
+++ b/numpy/core/tests/data/umath-validation-set-arccosh.csv
@@ -0,0 +1,1429 @@
+dtype,input,output,ulperrortol
+np.float32,0x3f83203f,0x3e61d9d6,2
+np.float32,0x3f98dea1,0x3f1d1af6,2
+np.float32,0x7fa00000,0x7fe00000,2
+np.float32,0x7eba99af,0x42b0d032,2
+np.float32,0x3fc95a13,0x3f833650,2
+np.float32,0x3fce9a45,0x3f8771e1,2
+np.float32,0x3fc1bd96,0x3f797811,2
+np.float32,0x7eba2391,0x42b0ceed,2
+np.float32,0x7d4e8f15,0x42acdb8c,2
+np.float32,0x3feca42e,0x3f9cc88e,2
+np.float32,0x7e2b314e,0x42af412e,2
+np.float32,0x7f7fffff,0x42b2d4fc,2
+np.float32,0x3f803687,0x3d6c4380,2
+np.float32,0x3fa0edbd,0x3f33e706,2
+np.float32,0x3faa8074,0x3f4b3d3c,2
+np.float32,0x3fa0c49e,0x3f337af3,2
+np.float32,0x3f8c9ec4,0x3ee18812,2
+np.float32,0x7efef78e,0x42b17006,2
+np.float32,0x3fc75720,0x3f818aa4,2
+np.float32,0x7f52d4c8,0x42b27198,2
+np.float32,0x3f88f21e,0x3ebe52b0,2
+np.float32,0x3ff7a042,0x3fa3a07a,2
+np.float32,0x7f52115c,0x42b26fbd,2
+np.float32,0x3fc6bf6f,0x3f810b42,2
+np.float32,0x3fd105d0,0x3f895649,2
+np.float32,0x3fee7c2a,0x3f9df66e,2
+np.float32,0x7f0ff9a5,0x42b1ae4f,2
+np.float32,0x7e81f075,0x42b016e7,2
+np.float32,0x3fa57d65,0x3f3f70c6,2
+np.float32,0x80800000,0xffc00000,2
+np.float32,0x7da239f5,0x42adc2bf,2
+np.float32,0x3f9e432c,0x3f2cbd80,2
+np.float32,0x3ff2839b,0x3fa07ee4,2
+np.float32,0x3fec8aef,0x3f9cb850,2
+np.float32,0x7d325893,0x42ac905b,2
+np.float32,0x3fa27431,0x3f37dade,2
+np.float32,0x3fce7408,0x3f8753ae,2
+np.float32,0x3fde6684,0x3f93353f,2
+np.float32,0x3feb9a3e,0x3f9c1cff,2
+np.float32,0x7deb34bb,0x42ae80f0,2
+np.float32,0x3fed9300,0x3f9d61b7,2
+np.float32,0x7f35e253,0x42b225fb,2
+np.float32,0x7e6db57f,0x42afe93f,2
+np.float32,0x3fa41f08,0x3f3c10bc,2
+np.float32,0x3fb0d4da,0x3f590de3,2
+np.float32,0x3fb5c690,0x3f632351,2
+np.float32,0x3fcde9ce,0x3f86e638,2
+np.float32,0x3f809c7b,0x3dc81161,2
+np.float32,0x3fd77291,0x3f8e3226,2
+np.float32,0x3fc21a06,0x3f7a1a82,2
+np.float32,0x3fba177e,0x3f6b8139,2
+np.float32,0x7f370dff,0x42b22944,2
+np.float32,0x3fe5bfcc,0x3f9841c1,2
+np.float32,0x3feb0caa,0x3f9bc139,2
+np.float32,0x7f4fe5c3,0x42b26a6c,2
+np.float32,0x7f1e1419,0x42b1de28,2
+np.float32,0x7f5e3c96,0x42b28c92,2
+np.float32,0x3f8cd313,0x3ee3521e,2
+np.float32,0x3fa97824,0x3f48e049,2
+np.float32,0x7d8ca281,0x42ad799e,2
+np.float32,0x3f96b51b,0x3f165193,2
+np.float32,0x3f81328a,0x3e0bf504,2
+np.float32,0x3ff60bf3,0x3fa2ab45,2
+np.float32,0x3ff9b629,0x3fa4e107,2
+np.float32,0x3fecacfc,0x3f9cce37,2
+np.float32,0x3fba8804,0x3f6c5600,2
+np.float32,0x3f81f752,0x3e333fdd,2
+np.float32,0x3fb5b262,0x3f62fb46,2
+np.float32,0x3fa21bc0,0x3f36f7e6,2
+np.float32,0x3fbc87bb,0x3f7011dc,2
+np.float32,0x3fe18b32,0x3f9565ae,2
+np.float32,0x7dfb6dd5,0x42aea316,2
+np.float32,0x3fb7c602,0x3f670ee3,2
+np.float32,0x7efeb6a2,0x42b16f84,2
+np.float32,0x3fa56180,0x3f3f2ca4,2
+np.float32,0x3f8dcaff,0x3eeb9ac0,2
+np.float32,0x7e876238,0x42b02beb,2
+np.float32,0x7f0bb67d,0x42b19eec,2
+np.float32,0x3faca01c,0x3f4fffa5,2
+np.float32,0x3fdb57ee,0x3f9108b8,2
+np.float32,0x3fe3bade,0x3f96e4b7,2
+np.float32,0x7f7aa2dd,0x42b2ca25,2
+np.float32,0x3fed92ec,0x3f9d61aa,2
+np.float32,0x7eb789b1,0x42b0c7b9,2
+np.float32,0x7f7f16e4,0x42b2d329,2
+np.float32,0x3fb6647e,0x3f645b84,2
+np.float32,0x3f99335e,0x3f1e1d96,2
+np.float32,0x7e690a11,0x42afdf17,2
+np.float32,0x7dff2f95,0x42aeaaae,2
+np.float32,0x7f70adfd,0x42b2b564,2
+np.float32,0x3fe92252,0x3f9a80fe,2
+np.float32,0x3fef54ce,0x3f9e7fe5,2
+np.float32,0x3ff24eaa,0x3fa05df9,2
+np.float32,0x7f04565a,0x42b18328,2
+np.float32,0x3fcb8b80,0x3f85007f,2
+np.float32,0x3fcd4d0a,0x3f866983,2
+np.float32,0x3fbe7d82,0x3f73a911,2
+np.float32,0x3f8a7a8a,0x3ecdc8f6,2
+np.float32,0x3f912441,0x3f030d56,2
+np.float32,0x3f9b29d6,0x3f23f663,2
+np.float32,0x3fab7f36,0x3f4d7c6c,2
+np.float32,0x7dfedafc,0x42aeaa04,2
+np.float32,0x3fe190c0,0x3f956982,2
+np.float32,0x3f927515,0x3f07e0bb,2
+np.float32,0x3ff6442a,0x3fa2cd7e,2
+np.float32,0x7f6656d0,0x42b29ee8,2
+np.float32,0x3fe29aa0,0x3f96201f,2
+np.float32,0x3fa4a247,0x3f3d5687,2
+np.float32,0x3fa1cf19,0x3f363226,2
+np.float32,0x3fc20037,0x3f79ed36,2
+np.float32,0x7cc1241a,0x42ab5645,2
+np.float32,0x3fafd540,0x3f56f25a,2
+np.float32,0x7e5b3f5f,0x42afbfdb,2
+np.float32,0x7f48de5f,0x42b258d0,2
+np.float32,0x3fce1ca0,0x3f870e85,2
+np.float32,0x7ee40bb2,0x42b136e4,2
+np.float32,0x7ecdb133,0x42b10212,2
+np.float32,0x3f9f181c,0x3f2f02ca,2
+np.float32,0x3f936cbf,0x3f0b4f63,2
+np.float32,0x3fa4f8ea,0x3f3e2c2f,2
+np.float32,0x3fcc03e2,0x3f8561ac,2
+np.float32,0x3fb801f2,0x3f67831b,2
+np.float32,0x7e141dad,0x42aef70c,2
+np.float32,0x3fe8c04e,0x3f9a4087,2
+np.float32,0x3f8548d5,0x3e929f37,2
+np.float32,0x7f148d7d,0x42b1be56,2
+np.float32,0x3fd2c9a2,0x3f8ab1ed,2
+np.float32,0x7eb374fd,0x42b0bc36,2
+np.float32,0x7f296d36,0x42b201a7,2
+np.float32,0x3ff138e2,0x3f9fb09d,2
+np.float32,0x3ff42898,0x3fa18347,2
+np.float32,0x7da8c5e1,0x42add700,2
+np.float32,0x7dcf72c4,0x42ae40a4,2
+np.float32,0x7ea571fc,0x42b09296,2
+np.float32,0x3fc0953d,0x3f776ba3,2
+np.float32,0x7f1773dd,0x42b1c83c,2
+np.float32,0x7ef53b68,0x42b15c17,2
+np.float32,0x3f85d69f,0x3e9a0f3a,2
+np.float32,0x7e8b9a05,0x42b03ba0,2
+np.float32,0x3ff07d20,0x3f9f3ad2,2
+np.float32,0x7e8da32c,0x42b0430a,2
+np.float32,0x7ef96004,0x42b164ab,2
+np.float32,0x3fdfaa62,0x3f941837,2
+np.float32,0x7f0057c5,0x42b17377,2
+np.float32,0x3fb2663f,0x3f5c5065,2
+np.float32,0x3fd3d8c3,0x3f8b8055,2
+np.float32,0x1,0xffc00000,2
+np.float32,0x3fd536c1,0x3f8c8862,2
+np.float32,0x3f91b953,0x3f053619,2
+np.float32,0x3fb3305c,0x3f5deee1,2
+np.float32,0x7ecd86b9,0x42b101a8,2
+np.float32,0x3fbf71c5,0x3f75624d,2
+np.float32,0x3ff5f0f4,0x3fa29ad2,2
+np.float32,0x3fe50389,0x3f97c328,2
+np.float32,0x3fa325a1,0x3f399e69,2
+np.float32,0x3fe4397a,0x3f973a9f,2
+np.float32,0x3f8684c6,0x3ea2b784,2
+np.float32,0x7f25ae00,0x42b1f634,2
+np.float32,0x3ff7cbf7,0x3fa3badb,2
+np.float32,0x7f73f0e0,0x42b2bc48,2
+np.float32,0x3fc88b70,0x3f828b92,2
+np.float32,0x3fb01c16,0x3f578886,2
+np.float32,0x7e557623,0x42afb229,2
+np.float32,0x3fcbcd5b,0x3f8535b4,2
+np.float32,0x7f7157e4,0x42b2b6cd,2
+np.float32,0x7f51d9d4,0x42b26f36,2
+np.float32,0x7f331a3b,0x42b21e17,2
+np.float32,0x7f777fb5,0x42b2c3b2,2
+np.float32,0x3f832001,0x3e61d11f,2
+np.float32,0x7f2cd055,0x42b20bca,2
+np.float32,0x3f89831f,0x3ec42f76,2
+np.float32,0x7f21da33,0x42b1ea3d,2
+np.float32,0x3f99e416,0x3f20330a,2
+np.float32,0x7f2c8ea1,0x42b20b07,2
+np.float32,0x7f462c98,0x42b251e6,2
+np.float32,0x7f4fdb3f,0x42b26a52,2
+np.float32,0x3fcc1338,0x3f856e07,2
+np.float32,0x3f823673,0x3e3e20da,2
+np.float32,0x7dbfe89d,0x42ae18c6,2
+np.float32,0x3fc9b04c,0x3f837d38,2
+np.float32,0x7dba3213,0x42ae094d,2
+np.float32,0x7ec5a483,0x42b0eda1,2
+np.float32,0x3fbc4d14,0x3f6fa543,2
+np.float32,0x3fc85ce2,0x3f8264f1,2
+np.float32,0x7f77c816,0x42b2c447,2
+np.float32,0x3f9c9281,0x3f280492,2
+np.float32,0x7f49b3e2,0x42b25aef,2
+np.float32,0x3fa7e4da,0x3f45347c,2
+np.float32,0x7e0c9df5,0x42aedc72,2
+np.float32,0x7f21fd1a,0x42b1eaab,2
+np.float32,0x7f7c63ad,0x42b2cdb6,2
+np.float32,0x7f4eb80a,0x42b26783,2
+np.float32,0x7e98038c,0x42b0673c,2
+np.float32,0x7e89ba08,0x42b034b4,2
+np.float32,0x3ffc06ba,0x3fa64094,2
+np.float32,0x3fae63f6,0x3f53db36,2
+np.float32,0x3fbc2d30,0x3f6f6a1c,2
+np.float32,0x7de0e5e5,0x42ae69fe,2
+np.float32,0x7e09ed18,0x42aed28d,2
+np.float32,0x3fea78f8,0x3f9b6129,2
+np.float32,0x7dfe0bcc,0x42aea863,2
+np.float32,0x7ee21d03,0x42b13289,2
+np.float32,0x3fcc3aed,0x3f858dfc,2
+np.float32,0x3fe6b3ba,0x3f98e4ea,2
+np.float32,0x3f90f25f,0x3f025225,2
+np.float32,0x7f1bcaf4,0x42b1d6b3,2
+np.float32,0x3f83ac81,0x3e74c20e,2
+np.float32,0x3f98681d,0x3f1bae16,2
+np.float32,0x3fe1f2d9,0x3f95ad08,2
+np.float32,0x3fa279d7,0x3f37e951,2
+np.float32,0x3feb922a,0x3f9c17c4,2
+np.float32,0x7f1c72e8,0x42b1d8da,2
+np.float32,0x3fea156b,0x3f9b2038,2
+np.float32,0x3fed6bda,0x3f9d48aa,2
+np.float32,0x3fa86142,0x3f46589c,2
+np.float32,0x3ff16bc2,0x3f9fd072,2
+np.float32,0x3fbebf65,0x3f74207b,2
+np.float32,0x7e7b78b5,0x42b00610,2
+np.float32,0x3ff51ab8,0x3fa217f0,2
+np.float32,0x3f8361bb,0x3e6adf07,2
+np.float32,0x7edbceed,0x42b1240e,2
+np.float32,0x7f10e2c0,0x42b1b18a,2
+np.float32,0x3fa7bc58,0x3f44d4ef,2
+np.float32,0x3f813bde,0x3e0e1138,2
+np.float32,0x7f30d5b9,0x42b21791,2
+np.float32,0x3fb4f450,0x3f61806a,2
+np.float32,0x7eee02c4,0x42b14cca,2
+np.float32,0x7ec74b62,0x42b0f1e4,2
+np.float32,0x3ff96bca,0x3fa4b498,2
+np.float32,0x7f50e304,0x42b26cda,2
+np.float32,0x7eb14c57,0x42b0b603,2
+np.float32,0x7c3f0733,0x42a9edbf,2
+np.float32,0x7ea57acb,0x42b092b1,2
+np.float32,0x7f2788dc,0x42b1fbe7,2
+np.float32,0x3fa39f14,0x3f3ad09b,2
+np.float32,0x3fc3a7e0,0x3f7ccfa0,2
+np.float32,0x3fe70a73,0x3f991eb0,2
+np.float32,0x7f4831f7,0x42b25718,2
+np.float32,0x3fe947d0,0x3f9a999c,2
+np.float32,0x7ef2b1c7,0x42b156c4,2
+np.float32,0x3fede0ea,0x3f9d937f,2
+np.float32,0x3f9fef8e,0x3f314637,2
+np.float32,0x3fc313c5,0x3f7bcebd,2
+np.float32,0x7ee99337,0x42b14328,2
+np.float32,0x7eb9042e,0x42b0cbd5,2
+np.float32,0x3fc9d3dc,0x3f839a69,2
+np.float32,0x3fb2c018,0x3f5d091d,2
+np.float32,0x3fcc4e8f,0x3f859dc5,2
+np.float32,0x3fa9363b,0x3f484819,2
+np.float32,0x7f72ce2e,0x42b2b9e4,2
+np.float32,0x7e639326,0x42afd2f1,2
+np.float32,0x7f4595d3,0x42b25060,2
+np.float32,0x7f6d0ac4,0x42b2ad97,2
+np.float32,0x7f1bda0d,0x42b1d6e5,2
+np.float32,0x3fd85ffd,0x3f8ee0ed,2
+np.float32,0x3f91d53f,0x3f059c8e,2
+np.float32,0x7d06e103,0x42ac0155,2
+np.float32,0x3fb83126,0x3f67de6e,2
+np.float32,0x7d81ce1f,0x42ad5097,2
+np.float32,0x7f79cb3b,0x42b2c86b,2
+np.float32,0x7f800000,0x7f800000,2
+np.float32,0x3fdbfffd,0x3f918137,2
+np.float32,0x7f4ecb1c,0x42b267b2,2
+np.float32,0x3fc2c122,0x3f7b3ed3,2
+np.float32,0x7f415854,0x42b24544,2
+np.float32,0x7e3d988b,0x42af7575,2
+np.float32,0x3f83ca99,0x3e789fcb,2
+np.float32,0x7f274f70,0x42b1fb38,2
+np.float32,0x7f0d20e6,0x42b1a416,2
+np.float32,0x3fdf3a1d,0x3f93c9c1,2
+np.float32,0x7efaa13e,0x42b1673d,2
+np.float32,0x3fb20b15,0x3f5b9434,2
+np.float32,0x3f86af9f,0x3ea4c664,2
+np.float32,0x3fe4fcb0,0x3f97be8a,2
+np.float32,0x3f920683,0x3f065085,2
+np.float32,0x3fa4b278,0x3f3d7e8b,2
+np.float32,0x3f8077a8,0x3daef77f,2
+np.float32,0x7e865be4,0x42b02807,2
+np.float32,0x3fcea7e2,0x3f877c9f,2
+np.float32,0x7e7e9db1,0x42b00c6d,2
+np.float32,0x3f9819aa,0x3f1aba7e,2
+np.float32,0x7f2b6c4b,0x42b207a7,2
+np.float32,0x7ef85e3e,0x42b16299,2
+np.float32,0x3fbd8290,0x3f71df8b,2
+np.float32,0x3fbbb615,0x3f6e8c8c,2
+np.float32,0x7f1bc7f5,0x42b1d6a9,2
+np.float32,0x3fbb4fea,0x3f6dcdad,2
+np.float32,0x3fb67e09,0x3f648dd1,2
+np.float32,0x3fc83495,0x3f824374,2
+np.float32,0x3fe52980,0x3f97dcbc,2
+np.float32,0x3f87d893,0x3eb25d7c,2
+np.float32,0x3fdb805a,0x3f9125c0,2
+np.float32,0x3fb33f0f,0x3f5e0ce1,2
+np.float32,0x3facc524,0x3f50516b,2
+np.float32,0x3ff40484,0x3fa16d0e,2
+np.float32,0x3ff078bf,0x3f9f3811,2
+np.float32,0x7f736747,0x42b2bb27,2
+np.float32,0x7f55768b,0x42b277f3,2
+np.float32,0x80000001,0xffc00000,2
+np.float32,0x7f6463d1,0x42b29a8e,2
+np.float32,0x3f8f8b59,0x3ef9d792,2
+np.float32,0x3f8a6f4d,0x3ecd5bf4,2
+np.float32,0x3fe958d9,0x3f9aa4ca,2
+np.float32,0x7f1e2ce2,0x42b1de78,2
+np.float32,0x3fb8584a,0x3f682a05,2
+np.float32,0x7dea3dc6,0x42ae7ed5,2
+np.float32,0x7f53a815,0x42b27399,2
+np.float32,0x7e0cf986,0x42aeddbf,2
+np.float32,0x7f3afb71,0x42b23422,2
+np.float32,0x3fd87d6e,0x3f8ef685,2
+np.float32,0x3ffcaa46,0x3fa6a0d7,2
+np.float32,0x7eecd276,0x42b14a3a,2
+np.float32,0x3ffc30b4,0x3fa65951,2
+np.float32,0x7e9c85e2,0x42b07634,2
+np.float32,0x3f95d862,0x3f1383de,2
+np.float32,0x7ef21410,0x42b15577,2
+np.float32,0x3fbfa1b5,0x3f75b86e,2
+np.float32,0x3fd6d90f,0x3f8dc086,2
+np.float32,0x0,0xffc00000,2
+np.float32,0x7e885dcd,0x42b02f9f,2
+np.float32,0x3fb3e057,0x3f5f54bf,2
+np.float32,0x7f40afdd,0x42b24385,2
+np.float32,0x3fb795c2,0x3f66b120,2
+np.float32,0x3fba7c11,0x3f6c3f73,2
+np.float32,0x3ffef620,0x3fa7f828,2
+np.float32,0x7d430508,0x42acbe1e,2
+np.float32,0x3f8d2892,0x3ee6369f,2
+np.float32,0x3fbea139,0x3f73e9d5,2
+np.float32,0x3ffaa928,0x3fa571b9,2
+np.float32,0x7fc00000,0x7fc00000,2
+np.float32,0x7f16f9ce,0x42b1c69f,2
+np.float32,0x3fa8f753,0x3f47b657,2
+np.float32,0x3fd48a63,0x3f8c06ac,2
+np.float32,0x7f13419e,0x42b1b9d9,2
+np.float32,0x3fdf1526,0x3f93afde,2
+np.float32,0x3f903c8b,0x3eff3be8,2
+np.float32,0x7f085323,0x42b1925b,2
+np.float32,0x7cdbe309,0x42ab98ac,2
+np.float32,0x3fba2cfd,0x3f6ba9f1,2
+np.float32,0x7f5a805d,0x42b283e4,2
+np.float32,0x7f6753dd,0x42b2a119,2
+np.float32,0x3fed9f02,0x3f9d6964,2
+np.float32,0x3f96422c,0x3f14ddba,2
+np.float32,0x7f22f2a9,0x42b1edb1,2
+np.float32,0x3fe3fcfd,0x3f97119d,2
+np.float32,0x7e018ad0,0x42aeb271,2
+np.float32,0x7db896f5,0x42ae04de,2
+np.float32,0x7e55c795,0x42afb2ec,2
+np.float32,0x7f58ef8d,0x42b28036,2
+np.float32,0x7f24a16a,0x42b1f2f3,2
+np.float32,0x3fcf714c,0x3f881b09,2
+np.float32,0x3fcdd056,0x3f86d200,2
+np.float32,0x7f02fad0,0x42b17de0,2
+np.float32,0x7eeab877,0x42b145a9,2
+np.float32,0x3fd6029d,0x3f8d20f7,2
+np.float32,0x3fd4f8cd,0x3f8c59d6,2
+np.float32,0x3fb29d4a,0x3f5cc1a5,2
+np.float32,0x3fb11e2d,0x3f59a77a,2
+np.float32,0x7eded576,0x42b12b0e,2
+np.float32,0x7f26c2a5,0x42b1f988,2
+np.float32,0x3fb6165b,0x3f63c151,2
+np.float32,0x7f3bca47,0x42b23657,2
+np.float32,0x7d8c93bf,0x42ad7968,2
+np.float32,0x3f8ede02,0x3ef47176,2
+np.float32,0x3fbef762,0x3f7485b9,2
+np.float32,0x7f1419af,0x42b1bcc6,2
+np.float32,0x7d9e8c79,0x42adb701,2
+np.float32,0x3fa26336,0x3f37af63,2
+np.float32,0x7f5f5590,0x42b28f18,2
+np.float32,0x3fddc93a,0x3f92c651,2
+np.float32,0x3ff0a5fc,0x3f9f547f,2
+np.float32,0x3fb2f6b8,0x3f5d790e,2
+np.float32,0x3ffe59a4,0x3fa79d2c,2
+np.float32,0x7e4df848,0x42af9fde,2
+np.float32,0x3fb0ab3b,0x3f58b678,2
+np.float32,0x7ea54d47,0x42b09225,2
+np.float32,0x3fdd6404,0x3f927eb2,2
+np.float32,0x3f846dc0,0x3e864caa,2
+np.float32,0x7d046aee,0x42abf7e7,2
+np.float32,0x7f7c5a05,0x42b2cda3,2
+np.float32,0x3faf6126,0x3f55fb21,2
+np.float32,0x7f36a910,0x42b22829,2
+np.float32,0x3fdc7b36,0x3f91d938,2
+np.float32,0x3fff443e,0x3fa82577,2
+np.float32,0x7ee7154a,0x42b13daa,2
+np.float32,0x3f944742,0x3f0e435c,2
+np.float32,0x7f5b510a,0x42b285cc,2
+np.float32,0x3f9bc940,0x3f25c4d2,2
+np.float32,0x3fee4782,0x3f9dd4ea,2
+np.float32,0x3fcfc2dd,0x3f885aea,2
+np.float32,0x7eab65cf,0x42b0a4af,2
+np.float32,0x3f9cf908,0x3f292689,2
+np.float32,0x7ed35501,0x42b10feb,2
+np.float32,0x7dabb70a,0x42addfd9,2
+np.float32,0x7f348919,0x42b2222b,2
+np.float32,0x3fb137d4,0x3f59dd17,2
+np.float32,0x7e7b36c9,0x42b0058a,2
+np.float32,0x7e351fa4,0x42af5e0d,2
+np.float32,0x3f973c0c,0x3f18011e,2
+np.float32,0xff800000,0xffc00000,2
+np.float32,0x3f9b0a4b,0x3f239a33,2
+np.float32,0x3f87c4cf,0x3eb17e7e,2
+np.float32,0x7ef67760,0x42b15eaa,2
+np.float32,0x3fc4d2c8,0x3f7ed20f,2
+np.float32,0x7e940dac,0x42b059b8,2
+np.float32,0x7f6e6a52,0x42b2b08d,2
+np.float32,0x3f838752,0x3e6fe4b2,2
+np.float32,0x3fd8f046,0x3f8f4a94,2
+np.float32,0x3fa82112,0x3f45c223,2
+np.float32,0x3fd49b16,0x3f8c1345,2
+np.float32,0x7f02a941,0x42b17ca1,2
+np.float32,0x3f8a9d2c,0x3ecf1768,2
+np.float32,0x7c9372e3,0x42aacc0f,2
+np.float32,0x3fd260b3,0x3f8a619a,2
+np.float32,0x3f8a1b88,0x3eca27cb,2
+np.float32,0x7d25d510,0x42ac6b1c,2
+np.float32,0x7ef5a578,0x42b15cf5,2
+np.float32,0x3fe6625d,0x3f98ae9a,2
+np.float32,0x3ff53240,0x3fa22658,2
+np.float32,0x3f8bb2e6,0x3ed944cf,2
+np.float32,0x7f4679b1,0x42b252ad,2
+np.float32,0x3fa8db30,0x3f4774fc,2
+np.float32,0x7ee5fafd,0x42b13b37,2
+np.float32,0x3fc405e0,0x3f7d71fb,2
+np.float32,0x3f9303cd,0x3f09ddfd,2
+np.float32,0x7f486e67,0x42b257b2,2
+np.float32,0x7e73f12b,0x42aff680,2
+np.float32,0x3fe80f8b,0x3f99cbe4,2
+np.float32,0x3f84200a,0x3e81a3f3,2
+np.float32,0x3fa14e5c,0x3f34e3ce,2
+np.float32,0x3fda22ec,0x3f9029bb,2
+np.float32,0x3f801772,0x3d1aef98,2
+np.float32,0x7eaa1428,0x42b0a0bb,2
+np.float32,0x3feae0b3,0x3f9ba4aa,2
+np.float32,0x7ea439b4,0x42b08ecc,2
+np.float32,0x3fa28b1c,0x3f381579,2
+np.float32,0x7e8af247,0x42b03937,2
+np.float32,0x3fd19216,0x3f89c2b7,2
+np.float32,0x7f6ea033,0x42b2b100,2
+np.float32,0x3fad4fbf,0x3f518224,2
+np.float32,0x3febd940,0x3f9c45bd,2
+np.float32,0x7f4643a3,0x42b25221,2
+np.float32,0x7ec34478,0x42b0e771,2
+np.float32,0x7f18c83b,0x42b1ccb5,2
+np.float32,0x3fc665ad,0x3f80bf94,2
+np.float32,0x3ff0a999,0x3f9f56c4,2
+np.float32,0x3faf1cd2,0x3f5568fe,2
+np.float32,0x7ecd9dc6,0x42b101e1,2
+np.float32,0x3faad282,0x3f4bf754,2
+np.float32,0x3ff905a0,0x3fa47771,2
+np.float32,0x7f596481,0x42b28149,2
+np.float32,0x7f1cb31f,0x42b1d9ac,2
+np.float32,0x7e266719,0x42af32a6,2
+np.float32,0x7eccce06,0x42b0ffdb,2
+np.float32,0x3f9b6f71,0x3f24c102,2
+np.float32,0x3f80e4ba,0x3df1d6bc,2
+np.float32,0x3f843d51,0x3e836a60,2
+np.float32,0x7f70bd88,0x42b2b585,2
+np.float32,0x3fe4cc96,0x3f979e18,2
+np.float32,0x3ff737c7,0x3fa36151,2
+np.float32,0x3ff1197e,0x3f9f9cf4,2
+np.float32,0x7f08e190,0x42b19471,2
+np.float32,0x3ff1542e,0x3f9fc1b2,2
+np.float32,0x3ff6673c,0x3fa2e2d2,2
+np.float32,0xbf800000,0xffc00000,2
+np.float32,0x7e3f9ba7,0x42af7add,2
+np.float32,0x7f658ff6,0x42b29d2d,2
+np.float32,0x3f93441c,0x3f0ac0d9,2
+np.float32,0x7f526a74,0x42b27096,2
+np.float32,0x7f5b00c8,0x42b28511,2
+np.float32,0x3ff212f8,0x3fa038cf,2
+np.float32,0x7e0bd60d,0x42aed998,2
+np.float32,0x7f71ef7f,0x42b2b80e,2
+np.float32,0x7f7a897e,0x42b2c9f1,2
+np.float32,0x7e8b76a6,0x42b03b1e,2
+np.float32,0x7efa0da3,0x42b1660f,2
+np.float32,0x3fce9166,0x3f876ae0,2
+np.float32,0x3fc4163d,0x3f7d8e30,2
+np.float32,0x3fdb3784,0x3f90f16b,2
+np.float32,0x7c5f177b,0x42aa3d30,2
+np.float32,0x3fc6276d,0x3f808af5,2
+np.float32,0x7bac9cc2,0x42a856f4,2
+np.float32,0x3fe5876f,0x3f981bea,2
+np.float32,0x3fef60e3,0x3f9e878a,2
+np.float32,0x3fb23cd8,0x3f5bfb06,2
+np.float32,0x3fe114e2,0x3f951402,2
+np.float32,0x7ca8ef04,0x42ab11b4,2
+np.float32,0x7d93c2ad,0x42ad92ec,2
+np.float32,0x3fe5bb8a,0x3f983ee6,2
+np.float32,0x7f0182fd,0x42b1781b,2
+np.float32,0x7da63bb2,0x42adcf3d,2
+np.float32,0x3fac46b7,0x3f4f399e,2
+np.float32,0x7f7a5d8f,0x42b2c997,2
+np.float32,0x7f76572e,0x42b2c14b,2
+np.float32,0x7f42d53e,0x42b24931,2
+np.float32,0x7f7ffd00,0x42b2d4f6,2
+np.float32,0x3fc346c3,0x3f7c2756,2
+np.float32,0x7f1f6ae3,0x42b1e27a,2
+np.float32,0x3f87fb56,0x3eb3e2ee,2
+np.float32,0x3fed17a2,0x3f9d12b4,2
+np.float32,0x7f5ea903,0x42b28d8c,2
+np.float32,0x3f967f82,0x3f15a4ab,2
+np.float32,0x7d3b540c,0x42aca984,2
+np.float32,0x7f56711a,0x42b27a4a,2
+np.float32,0x7f122223,0x42b1b5ee,2
+np.float32,0x3fd6fa34,0x3f8dd919,2
+np.float32,0x3fadd62e,0x3f52a7b3,2
+np.float32,0x3fb7bf0c,0x3f67015f,2
+np.float32,0x7edf4ba7,0x42b12c1d,2
+np.float32,0x7e33cc65,0x42af5a4b,2
+np.float32,0x3fa6be17,0x3f427831,2
+np.float32,0x3fa07aa8,0x3f32b7d4,2
+np.float32,0x3fa4a3af,0x3f3d5a01,2
+np.float32,0x3fdbb267,0x3f9149a8,2
+np.float32,0x7ed45e25,0x42b1126c,2
+np.float32,0x3fe3f432,0x3f970ba6,2
+np.float32,0x7f752080,0x42b2bec3,2
+np.float32,0x3f872747,0x3eaa62ea,2
+np.float32,0x7e52175d,0x42afaa03,2
+np.float32,0x3fdc766c,0x3f91d5ce,2
+np.float32,0x7ecd6841,0x42b1015c,2
+np.float32,0x7f3d6c40,0x42b23ac6,2
+np.float32,0x3fb80c14,0x3f6796b9,2
+np.float32,0x3ff6ad56,0x3fa30d68,2
+np.float32,0x3fda44c3,0x3f90423e,2
+np.float32,0x3fdcba0c,0x3f9205fc,2
+np.float32,0x7e14a720,0x42aef8e6,2
+np.float32,0x3fe9e489,0x3f9b0047,2
+np.float32,0x7e69f933,0x42afe123,2
+np.float32,0x3ff3ee6d,0x3fa15f71,2
+np.float32,0x3f8538cd,0x3e91c1a7,2
+np.float32,0x3fdc3f07,0x3f91ae46,2
+np.float32,0x3fba2ef0,0x3f6bada2,2
+np.float32,0x7da64cd8,0x42adcf71,2
+np.float32,0x3fc34bd2,0x3f7c301d,2
+np.float32,0x3fa273aa,0x3f37d984,2
+np.float32,0x3ff0338c,0x3f9f0c86,2
+np.float32,0x7ed62cef,0x42b116c3,2
+np.float32,0x3f911e7e,0x3f02f7c6,2
+np.float32,0x7c8514c9,0x42aa9792,2
+np.float32,0x3fea2a74,0x3f9b2df5,2
+np.float32,0x3fe036f8,0x3f947a25,2
+np.float32,0x7c5654bf,0x42aa28ad,2
+np.float32,0x3fd9e423,0x3f8ffc32,2
+np.float32,0x7eec0439,0x42b1487b,2
+np.float32,0x3fc580f4,0x3f7ffb62,2
+np.float32,0x3fb0e316,0x3f592bbe,2
+np.float32,0x7c4cfb7d,0x42aa11d8,2
+np.float32,0x3faf9704,0x3f566e00,2
+np.float32,0x3fa7cf8a,0x3f45023d,2
+np.float32,0x7f7b724d,0x42b2cbcc,2
+np.float32,0x7f05bfe3,0x42b18897,2
+np.float32,0x3f90bde3,0x3f018bf3,2
+np.float32,0x7c565479,0x42aa28ad,2
+np.float32,0x3f94b517,0x3f0fb8e5,2
+np.float32,0x3fd6aadd,0x3f8d9e3c,2
+np.float32,0x7f09b37c,0x42b1977f,2
+np.float32,0x7f2b45ea,0x42b20734,2
+np.float32,0x3ff1d15e,0x3fa00fe9,2
+np.float32,0x3f99bce6,0x3f1fbd6c,2
+np.float32,0x7ecd1f76,0x42b100a7,2
+np.float32,0x7f443e2b,0x42b24ce2,2
+np.float32,0x7da7d6a5,0x42add428,2
+np.float32,0x7ebe0193,0x42b0d975,2
+np.float32,0x7ee13c43,0x42b1308b,2
+np.float32,0x3f8adf1b,0x3ed18e0c,2
+np.float32,0x7f76ce65,0x42b2c242,2
+np.float32,0x7e34f43d,0x42af5d92,2
+np.float32,0x7f306b76,0x42b2165d,2
+np.float32,0x7e1fd07f,0x42af1df7,2
+np.float32,0x3fab9a41,0x3f4db909,2
+np.float32,0x3fc23d1a,0x3f7a5803,2
+np.float32,0x3f8b7403,0x3ed70245,2
+np.float32,0x3f8c4dd6,0x3edebbae,2
+np.float32,0x3fe5f411,0x3f9864cd,2
+np.float32,0x3f88128b,0x3eb4e508,2
+np.float32,0x3fcb09de,0x3f84976f,2
+np.float32,0x7f32f2f5,0x42b21da6,2
+np.float32,0x3fe75610,0x3f9950f6,2
+np.float32,0x3f993edf,0x3f1e408d,2
+np.float32,0x3fc4a9d7,0x3f7e8be9,2
+np.float32,0x7f74551a,0x42b2bd1a,2
+np.float32,0x7de87129,0x42ae7ae2,2
+np.float32,0x7f18bbbd,0x42b1cc8c,2
+np.float32,0x7e7e1dd4,0x42b00b6c,2
+np.float32,0x3ff6e55b,0x3fa32f64,2
+np.float32,0x3fa634c8,0x3f412df3,2
+np.float32,0x3fd0fb7c,0x3f894e49,2
+np.float32,0x3ff4f6a6,0x3fa201d7,2
+np.float32,0x7f69d418,0x42b2a69a,2
+np.float32,0x7cb9632d,0x42ab414a,2
+np.float32,0x3fc57d36,0x3f7ff503,2
+np.float32,0x7e9e2ed7,0x42b07b9b,2
+np.float32,0x7f2e6868,0x42b2107d,2
+np.float32,0x3fa3169a,0x3f39785d,2
+np.float32,0x7f03cde0,0x42b18117,2
+np.float32,0x7f6d75d2,0x42b2ae7f,2
+np.float32,0x3ff483f2,0x3fa1bb75,2
+np.float32,0x7f1b39f7,0x42b1d4d6,2
+np.float32,0x3f8c7a7d,0x3ee0481e,2
+np.float32,0x3f989095,0x3f1c2b19,2
+np.float32,0x3fa4cbfd,0x3f3dbd87,2
+np.float32,0x7f75b00f,0x42b2bfef,2
+np.float32,0x3f940724,0x3f0d6756,2
+np.float32,0x7f5e5a1a,0x42b28cd6,2
+np.float32,0x800000,0xffc00000,2
+np.float32,0x7edd1d29,0x42b12716,2
+np.float32,0x3fa3e9e4,0x3f3b8c16,2
+np.float32,0x7e46d70e,0x42af8dd5,2
+np.float32,0x3f824745,0x3e40ec1e,2
+np.float32,0x3fd67623,0x3f8d770a,2
+np.float32,0x3fe9a6f3,0x3f9ad7fa,2
+np.float32,0x3fdda67c,0x3f92adc1,2
+np.float32,0x7ccb6c9a,0x42ab70d4,2
+np.float32,0x3ffd364a,0x3fa6f2fe,2
+np.float32,0x7e02424c,0x42aeb545,2
+np.float32,0x3fb6d2f2,0x3f6534a1,2
+np.float32,0x3fe1fe26,0x3f95b4cc,2
+np.float32,0x7e93ac57,0x42b05867,2
+np.float32,0x7f7b3433,0x42b2cb4d,2
+np.float32,0x3fb76803,0x3f66580d,2
+np.float32,0x3f9af881,0x3f23661b,2
+np.float32,0x3fd58062,0x3f8cbf98,2
+np.float32,0x80000000,0xffc00000,2
+np.float32,0x7f1af8f4,0x42b1d3ff,2
+np.float32,0x3fe66bba,0x3f98b4dc,2
+np.float32,0x7f6bd7bf,0x42b2aaff,2
+np.float32,0x3f84f79a,0x3e8e2e49,2
+np.float32,0x7e475b06,0x42af8f28,2
+np.float32,0x3faff89b,0x3f573d5e,2
+np.float32,0x7de5aa77,0x42ae74bb,2
+np.float32,0x3f8e9e42,0x3ef26cd2,2
+np.float32,0x3fb1cec3,0x3f5b1740,2
+np.float32,0x3f8890d6,0x3eba4821,2
+np.float32,0x3f9b39e9,0x3f242547,2
+np.float32,0x3fc895a4,0x3f829407,2
+np.float32,0x7f77943c,0x42b2c3dc,2
+np.float32,0x7f390d58,0x42b22ed2,2
+np.float32,0x3fe7e160,0x3f99ad58,2
+np.float32,0x3f93d2a0,0x3f0cb205,2
+np.float32,0x7f29499b,0x42b2013c,2
+np.float32,0x3f8c11b2,0x3edca10f,2
+np.float32,0x7e898ef8,0x42b03413,2
+np.float32,0x3fdff942,0x3f944f34,2
+np.float32,0x7f3d602f,0x42b23aa5,2
+np.float32,0x3f8a50f3,0x3ecc345b,2
+np.float32,0x3fa1f86d,0x3f369ce4,2
+np.float32,0x3f97ad95,0x3f19681d,2
+np.float32,0x3ffad1e0,0x3fa589e5,2
+np.float32,0x3fa70590,0x3f432311,2
+np.float32,0x7e6840cb,0x42afdd5c,2
+np.float32,0x3fd4036d,0x3f8ba0aa,2
+np.float32,0x7f7cc953,0x42b2ce84,2
+np.float32,0x7f228e1e,0x42b1ec74,2
+np.float32,0x7e37a866,0x42af652a,2
+np.float32,0x3fda22d0,0x3f9029a7,2
+np.float32,0x7f736bff,0x42b2bb31,2
+np.float32,0x3f9833b6,0x3f1b0b8e,2
+np.float32,0x7f466001,0x42b2526a,2
+np.float32,0xff7fffff,0xffc00000,2
+np.float32,0x7dd62bcd,0x42ae50f8,2
+np.float32,0x7f1d2bfe,0x42b1db36,2
+np.float32,0x7ecffe9e,0x42b107c5,2
+np.float32,0x7ebefe0a,0x42b0dc1b,2
+np.float32,0x7f45c63d,0x42b250dd,2
+np.float32,0x7f601af0,0x42b290db,2
+np.float32,0x3fcbb88a,0x3f8524e5,2
+np.float32,0x7ede55ff,0x42b129e8,2
+np.float32,0x7ea5dd5a,0x42b093e2,2
+np.float32,0x3ff53857,0x3fa22a12,2
+np.float32,0x3f8dbd6a,0x3eeb28a4,2
+np.float32,0x3fd1b467,0x3f89dd2c,2
+np.float32,0x3fe0423f,0x3f9481fc,2
+np.float32,0x3f84b421,0x3e8a6174,2
+np.float32,0x7f4efc97,0x42b2682c,2
+np.float32,0x7f601b33,0x42b290dc,2
+np.float32,0x3f94f240,0x3f108719,2
+np.float32,0x7decd251,0x42ae8471,2
+np.float32,0x3fdc457c,0x3f91b2e2,2
+np.float32,0x3f92a966,0x3f089c5a,2
+np.float32,0x3fc9732f,0x3f834afc,2
+np.float32,0x3f97948f,0x3f19194e,2
+np.float32,0x7f0824a1,0x42b191ac,2
+np.float32,0x7f0365a5,0x42b17f81,2
+np.float32,0x3f800000,0x0,2
+np.float32,0x7f0054c6,0x42b1736b,2
+np.float32,0x3fe86544,0x3f9a0484,2
+np.float32,0x7e95f844,0x42b0604e,2
+np.float32,0x3fce8602,0x3f8761e2,2
+np.float32,0x3fc726c8,0x3f81621d,2
+np.float32,0x3fcf6b03,0x3f88161b,2
+np.float32,0x3fceb843,0x3f87898a,2
+np.float32,0x3fe2f8b2,0x3f966071,2
+np.float32,0x7f3c8e7f,0x42b2386d,2
+np.float32,0x3fcee13a,0x3f87a9d2,2
+np.float32,0x3fc4df27,0x3f7ee73c,2
+np.float32,0x3ffde486,0x3fa758e3,2
+np.float32,0x3fa91be0,0x3f480b17,2
+np.float32,0x7f2a5a7d,0x42b20472,2
+np.float32,0x7e278d80,0x42af362d,2
+np.float32,0x3f96d091,0x3f16a9d5,2
+np.float32,0x7e925225,0x42b053b2,2
+np.float32,0x7f7ef83a,0x42b2d2ec,2
+np.float32,0x7eb4923a,0x42b0bf61,2
+np.float32,0x7e98bf19,0x42b069b3,2
+np.float32,0x3fac93a2,0x3f4fe410,2
+np.float32,0x7f46389c,0x42b25205,2
+np.float32,0x3f9fd447,0x3f30fd54,2
+np.float32,0x3fef42d4,0x3f9e7483,2
+np.float32,0x7f482174,0x42b256ed,2
+np.float32,0x3f97aedb,0x3f196c1e,2
+np.float32,0x7f764edd,0x42b2c13a,2
+np.float32,0x3f9117b5,0x3f02de5c,2
+np.float32,0x3fc7984e,0x3f81c12d,2
+np.float64,0x3ff1e2cb7463c597,0x3fdec6caf39e0c0e,2
+np.float64,0x3ffe4f89789c9f13,0x3ff40f4b1da0f3e9,2
+np.float64,0x7f6a5c9ac034b935,0x408605e51703c145,2
+np.float64,0x7fdcb6ece3b96dd9,0x40862d6521e16d60,2
+np.float64,0x3ff6563e182cac7c,0x3feb9d8210f3fa88,2
+np.float64,0x7fde32025f3c6404,0x40862dcc1d1a9b7f,2
+np.float64,0x7fd755ed35aeabd9,0x40862bbc5522b779,2
+np.float64,0x3ff5c81f4bcb903e,0x3fea71f10b954ea3,2
+np.float64,0x3fffe805d35fd00c,0x3ff50463a1ba2938,2
+np.float64,0x7fd045a1c1a08b43,0x408628d9f431f2f5,2
+np.float64,0x3ff49f7dd9893efc,0x3fe7c6736e17ea8e,2
+np.float64,0x7fccfbc1fd39f783,0x408627eca79acf51,2
+np.float64,0x3ff1af0a00035e14,0x3fdd1c0e7d5706ea,2
+np.float64,0x7fe7bd17162f7a2d,0x4086316af683502b,2
+np.float64,0x3ff0941b8d012837,0x3fd128d274065ac0,2
+np.float64,0x3ffa0c5d98b418bb,0x3ff11af9c8edd17f,2
+np.float64,0x3ffad9733355b2e6,0x3ff1b6d1307acb42,2
+np.float64,0x3ffabb2a33d57654,0x3ff1a0442b034e50,2
+np.float64,0x3ff36118b0c6c231,0x3fe472b7dfb23516,2
+np.float64,0x3ff2441d3664883a,0x3fe0d61145608f0c,2
+np.float64,0x7fe039862d20730b,0x40862e5f8ed752d3,2
+np.float64,0x7fb1dde24023bbc4,0x40861e824cdb0664,2
+np.float64,0x7face6335839cc66,0x40861ccf90a26e16,2
+np.float64,0x3ffb5d0e1af6ba1c,0x3ff2170f6f42fafe,2
+np.float64,0x3ff5c2c6a50b858d,0x3fea665aabf04407,2
+np.float64,0x3ffabb409db57681,0x3ff1a054ea32bfc3,2
+np.float64,0x3ff1e054e983c0aa,0x3fdeb30c17286cb6,2
+np.float64,0x7fe467f73268cfed,0x4086303529e52e9b,2
+np.float64,0x7fe0e86bf961d0d7,0x40862eb40788b04a,2
+np.float64,0x3ffb743542f6e86a,0x3ff227b4ea5acee0,2
+np.float64,0x3ff2de6826e5bcd0,0x3fe2e31fcde0a96c,2
+np.float64,0x7fd6b27ccfad64f9,0x40862b8385697c31,2
+np.float64,0x7fe0918e8d21231c,0x40862e8a82d9517a,2
+np.float64,0x7fd0ca0395a19406,0x4086291a0696ed33,2
+np.float64,0x3ffb042496960849,0x3ff1d658c928abfc,2
+np.float64,0x3ffcd0409799a081,0x3ff31877df0cb245,2
+np.float64,0x7fe429bd06685379,0x4086301c9f259934,2
+np.float64,0x3ff933076092660f,0x3ff06d2e5f4d9ab7,2
+np.float64,0x7feaefcb28f5df95,0x4086326dccf88e6f,2
+np.float64,0x7fb5f2c1f82be583,0x40862027ac02a39d,2
+np.float64,0x3ffb5d9e3bd6bb3c,0x3ff21777501d097e,2
+np.float64,0x10000000000000,0xfff8000000000000,2
+np.float64,0x3ff70361596e06c3,0x3fecf675ceda7e19,2
+np.float64,0x3ff71a21b5ee3444,0x3fed224fa048d9a9,2
+np.float64,0x3ffb102b86762057,0x3ff1df2cc9390518,2
+np.float64,0x7feaaeb35c355d66,0x4086325a60704a90,2
+np.float64,0x7fd9a3d0a93347a0,0x40862c7d300fc076,2
+np.float64,0x7fabcf159c379e2a,0x40861c80cdbbff27,2
+np.float64,0x7fd1c066ec2380cd,0x4086298c3006fee6,2
+np.float64,0x3ff3d5ae2d67ab5c,0x3fe5bc16447428db,2
+np.float64,0x3ff4b76add696ed6,0x3fe800f5bbf21376,2
+np.float64,0x3ff60d89ee0c1b14,0x3feb063fdebe1a68,2
+np.float64,0x7f1d2648003a4c8f,0x4085eaf9238af95a,2
+np.float64,0x7fe8b45f6df168be,0x408631bca5abf6d6,2
+np.float64,0x7fe9ea5308f3d4a5,0x4086321ea2bd3af9,2
+np.float64,0x7fcb6ba5a636d74a,0x4086277b208075ed,2
+np.float64,0x3ff621cfd74c43a0,0x3feb30d59baf5919,2
+np.float64,0x3ff7bc8ca0af7919,0x3fee524da8032896,2
+np.float64,0x7fda22dd0c3445b9,0x40862ca47326d063,2
+np.float64,0x7fd02ed4b2a05da8,0x408628ceb6919421,2
+np.float64,0x3ffe64309fdcc861,0x3ff41c1b18940709,2
+np.float64,0x3ffee4042abdc808,0x3ff46a6005bccb41,2
+np.float64,0x3ff078145b00f029,0x3fceeb3d6bfae0eb,2
+np.float64,0x7fda20fd20b441f9,0x40862ca3e03b990b,2
+np.float64,0x3ffa9e9e9af53d3d,0x3ff18ade3cbee789,2
+np.float64,0x3ff0a1062501420c,0x3fd1e32de6d18c0d,2
+np.float64,0x3ff3bdf118477be2,0x3fe57ad89b7fdf8b,2
+np.float64,0x3ff101c0d5c20382,0x3fd6965d3539be47,2
+np.float64,0x7feba3b53b774769,0x408632a28c7aca4d,2
+np.float64,0x3ff598db5d4b31b7,0x3fea0aa65c0b421a,2
+np.float64,0x3ff5fdfbb72bfbf8,0x3feae55accde4a5e,2
+np.float64,0x7fe5bae53aab75c9,0x408630b5e7a5b92a,2
+np.float64,0x3ff8f668afd1ecd2,0x3ff03af686666c9c,2
+np.float64,0x3ff5ba72dd2b74e6,0x3fea5441f223c093,2
+np.float64,0x3ff8498147109302,0x3fef4e45d501601d,2
+np.float64,0x7feddcfa5efbb9f4,0x4086334106a6e76b,2
+np.float64,0x7fd1a30200234603,0x4086297ee5cc562c,2
+np.float64,0x3ffffa8ee07ff51e,0x3ff50f1dc46f1303,2
+np.float64,0x7fef7ed00ebefd9f,0x408633ae01dabe52,2
+np.float64,0x3ffb6e062276dc0c,0x3ff22344c58c2016,2
+np.float64,0x7fcf2b59943e56b2,0x4086288190dd5eeb,2
+np.float64,0x3ffa589f9254b13f,0x3ff155cc081eee0b,2
+np.float64,0x3ff05415ca60a82c,0x3fc9e45565baef0a,2
+np.float64,0x7feb34bed576697d,0x408632822d5a178c,2
+np.float64,0x3ff3993845c73270,0x3fe51423baf246c3,2
+np.float64,0x3ff88367aaf106d0,0x3fefb2d9ca9f1192,2
+np.float64,0x7fef364304fe6c85,0x4086339b7ed82997,2
+np.float64,0x7fcba2c317374585,0x4086278b24e42934,2
+np.float64,0x3ff1aef885e35df1,0x3fdd1b79f55b20c0,2
+np.float64,0x7fe19367886326ce,0x40862f035f867445,2
+np.float64,0x3ff3c8295e279053,0x3fe5970aa670d32e,2
+np.float64,0x3ff6edda164ddbb4,0x3feccca9eb59d6b9,2
+np.float64,0x7fdeaea940bd5d52,0x40862dece02d151b,2
+np.float64,0x7fea9d6324353ac5,0x408632552ddf0d4f,2
+np.float64,0x7fe60e39e66c1c73,0x408630d45b1ad0c4,2
+np.float64,0x7fde06325abc0c64,0x40862dc07910038c,2
+np.float64,0x7f9ec89d303d9139,0x408617c55ea4c576,2
+np.float64,0x3ff9801930530032,0x3ff0abe5be046051,2
+np.float64,0x3ff4d5859689ab0b,0x3fe849a7f7a19fa3,2
+np.float64,0x3ff38afbc48715f8,0x3fe4ebb7710cbab9,2
+np.float64,0x3ffd88a0e77b1142,0x3ff3916964407e21,2
+np.float64,0x1,0xfff8000000000000,2
+np.float64,0x3ff5db59e58bb6b4,0x3fea9b6b5ccc116f,2
+np.float64,0x3ffd4b05b15a960c,0x3ff369792f661a90,2
+np.float64,0x7fdcebc4fb39d789,0x40862d73cd623378,2
+np.float64,0x3ff5b56f944b6adf,0x3fea4955d6b06ca3,2
+np.float64,0x7fd4e4abf2a9c957,0x40862ad9e9da3c61,2
+np.float64,0x7fe08e0d6aa11c1a,0x40862e88d17ef277,2
+np.float64,0x3ff0dfc97da1bf93,0x3fd50f9004136d8f,2
+np.float64,0x7fdec38eaebd871c,0x40862df2511e26b4,2
+np.float64,0x7ff8000000000000,0x7ff8000000000000,2
+np.float64,0x3ff21865504430cb,0x3fe033fe3cf3947a,2
+np.float64,0x7fdc139708b8272d,0x40862d371cfbad03,2
+np.float64,0x7fe1fe3be3a3fc77,0x40862f336e3ba63a,2
+np.float64,0x7fd9fa2493b3f448,0x40862c97f2960be9,2
+np.float64,0x3ff0a027db414050,0x3fd1d6e54a707c87,2
+np.float64,0x3ff568b16f4ad163,0x3fe99f5c6d7b6e18,2
+np.float64,0x3ffe2f82877c5f05,0x3ff3fb54bd0da753,2
+np.float64,0x7fbaf5778435eaee,0x408621ccc9e2c1be,2
+np.float64,0x7fc5aaf8362b55ef,0x40862598e7072a49,2
+np.float64,0x7fe0ebfdd4a1d7fb,0x40862eb5b7bf99d5,2
+np.float64,0x7fd8efeb5931dfd6,0x40862c444636f408,2
+np.float64,0x3ff361a308c6c346,0x3fe4744cae63e6df,2
+np.float64,0x7fef287d39be50f9,0x40863397f65c807e,2
+np.float64,0x7fe72c4a14ae5893,0x4086313992e52082,2
+np.float64,0x3ffd1be44cba37c8,0x3ff34a9a45239eb9,2
+np.float64,0x3ff50369c18a06d4,0x3fe8b69319f091f1,2
+np.float64,0x3ffb333c25766678,0x3ff1f8c78eeb28f1,2
+np.float64,0x7fe12050416240a0,0x40862ece4e2f2f24,2
+np.float64,0x7fe348f5526691ea,0x40862fc16fbe7b6c,2
+np.float64,0x3ff343cc4d068799,0x3fe41c2a30cab7d2,2
+np.float64,0x7fd1b0daaa2361b4,0x408629852b3104ff,2
+np.float64,0x3ff6a41f37ad483e,0x3fec3b36ee6c6d4a,2
+np.float64,0x3ffad9439435b287,0x3ff1b6add9a1b3d7,2
+np.float64,0x7fbeb9a2f23d7345,0x408622d89ac1eaba,2
+np.float64,0x3ffab3d39fb567a7,0x3ff19ac75b4427f3,2
+np.float64,0x3ff890003ed12000,0x3fefc8844471c6ad,2
+np.float64,0x3ffc9f595e593eb2,0x3ff2f7a8699f06d8,2
+np.float64,0x7fe2224ef6e4449d,0x40862f43684a154a,2
+np.float64,0x3ffa67ba08d4cf74,0x3ff161525778df99,2
+np.float64,0x7fe87e24b570fc48,0x408631ab02b159fb,2
+np.float64,0x7fd6e99be92dd337,0x40862b96dba73685,2
+np.float64,0x7fe90f39fdf21e73,0x408631d9dbd36c1e,2
+np.float64,0x3ffb7806abd6f00e,0x3ff22a719b0f4c46,2
+np.float64,0x3ffa511ba3d4a238,0x3ff1500c124f6e17,2
+np.float64,0x3ff5d7a569abaf4b,0x3fea937391c280e8,2
+np.float64,0x7fc4279d20284f39,0x40862504a5cdcb96,2
+np.float64,0x3ffe8791b1fd0f24,0x3ff431f1ed7eaba0,2
+np.float64,0x7fe3b2f5276765e9,0x40862fecf15e2535,2
+np.float64,0x7feeab0e7abd561c,0x408633778044cfbc,2
+np.float64,0x7fdba88531375109,0x40862d1860306d7a,2
+np.float64,0x7fe7b19b3def6335,0x4086316716d6890b,2
+np.float64,0x3ff9e9437413d287,0x3ff0ff89431c748c,2
+np.float64,0x3ff960716a52c0e3,0x3ff092498028f802,2
+np.float64,0x3ff271bf56a4e37f,0x3fe1786fc8dd775d,2
+np.float64,0x3fff2a6578be54cb,0x3ff494bbe303eeb5,2
+np.float64,0x3ffd842eb5fb085e,0x3ff38e8b7ba42bc5,2
+np.float64,0x3ff91600e5d22c02,0x3ff0553c6a6b3d93,2
+np.float64,0x3ff9153f45f22a7e,0x3ff0549c0eaecf95,2
+np.float64,0x7fe0ab319da15662,0x40862e96da3b19f9,2
+np.float64,0x3ff06acd1f60d59a,0x3fcd2aca543d2772,2
+np.float64,0x3ffb3e7a54d67cf4,0x3ff200f288cd391b,2
+np.float64,0x3ffd01356f1a026b,0x3ff339003462a56c,2
+np.float64,0x3ffacd35def59a6c,0x3ff1adb8d32b3ec0,2
+np.float64,0x3ff6f953264df2a6,0x3fece2f992948d6e,2
+np.float64,0x3ff0fa91f5a1f524,0x3fd64609a28f1590,2
+np.float64,0x7fd1b7610ca36ec1,0x408629881e03dc7d,2
+np.float64,0x3ff4317fb7c86300,0x3fe6b086ed265887,2
+np.float64,0x3ff3856198070ac3,0x3fe4dbb6bc88b9e3,2
+np.float64,0x7fed7fc4573aff88,0x40863327e7013a81,2
+np.float64,0x3ffe53cbbf5ca798,0x3ff411f07a29b1f4,2
+np.float64,0x3ff092195b012433,0x3fd10b1c0b4b14fe,2
+np.float64,0x3ff1a3171163462e,0x3fdcb5c301d5d40d,2
+np.float64,0x3ffa1401f1742804,0x3ff120eb319e9faa,2
+np.float64,0x7fd352f6f426a5ed,0x40862a3a048feb6d,2
+np.float64,0x7fd4ee246fa9dc48,0x40862add895d808f,2
+np.float64,0x3ff0675cfa00ceba,0x3fccb2222c5493ca,2
+np.float64,0x3ffe5cb38f3cb967,0x3ff417773483d161,2
+np.float64,0x7fe11469ea2228d3,0x40862ec8bd3e497f,2
+np.float64,0x3fff13cba67e2798,0x3ff4872fe2c26104,2
+np.float64,0x3ffb73d3d316e7a8,0x3ff2276f08612ea2,2
+np.float64,0x7febfb70f237f6e1,0x408632bbc9450721,2
+np.float64,0x3ff84a0d87b0941b,0x3fef4f3b707e3145,2
+np.float64,0x7fd71fd5082e3fa9,0x40862ba9b4091172,2
+np.float64,0x3ff560737d8ac0e7,0x3fe98cc9c9ba2f61,2
+np.float64,0x3ff46a266ae8d44d,0x3fe74190e5234822,2
+np.float64,0x7fe8cc9225719923,0x408631c477db9708,2
+np.float64,0x3ff871de5930e3bc,0x3fef948f7d00fbef,2
+np.float64,0x3ffd0bc7895a178f,0x3ff33ffc18357721,2
+np.float64,0x3ff66099f9ccc134,0x3febb2bc775b4720,2
+np.float64,0x7fe91f1be9723e37,0x408631deec3a5c9e,2
+np.float64,0x7fd60462f12c08c5,0x40862b4537e1c1c6,2
+np.float64,0x3ff053100ba0a620,0x3fc9bc0c21e2284f,2
+np.float64,0x7fd864c611b0c98b,0x40862c1724506255,2
+np.float64,0x7fd191decb2323bd,0x408629771bfb68cc,2
+np.float64,0x3ff792a1656f2543,0x3fee054f2e135fcf,2
+np.float64,0x7fd03625cea06c4b,0x408628d253b840e3,2
+np.float64,0x7fc3967716272ced,0x408624ca35451042,2
+np.float64,0x7fe6636cb32cc6d8,0x408630f3073a22a7,2
+np.float64,0x3ffc2d3976585a73,0x3ff2a9d4c0dae607,2
+np.float64,0x3fffd10ee79fa21e,0x3ff4f70db69888be,2
+np.float64,0x3ff1d4fcae23a9f9,0x3fde57675007b23c,2
+np.float64,0x3ffa5da19e14bb43,0x3ff1599f74d1c113,2
+np.float64,0x3ff7f4eb0d6fe9d6,0x3feeb85189659e99,2
+np.float64,0x7fbcca44d8399489,0x408622536234f7c1,2
+np.float64,0x7fef5f97ec3ebf2f,0x408633a60fdde0d7,2
+np.float64,0x7fde4a66da3c94cd,0x40862dd290ebc184,2
+np.float64,0x3ff072957a40e52b,0x3fce34d913d87613,2
+np.float64,0x3ff2bc4c9dc57899,0x3fe27497e6ebe27d,2
+np.float64,0x7fd7d152b4afa2a4,0x40862be63469eecd,2
+np.float64,0x3ff957d768f2afaf,0x3ff08b4ad8062a73,2
+np.float64,0x7fe4bc5f45a978be,0x40863055fd66e4eb,2
+np.float64,0x7fc90de345321bc6,0x408626c24ce7e370,2
+np.float64,0x3ff2d7a37d85af47,0x3fe2cd6a40b544a0,2
+np.float64,0x7fe536ea1f6a6dd3,0x40863084bade76a3,2
+np.float64,0x3fff970c9cdf2e19,0x3ff4d524572356dd,2
+np.float64,0x3ffe173ae63c2e76,0x3ff3ec1ee35ad28c,2
+np.float64,0x3ff714025cce2805,0x3fed168aedff4a2b,2
+np.float64,0x7fce7b414c3cf682,0x40862853dcdd19d4,2
+np.float64,0x3ff019623f2032c4,0x3fbc7c602df0bbaf,2
+np.float64,0x3ff72f57fd0e5eb0,0x3fed4ae75f697432,2
+np.float64,0x3ff283778e8506ef,0x3fe1b5c5725b0dfd,2
+np.float64,0x3ff685a29aed0b45,0x3febfdfdedd581e2,2
+np.float64,0x3ff942d24fb285a4,0x3ff07a224c3ecfaf,2
+np.float64,0x3ff2e4a9f465c954,0x3fe2f71905399e8f,2
+np.float64,0x7fdfa1c7fa3f438f,0x40862e2b4e06f098,2
+np.float64,0x3ff49b59c26936b4,0x3fe7bc41c8c1e59d,2
+np.float64,0x3ff2102d3704205a,0x3fe014bf7e28924e,2
+np.float64,0x3ff88de3b8311bc8,0x3fefc4e3e0a15a89,2
+np.float64,0x7fea5ba25374b744,0x40863241519c9b66,2
+np.float64,0x3fffe5df637fcbbf,0x3ff5032488f570f9,2
+np.float64,0x7fe67cfefe6cf9fd,0x408630fc25333cb4,2
+np.float64,0x3ff090bf2b01217e,0x3fd0f6fcf1092b4a,2
+np.float64,0x7fecd75bc5f9aeb7,0x408632f9b6c2e013,2
+np.float64,0x7fe15df38c62bbe6,0x40862eeae5ac944b,2
+np.float64,0x3ff4757875a8eaf1,0x3fe75e0eafbe28ce,2
+np.float64,0x7fecca8a51b99514,0x408632f627c23923,2
+np.float64,0x3ff91ca529d2394a,0x3ff05abb327fd1ca,2
+np.float64,0x3ffb962993b72c53,0x3ff23ff831717579,2
+np.float64,0x3ffd548a2c7aa914,0x3ff36fac7f56d716,2
+np.float64,0x7fbafb5cb035f6b8,0x408621ce898a02fb,2
+np.float64,0x3ff1d86daca3b0db,0x3fde73536c29218c,2
+np.float64,0x7fa8d0f8f431a1f1,0x40861b97a03c3a18,2
+np.float64,0x3ff44f1067489e21,0x3fe6fcbd8144ab2a,2
+np.float64,0x7fec062b07380c55,0x408632bed9c6ce85,2
+np.float64,0x3ff7e11e0fcfc23c,0x3fee94ada7efaac4,2
+np.float64,0x7fe77505c1aeea0b,0x4086315287dda0ba,2
+np.float64,0x7fc465af2728cb5d,0x4086251d236107f7,2
+np.float64,0x3ffe811c4a7d0238,0x3ff42df7e8b6cf2d,2
+np.float64,0x7fe05a471260b48d,0x40862e6fa502738b,2
+np.float64,0x7fec32cd9778659a,0x408632cb8d98c5a3,2
+np.float64,0x7fd203a220a40743,0x408629aa43b010c0,2
+np.float64,0x7fed71f7d17ae3ef,0x4086332428207101,2
+np.float64,0x3ff3918999e72313,0x3fe4fe5e8991402f,2
+np.float64,0x3ff3ecae38c7d95c,0x3fe5fa787d887981,2
+np.float64,0x7fd65345b82ca68a,0x40862b61aed8c64e,2
+np.float64,0x3ff1efdd01c3dfba,0x3fdf2eae36139204,2
+np.float64,0x3ffba9344f375268,0x3ff24d7fdcfc313b,2
+np.float64,0x7fd0469b35208d35,0x408628da6ed24bdd,2
+np.float64,0x7fe525782daa4aef,0x4086307e240c8b30,2
+np.float64,0x3ff8e473d371c8e8,0x3ff02beebd4171c7,2
+np.float64,0x3ff59a43898b3487,0x3fea0dc0a6acea0a,2
+np.float64,0x7fef50c7263ea18d,0x408633a247d7cd42,2
+np.float64,0x7fe8b5a301f16b45,0x408631bd0e71c855,2
+np.float64,0x3ff209369de4126d,0x3fdff4264334446b,2
+np.float64,0x3ffbe2ff4437c5fe,0x3ff2763b356814c7,2
+np.float64,0x3ff55938156ab270,0x3fe97c70514f91bf,2
+np.float64,0x3fff5d8bf81ebb18,0x3ff4b333b230672a,2
+np.float64,0x3ff16a317bc2d463,0x3fdab84e7faa468f,2
+np.float64,0x3ff7e64f8dafcc9f,0x3fee9e0bd57e9566,2
+np.float64,0x7fef4dc065be9b80,0x408633a181e25abb,2
+np.float64,0x3ff64a24a62c9449,0x3feb849ced76437e,2
+np.float64,0x7fc3cb85ef27970b,0x408624dfc39c8f74,2
+np.float64,0x7fec2162a77842c4,0x408632c69b0d43b6,2
+np.float64,0x7feccee6dc399dcd,0x408632f75de98c46,2
+np.float64,0x7faff4f5f43fe9eb,0x40861d9d89be14c9,2
+np.float64,0x7fee82df60fd05be,0x4086336cfdeb7317,2
+np.float64,0x3ffe54588d9ca8b1,0x3ff41247eb2f75ca,2
+np.float64,0x3ffe5615b55cac2c,0x3ff4135c4eb11620,2
+np.float64,0x3ffdaf9a6a1b5f35,0x3ff3aa70e50d1692,2
+np.float64,0x3ff69c045f4d3809,0x3fec2b00734e2cde,2
+np.float64,0x7fd049239aa09246,0x408628dbad6dd995,2
+np.float64,0x3ff2acbe8465597d,0x3fe24138652195e1,2
+np.float64,0x3ffb288302365106,0x3ff1f0f86ca7e5d1,2
+np.float64,0x3fff6fe8d87edfd2,0x3ff4be136acf53c5,2
+np.float64,0x3ffc87c8bfb90f92,0x3ff2e7bbd65867cb,2
+np.float64,0x3ff173327ca2e665,0x3fdb0b945abb00d7,2
+np.float64,0x3ff9a5cf7a134b9f,0x3ff0ca2450f07c78,2
+np.float64,0x7faf782b043ef055,0x40861d7e0e9b35ef,2
+np.float64,0x3ffa0874975410e9,0x3ff117ee3dc8f5ba,2
+np.float64,0x7fc710fc7f2e21f8,0x40862618fed167fb,2
+np.float64,0x7feb73f4c876e7e9,0x40863294ae3ac1eb,2
+np.float64,0x8000000000000000,0xfff8000000000000,2
+np.float64,0x7fb46615c028cc2b,0x40861f91bade4dad,2
+np.float64,0x7fc26b064624d60c,0x4086244c1b76c938,2
+np.float64,0x3ff06ab9fa40d574,0x3fcd282fd971d1b4,2
+np.float64,0x3ff61da7410c3b4e,0x3feb28201031af02,2
+np.float64,0x3ffec7ba1b9d8f74,0x3ff459342511f952,2
+np.float64,0x7ff4000000000000,0x7ffc000000000000,2
+np.float64,0x7fe5d570422baae0,0x408630bfa75008c9,2
+np.float64,0x3ffa895832f512b0,0x3ff17ad41555dccb,2
+np.float64,0x7fd343ac21a68757,0x40862a33ad59947a,2
+np.float64,0x3ffc1eeb37383dd6,0x3ff29ff29e55a006,2
+np.float64,0x7fee3c5c507c78b8,0x4086335a6b768090,2
+np.float64,0x7fe96d774a32daee,0x408631f7b9937e36,2
+np.float64,0x7fb878362430f06b,0x40862106603497b6,2
+np.float64,0x7fec0a79c03814f3,0x408632c01479905e,2
+np.float64,0x3ffa2f143c145e28,0x3ff135e25d902e1a,2
+np.float64,0x3ff14ccff80299a0,0x3fd9a0cd3397b14c,2
+np.float64,0x3ff97980dcb2f302,0x3ff0a6942a8133ab,2
+np.float64,0x3ff872e2d1f0e5c6,0x3fef96526eb2f756,2
+np.float64,0x7fdf1c9b46be3936,0x40862e0957fee329,2
+np.float64,0x7fcab6525d356ca4,0x408627458791f029,2
+np.float64,0x3ff964e74a52c9ce,0x3ff095e8845d523c,2
+np.float64,0x3ffb3aa23c967544,0x3ff1fe282d897c13,2
+np.float64,0x7fdd8a36afbb146c,0x40862d9f2b05f61b,2
+np.float64,0x3ffea39f42fd473e,0x3ff4432a48176399,2
+np.float64,0x7fea614f68b4c29e,0x408632430a750385,2
+np.float64,0x7feeafb86abd5f70,0x40863378b79f70cf,2
+np.float64,0x3ff80bc94eb01792,0x3feee138e9d626bd,2
+np.float64,0x7fcaca74743594e8,0x4086274b8ce4d1e1,2
+np.float64,0x3ff8b14815316290,0x3ff000b3526c8321,2
+np.float64,0x7fc698eb5f2d31d6,0x408625eeec86cd2b,2
+np.float64,0x7fe15429a3e2a852,0x40862ee6621205b8,2
+np.float64,0x7fee37f81b7c6fef,0x4086335941ed80dd,2
+np.float64,0x3ff8097ab3f012f6,0x3feedd1bafc3196e,2
+np.float64,0x7fe7c889ceaf9113,0x4086316ed13f2394,2
+np.float64,0x7fceca94513d9528,0x4086286893a06824,2
+np.float64,0x3ff593a103cb2742,0x3fe9ff1af4f63cc9,2
+np.float64,0x7fee237d24bc46f9,0x40863353d4142c87,2
+np.float64,0x3ffbf71e4777ee3c,0x3ff2844c0ed9f4d9,2
+np.float64,0x3ff490c65c09218d,0x3fe7a2216d9f69fd,2
+np.float64,0x3fff5ceaf1feb9d6,0x3ff4b2d430a90110,2
+np.float64,0x3ff55baecceab75e,0x3fe98203980666c4,2
+np.float64,0x3ff511bc306a2378,0x3fe8d81ce7be7b50,2
+np.float64,0x3ff38f83dcc71f08,0x3fe4f89f130d5f87,2
+np.float64,0x3ff73a3676ee746d,0x3fed5f98a65107ee,2
+np.float64,0x7fc27e50c824fca1,0x408624547828bc49,2
+np.float64,0xfff0000000000000,0xfff8000000000000,2
+np.float64,0x3fff38959ebe712b,0x3ff49d362c7ba16a,2
+np.float64,0x3ffad6d23a75ada4,0x3ff1b4dda6394ed0,2
+np.float64,0x3ffe77c6c2dcef8e,0x3ff4283698835ecb,2
+np.float64,0x3fff5feb413ebfd6,0x3ff4b49bcbdb3aa9,2
+np.float64,0x3ff0d30aa161a615,0x3fd4751bcdd7d727,2
+np.float64,0x3ff51e07e00a3c10,0x3fe8f4bd1408d694,2
+np.float64,0x8010000000000000,0xfff8000000000000,2
+np.float64,0x7fd231d2fe2463a5,0x408629beaceafcba,2
+np.float64,0x3fff6b4aee1ed696,0x3ff4bb58544bf8eb,2
+np.float64,0x3ff91fcd2f323f9a,0x3ff05d56e33db6b3,2
+np.float64,0x3ff3b889ab477113,0x3fe56bdeab74cce5,2
+np.float64,0x3ff99bfe30d337fc,0x3ff0c24bbf265561,2
+np.float64,0x3ffbe9e5eaf7d3cc,0x3ff27b0fe60f827a,2
+np.float64,0x7fd65678e92cacf1,0x40862b62d44fe8b6,2
+np.float64,0x7fd9cc477233988e,0x40862c89c638ee48,2
+np.float64,0x3ffc123c72d82479,0x3ff297294d05cbc0,2
+np.float64,0x3ff58abad58b1576,0x3fe9eb65da2a867a,2
+np.float64,0x7fe534887b2a6910,0x40863083d4ec2877,2
+np.float64,0x7fe1d3dcb123a7b8,0x40862f208116c55e,2
+np.float64,0x7fd4d570dba9aae1,0x40862ad412c413cd,2
+np.float64,0x3fffce7d3fdf9cfa,0x3ff4f58f02451928,2
+np.float64,0x3ffa76901c74ed20,0x3ff16c9a5851539c,2
+np.float64,0x7fdd88ffa23b11fe,0x40862d9ed6c6f426,2
+np.float64,0x3ff09fdbb9e13fb7,0x3fd1d2ae4fcbf713,2
+np.float64,0x7fe64567772c8ace,0x408630e845dbc290,2
+np.float64,0x7fb1a849ba235092,0x40861e6a291535b2,2
+np.float64,0x3ffaddb105f5bb62,0x3ff1b9f68f4c419b,2
+np.float64,0x7fd2fc3d5025f87a,0x40862a15cbc1df75,2
+np.float64,0x7fdea7d872bd4fb0,0x40862deb190b2c50,2
+np.float64,0x7fd50ea97eaa1d52,0x40862ae9edc4c812,2
+np.float64,0x3fff659c245ecb38,0x3ff4b7fb18b31aea,2
+np.float64,0x3ff3f1fbb7c7e3f7,0x3fe608bd9d76268c,2
+np.float64,0x3ff76869d9aed0d4,0x3fedb6c23d3a317b,2
+np.float64,0x7fedd4efe93ba9df,0x4086333edeecaa43,2
+np.float64,0x3ff9a5bd4eb34b7a,0x3ff0ca15d02bc960,2
+np.float64,0x3ffd9359cc5b26b4,0x3ff39850cb1a6b6c,2
+np.float64,0x7fe912d0427225a0,0x408631db00e46272,2
+np.float64,0x3ffb3802fe567006,0x3ff1fc4093646465,2
+np.float64,0x3ff02cc38a205987,0x3fc2e8182802a07b,2
+np.float64,0x3ffda953dd1b52a8,0x3ff3a66c504cf207,2
+np.float64,0x7fe0a487e4a1490f,0x40862e93a6f20152,2
+np.float64,0x7fed265ed1fa4cbd,0x4086330f838ae431,2
+np.float64,0x7fd0000114200001,0x408628b76ec48b5c,2
+np.float64,0x3ff2c262786584c5,0x3fe288860d354b0f,2
+np.float64,0x8000000000000001,0xfff8000000000000,2
+np.float64,0x3ffdae9f075b5d3e,0x3ff3a9d006ae55c1,2
+np.float64,0x3ffb69c72156d38e,0x3ff22037cbb85e5b,2
+np.float64,0x7feeae255f7d5c4a,0x408633784e89bc05,2
+np.float64,0x7feb13927c362724,0x408632786630c55d,2
+np.float64,0x7fef49e072be93c0,0x408633a08451d476,2
+np.float64,0x3fff23d6337e47ac,0x3ff490ceb6e634ae,2
+np.float64,0x3ffba82cf8f7505a,0x3ff24cc51c73234d,2
+np.float64,0x7fe948719ef290e2,0x408631ec0b36476e,2
+np.float64,0x3ff41926c5e8324e,0x3fe670e14bbda8cd,2
+np.float64,0x3ff91f09c1523e14,0x3ff05cb5731878da,2
+np.float64,0x3ff6ae6afccd5cd6,0x3fec4fbeca764086,2
+np.float64,0x3ff927f7e0f24ff0,0x3ff06413eeb8eb1e,2
+np.float64,0x3ff19dd2b9e33ba5,0x3fdc882f97994600,2
+np.float64,0x7fe8e502c5b1ca05,0x408631cc56526fff,2
+np.float64,0x7feb49f70fb693ed,0x4086328868486fcd,2
+np.float64,0x3ffd942d535b285a,0x3ff398d8d89f52ca,2
+np.float64,0x7fc3b9c5c627738b,0x408624d893e692ca,2
+np.float64,0x7fea0780ff340f01,0x408632279fa46704,2
+np.float64,0x7fe4c90066a99200,0x4086305adb47a598,2
+np.float64,0x7fdb209113364121,0x40862cf0ab64fd7d,2
+np.float64,0x3ff38617e5470c30,0x3fe4ddc0413b524f,2
+np.float64,0x7fea1b5b803436b6,0x4086322db767f091,2
+np.float64,0x7fe2004898e40090,0x40862f3457795dc5,2
+np.float64,0x3ff3c4360ac7886c,0x3fe58c29843a4c75,2
+np.float64,0x3ff504bc168a0978,0x3fe8b9ada7f698e6,2
+np.float64,0x3ffd3e936fda7d27,0x3ff3615912c5b4ac,2
+np.float64,0x3ffbdc52fb97b8a6,0x3ff2718dae5f1f2b,2
+np.float64,0x3fffef6d84ffdedb,0x3ff508adbc8556cf,2
+np.float64,0x3ff23b65272476ca,0x3fe0b646ed2579eb,2
+np.float64,0x7fe4633068a8c660,0x408630334a4b7ff7,2
+np.float64,0x3ff769b754aed36f,0x3fedb932af0223f9,2
+np.float64,0x7fe7482d92ee905a,0x408631432de1b057,2
+np.float64,0x3ff5dd682aabbad0,0x3fea9fd5e506a86d,2
+np.float64,0x7fd68399a2ad0732,0x40862b72ed89805d,2
+np.float64,0x3ffad7acc3d5af5a,0x3ff1b57fe632c948,2
+np.float64,0x3ffc68e43698d1c8,0x3ff2d2be6f758761,2
+np.float64,0x3ff4e517fbc9ca30,0x3fe86eddf5e63a58,2
+np.float64,0x3ff34c63c56698c8,0x3fe435b74ccd6a13,2
+np.float64,0x7fea9456c17528ad,0x4086325275237015,2
+np.float64,0x7fee6573f2fccae7,0x4086336543760346,2
+np.float64,0x7fd5496fb9aa92de,0x40862b0023235667,2
+np.float64,0x7ff0000000000000,0x7ff0000000000000,2
+np.float64,0x3ffb70e31256e1c6,0x3ff22552f54b13e0,2
+np.float64,0x3ff66a33988cd467,0x3febc656da46a1ca,2
+np.float64,0x3fff0af2eb1e15e6,0x3ff481dec325f5c8,2
+np.float64,0x3ff6a0233d0d4046,0x3fec33400958eda1,2
+np.float64,0x7fdb11e2d5b623c5,0x40862cec55e405f9,2
+np.float64,0x3ffb8a015ad71402,0x3ff2374d7b563a72,2
+np.float64,0x3ff1807d8ce300fb,0x3fdb849e4bce8335,2
+np.float64,0x3ffefd535e3dfaa6,0x3ff479aaac6ffe79,2
+np.float64,0x3ff701e23a6e03c4,0x3fecf39072d96fc7,2
+np.float64,0x3ff4ac809f895901,0x3fe7e6598f2335a5,2
+np.float64,0x3ff0309f26a0613e,0x3fc3b3f4b2783690,2
+np.float64,0x3ff241dd0ce483ba,0x3fe0cde2cb639144,2
+np.float64,0x3ffabce63fb579cc,0x3ff1a18fe2a2da59,2
+np.float64,0x3ffd84b967db0973,0x3ff38ee4f240645d,2
+np.float64,0x7fc3f88b9a27f116,0x408624f1e10cdf3f,2
+np.float64,0x7fe1d5fd5923abfa,0x40862f2175714a3a,2
+np.float64,0x7fe487b145690f62,0x4086304190700183,2
+np.float64,0x7fe7997feaef32ff,0x4086315eeefdddd2,2
+np.float64,0x3ff8f853b671f0a8,0x3ff03c907353a8da,2
+np.float64,0x7fca4c23b5349846,0x408627257ace5778,2
+np.float64,0x7fe0c9bf3a21937d,0x40862ea576c3ea43,2
+np.float64,0x7fc442b389288566,0x4086250f5f126ec9,2
+np.float64,0x7fc6d382ed2da705,0x40862603900431b0,2
+np.float64,0x7fe40b069068160c,0x4086301066468124,2
+np.float64,0x3ff7f62a146fec54,0x3feeba8dfc4363fe,2
+np.float64,0x3ff721e8e94e43d2,0x3fed313a6755d34f,2
+np.float64,0x7fe579feaf2af3fc,0x4086309ddefb6112,2
+np.float64,0x3ffe2c6bde5c58d8,0x3ff3f9665dc9a16e,2
+np.float64,0x7fcf9998ed3f3331,0x4086289dab274788,2
+np.float64,0x7fdb03af2236075d,0x40862ce82252e490,2
+np.float64,0x7fe72799392e4f31,0x40863137f428ee71,2
+np.float64,0x7f9f2190603e4320,0x408617dc5b3b3c3c,2
+np.float64,0x3ff69c56d52d38ae,0x3fec2ba59fe938b2,2
+np.float64,0x7fdcde27bf39bc4e,0x40862d70086cd06d,2
+np.float64,0x3ff654d6b8eca9ae,0x3feb9aa0107609a6,2
+np.float64,0x7fdf69d967bed3b2,0x40862e1d1c2b94c2,2
+np.float64,0xffefffffffffffff,0xfff8000000000000,2
+np.float64,0x7fedfd073f3bfa0d,0x40863349980c2c8b,2
+np.float64,0x7f7c1856803830ac,0x40860bf312b458c7,2
+np.float64,0x7fe9553f1bb2aa7d,0x408631f0173eadd5,2
+np.float64,0x3ff6e92efc2dd25e,0x3fecc38f98e7e1a7,2
+np.float64,0x7fe9719ac532e335,0x408631f906cd79c3,2
+np.float64,0x3ff60e56ae4c1cad,0x3feb07ef8637ec7e,2
+np.float64,0x3ff0d0803501a100,0x3fd455c0af195a9c,2
+np.float64,0x7fe75248a3eea490,0x40863146a614aec1,2
+np.float64,0x7fdff61ead3fec3c,0x40862e408643d7aa,2
+np.float64,0x7fed4ac7a4fa958e,0x408633197b5cf6ea,2
+np.float64,0x7fe58d44562b1a88,0x408630a5098d1bbc,2
+np.float64,0x7fd89dcdb1b13b9a,0x40862c29c2979288,2
+np.float64,0x3ff205deda240bbe,0x3fdfda67c84fd3a8,2
+np.float64,0x7fdf84c15abf0982,0x40862e23f361923d,2
+np.float64,0x3ffe012b3afc0256,0x3ff3de3dfa5f47ce,2
+np.float64,0x3ffe2f3512dc5e6a,0x3ff3fb245206398e,2
+np.float64,0x7fed6174c2bac2e9,0x4086331faa699617,2
+np.float64,0x3ff1f30f8783e61f,0x3fdf47e06f2c40d1,2
+np.float64,0x3ff590da9eab21b5,0x3fe9f8f7b4baf3c2,2
+np.float64,0x3ffb3ca1eb967944,0x3ff1ff9baf66d704,2
+np.float64,0x7fe50ba9a5aa1752,0x408630745ab7fd3c,2
+np.float64,0x3ff43743a4a86e87,0x3fe6bf7ae80b1dda,2
+np.float64,0x3ff47e1a24e8fc34,0x3fe773acca44c7d6,2
+np.float64,0x3ff589ede9eb13dc,0x3fe9e99f28fab3a4,2
+np.float64,0x3ff72f2cbf8e5e5a,0x3fed4a94e7edbf24,2
+np.float64,0x3ffa4f9bbc549f38,0x3ff14ee60aea45d3,2
+np.float64,0x3ff975dae732ebb6,0x3ff0a3a1fbd7284a,2
+np.float64,0x7fbcf14ee039e29d,0x4086225e33f3793e,2
+np.float64,0x3ff10e027f621c05,0x3fd71cce2452b4e0,2
+np.float64,0x3ff33ea193067d43,0x3fe40cbac4daaddc,2
+np.float64,0x7fbef8f2263df1e3,0x408622e905c8e1b4,2
+np.float64,0x3fff7f5bfe3efeb8,0x3ff4c732e83df253,2
+np.float64,0x3ff5700a6b4ae015,0x3fe9afdd7b8b82b0,2
+np.float64,0x3ffd5099da5aa134,0x3ff36d1bf26e55bf,2
+np.float64,0x3ffed8e0f89db1c2,0x3ff4639ff065107a,2
+np.float64,0x3fff9d0c463f3a18,0x3ff4d8a9f297cf52,2
+np.float64,0x3ff23db5b2e47b6b,0x3fe0bebdd48f961a,2
+np.float64,0x3ff042bff1e08580,0x3fc713bf24cc60ef,2
+np.float64,0x7feb4fe97a769fd2,0x4086328a26675646,2
+np.float64,0x3ffeafbfeedd5f80,0x3ff44a955a553b1c,2
+np.float64,0x3ff83fb524507f6a,0x3fef3d1729ae0976,2
+np.float64,0x3ff1992294433245,0x3fdc5f5ce53dd197,2
+np.float64,0x7fe89fe629b13fcb,0x408631b601a83867,2
+np.float64,0x7fe53e4d74aa7c9a,0x40863087839b52f1,2
+np.float64,0x3ff113713e6226e2,0x3fd757631ca7cd09,2
+np.float64,0x7fd4a0b7a629416e,0x40862abfba27a09b,2
+np.float64,0x3ff184c6e2a3098e,0x3fdbab2e3966ae57,2
+np.float64,0x3ffafbbf77f5f77f,0x3ff1d02bb331d9f9,2
+np.float64,0x3ffc6099a358c134,0x3ff2cd16941613d1,2
+np.float64,0x3ffb7c441ef6f888,0x3ff22d7b12e31432,2
+np.float64,0x3ff625ba5eec4b75,0x3feb39060e55fb79,2
+np.float64,0x7fde879acbbd0f35,0x40862de2aab4d72d,2
+np.float64,0x7f930aed982615da,0x408613edb6df8528,2
+np.float64,0x7fa4b82dac29705a,0x40861a261c0a9aae,2
+np.float64,0x7fced5c16b3dab82,0x4086286b7a73e611,2
+np.float64,0x7fe133749d2266e8,0x40862ed73a41b112,2
+np.float64,0x3ff2d8146ea5b029,0x3fe2ced55dbf997d,2
+np.float64,0x3ff60dac77ac1b59,0x3feb0688b0e54c7b,2
+np.float64,0x3ff275d9b024ebb3,0x3fe186b87258b834,2
+np.float64,0x3ff533e6500a67cd,0x3fe92746c8b50ddd,2
+np.float64,0x7fe370896666e112,0x40862fd1ca144736,2
+np.float64,0x7fee7695357ced29,0x40863369c459420e,2
+np.float64,0x7fd1e0528023c0a4,0x4086299a85caffd0,2
+np.float64,0x7fd05c7b24a0b8f5,0x408628e52824386f,2
+np.float64,0x3ff11dcc3b023b98,0x3fd7c56c8cef1be1,2
+np.float64,0x7fc9d9fae933b3f5,0x408627027404bc5f,2
+np.float64,0x7fe2359981246b32,0x40862f4be675e90d,2
+np.float64,0x3ffb10a949962152,0x3ff1df88f83b8cde,2
+np.float64,0x3ffa65b53654cb6a,0x3ff15fc8956ccc87,2
+np.float64,0x3ff0000000000000,0x0,2
+np.float64,0x7fad97ef703b2fde,0x40861d002f3d02da,2
+np.float64,0x3ff57aaf93aaf55f,0x3fe9c7b01f194edb,2
+np.float64,0x7fe9ecd73f33d9ad,0x4086321f69917205,2
+np.float64,0x3ff0dcb79c61b96f,0x3fd4eac86a7a9c38,2
+np.float64,0x7fee9c12ffbd3825,0x4086337396cd706d,2
+np.float64,0x3ff52c40af4a5881,0x3fe915a8a7de8f00,2
+np.float64,0x3ffbcfff59779ffe,0x3ff268e523fe8dda,2
+np.float64,0x7fe014cb4b602996,0x40862e4d5de42a03,2
+np.float64,0x7fae2370e83c46e1,0x40861d258dd5b3ee,2
+np.float64,0x7fe9e33602f3c66b,0x4086321c704ac2bb,2
+np.float64,0x3ff648acd74c915a,0x3feb8195ca53bcaa,2
+np.float64,0x7fe385f507670be9,0x40862fda95ebaf44,2
+np.float64,0x3ffb0e382c361c70,0x3ff1ddbea963e0a7,2
+np.float64,0x3ff47d6b6ae8fad7,0x3fe771f80ad37cd2,2
+np.float64,0x3ffca7d538f94faa,0x3ff2fd5f62e851ac,2
+np.float64,0x3ff83e949c107d29,0x3fef3b1c5bbac99b,2
+np.float64,0x7fc6fb933a2df725,0x408626118e51a286,2
+np.float64,0x7fe43a1454e87428,0x4086302318512d9b,2
+np.float64,0x7fe51fe32aaa3fc5,0x4086307c07271348,2
+np.float64,0x3ff35e563966bcac,0x3fe46aa2856ef85f,2
+np.float64,0x3ff84dd4e4909baa,0x3fef55d86d1d5c2e,2
+np.float64,0x7febe3d84077c7b0,0x408632b507686f03,2
+np.float64,0x3ff6aca2e32d5946,0x3fec4c32a2368ee3,2
+np.float64,0x7fe7070e3e6e0e1b,0x4086312caddb0454,2
+np.float64,0x7fd3657f2aa6cafd,0x40862a41acf47e70,2
+np.float64,0x3ff61534456c2a68,0x3feb1663900af13b,2
+np.float64,0x3ff8bc556eb178ab,0x3ff00a16b5403f88,2
+np.float64,0x3ffa7782e3f4ef06,0x3ff16d529c94a438,2
+np.float64,0x7fc15785ed22af0b,0x408623d0cd94fb86,2
+np.float64,0x3ff2e3eeb6e5c7dd,0x3fe2f4c4876d3edf,2
+np.float64,0x3ff2e4e17e85c9c3,0x3fe2f7c9e437b22e,2
+np.float64,0x7feb3aaf67f6755e,0x40863283ec4a0d76,2
+np.float64,0x7fe89efcf7313df9,0x408631b5b5e41263,2
+np.float64,0x3ffcc6fad4f98df6,0x3ff31245778dff6d,2
+np.float64,0x3ff356114466ac22,0x3fe45253d040a024,2
+np.float64,0x3ff81c70d2d038e2,0x3feefed71ebac776,2
+np.float64,0x7fdb75c96136eb92,0x40862d09a603f03e,2
+np.float64,0x3ff340f91b8681f2,0x3fe413bb6e6d4a54,2
+np.float64,0x3fff906079df20c1,0x3ff4d13869d16bc7,2
+np.float64,0x3ff226a42d644d48,0x3fe0698d316f1ac0,2
+np.float64,0x3ff948abc3b29158,0x3ff07eeb0b3c81ba,2
+np.float64,0x3ffc25df1fb84bbe,0x3ff2a4c13ad4edad,2
+np.float64,0x7fe07ea3b960fd46,0x40862e815b4cf43d,2
+np.float64,0x3ff497d3dae92fa8,0x3fe7b3917bf10311,2
+np.float64,0x7fea561db1f4ac3a,0x4086323fa4aef2a9,2
+np.float64,0x7fd1b49051236920,0x40862986d8759ce5,2
+np.float64,0x7f7ba3bd6037477a,0x40860bd19997fd90,2
+np.float64,0x3ff01126dd00224e,0x3fb76b67938dfb11,2
+np.float64,0x3ff29e1105053c22,0x3fe2102a4c5fa102,2
+np.float64,0x3ff9de2a6553bc55,0x3ff0f6cfe4dea30e,2
+np.float64,0x7fc558e7d42ab1cf,0x4086257a608fc055,2
+np.float64,0x3ff79830a74f3061,0x3fee0f93db153d65,2
+np.float64,0x7fe2661648e4cc2c,0x40862f6117a71eb2,2
+np.float64,0x3ff140cf4262819e,0x3fd92aefedae1ab4,2
+np.float64,0x3ff5f36251abe6c5,0x3feaced481ceaee3,2
+np.float64,0x7fc80911d5301223,0x4086266d4757f768,2
+np.float64,0x3ff9079a6c320f35,0x3ff04949d21ebe1e,2
+np.float64,0x3ffde8d2e09bd1a6,0x3ff3cedca8a5db5d,2
+np.float64,0x3ffadd1de375ba3c,0x3ff1b989790e8d93,2
+np.float64,0x3ffdbc40ee1b7882,0x3ff3b286b1c7da57,2
+np.float64,0x3ff8ff514771fea2,0x3ff04264add00971,2
+np.float64,0x7fefd7d0e63fafa1,0x408633c47d9f7ae4,2
+np.float64,0x3ffc47798c588ef3,0x3ff2bbe441fa783a,2
+np.float64,0x7fe6ebc55b6dd78a,0x408631232d9abf31,2
+np.float64,0xbff0000000000000,0xfff8000000000000,2
+np.float64,0x7fd378e4afa6f1c8,0x40862a49a8f98cb4,2
+np.float64,0x0,0xfff8000000000000,2
+np.float64,0x3ffe88ed7efd11db,0x3ff432c7ecb95492,2
+np.float64,0x3ff4f5509289eaa1,0x3fe8955a11656323,2
+np.float64,0x7fda255b41344ab6,0x40862ca53676a23e,2
+np.float64,0x3ffebe85b9bd7d0c,0x3ff453992cd55dea,2
+np.float64,0x3ff5d6180b8bac30,0x3fea901c2160c3bc,2
+np.float64,0x3ffcdfb8fcf9bf72,0x3ff322c83b3bc735,2
+np.float64,0x3ff3c91c26679238,0x3fe599a652b7cf59,2
+np.float64,0x7fc389f7a62713ee,0x408624c518edef93,2
+np.float64,0x3ffe1245ba1c248c,0x3ff3e901b2c4a47a,2
+np.float64,0x7fe1e76e95e3cedc,0x40862f29446f9eff,2
+np.float64,0x3ff02ae4f92055ca,0x3fc28221abd63daa,2
+np.float64,0x7fbf648a143ec913,0x40862304a0619d03,2
+np.float64,0x3ff2be7ef8657cfe,0x3fe27bcc6c97522e,2
+np.float64,0x3ffa7595e514eb2c,0x3ff16bdc64249ad1,2
+np.float64,0x3ff4ee130049dc26,0x3fe884354cbad8c9,2
+np.float64,0x3ff19211fc232424,0x3fdc2160bf3eae40,2
+np.float64,0x3ffec215aedd842c,0x3ff455c4cdd50c32,2
+np.float64,0x7fe7cb50ffaf96a1,0x4086316fc06a53af,2
+np.float64,0x3fffa679161f4cf2,0x3ff4de30ba7ac5b8,2
+np.float64,0x7fdcb459763968b2,0x40862d646a21011d,2
+np.float64,0x3ff9f338d6d3e672,0x3ff1075835d8f64e,2
+np.float64,0x3ff8de3319d1bc66,0x3ff026ae858c0458,2
+np.float64,0x7fee0199d33c0333,0x4086334ad03ac683,2
+np.float64,0x3ffc06076c380c0f,0x3ff28eaec3814faa,2
+np.float64,0x3ffe9e2e235d3c5c,0x3ff43fd4d2191a7f,2
+np.float64,0x3ffd93b06adb2761,0x3ff398888239cde8,2
+np.float64,0x7fefe4b71cffc96d,0x408633c7ba971b92,2
+np.float64,0x7fb2940352252806,0x40861ed244bcfed6,2
+np.float64,0x3ffba4647e3748c9,0x3ff24a15f02e11b9,2
+np.float64,0x7fd2d9543725b2a7,0x40862a0708446596,2
+np.float64,0x7fc04997f120932f,0x4086235055d35251,2
+np.float64,0x3ff6d14313ada286,0x3fec94b177f5d3fc,2
+np.float64,0x3ff279fc8684f3f9,0x3fe19511c3e5b9a8,2
+np.float64,0x3ff42f4609085e8c,0x3fe6aabe526ce2bc,2
+np.float64,0x7fc1c6c62a238d8b,0x408624037de7f6ec,2
+np.float64,0x7fe31ff4b8e63fe8,0x40862fb05b40fd16,2
+np.float64,0x7fd2a8825fa55104,0x408629f234d460d6,2
+np.float64,0x3ffe8c1d725d183b,0x3ff434bdc444143f,2
+np.float64,0x3ff0e9dc3e21d3b8,0x3fd58676e2c13fc9,2
+np.float64,0x3ffed03172fda063,0x3ff45e59f7aa6c8b,2
+np.float64,0x7fd74621962e8c42,0x40862bb6e90d66f8,2
+np.float64,0x3ff1faa29663f545,0x3fdf833a2c5efde1,2
+np.float64,0x7fda02834db40506,0x40862c9a860d6747,2
+np.float64,0x7f709b2fc021365f,0x408607be328eb3eb,2
+np.float64,0x7fec0d58aa381ab0,0x408632c0e61a1af6,2
+np.float64,0x3ff524d1720a49a3,0x3fe90479968d40fd,2
+np.float64,0x7fd64cb3b32c9966,0x40862b5f53c4b0b4,2
+np.float64,0x3ff9593e3ed2b27c,0x3ff08c6eea5f6e8b,2
+np.float64,0x3ff7de8b1f6fbd16,0x3fee9007abcfdf7b,2
+np.float64,0x7fe8d816d6b1b02d,0x408631c82e38a894,2
+np.float64,0x7fd726bbe22e4d77,0x40862bac16ee8d52,2
+np.float64,0x7fa70b07d42e160f,0x40861affcc4265e2,2
+np.float64,0x7fe18b4091e31680,0x40862effa8bce66f,2
+np.float64,0x3ff830253010604a,0x3fef21b2eaa75758,2
+np.float64,0x3fffcade407f95bc,0x3ff4f3734b24c419,2
+np.float64,0x3ff8c17cecb182fa,0x3ff00e75152d7bda,2
+np.float64,0x7fdad9b9d035b373,0x40862cdbabb793ba,2
+np.float64,0x3ff9f9e154f3f3c2,0x3ff10c8dfdbd2510,2
+np.float64,0x3ff465e162e8cbc3,0x3fe736c751c75b73,2
+np.float64,0x3ff9b4cd8493699b,0x3ff0d616235544b8,2
+np.float64,0x7fe557c4a56aaf88,0x4086309114ed12d9,2
+np.float64,0x7fe5999133eb3321,0x408630a9991a9b54,2
+np.float64,0x7fe7c9009e2f9200,0x4086316ef9359a47,2
+np.float64,0x3ff8545cabd0a8ba,0x3fef6141f1030c36,2
+np.float64,0x3ffa1f1712943e2e,0x3ff129849d492ce3,2
+np.float64,0x7fea803a14750073,0x4086324c652c276c,2
+np.float64,0x3ff5b6f97fcb6df3,0x3fea4cb0b97b18e9,2
+np.float64,0x7fc2efdfc425dfbf,0x40862485036a5c6e,2
+np.float64,0x7fe2c78e5be58f1c,0x40862f8b0a5e7baf,2
+np.float64,0x7fe80d7fff301aff,0x40863185e234060a,2
+np.float64,0x3ffd895d457b12ba,0x3ff391e2cac7a3f8,2
+np.float64,0x3ff44c9764a8992f,0x3fe6f6690396c232,2
+np.float64,0x3ff731688b8e62d1,0x3fed4ed70fac3839,2
+np.float64,0x3ff060200460c040,0x3fcbad4a07d97f0e,2
+np.float64,0x3ffbd2f70a17a5ee,0x3ff26afb46ade929,2
+np.float64,0x7febe9e841f7d3d0,0x408632b6c465ddd9,2
+np.float64,0x3ff2532f8be4a65f,0x3fe10c6cd8d64cf4,2
+np.float64,0x7fefffffffffffff,0x408633ce8fb9f87e,2
+np.float64,0x3ff3a1ae3a47435c,0x3fe52c00210cc459,2
+np.float64,0x7fe9c34ae6b38695,0x408632128d150149,2
+np.float64,0x3fff311029fe6220,0x3ff498b852f30bff,2
+np.float64,0x3ffd4485a1ba890c,0x3ff3653b6fa701cd,2
+np.float64,0x7fd52718b1aa4e30,0x40862af330d9c68c,2
+np.float64,0x3ff10b695a4216d3,0x3fd7009294e367b7,2
+np.float64,0x3ffdf73de59bee7c,0x3ff3d7fa96d2c1ae,2
+np.float64,0x3ff2f1c75965e38f,0x3fe320aaff3db882,2
+np.float64,0x3ff2a56a5a854ad5,0x3fe228cc4ad7e7a5,2
+np.float64,0x7fe60cd1cf6c19a3,0x408630d3d87a04b3,2
+np.float64,0x3ff89fa65c113f4c,0x3fefe3543773180c,2
+np.float64,0x3ffd253130ba4a62,0x3ff350b76ba692a0,2
+np.float64,0x7feaad7051f55ae0,0x40863259ff932d62,2
+np.float64,0x7fd9cc37cf33986f,0x40862c89c15f963b,2
+np.float64,0x3ff8c08de771811c,0x3ff00daa9c17acd7,2
+np.float64,0x7fea58b25d34b164,0x408632406d54cc6f,2
+np.float64,0x7fe5f161fd2be2c3,0x408630c9ddf272a5,2
+np.float64,0x3ff5840dbf8b081c,0x3fe9dc9117b4cbc7,2
+np.float64,0x3ff3fd762307faec,0x3fe6277cd530c640,2
+np.float64,0x3ff9095c98b212b9,0x3ff04abff170ac24,2
+np.float64,0x7feaac66017558cb,0x40863259afb4f8ce,2
+np.float64,0x7fd78f96bcaf1f2c,0x40862bd00175fdf9,2
+np.float64,0x3ffaca27e0959450,0x3ff1ab72b8f8633e,2
+np.float64,0x3ffb7f18cb96fe32,0x3ff22f81bcb8907b,2
+np.float64,0x3ffcce48d1199c92,0x3ff317276f62c0b2,2
+np.float64,0x3ffcb9a7f3797350,0x3ff30958e0d6a34d,2
+np.float64,0x7fda569ef6b4ad3d,0x40862cb43b33275a,2
+np.float64,0x7fde9f0893bd3e10,0x40862de8cc036283,2
+np.float64,0x3ff428be3928517c,0x3fe699bb5ab58904,2
+np.float64,0x7fa4d3344029a668,0x40861a3084989291,2
+np.float64,0x3ff03607bd006c0f,0x3fc4c4840cf35f48,2
+np.float64,0x3ff2b1335c056267,0x3fe25000846b75a2,2
+np.float64,0x7fe0cb8bd8e19717,0x40862ea65237d496,2
+np.float64,0x3fff4b1b7b9e9637,0x3ff4a83fb08e7b24,2
+np.float64,0x7fe7526140aea4c2,0x40863146ae86069c,2
+np.float64,0x7fbfcfb7c23f9f6f,0x4086231fc246ede5,2
diff --git a/numpy/core/tests/data/umath-validation-set-arcsin.csv b/numpy/core/tests/data/umath-validation-set-arcsin.csv
new file mode 100644
index 000000000..cb94c93c9
--- /dev/null
+++ b/numpy/core/tests/data/umath-validation-set-arcsin.csv
@@ -0,0 +1,1429 @@
+dtype,input,output,ulperrortol
+np.float32,0xbe7d3a7c,0xbe7fe217,4
+np.float32,0x3dc102f0,0x3dc14c60,4
+np.float32,0xbe119c28,0xbe121aef,4
+np.float32,0xbe51cd68,0xbe534c75,4
+np.float32,0x3c04a300,0x3c04a35f,4
+np.float32,0xbf4f0b62,0xbf712a69,4
+np.float32,0x3ef61a5c,0x3f005cf6,4
+np.float32,0xbf13024c,0xbf1c97df,4
+np.float32,0x3e93b580,0x3e95d6b5,4
+np.float32,0x3e44e7b8,0x3e4623a5,4
+np.float32,0xbe35df20,0xbe36d773,4
+np.float32,0x3eecd2c0,0x3ef633cf,4
+np.float32,0x3f2772ba,0x3f36862a,4
+np.float32,0x3e211ea8,0x3e21cac5,4
+np.float32,0x3e3b3d90,0x3e3c4cc6,4
+np.float32,0x3f37c962,0x3f4d018c,4
+np.float32,0x3e92ad88,0x3e94c31a,4
+np.float32,0x3f356ffc,0x3f49a766,4
+np.float32,0x3f487ba2,0x3f665254,4
+np.float32,0x3f061c46,0x3f0d27ae,4
+np.float32,0xbee340a2,0xbeeb7722,4
+np.float32,0xbe85aede,0xbe874026,4
+np.float32,0x3f34cf9a,0x3f48c474,4
+np.float32,0x3e29a690,0x3e2a6fbd,4
+np.float32,0xbeb29428,0xbeb669d1,4
+np.float32,0xbe606d40,0xbe624370,4
+np.float32,0x3dae6860,0x3dae9e85,4
+np.float32,0xbf04872b,0xbf0b4d25,4
+np.float32,0x3f2080e2,0x3f2d7ab0,4
+np.float32,0xbec77dcc,0xbecceb27,4
+np.float32,0x3e0dda10,0x3e0e4f38,4
+np.float32,0xbefaf970,0xbf03262c,4
+np.float32,0x3f576a0c,0x3f7ffee6,4
+np.float32,0x3f222382,0x3f2f95d6,4
+np.float32,0x7fc00000,0x7fc00000,4
+np.float32,0x3e41c468,0x3e42f14e,4
+np.float32,0xbf2f64dd,0xbf4139a8,4
+np.float32,0xbf60ef90,0xbf895956,4
+np.float32,0xbf67c855,0xbf90eff0,4
+np.float32,0xbed35aee,0xbed9df00,4
+np.float32,0xbf2c7d92,0xbf3d448f,4
+np.float32,0x3f7b1604,0x3faff122,4
+np.float32,0xbf7c758b,0xbfb3bf87,4
+np.float32,0x3ecda1c8,0x3ed39acf,4
+np.float32,0x3f3af8ae,0x3f519fcb,4
+np.float32,0xbf16e6a3,0xbf2160fd,4
+np.float32,0x3f0c97d2,0x3f14d668,4
+np.float32,0x3f0a8060,0x3f1257b9,4
+np.float32,0x3f27905a,0x3f36ad57,4
+np.float32,0x3eeaeba4,0x3ef40efe,4
+np.float32,0x3e58dde0,0x3e5a8580,4
+np.float32,0xbf0cabe2,0xbf14ee6b,4
+np.float32,0xbe805ca8,0xbe81bf03,4
+np.float32,0x3f5462ba,0x3f7a7b85,4
+np.float32,0xbee235d0,0xbeea4d8b,4
+np.float32,0xbe880cb0,0xbe89b426,4
+np.float32,0x80000001,0x80000001,4
+np.float32,0x3f208c00,0x3f2d88f6,4
+np.float32,0xbf34f3d2,0xbf48f7a2,4
+np.float32,0x3f629428,0x3f8b1763,4
+np.float32,0xbf52a900,0xbf776b4a,4
+np.float32,0xbd17f8d0,0xbd1801be,4
+np.float32,0xbef7cada,0xbf0153d1,4
+np.float32,0x3f7d3b90,0x3fb63967,4
+np.float32,0xbd6a20b0,0xbd6a4160,4
+np.float32,0x3f740496,0x3fa1beb7,4
+np.float32,0x3ed8762c,0x3edf7dd9,4
+np.float32,0x3f53b066,0x3f793d42,4
+np.float32,0xbe9de718,0xbea084f9,4
+np.float32,0x3ea3ae90,0x3ea69b4b,4
+np.float32,0x3f1b8f00,0x3f273183,4
+np.float32,0x3f5cd6ac,0x3f852ead,4
+np.float32,0x3f29d510,0x3f39b169,4
+np.float32,0x3ee2a934,0x3eeace33,4
+np.float32,0x3eecac94,0x3ef608c2,4
+np.float32,0xbea915e2,0xbeac5203,4
+np.float32,0xbd316e90,0xbd317cc8,4
+np.float32,0xbf70b495,0xbf9c97b6,4
+np.float32,0xbe80d976,0xbe823ff3,4
+np.float32,0x3e9205f8,0x3e94143f,4
+np.float32,0x3f49247e,0x3f676296,4
+np.float32,0x3d9030c0,0x3d904f50,4
+np.float32,0x3e4df058,0x3e4f5a5c,4
+np.float32,0xbe1fd360,0xbe207b58,4
+np.float32,0xbf69dc7c,0xbf937006,4
+np.float32,0x3f36babe,0x3f4b7df3,4
+np.float32,0xbe8c9758,0xbe8e6bb7,4
+np.float32,0xbf4de72d,0xbf6f3c20,4
+np.float32,0xbecdad68,0xbed3a780,4
+np.float32,0xbf73e2cf,0xbfa18702,4
+np.float32,0xbece16a8,0xbed41a75,4
+np.float32,0x3f618a96,0x3f89fc6d,4
+np.float32,0xbf325853,0xbf454ea9,4
+np.float32,0x3f138568,0x3f1d3828,4
+np.float32,0xbf56a6e9,0xbf7e9748,4
+np.float32,0x3ef5d594,0x3f0035bf,4
+np.float32,0xbf408220,0xbf59dfaa,4
+np.float32,0xbed120e6,0xbed76dd5,4
+np.float32,0xbf6dbda5,0xbf986cee,4
+np.float32,0x3f744a38,0x3fa23282,4
+np.float32,0xbe4b56d8,0xbe4cb329,4
+np.float32,0x3f54c5f2,0x3f7b2d97,4
+np.float32,0xbd8b1c90,0xbd8b3801,4
+np.float32,0x3ee19a48,0x3ee9a03b,4
+np.float32,0x3f48460e,0x3f65fc3d,4
+np.float32,0x3eb541c0,0x3eb9461e,4
+np.float32,0xbea7d098,0xbeaaf98c,4
+np.float32,0xbda99e40,0xbda9d00c,4
+np.float32,0xbefb2ca6,0xbf03438d,4
+np.float32,0x3f4256be,0x3f5cab0b,4
+np.float32,0xbdbdb198,0xbdbdf74d,4
+np.float32,0xbf325b5f,0xbf4552e9,4
+np.float32,0xbf704d1a,0xbf9c00b4,4
+np.float32,0x3ebb1d04,0x3ebf8cf8,4
+np.float32,0xbed03566,0xbed66bf1,4
+np.float32,0x3e8fcee8,0x3e91c501,4
+np.float32,0xbf2e1eec,0xbf3f7b9d,4
+np.float32,0x3f33c4d2,0x3f474cac,4
+np.float32,0x3f598ef4,0x3f8201b4,4
+np.float32,0x3e09bb30,0x3e0a2660,4
+np.float32,0x3ed4e228,0x3edb8cdb,4
+np.float32,0x3eb7a190,0x3ebbd0a1,4
+np.float32,0xbd9ae630,0xbd9b0c18,4
+np.float32,0x3f43020e,0x3f5db2d7,4
+np.float32,0xbec06ac0,0xbec542d4,4
+np.float32,0x3f3dfde0,0x3f561674,4
+np.float32,0xbf64084a,0xbf8cabe6,4
+np.float32,0xbd6f95b0,0xbd6fb8b7,4
+np.float32,0x3f268640,0x3f354e2d,4
+np.float32,0xbe72b4bc,0xbe7509b2,4
+np.float32,0xbf3414fa,0xbf47bd5a,4
+np.float32,0xbf375218,0xbf4c566b,4
+np.float32,0x3f203c1a,0x3f2d2273,4
+np.float32,0xbd503530,0xbd504c2b,4
+np.float32,0xbc45e540,0xbc45e67b,4
+np.float32,0xbf175c4f,0xbf21f2c6,4
+np.float32,0x3f7432a6,0x3fa20b2b,4
+np.float32,0xbf43367f,0xbf5e03d8,4
+np.float32,0x3eb3997c,0x3eb780c4,4
+np.float32,0x3e5574c8,0x3e570878,4
+np.float32,0xbf04b57b,0xbf0b8349,4
+np.float32,0x3f6216d8,0x3f8a914b,4
+np.float32,0xbf57a237,0xbf80337d,4
+np.float32,0xbee1403a,0xbee93bee,4
+np.float32,0xbeaf9b9a,0xbeb33f3b,4
+np.float32,0xbf109374,0xbf19a223,4
+np.float32,0xbeae6824,0xbeb1f810,4
+np.float32,0xbcff9320,0xbcff9dbe,4
+np.float32,0x3ed205c0,0x3ed868a9,4
+np.float32,0x3d897c30,0x3d8996ad,4
+np.float32,0xbf2899d2,0xbf380d4c,4
+np.float32,0xbf54cb0b,0xbf7b36c2,4
+np.float32,0x3ea8e8ec,0x3eac2262,4
+np.float32,0x3ef5e1a0,0x3f003c9d,4
+np.float32,0xbf00c81e,0xbf06f1e2,4
+np.float32,0xbf346775,0xbf483181,4
+np.float32,0x3f7a4fe4,0x3fae077c,4
+np.float32,0x3f00776e,0x3f06948f,4
+np.float32,0xbe0a3078,0xbe0a9cbc,4
+np.float32,0xbeba0b06,0xbebe66be,4
+np.float32,0xbdff4e38,0xbdfff8b2,4
+np.float32,0xbe927f70,0xbe9492ff,4
+np.float32,0x3ebb07e0,0x3ebf7642,4
+np.float32,0x3ebcf8e0,0x3ec18c95,4
+np.float32,0x3f49bdfc,0x3f685b51,4
+np.float32,0x3cbc29c0,0x3cbc2dfd,4
+np.float32,0xbe9e951a,0xbea13bf1,4
+np.float32,0xbe8c237c,0xbe8df33d,4
+np.float32,0x3e17f198,0x3e1881c4,4
+np.float32,0xbd0b5220,0xbd0b5902,4
+np.float32,0xbf34c4a2,0xbf48b4f5,4
+np.float32,0xbedaa814,0xbee1ea94,4
+np.float32,0x3ebf5d6c,0x3ec42053,4
+np.float32,0x3cd04b40,0x3cd050ff,4
+np.float32,0xbec33fe0,0xbec85244,4
+np.float32,0xbf00b27a,0xbf06d8d8,4
+np.float32,0x3f15d7be,0x3f201243,4
+np.float32,0xbe3debd0,0xbe3f06f7,4
+np.float32,0xbea81704,0xbeab4418,4
+np.float32,0x1,0x1,4
+np.float32,0x3f49e6ba,0x3f689d8b,4
+np.float32,0x3f351030,0x3f491fc0,4
+np.float32,0x3e607de8,0x3e625482,4
+np.float32,0xbe8dbbe4,0xbe8f9c0e,4
+np.float32,0x3edbf350,0x3ee35924,4
+np.float32,0xbf0c84c4,0xbf14bf9c,4
+np.float32,0x3eb218b0,0x3eb5e61a,4
+np.float32,0x3e466dd0,0x3e47b138,4
+np.float32,0xbe8ece94,0xbe90ba01,4
+np.float32,0xbe82ec2a,0xbe84649a,4
+np.float32,0xbf7e1f10,0xbfb98b9e,4
+np.float32,0xbf2d00ea,0xbf3df688,4
+np.float32,0x3db7cdd0,0x3db80d36,4
+np.float32,0xbe388b98,0xbe398f25,4
+np.float32,0xbd86cb40,0xbd86e436,4
+np.float32,0x7f7fffff,0x7fc00000,4
+np.float32,0x3f472a60,0x3f6436c6,4
+np.float32,0xbf5b2c1d,0xbf838d87,4
+np.float32,0x3f0409ea,0x3f0abad8,4
+np.float32,0x3f47dd0e,0x3f6553f0,4
+np.float32,0x3e3eab00,0x3e3fc98a,4
+np.float32,0xbf7c2a7f,0xbfb2e19b,4
+np.float32,0xbeda0048,0xbee13112,4
+np.float32,0x3f46600a,0x3f62f5b2,4
+np.float32,0x3f45aef4,0x3f61de43,4
+np.float32,0x3dd40a50,0x3dd46bc4,4
+np.float32,0xbf6cdd0b,0xbf974191,4
+np.float32,0x3f78de4c,0x3faac725,4
+np.float32,0x3f3c39a4,0x3f53777f,4
+np.float32,0xbe2a30ec,0xbe2afc0b,4
+np.float32,0xbf3c0ef0,0xbf533887,4
+np.float32,0x3ecb6548,0x3ed12a53,4
+np.float32,0x3eb994e8,0x3ebde7fc,4
+np.float32,0x3d4c1ee0,0x3d4c3487,4
+np.float32,0xbf52cb6d,0xbf77a7eb,4
+np.float32,0x3eb905d4,0x3ebd4e80,4
+np.float32,0x3e712428,0x3e736d72,4
+np.float32,0xbf79ee6e,0xbfad22be,4
+np.float32,0x3de6f8b0,0x3de776c1,4
+np.float32,0x3e9b2898,0x3e9da325,4
+np.float32,0x3ea09b20,0x3ea35d20,4
+np.float32,0x3d0ea9a0,0x3d0eb103,4
+np.float32,0xbd911500,0xbd913423,4
+np.float32,0x3e004618,0x3e009c97,4
+np.float32,0x3f5e0e5a,0x3f86654c,4
+np.float32,0x3f2e6300,0x3f3fd88b,4
+np.float32,0x3e0cf5d0,0x3e0d68c3,4
+np.float32,0x3d6a16c0,0x3d6a376c,4
+np.float32,0x3f7174aa,0x3f9db53c,4
+np.float32,0xbe04bba0,0xbe051b81,4
+np.float32,0xbe6fdcb4,0xbe721c92,4
+np.float32,0x3f4379f0,0x3f5e6c31,4
+np.float32,0xbf680098,0xbf913257,4
+np.float32,0xbf3c31ca,0xbf536bea,4
+np.float32,0x3f59db58,0x3f824a4e,4
+np.float32,0xbf3ffc84,0xbf591554,4
+np.float32,0x3d1d5160,0x3d1d5b48,4
+np.float32,0x3f6c64ae,0x3f96a3da,4
+np.float32,0xbf1b49fd,0xbf26daaa,4
+np.float32,0x3ec80be0,0x3ecd8576,4
+np.float32,0x3f3becc0,0x3f530629,4
+np.float32,0xbea93890,0xbeac76c1,4
+np.float32,0x3f5b3acc,0x3f839bbd,4
+np.float32,0xbf5d6818,0xbf85bef9,4
+np.float32,0x3f794266,0x3fab9fa6,4
+np.float32,0xbee8eb7c,0xbef1cf3b,4
+np.float32,0xbf360a06,0xbf4a821e,4
+np.float32,0x3f441cf6,0x3f5f693d,4
+np.float32,0x3e60de40,0x3e62b742,4
+np.float32,0xbebb3d7e,0xbebfafdc,4
+np.float32,0x3e56a3a0,0x3e583e28,4
+np.float32,0x3f375bfe,0x3f4c6499,4
+np.float32,0xbf384d7d,0xbf4dbf9a,4
+np.float32,0x3efb03a4,0x3f032c06,4
+np.float32,0x3f1d5d10,0x3f29794d,4
+np.float32,0xbe25f7dc,0xbe26b41d,4
+np.float32,0x3f6d2f88,0x3f97aebb,4
+np.float32,0xbe9fa100,0xbea255cb,4
+np.float32,0xbf21dafa,0xbf2f382a,4
+np.float32,0x3d3870e0,0x3d3880d9,4
+np.float32,0x3eeaf00c,0x3ef413f4,4
+np.float32,0xbc884ea0,0xbc88503c,4
+np.float32,0xbf7dbdad,0xbfb80b6d,4
+np.float32,0xbf4eb713,0xbf709b46,4
+np.float32,0xbf1c0ad4,0xbf27cd92,4
+np.float32,0x3f323088,0x3f451737,4
+np.float32,0x3e405d88,0x3e4183e1,4
+np.float32,0x3d7ad580,0x3d7afdb4,4
+np.float32,0xbf207338,0xbf2d6927,4
+np.float32,0xbecf7948,0xbed59e1a,4
+np.float32,0x3f16ff94,0x3f217fde,4
+np.float32,0xbdf19588,0xbdf225dd,4
+np.float32,0xbf4d9654,0xbf6eb442,4
+np.float32,0xbf390b9b,0xbf4ed220,4
+np.float32,0xbe155a74,0xbe15e354,4
+np.float32,0x3f519e4c,0x3f759850,4
+np.float32,0xbee3f08c,0xbeec3b84,4
+np.float32,0xbf478be7,0xbf64d23b,4
+np.float32,0xbefdee50,0xbf04d92a,4
+np.float32,0x3e8def78,0x3e8fd1bc,4
+np.float32,0x3e3df2a8,0x3e3f0dee,4
+np.float32,0xbf413e22,0xbf5afd97,4
+np.float32,0xbf1b8bc4,0xbf272d71,4
+np.float32,0xbf31e5be,0xbf44af22,4
+np.float32,0x3de7e080,0x3de86010,4
+np.float32,0xbf5ddf7e,0xbf863645,4
+np.float32,0x3f3eba6a,0x3f57306e,4
+np.float32,0xff7fffff,0x7fc00000,4
+np.float32,0x3ec22d5c,0x3ec72973,4
+np.float32,0x80800000,0x80800000,4
+np.float32,0x3f032e0c,0x3f09ba82,4
+np.float32,0x3d74bd60,0x3d74e2b7,4
+np.float32,0xbea0d61e,0xbea39b42,4
+np.float32,0xbefdfa78,0xbf04e02a,4
+np.float32,0x3e5cb220,0x3e5e70ec,4
+np.float32,0xbe239e54,0xbe2452a4,4
+np.float32,0x3f452738,0x3f61090e,4
+np.float32,0x3e99a2e0,0x3e9c0a66,4
+np.float32,0x3e4394d8,0x3e44ca5f,4
+np.float32,0x3f4472e2,0x3f5fef14,4
+np.float32,0xbf46bc70,0xbf638814,4
+np.float32,0xbf0b910f,0xbf139c7a,4
+np.float32,0x3f36b4a6,0x3f4b753f,4
+np.float32,0x3e0bf478,0x3e0c64f6,4
+np.float32,0x3ce02480,0x3ce02ba9,4
+np.float32,0xbd904b10,0xbd9069b1,4
+np.float32,0xbf7f5d72,0xbfc00b70,4
+np.float32,0x3f62127e,0x3f8a8ca8,4
+np.float32,0xbf320253,0xbf44d6e4,4
+np.float32,0x3f2507be,0x3f335833,4
+np.float32,0x3f299284,0x3f395887,4
+np.float32,0xbd8211b0,0xbd82281d,4
+np.float32,0xbd3374c0,0xbd338376,4
+np.float32,0x3f36c56a,0x3f4b8d30,4
+np.float32,0xbf51f704,0xbf76331f,4
+np.float32,0xbe9871ca,0xbe9acab2,4
+np.float32,0xbe818d8c,0xbe82fa0f,4
+np.float32,0x3f08b958,0x3f103c18,4
+np.float32,0x3f22559a,0x3f2fd698,4
+np.float32,0xbf11f388,0xbf1b4db8,4
+np.float32,0x3ebe1990,0x3ec2c359,4
+np.float32,0xbe75ab38,0xbe7816b6,4
+np.float32,0x3e96102c,0x3e984c99,4
+np.float32,0xbe80d9d2,0xbe824052,4
+np.float32,0x3ef47588,0x3efeda7f,4
+np.float32,0xbe45e524,0xbe4725ea,4
+np.float32,0x3f7f9e7a,0x3fc213ff,4
+np.float32,0x3f1d3c36,0x3f294faa,4
+np.float32,0xbf3c58db,0xbf53a591,4
+np.float32,0x3f0d3d20,0x3f159c69,4
+np.float32,0x3f744be6,0x3fa23552,4
+np.float32,0x3f2e0cea,0x3f3f630e,4
+np.float32,0x3e193c10,0x3e19cff7,4
+np.float32,0xbf4150ac,0xbf5b19dd,4
+np.float32,0xbf145f72,0xbf1e4355,4
+np.float32,0xbb76cc00,0xbb76cc26,4
+np.float32,0x3f756780,0x3fa41b3e,4
+np.float32,0x3ea9b868,0x3eacfe3c,4
+np.float32,0x3d07c920,0x3d07cf7f,4
+np.float32,0xbf2263d4,0xbf2fe8ff,4
+np.float32,0x3e53b3f8,0x3e553daa,4
+np.float32,0xbf785be8,0xbfa9b5ba,4
+np.float32,0x3f324f7a,0x3f454254,4
+np.float32,0xbf2188f2,0xbf2ece5b,4
+np.float32,0xbe33781c,0xbe3466a2,4
+np.float32,0xbd3cf120,0xbd3d024c,4
+np.float32,0x3f06b18a,0x3f0dd70f,4
+np.float32,0x3f40d63e,0x3f5a5f6a,4
+np.float32,0x3f752340,0x3fa3a41e,4
+np.float32,0xbe1cf1c0,0xbe1d90bc,4
+np.float32,0xbf02d948,0xbf0957d7,4
+np.float32,0x3f73bed0,0x3fa14bf7,4
+np.float32,0x3d914920,0x3d916864,4
+np.float32,0x7fa00000,0x7fe00000,4
+np.float32,0xbe67a5d8,0xbe69aba7,4
+np.float32,0x3f689c4a,0x3f91eb9f,4
+np.float32,0xbf196e00,0xbf248601,4
+np.float32,0xbf50dacb,0xbf7444fe,4
+np.float32,0x3f628b86,0x3f8b0e1e,4
+np.float32,0x3f6ee2f2,0x3f99fe7f,4
+np.float32,0x3ee5df40,0x3eee6492,4
+np.float32,0x3f501746,0x3f72f41b,4
+np.float32,0xbf1f0f18,0xbf2ba164,4
+np.float32,0xbf1a8bfd,0xbf25ec01,4
+np.float32,0xbd4926f0,0xbd493ba9,4
+np.float32,0xbf4e364f,0xbf6fc17b,4
+np.float32,0x3e50c578,0x3e523ed4,4
+np.float32,0x3f65bf10,0x3f8e95ce,4
+np.float32,0xbe8d75a2,0xbe8f52f2,4
+np.float32,0xbf3f557e,0xbf581962,4
+np.float32,0xbeff2bfc,0xbf05903a,4
+np.float32,0x3f5e8bde,0x3f86e3d8,4
+np.float32,0xbf7a0012,0xbfad4b9b,4
+np.float32,0x3edefce0,0x3ee6b790,4
+np.float32,0xbf0003de,0xbf060f09,4
+np.float32,0x3efc4650,0x3f03e548,4
+np.float32,0x3f4582e4,0x3f6198f5,4
+np.float32,0x3f10086c,0x3f18f9d0,4
+np.float32,0x3f1cd304,0x3f28ca77,4
+np.float32,0x3f683366,0x3f916e8d,4
+np.float32,0xbed49392,0xbedb3675,4
+np.float32,0xbf6fe5f6,0xbf9b6c0e,4
+np.float32,0xbf59b416,0xbf8224f6,4
+np.float32,0x3d20c960,0x3d20d3f4,4
+np.float32,0x3f6b00d6,0x3f94dbe7,4
+np.float32,0x3f6c26ae,0x3f965352,4
+np.float32,0xbf370ea6,0xbf4bf5dd,4
+np.float32,0x3dfe7230,0x3dff1af1,4
+np.float32,0xbefc21a8,0xbf03d038,4
+np.float32,0x3f16a990,0x3f21156a,4
+np.float32,0xbef8ac0c,0xbf01d48f,4
+np.float32,0x3f170de8,0x3f21919d,4
+np.float32,0x3db9ef80,0x3dba3122,4
+np.float32,0x3d696400,0x3d698461,4
+np.float32,0x3f007aa2,0x3f069843,4
+np.float32,0x3f22827c,0x3f3010a9,4
+np.float32,0x3f3650dc,0x3f4ae6f1,4
+np.float32,0xbf1d8037,0xbf29a5e1,4
+np.float32,0xbf08fdc4,0xbf108d0e,4
+np.float32,0xbd8df350,0xbd8e1079,4
+np.float32,0xbf36bb32,0xbf4b7e98,4
+np.float32,0x3f2e3756,0x3f3f9ced,4
+np.float32,0x3d5a6f20,0x3d5a89aa,4
+np.float32,0x3f55d568,0x3f7d1889,4
+np.float32,0x3e1ed110,0x3e1f75d9,4
+np.float32,0x3e7386b8,0x3e75e1dc,4
+np.float32,0x3f48ea0e,0x3f670434,4
+np.float32,0x3e921fb0,0x3e942f14,4
+np.float32,0xbf0d4d0b,0xbf15af7f,4
+np.float32,0x3f179ed2,0x3f224549,4
+np.float32,0xbf3a328e,0xbf507e6d,4
+np.float32,0xbf74591a,0xbfa24b6e,4
+np.float32,0x3ec7d1c4,0x3ecd4657,4
+np.float32,0xbf6ecbed,0xbf99de85,4
+np.float32,0x3db0bd00,0x3db0f559,4
+np.float32,0x7f800000,0x7fc00000,4
+np.float32,0x3e0373b8,0x3e03d0d6,4
+np.float32,0xbf439784,0xbf5e9a04,4
+np.float32,0xbef97a9e,0xbf024ac6,4
+np.float32,0x3e4d71a8,0x3e4ed90a,4
+np.float32,0xbf14d868,0xbf1ed7e3,4
+np.float32,0xbf776870,0xbfa7ce37,4
+np.float32,0xbe32a500,0xbe339038,4
+np.float32,0xbf326d8a,0xbf456c3d,4
+np.float32,0xbe9b758c,0xbe9df3e7,4
+np.float32,0x3d9515a0,0x3d95376a,4
+np.float32,0x3e3f7320,0x3e40953e,4
+np.float32,0xbee57e7e,0xbeedf84f,4
+np.float32,0x3e821e94,0x3e838ffd,4
+np.float32,0x3f74beaa,0x3fa2f721,4
+np.float32,0xbe9b7672,0xbe9df4d9,4
+np.float32,0x3f4041fc,0x3f597e71,4
+np.float32,0xbe9ea7c4,0xbea14f92,4
+np.float32,0xbf800000,0xbfc90fdb,4
+np.float32,0x3e04fb90,0x3e055bfd,4
+np.float32,0xbf14d3d6,0xbf1ed245,4
+np.float32,0xbe84ebec,0xbe86763e,4
+np.float32,0x3f08e568,0x3f107039,4
+np.float32,0x3d8dc9e0,0x3d8de6ef,4
+np.float32,0x3ea4549c,0x3ea74a94,4
+np.float32,0xbebd2806,0xbec1bf51,4
+np.float32,0x3f311a26,0x3f439498,4
+np.float32,0xbf3d2222,0xbf54cf7e,4
+np.float32,0x3e00c500,0x3e011c81,4
+np.float32,0xbe35ed1c,0xbe36e5a9,4
+np.float32,0xbd4ec020,0xbd4ed6a0,4
+np.float32,0x3e1eb088,0x3e1f54eb,4
+np.float32,0x3cf94840,0x3cf9521a,4
+np.float32,0xbf010c5d,0xbf0740e0,4
+np.float32,0xbf3bd63b,0xbf52e502,4
+np.float32,0x3f233f30,0x3f310542,4
+np.float32,0x3ea24128,0x3ea519d7,4
+np.float32,0x3f478b38,0x3f64d124,4
+np.float32,0x3f1e0c6c,0x3f2a57ec,4
+np.float32,0xbf3ad294,0xbf51680a,4
+np.float32,0x3ede0554,0x3ee5a4b4,4
+np.float32,0x3e451a98,0x3e46577d,4
+np.float32,0x3f520164,0x3f764542,4
+np.float32,0x0,0x0,4
+np.float32,0xbd056cd0,0xbd0572db,4
+np.float32,0xbf58b018,0xbf812f5e,4
+np.float32,0x3e036eb0,0x3e03cbc3,4
+np.float32,0x3d1377a0,0x3d137fc9,4
+np.float32,0xbf692d3a,0xbf929a2c,4
+np.float32,0xbec60fb8,0xbecb5dea,4
+np.float32,0x3ed23340,0x3ed89a8e,4
+np.float32,0x3c87f040,0x3c87f1d9,4
+np.float32,0x3dac62f0,0x3dac9737,4
+np.float32,0xbed97c16,0xbee09f02,4
+np.float32,0xbf2d5f3c,0xbf3e769c,4
+np.float32,0xbc3b7c40,0xbc3b7d4c,4
+np.float32,0x3ed998ec,0x3ee0bedd,4
+np.float32,0x3dd86630,0x3dd8cdcb,4
+np.float32,0x3e8b4304,0x3e8d09ea,4
+np.float32,0x3f51e6b0,0x3f761697,4
+np.float32,0x3ec51f24,0x3eca5923,4
+np.float32,0xbf647430,0xbf8d2307,4
+np.float32,0x3f253d9c,0x3f339eb2,4
+np.float32,0x3dc969d0,0x3dc9bd4b,4
+np.float32,0xbc2f1300,0xbc2f13da,4
+np.float32,0xbf170007,0xbf21806d,4
+np.float32,0x3f757d10,0x3fa4412e,4
+np.float32,0xbe7864ac,0xbe7ae564,4
+np.float32,0x3f2ffe90,0x3f420cfb,4
+np.float32,0xbe576138,0xbe590012,4
+np.float32,0xbf517a21,0xbf755959,4
+np.float32,0xbf159cfe,0xbf1fc9d5,4
+np.float32,0xbf638b2a,0xbf8c22cf,4
+np.float32,0xff800000,0x7fc00000,4
+np.float32,0x3ed19ca0,0x3ed7f569,4
+np.float32,0x3f7c4460,0x3fb32d26,4
+np.float32,0x3ebfae6c,0x3ec477ab,4
+np.float32,0x3dd452d0,0x3dd4b4a8,4
+np.float32,0x3f471482,0x3f6413fb,4
+np.float32,0xbf49d704,0xbf6883fe,4
+np.float32,0xbd42c4e0,0xbd42d7af,4
+np.float32,0xbeb02994,0xbeb3d668,4
+np.float32,0x3f4d1fd8,0x3f6dedd2,4
+np.float32,0x3efb591c,0x3f035d11,4
+np.float32,0x80000000,0x80000000,4
+np.float32,0xbf50f782,0xbf7476ad,4
+np.float32,0x3d7232c0,0x3d7256f0,4
+np.float32,0x3f649460,0x3f8d46bb,4
+np.float32,0x3f5561bc,0x3f7c46a9,4
+np.float32,0x3e64f6a0,0x3e66ea5d,4
+np.float32,0x3e5b0470,0x3e5cb8f9,4
+np.float32,0xbe9b6b2c,0xbe9de904,4
+np.float32,0x3f6c33f4,0x3f966486,4
+np.float32,0x3f5cee54,0x3f854613,4
+np.float32,0x3ed3e044,0x3eda716e,4
+np.float32,0xbf3cac7f,0xbf542131,4
+np.float32,0x3c723500,0x3c723742,4
+np.float32,0x3de59900,0x3de614d3,4
+np.float32,0xbdf292f8,0xbdf32517,4
+np.float32,0x3f05c8b2,0x3f0cc59b,4
+np.float32,0xbf1ab182,0xbf261b14,4
+np.float32,0xbda396f0,0xbda3c39a,4
+np.float32,0xbf270ed0,0xbf360231,4
+np.float32,0x3f2063e6,0x3f2d557e,4
+np.float32,0x3c550280,0x3c550409,4
+np.float32,0xbe103b48,0xbe10b679,4
+np.float32,0xbebae390,0xbebf4f40,4
+np.float32,0x3f3bc868,0x3f52d0aa,4
+np.float32,0xbd62f880,0xbd631647,4
+np.float32,0xbe7a38f4,0xbe7cc833,4
+np.float32,0x3f09d796,0x3f118f39,4
+np.float32,0xbf5fa558,0xbf8802d0,4
+np.float32,0x3f111cc8,0x3f1a48b0,4
+np.float32,0x3e831958,0x3e849356,4
+np.float32,0xbf614dbd,0xbf89bc3b,4
+np.float32,0xbd521510,0xbd522cac,4
+np.float32,0x3f05af22,0x3f0ca7a0,4
+np.float32,0xbf1ac60e,0xbf2634df,4
+np.float32,0xbf6bd05e,0xbf95e3fe,4
+np.float32,0xbd1fa6e0,0xbd1fb13b,4
+np.float32,0xbeb82f7a,0xbebc68b1,4
+np.float32,0xbd92aaf8,0xbd92cb23,4
+np.float32,0xbe073a54,0xbe079fbf,4
+np.float32,0xbf198655,0xbf24a468,4
+np.float32,0x3f62f6d8,0x3f8b81ba,4
+np.float32,0x3eef4310,0x3ef8f4f9,4
+np.float32,0x3e8988e0,0x3e8b3eae,4
+np.float32,0xbf3ddba5,0xbf55e367,4
+np.float32,0x3dc6d2e0,0x3dc7232b,4
+np.float32,0xbf31040e,0xbf437601,4
+np.float32,0x3f1bb74a,0x3f276442,4
+np.float32,0xbf0075d2,0xbf0692b3,4
+np.float32,0xbf606ce0,0xbf88d0ff,4
+np.float32,0xbf083856,0xbf0fa39d,4
+np.float32,0xbdb25b20,0xbdb2950a,4
+np.float32,0xbeb86860,0xbebca5ae,4
+np.float32,0x3de83160,0x3de8b176,4
+np.float32,0xbf33a98f,0xbf472664,4
+np.float32,0x3e7795f8,0x3e7a1058,4
+np.float32,0x3e0ca6f8,0x3e0d192a,4
+np.float32,0xbf1aef60,0xbf2668c3,4
+np.float32,0xbda53b58,0xbda5695e,4
+np.float32,0xbf178096,0xbf221fc5,4
+np.float32,0xbf0a4159,0xbf120ccf,4
+np.float32,0x3f7bca36,0x3fb1d0df,4
+np.float32,0xbef94360,0xbf022b26,4
+np.float32,0xbef16f36,0xbefb6ad6,4
+np.float32,0x3f53a7e6,0x3f792e25,4
+np.float32,0xbf7c536f,0xbfb35993,4
+np.float32,0xbe84aaa0,0xbe8632a2,4
+np.float32,0x3ecb3998,0x3ed0fab9,4
+np.float32,0x3f539304,0x3f79090a,4
+np.float32,0xbf3c7816,0xbf53d3b3,4
+np.float32,0xbe7a387c,0xbe7cc7b7,4
+np.float32,0x3f7000e4,0x3f9b92b1,4
+np.float32,0x3e08fd70,0x3e0966e5,4
+np.float32,0x3db97ba0,0x3db9bcc8,4
+np.float32,0xbee99056,0xbef2886a,4
+np.float32,0xbf0668da,0xbf0d819e,4
+np.float32,0x3e58a408,0x3e5a4a51,4
+np.float32,0x3f3440b8,0x3f47faed,4
+np.float32,0xbf19a2ce,0xbf24c7ff,4
+np.float32,0xbe75e990,0xbe7856ee,4
+np.float32,0x3f3c865c,0x3f53e8cb,4
+np.float32,0x3e5e03d0,0x3e5fcac9,4
+np.float32,0x3edb8e34,0x3ee2e932,4
+np.float32,0xbf7e1f5f,0xbfb98ce4,4
+np.float32,0xbf7372ff,0xbfa0d0ae,4
+np.float32,0xbf3ee850,0xbf577548,4
+np.float32,0x3ef19658,0x3efb9737,4
+np.float32,0xbe8088de,0xbe81ecaf,4
+np.float32,0x800000,0x800000,4
+np.float32,0xbde39dd8,0xbde4167a,4
+np.float32,0xbf065d7a,0xbf0d7441,4
+np.float32,0xbde52c78,0xbde5a79b,4
+np.float32,0xbe3a28c0,0xbe3b333e,4
+np.float32,0x3f6e8b3c,0x3f998516,4
+np.float32,0x3f3485c2,0x3f485c39,4
+np.float32,0x3e6f2c68,0x3e71673e,4
+np.float32,0xbe4ec9cc,0xbe50385e,4
+np.float32,0xbf1c3bb0,0xbf280b39,4
+np.float32,0x3ec8ea18,0x3ece76f7,4
+np.float32,0x3e26b5f8,0x3e2774c9,4
+np.float32,0x3e1e4a38,0x3e1eed5c,4
+np.float32,0xbee7a106,0xbef05c6b,4
+np.float32,0xbf305928,0xbf4289d8,4
+np.float32,0x3f0c431c,0x3f147118,4
+np.float32,0xbe57ba6c,0xbe595b52,4
+np.float32,0x3eabc9cc,0x3eaf2fc7,4
+np.float32,0xbef1ed24,0xbefbf9ae,4
+np.float32,0xbf61b576,0xbf8a29cc,4
+np.float32,0x3e9c1ff4,0x3e9ea6cb,4
+np.float32,0x3f6c53b2,0x3f968dbe,4
+np.float32,0x3e2d1b80,0x3e2df156,4
+np.float32,0x3e9f2f70,0x3ea1de4a,4
+np.float32,0xbf5861ee,0xbf80e61a,4
+np.float32,0x3f429144,0x3f5d0505,4
+np.float32,0x3e235cc8,0x3e24103e,4
+np.float32,0xbf354879,0xbf496f6a,4
+np.float32,0xbf20a146,0xbf2da447,4
+np.float32,0x3e8d8968,0x3e8f6785,4
+np.float32,0x3f3fbc94,0x3f58b4c1,4
+np.float32,0x3f2c5f50,0x3f3d1b9f,4
+np.float32,0x3f7bf0f8,0x3fb23d23,4
+np.float32,0xbf218282,0xbf2ec60f,4
+np.float32,0x3f2545aa,0x3f33a93e,4
+np.float32,0xbf4b17be,0xbf6a9018,4
+np.float32,0xbb9df700,0xbb9df728,4
+np.float32,0x3f685d54,0x3f91a06c,4
+np.float32,0x3efdfe2c,0x3f04e24c,4
+np.float32,0x3ef1c5a0,0x3efbccd9,4
+np.float32,0xbf41d731,0xbf5be76e,4
+np.float32,0x3ebd1360,0x3ec1a919,4
+np.float32,0xbf706bd4,0xbf9c2d58,4
+np.float32,0x3ea525e4,0x3ea8279d,4
+np.float32,0xbe51f1b0,0xbe537186,4
+np.float32,0x3f5e8cf6,0x3f86e4f4,4
+np.float32,0xbdad2520,0xbdad5a19,4
+np.float32,0xbf5c5704,0xbf84b0e5,4
+np.float32,0x3f47b54e,0x3f65145e,4
+np.float32,0x3eb4fc78,0x3eb8fc0c,4
+np.float32,0x3dca1450,0x3dca68a1,4
+np.float32,0x3eb02a74,0x3eb3d757,4
+np.float32,0x3f74ae6a,0x3fa2db75,4
+np.float32,0x3f800000,0x3fc90fdb,4
+np.float32,0xbdb46a00,0xbdb4a5f2,4
+np.float32,0xbe9f2ba6,0xbea1da4e,4
+np.float32,0x3f0afa70,0x3f12e8f7,4
+np.float32,0xbf677b20,0xbf909547,4
+np.float32,0x3eff9188,0x3f05cacf,4
+np.float32,0x3f720562,0x3f9e911b,4
+np.float32,0xbf7180d8,0xbf9dc794,4
+np.float32,0xbee7d076,0xbef0919d,4
+np.float32,0x3f0432ce,0x3f0aea95,4
+np.float32,0x3f3bc4c8,0x3f52cb54,4
+np.float32,0xbea72f30,0xbeaa4ebe,4
+np.float32,0x3e90ed00,0x3e92ef33,4
+np.float32,0xbda63670,0xbda6654a,4
+np.float32,0xbf5a6f85,0xbf82d7e0,4
+np.float32,0x3e6e8808,0x3e70be34,4
+np.float32,0xbf4f3822,0xbf71768f,4
+np.float32,0x3e5c8a68,0x3e5e483f,4
+np.float32,0xbf0669d4,0xbf0d82c4,4
+np.float32,0xbf79f77c,0xbfad37b0,4
+np.float32,0x3f25c82c,0x3f345453,4
+np.float32,0x3f1b2948,0x3f26b188,4
+np.float32,0x3ef7e288,0x3f016159,4
+np.float32,0x3c274280,0x3c27433e,4
+np.float32,0xbf4c8fa0,0xbf6cfd5e,4
+np.float32,0x3ea4ccb4,0x3ea7c966,4
+np.float32,0xbf7b157e,0xbfafefca,4
+np.float32,0xbee4c2b0,0xbeed264d,4
+np.float32,0xbc1fd640,0xbc1fd6e6,4
+np.float32,0x3e892308,0x3e8ad4f6,4
+np.float32,0xbf3f69c7,0xbf5837ed,4
+np.float32,0x3ec879e8,0x3ecdfd05,4
+np.float32,0x3f07a8c6,0x3f0efa30,4
+np.float32,0x3f67b880,0x3f90dd4d,4
+np.float32,0x3e8a11c8,0x3e8bccd5,4
+np.float32,0x3f7df6fc,0x3fb8e935,4
+np.float32,0xbef3e498,0xbefe3599,4
+np.float32,0xbf18ad7d,0xbf2395d8,4
+np.float32,0x3f2bce74,0x3f3c57f5,4
+np.float32,0xbf38086e,0xbf4d5c2e,4
+np.float32,0x3f772d7a,0x3fa75c35,4
+np.float32,0xbf3b6e24,0xbf524c00,4
+np.float32,0xbdd39108,0xbdd3f1d4,4
+np.float32,0xbf691f6b,0xbf928974,4
+np.float32,0x3f146188,0x3f1e45e4,4
+np.float32,0xbf56045b,0xbf7d6e03,4
+np.float32,0xbf4b2ee4,0xbf6ab622,4
+np.float32,0xbf3fa3f6,0xbf588f9d,4
+np.float32,0x3f127bb0,0x3f1bf398,4
+np.float32,0x3ed858a0,0x3edf5d3e,4
+np.float32,0xbd6de3b0,0xbd6e05fa,4
+np.float32,0xbecc662c,0xbed24261,4
+np.float32,0xbd6791d0,0xbd67b170,4
+np.float32,0xbf146016,0xbf1e441e,4
+np.float32,0xbf61f04c,0xbf8a6841,4
+np.float32,0xbe7f16d0,0xbe80e6e7,4
+np.float32,0xbebf93e6,0xbec45b10,4
+np.float32,0xbe8a59fc,0xbe8c17d1,4
+np.float32,0xbebc7a0c,0xbec10426,4
+np.float32,0xbf2a682e,0xbf3a7649,4
+np.float32,0xbe18d0cc,0xbe19637b,4
+np.float32,0x3d7f5100,0x3d7f7b66,4
+np.float32,0xbf10f5fa,0xbf1a1998,4
+np.float32,0x3f25e956,0x3f347fdc,4
+np.float32,0x3e6e8658,0x3e70bc78,4
+np.float32,0x3f21a5de,0x3f2ef3a5,4
+np.float32,0xbf4e71d4,0xbf702607,4
+np.float32,0xbf49d6b6,0xbf688380,4
+np.float32,0xbdb729c0,0xbdb7687c,4
+np.float32,0xbf63e1f4,0xbf8c81c7,4
+np.float32,0x3dda6cb0,0x3ddad73e,4
+np.float32,0x3ee1bc40,0x3ee9c612,4
+np.float32,0x3ebdb5f8,0x3ec2581b,4
+np.float32,0x3f7d9576,0x3fb77646,4
+np.float32,0x3e087140,0x3e08d971,4
+np.float64,0xbfdba523cfb74a48,0xbfdc960ddd9c0506,3
+np.float64,0x3fb51773622a2ee0,0x3fb51d93f77089d5,3
+np.float64,0x3fc839f6d33073f0,0x3fc85f9a47dfe8e6,3
+np.float64,0xbfecba2d82f9745b,0xbff1d55416c6c993,3
+np.float64,0x3fd520fe47aa41fc,0x3fd58867f1179634,3
+np.float64,0x3fe1b369c56366d4,0x3fe2c1ac9dd2c45a,3
+np.float64,0xbfec25a7cd784b50,0xbff133417389b12d,3
+np.float64,0xbfd286342ea50c68,0xbfd2cb0bca22e66d,3
+np.float64,0x3fd5f6fe5eabedfc,0x3fd66bad16680d08,3
+np.float64,0xbfe863a87570c751,0xbfebbb9b637eb6dc,3
+np.float64,0x3fc97f5b4d32feb8,0x3fc9ab5066d8eaec,3
+np.float64,0xbfcb667af936ccf4,0xbfcb9d3017047a1d,3
+np.float64,0xbfd1b7b9afa36f74,0xbfd1f3c175706154,3
+np.float64,0x3fef97385b7f2e70,0x3ff6922a1a6c709f,3
+np.float64,0xbfd13e4205a27c84,0xbfd1757c993cdb74,3
+np.float64,0xbfd18d88aca31b12,0xbfd1c7dd75068f7d,3
+np.float64,0x3fe040ce0f60819c,0x3fe10c59d2a27089,3
+np.float64,0xbfddc7deddbb8fbe,0xbfdef9de5baecdda,3
+np.float64,0xbfcf6e96193edd2c,0xbfcfc1bb7396b9a3,3
+np.float64,0x3fd544f494aa89e8,0x3fd5ae850e2b37dd,3
+np.float64,0x3fe15b381fe2b670,0x3fe25841c7bfe2af,3
+np.float64,0xbfde793420bcf268,0xbfdfc2ddc7b4a341,3
+np.float64,0x3fd0d5db30a1abb8,0x3fd1092cef4aa4fb,3
+np.float64,0x3fe386a08c670d42,0x3fe50059bbf7f491,3
+np.float64,0xbfe0aae3a96155c8,0xbfe1880ef13e95ce,3
+np.float64,0xbfe80eeb03f01dd6,0xbfeb39e9f107e944,3
+np.float64,0xbfd531af3caa635e,0xbfd59a178f17552a,3
+np.float64,0x3fcced14ab39da28,0x3fcd2d9a806337ef,3
+np.float64,0xbfdb4c71bcb698e4,0xbfdc33d9d9daf708,3
+np.float64,0xbfde7375ecbce6ec,0xbfdfbc5611bc48ff,3
+np.float64,0x3fecc5707a798ae0,0x3ff1e2268d778017,3
+np.float64,0x3fe8f210a1f1e422,0x3fec9b3349a5baa2,3
+np.float64,0x3fe357f9b8e6aff4,0x3fe4c5a0b89a9228,3
+np.float64,0xbfe0f863b761f0c8,0xbfe1e3283494c3d4,3
+np.float64,0x3fd017c395a02f88,0x3fd044761f2f4a66,3
+np.float64,0x3febeb4746f7d68e,0x3ff0f6b955e7feb6,3
+np.float64,0xbfbdaaeeae3b55e0,0xbfbdbc0950109261,3
+np.float64,0xbfea013095f40261,0xbfee5b8fe8ad8593,3
+np.float64,0xbfe9f87b7973f0f7,0xbfee4ca3a8438d72,3
+np.float64,0x3fd37f77cfa6fef0,0x3fd3d018c825f057,3
+np.float64,0x3fb0799cee20f340,0x3fb07c879e7cb63f,3
+np.float64,0xbfdcfd581cb9fab0,0xbfde15e35314b52d,3
+np.float64,0xbfd49781b8a92f04,0xbfd4f6fa1516fefc,3
+np.float64,0x3fb3fcb6d627f970,0x3fb401ed44a713a8,3
+np.float64,0x3fd5737ef8aae6fc,0x3fd5dfe42d4416c7,3
+np.float64,0x7ff4000000000000,0x7ffc000000000000,3
+np.float64,0xbfe56ae780ead5cf,0xbfe776ea5721b900,3
+np.float64,0x3fd4567786a8acf0,0x3fd4b255421c161a,3
+np.float64,0x3fef6fb58cfedf6c,0x3ff62012dfcf0a33,3
+np.float64,0xbfd1dbcd3da3b79a,0xbfd2194fd628f74d,3
+np.float64,0x3fd9350016b26a00,0x3fd9e8b01eb023e9,3
+np.float64,0xbfe4fb3a69e9f675,0xbfe6e1d2c9eca56c,3
+np.float64,0x3fe9fe0f73f3fc1e,0x3fee5631cfd39772,3
+np.float64,0xbfd51c1bc6aa3838,0xbfd5833b3bd53543,3
+np.float64,0x3fc64158e12c82b0,0x3fc65e7352f237d7,3
+np.float64,0x3fd0d8ee1ba1b1dc,0x3fd10c5c99a16f0e,3
+np.float64,0x3fd5554e15aaaa9c,0x3fd5bfdb9ec9e873,3
+np.float64,0x3fe61ce209ec39c4,0x3fe869bc4c28437d,3
+np.float64,0xbfe4e42c8c69c859,0xbfe6c356dac7e2db,3
+np.float64,0xbfe157021062ae04,0xbfe2533ed39f4212,3
+np.float64,0x3fe844066cf0880c,0x3feb8aea0b7bd0a4,3
+np.float64,0x3fe55016586aa02c,0x3fe752e4b2a67b9f,3
+np.float64,0x3fdabce619b579cc,0x3fdb95809bc789d9,3
+np.float64,0x3fee03bae37c0776,0x3ff3778ba38ca882,3
+np.float64,0xbfeb2f5844f65eb0,0xbff03dd1b767d3c8,3
+np.float64,0x3fedcfdbaffb9fb8,0x3ff32e81d0639164,3
+np.float64,0x3fe06fc63ee0df8c,0x3fe142fc27f92eaf,3
+np.float64,0x3fe7ce90fd6f9d22,0x3fead8f832bbbf5d,3
+np.float64,0xbfbc0015ce380028,0xbfbc0e7470e06e86,3
+np.float64,0xbfe9b3de90f367bd,0xbfedd857931dfc6b,3
+np.float64,0xbfcb588f5936b120,0xbfcb8ef0124a4f21,3
+np.float64,0x3f8d376a503a6f00,0x3f8d37ab43e7988d,3
+np.float64,0xbfdb123a40b62474,0xbfdbf38b6cf5db92,3
+np.float64,0xbfee7da6be7cfb4e,0xbff433042cd9d5eb,3
+np.float64,0xbfc4c9e01b2993c0,0xbfc4e18dbafe37ef,3
+np.float64,0x3fedd42faffba860,0x3ff334790cd18a19,3
+np.float64,0x3fe9cdf772f39bee,0x3fee044f87b856ab,3
+np.float64,0x3fe0245881e048b2,0x3fe0eb5a1f739c8d,3
+np.float64,0xbfe4712bd9e8e258,0xbfe62cb3d82034aa,3
+np.float64,0x3fe9a16b46f342d6,0x3fedb972b2542551,3
+np.float64,0xbfe57ab4536af568,0xbfe78c34b03569c2,3
+np.float64,0x3fb6d6ceb22dada0,0x3fb6de976964d6dd,3
+np.float64,0x3fc3ac23a3275848,0x3fc3c02de53919b8,3
+np.float64,0xbfccb531e7396a64,0xbfccf43ec69f6281,3
+np.float64,0xbfd2f07fc8a5e100,0xbfd33a35a8c41b62,3
+np.float64,0xbfe3e5dd04e7cbba,0xbfe57940157c27ba,3
+np.float64,0x3feefe40757dfc80,0x3ff51bc72b846af6,3
+np.float64,0x8000000000000001,0x8000000000000001,3
+np.float64,0x3fecb7b766796f6e,0x3ff1d28972a0fc7e,3
+np.float64,0xbfea1bf1357437e2,0xbfee89a6532bfd71,3
+np.float64,0xbfca3983b7347308,0xbfca696463b791ef,3
+np.float64,0x10000000000000,0x10000000000000,3
+np.float64,0xbf886b45d030d680,0xbf886b6bbc04314b,3
+np.float64,0x3fd5224bb5aa4498,0x3fd589c92e82218f,3
+np.float64,0xbfec799874f8f331,0xbff18d5158b8e640,3
+np.float64,0xbf88124410302480,0xbf88126863350a16,3
+np.float64,0xbfe37feaaa66ffd6,0xbfe4f7e24382e79d,3
+np.float64,0x3fd777eca1aeefd8,0x3fd8076ead6d55dc,3
+np.float64,0x3fecaaeb3af955d6,0x3ff1c4159fa3e965,3
+np.float64,0xbfeb81e4e6f703ca,0xbff08d4e4c77fada,3
+np.float64,0xbfd7d0a0edafa142,0xbfd866e37010312e,3
+np.float64,0x3feda48c00fb4918,0x3ff2f3fd33c36307,3
+np.float64,0x3feb87ecc4770fda,0x3ff09336e490deda,3
+np.float64,0xbfefd78ad27faf16,0xbff78abbafb50ac1,3
+np.float64,0x3fe58e918c6b1d24,0x3fe7a70b38cbf016,3
+np.float64,0x3fda163b95b42c78,0x3fdade86b88ba4ee,3
+np.float64,0x3fe8fc1aaf71f836,0x3fecab3f93b59df5,3
+np.float64,0xbf8de56f903bcac0,0xbf8de5b527cec797,3
+np.float64,0xbfec112db2f8225b,0xbff11dd648de706f,3
+np.float64,0x3fc3214713264290,0x3fc333b1c862f7d0,3
+np.float64,0xbfeb5e5836f6bcb0,0xbff06ac364b49177,3
+np.float64,0x3fc23d9777247b30,0x3fc24d8ae3bcb615,3
+np.float64,0xbfdf0eed65be1dda,0xbfe036cea9b9dfb6,3
+np.float64,0xbfb2d5c85a25ab90,0xbfb2da24bb409ff3,3
+np.float64,0xbfecdda0c3f9bb42,0xbff1fdf94fc6e89e,3
+np.float64,0x3fdfe79154bfcf24,0x3fe0b338e0476a9d,3
+np.float64,0xbfd712ac6bae2558,0xbfd79abde21f287b,3
+np.float64,0x3fea3f148a747e2a,0x3feec6bed9d4fa04,3
+np.float64,0x3fd4879e4ca90f3c,0x3fd4e632fa4e2edd,3
+np.float64,0x3fe9137a9e7226f6,0x3fecd0c441088d6a,3
+np.float64,0xbfc75bf4ef2eb7e8,0xbfc77da8347d742d,3
+np.float64,0xbfd94090a0b28122,0xbfd9f5458816ed5a,3
+np.float64,0x3fde439cbcbc8738,0x3fdf85fbf496b61f,3
+np.float64,0xbfe18bacdce3175a,0xbfe29210e01237f7,3
+np.float64,0xbfd58ec413ab1d88,0xbfd5fcd838f0a934,3
+np.float64,0xbfeae5af2d75cb5e,0xbfeff1de1b4a06be,3
+np.float64,0x3fb64d1a162c9a30,0x3fb65458fb831354,3
+np.float64,0x3fc18b1e15231640,0x3fc1994c6ffd7a6a,3
+np.float64,0xbfd7b881bcaf7104,0xbfd84ce89a9ee8c7,3
+np.float64,0x3feb916a40f722d4,0x3ff09c8aa851d7c4,3
+np.float64,0x3fdab5fbb5b56bf8,0x3fdb8de43961bbde,3
+np.float64,0x3fe4f35402e9e6a8,0x3fe6d75dc5082894,3
+np.float64,0x3fe2fdb2e5e5fb66,0x3fe454e32a5d2182,3
+np.float64,0x3fe8607195f0c0e4,0x3febb6a4c3bf6a5c,3
+np.float64,0x3fd543ca9aaa8794,0x3fd5ad49203ae572,3
+np.float64,0x3fe8e05ca1f1c0ba,0x3fec7eff123dcc58,3
+np.float64,0x3fe298b6ca65316e,0x3fe3d81d2927c4dd,3
+np.float64,0x3fcfecea733fd9d8,0x3fd0220f1d0faf78,3
+np.float64,0xbfe2e739f065ce74,0xbfe439004e73772a,3
+np.float64,0xbfd1ae6b82a35cd8,0xbfd1ea129a5ee756,3
+np.float64,0xbfeb7edff576fdc0,0xbff08a5a638b8a8b,3
+np.float64,0x3fe5b645ff6b6c8c,0x3fe7dcee1faefe3f,3
+np.float64,0xbfd478427ba8f084,0xbfd4d5fc7c239e60,3
+np.float64,0xbfe39904e3e7320a,0xbfe517972b30b1e5,3
+np.float64,0xbfd3b75b6ba76eb6,0xbfd40acf20a6e074,3
+np.float64,0x3fd596267aab2c4c,0x3fd604b01faeaf75,3
+np.float64,0x3fe134463762688c,0x3fe229fc36784a72,3
+np.float64,0x3fd25dadf7a4bb5c,0x3fd2a0b9e04ea060,3
+np.float64,0xbfc05d3e0b20ba7c,0xbfc068bd2bb9966f,3
+np.float64,0x3f8cf517b039ea00,0x3f8cf556ed74b163,3
+np.float64,0x3fda87361cb50e6c,0x3fdb5a75af897e7f,3
+np.float64,0x3fe53e1926ea7c32,0x3fe73acf01b8ff31,3
+np.float64,0x3fe2e94857e5d290,0x3fe43b8cc820f9c7,3
+np.float64,0x3fd81fe6acb03fcc,0x3fd8bc623c0068cf,3
+np.float64,0xbfddf662c3bbecc6,0xbfdf2e76dc90786e,3
+np.float64,0x3fece174fbf9c2ea,0x3ff2026a1a889580,3
+np.float64,0xbfdc83c5b8b9078c,0xbfdd8dcf6ee3b7da,3
+np.float64,0x3feaf5448f75ea8a,0x3ff0075b108bcd0d,3
+np.float64,0xbfebf32f7ef7e65f,0xbff0fed42aaa826a,3
+np.float64,0x3fe389e5e8e713cc,0x3fe5047ade055ccb,3
+np.float64,0x3f635cdcc026ba00,0x3f635cddeea082ce,3
+np.float64,0x3fae580f543cb020,0x3fae5c9d5108a796,3
+np.float64,0x3fec9fafce793f60,0x3ff1b77bec654f00,3
+np.float64,0x3fb19d226e233a40,0x3fb1a0b32531f7ee,3
+np.float64,0xbfdf9a71e7bf34e4,0xbfe086cef88626c7,3
+np.float64,0x8010000000000000,0x8010000000000000,3
+np.float64,0xbfef170ba2fe2e17,0xbff54ed4675f5b8a,3
+np.float64,0xbfcc6e2f8f38dc60,0xbfccab65fc34d183,3
+np.float64,0x3fee756c4bfcead8,0x3ff4258782c137e6,3
+np.float64,0xbfd461c218a8c384,0xbfd4be3e391f0ff4,3
+np.float64,0xbfe3b64686e76c8d,0xbfe53caa16d6c90f,3
+np.float64,0xbfc1c65d8d238cbc,0xbfc1d51e58f82403,3
+np.float64,0x3fe6e06c63edc0d8,0x3fe97cb832eeb6a2,3
+np.float64,0xbfc9fc20b933f840,0xbfca2ab004312d85,3
+np.float64,0xbfe29aa6df65354e,0xbfe3da7ecf3ba466,3
+np.float64,0x3fea4df7d1749bf0,0x3feee0d448bd4746,3
+np.float64,0xbfedec6161fbd8c3,0xbff3563e1d943aa2,3
+np.float64,0x3fdb6f0437b6de08,0x3fdc5a1888b1213d,3
+np.float64,0xbfe270cbd3e4e198,0xbfe3a72ac27a0b0c,3
+np.float64,0xbfdfff8068bfff00,0xbfe0c1088e3b8983,3
+np.float64,0xbfd28edbe6a51db8,0xbfd2d416c8ed363e,3
+np.float64,0xbfb4e35f9229c6c0,0xbfb4e9531d2a737f,3
+np.float64,0xbfee6727e97cce50,0xbff40e7717576e46,3
+np.float64,0xbfddb5fbddbb6bf8,0xbfdee5aad78f5361,3
+np.float64,0xbfdf9d3e9dbf3a7e,0xbfe0886b191f2957,3
+np.float64,0x3fa57e77042afce0,0x3fa5801518ea9342,3
+np.float64,0x3f95c4e4882b89c0,0x3f95c55003c8e714,3
+np.float64,0x3fd9b10f61b36220,0x3fda6fe5d635a8aa,3
+np.float64,0xbfe2973411652e68,0xbfe3d641fe9885fd,3
+np.float64,0xbfee87bd5a7d0f7b,0xbff443bea81b3fff,3
+np.float64,0x3f9ea064c83d40c0,0x3f9ea19025085b2f,3
+np.float64,0xbfe4b823dfe97048,0xbfe689623d30dc75,3
+np.float64,0xbfa06a326c20d460,0xbfa06aeacbcd3eb8,3
+np.float64,0x3fe1e5c4c1e3cb8a,0x3fe2fe44b822f20e,3
+np.float64,0x3f99dafaa833b600,0x3f99dbaec10a1a0a,3
+np.float64,0xbfed7cb3877af967,0xbff2bfe9e556aaf9,3
+np.float64,0x3fd604f2e2ac09e4,0x3fd67a89408ce6ba,3
+np.float64,0x3fec57b60f78af6c,0x3ff16881f46d60f7,3
+np.float64,0xbfea2e3a17745c74,0xbfeea95c7190fd42,3
+np.float64,0xbfd60a7c37ac14f8,0xbfd6806ed642de35,3
+np.float64,0xbfe544b9726a8973,0xbfe743ac399d81d7,3
+np.float64,0xbfd13520faa26a42,0xbfd16c02034a8fe0,3
+np.float64,0xbfea9ea59ff53d4b,0xbfef70538ee12e00,3
+np.float64,0x3fd66633f8accc68,0x3fd6e23c13ab0e9e,3
+np.float64,0xbfe4071bd3e80e38,0xbfe5a3c9ba897d81,3
+np.float64,0xbfbe1659fa3c2cb0,0xbfbe2831d4fed196,3
+np.float64,0xbfd3312777a6624e,0xbfd37df09b9baeba,3
+np.float64,0x3fd13997caa27330,0x3fd170a4900c8907,3
+np.float64,0xbfe7cbc235ef9784,0xbfead4c4d6cbf129,3
+np.float64,0xbfe1456571628acb,0xbfe23e4ec768c8e2,3
+np.float64,0xbfedf1a044fbe340,0xbff35da96773e176,3
+np.float64,0x3fce38b1553c7160,0x3fce8270709774f9,3
+np.float64,0xbfecb01761f9602f,0xbff1c9e9d382f1f8,3
+np.float64,0xbfe0a03560e1406b,0xbfe17b8d5a1ca662,3
+np.float64,0x3fe50f37cbea1e70,0x3fe6fc55e1ae7da6,3
+np.float64,0xbfe12d64a0625aca,0xbfe221d3a7834e43,3
+np.float64,0xbf6fb288403f6500,0xbf6fb28d6f389db6,3
+np.float64,0x3fda831765b50630,0x3fdb55eecae58ca9,3
+np.float64,0x3fe1a0fe4c6341fc,0x3fe2ab9564304425,3
+np.float64,0xbfef2678a77e4cf1,0xbff56ff42b2797bb,3
+np.float64,0xbfab269c1c364d40,0xbfab29df1cd48779,3
+np.float64,0x3fe8ec82a271d906,0x3fec92567d7a6675,3
+np.float64,0xbfc235115f246a24,0xbfc244ee567682ea,3
+np.float64,0x3feef5bf8d7deb80,0x3ff50ad4875ee9bd,3
+np.float64,0x3fe768b5486ed16a,0x3fea421356160e65,3
+np.float64,0xbfd4255684a84aae,0xbfd47e8baf7ec7f6,3
+np.float64,0x3fc7f67f2b2fed00,0x3fc81ae83cf92dd5,3
+np.float64,0x3fe9b1b19a736364,0x3fedd4b0e24ee741,3
+np.float64,0x3fb27eb9e624fd70,0x3fb282dacd89ce28,3
+np.float64,0xbfd490b710a9216e,0xbfd4efcdeb213458,3
+np.float64,0xbfd1347b2ca268f6,0xbfd16b55dece2d38,3
+np.float64,0x3fc6a5668d2d4ad0,0x3fc6c41452c0c087,3
+np.float64,0xbfca7b209f34f640,0xbfcaac710486f6bd,3
+np.float64,0x3fc23a1a47247438,0x3fc24a047fd4c27a,3
+np.float64,0x3fdb1413a8b62828,0x3fdbf595e2d994bc,3
+np.float64,0xbfea69b396f4d367,0xbfef11bdd2b0709a,3
+np.float64,0x3fd14c9958a29934,0x3fd1846161b10422,3
+np.float64,0xbfe205f44be40be8,0xbfe325283aa3c6a8,3
+np.float64,0x3fecd03c9ef9a07a,0x3ff1ee85aaf52a01,3
+np.float64,0x3fe34281d7e68504,0x3fe4aab63e6de816,3
+np.float64,0xbfe120e2376241c4,0xbfe213023ab03939,3
+np.float64,0xbfe951edc4f2a3dc,0xbfed3615e38576f8,3
+np.float64,0x3fe5a2286f6b4450,0x3fe7c196e0ec10ed,3
+np.float64,0xbfed7a3e1f7af47c,0xbff2bcc0793555d2,3
+np.float64,0x3fe050274960a04e,0x3fe11e2e256ea5cc,3
+np.float64,0xbfcfa71f653f4e40,0xbfcffc11483d6a06,3
+np.float64,0x3f6ead2e403d5a00,0x3f6ead32f314c052,3
+np.float64,0x3fe3a2a026674540,0x3fe523bfe085f6ec,3
+np.float64,0xbfe294a62e65294c,0xbfe3d31ebd0b4ca2,3
+np.float64,0xbfb4894d06291298,0xbfb48ef4b8e256b8,3
+np.float64,0xbfc0c042c1218084,0xbfc0cc98ac2767c4,3
+np.float64,0xbfc6a32cb52d4658,0xbfc6c1d1597ed06b,3
+np.float64,0xbfd30f7777a61eee,0xbfd35aa39fee34eb,3
+np.float64,0x3fe7fc2c2eeff858,0x3feb1d8a558b5537,3
+np.float64,0x7fefffffffffffff,0x7ff8000000000000,3
+np.float64,0xbfdadf917bb5bf22,0xbfdbbbae9a9f67a0,3
+np.float64,0xbfcf0395e13e072c,0xbfcf5366015f7362,3
+np.float64,0xbfe8644c9170c899,0xbfebbc98e74a227d,3
+np.float64,0x3fc3b2d8e52765b0,0x3fc3c6f7d44cffaa,3
+np.float64,0x3fc57407b92ae810,0x3fc58e12ccdd47a1,3
+np.float64,0x3fd56a560daad4ac,0x3fd5d62b8dfcc058,3
+np.float64,0x3fd595deefab2bbc,0x3fd6046420b2f79b,3
+np.float64,0xbfd5360f50aa6c1e,0xbfd59ebaacd815b8,3
+np.float64,0x3fdfb6aababf6d54,0x3fe0970b8aac9f61,3
+np.float64,0x3ff0000000000000,0x3ff921fb54442d18,3
+np.float64,0xbfeb3a8958f67513,0xbff04872e8278c79,3
+np.float64,0x3f9e1ea6683c3d40,0x3f9e1fc326186705,3
+np.float64,0x3fe6b6d5986d6dac,0x3fe94175bd60b19d,3
+np.float64,0xbfee4d90b77c9b21,0xbff3e60e9134edc2,3
+np.float64,0x3fd806ce0cb00d9c,0x3fd8a14c4855a8f5,3
+np.float64,0x3fd54acc75aa9598,0x3fd5b4b72fcbb5df,3
+np.float64,0xbfe59761f16b2ec4,0xbfe7b2fa5d0244ac,3
+np.float64,0xbfcd4fa3513a9f48,0xbfcd92d0814a5383,3
+np.float64,0xbfdc827523b904ea,0xbfdd8c577b53053c,3
+np.float64,0xbfd4bb7f34a976fe,0xbfd51d00d9a99360,3
+np.float64,0xbfe818bc87f03179,0xbfeb48d1ea0199c5,3
+np.float64,0xbfa8a2e15c3145c0,0xbfa8a5510ba0e45c,3
+np.float64,0xbfb6d15f422da2c0,0xbfb6d922689da015,3
+np.float64,0x3fcd04eaab3a09d8,0x3fcd46131746ef08,3
+np.float64,0x3fcfb5cfbb3f6ba0,0x3fd0059d308237f3,3
+np.float64,0x3fe8dcf609f1b9ec,0x3fec7997973010b6,3
+np.float64,0xbfdf1834d7be306a,0xbfe03c1d4e2b48f0,3
+np.float64,0x3fee82ae50fd055c,0x3ff43b545066fe1a,3
+np.float64,0xbfde039c08bc0738,0xbfdf3d6ed4d2ee5c,3
+np.float64,0x3fec07389bf80e72,0x3ff1137ed0acd161,3
+np.float64,0xbfef44c010fe8980,0xbff5b488ad22a4c5,3
+np.float64,0x3f76e722e02dce00,0x3f76e72ab2759d88,3
+np.float64,0xbfcaa9e6053553cc,0xbfcadc41125fca93,3
+np.float64,0x3fed6088147ac110,0x3ff29c06c4ef35fc,3
+np.float64,0x3fd32bd836a657b0,0x3fd3785fdb75909f,3
+np.float64,0xbfeedbb1d97db764,0xbff4d87f6c82a93c,3
+np.float64,0xbfe40f31d5e81e64,0xbfe5ae292cf258a2,3
+np.float64,0x7ff8000000000000,0x7ff8000000000000,3
+np.float64,0xbfeb2b25bc76564c,0xbff039d81388550c,3
+np.float64,0x3fec5008fa78a012,0x3ff1604195801da3,3
+np.float64,0x3fce2d4f293c5aa0,0x3fce76b99c2db4da,3
+np.float64,0xbfdc435412b886a8,0xbfdd45e7b7813f1e,3
+np.float64,0x3fdf2c9d06be593c,0x3fe047cb03c141b6,3
+np.float64,0x3fddefc61ebbdf8c,0x3fdf26fb8fad9fae,3
+np.float64,0x3fab50218436a040,0x3fab537395eaf3bb,3
+np.float64,0xbfd5b95a8fab72b6,0xbfd62a191a59343a,3
+np.float64,0x3fdbf803b4b7f008,0x3fdcf211578e98c3,3
+np.float64,0xbfec8c255979184b,0xbff1a1bee108ed30,3
+np.float64,0x3fe33cdaffe679b6,0x3fe4a3a318cd994f,3
+np.float64,0x3fd8cf585cb19eb0,0x3fd97a408bf3c38c,3
+np.float64,0x3fe919dde07233bc,0x3fecdb0ea13a2455,3
+np.float64,0xbfd5ba35e4ab746c,0xbfd62b024805542d,3
+np.float64,0x3fd2f933e7a5f268,0x3fd343527565e97c,3
+np.float64,0xbfe5b9f8ddeb73f2,0xbfe7e1f772c3e438,3
+np.float64,0x3fe843cd92f0879c,0x3feb8a92d68eae3e,3
+np.float64,0xbfd096b234a12d64,0xbfd0c7beca2c6605,3
+np.float64,0xbfef3363da7e66c8,0xbff58c98dde6c27c,3
+np.float64,0x3fd51b01ddaa3604,0x3fd582109d89ead1,3
+np.float64,0x3fea0f10ff741e22,0x3fee736c2d2a2067,3
+np.float64,0x3fc276e7b724edd0,0x3fc28774520bc6d4,3
+np.float64,0xbfef9abc9f7f3579,0xbff69d49762b1889,3
+np.float64,0x3fe1539ec0e2a73e,0x3fe24f370b7687d0,3
+np.float64,0x3fad72350c3ae460,0x3fad765e7766682a,3
+np.float64,0x3fa289a47c251340,0x3fa28aae12f41646,3
+np.float64,0xbfe5c488e5eb8912,0xbfe7f05d7e7dcddb,3
+np.float64,0xbfc22ef1d7245de4,0xbfc23ebeb990a1b8,3
+np.float64,0x3fe59a0b80eb3418,0x3fe7b695fdcba1de,3
+np.float64,0xbfe9cad619f395ac,0xbfedff0514d91e2c,3
+np.float64,0x3fc8bc74eb3178e8,0x3fc8e48cb22da666,3
+np.float64,0xbfc5389a3f2a7134,0xbfc551cd6febc544,3
+np.float64,0x3fce82feb33d0600,0x3fceceecce2467ef,3
+np.float64,0x3fda346791b468d0,0x3fdaff95154a4ca6,3
+np.float64,0x3fd04501fea08a04,0x3fd073397b32607e,3
+np.float64,0xbfb6be498a2d7c90,0xbfb6c5f93aeb0e57,3
+np.float64,0x3fe1f030dd63e062,0x3fe30ad8fb97cce0,3
+np.float64,0xbfee3fb36dfc7f67,0xbff3d0a5e380b86f,3
+np.float64,0xbfa876773c30ecf0,0xbfa878d9d3df6a3f,3
+np.float64,0x3fdb58296eb6b054,0x3fdc40ceffb17f82,3
+np.float64,0xbfea16b5d8742d6c,0xbfee809b99fd6adc,3
+np.float64,0xbfdc5062b6b8a0c6,0xbfdd547623275fdb,3
+np.float64,0x3fef6db242fedb64,0x3ff61ab4cdaef467,3
+np.float64,0xbfc9f778f933eef0,0xbfca25eef1088167,3
+np.float64,0xbfd22063eba440c8,0xbfd260c8766c69cf,3
+np.float64,0x3fdd2379f2ba46f4,0x3fde40b025cb1ffa,3
+np.float64,0xbfea967af2f52cf6,0xbfef61a178774636,3
+np.float64,0x3fe4f5b49fe9eb6a,0x3fe6da8311a5520e,3
+np.float64,0x3feccde17b799bc2,0x3ff1ebd0ea228b71,3
+np.float64,0x3fe1bb76506376ec,0x3fe2cb56fca01840,3
+np.float64,0xbfef94e583ff29cb,0xbff68aeab8ba75a2,3
+np.float64,0x3fed024a55fa0494,0x3ff228ea5d456e9d,3
+np.float64,0xbfe877b2a8f0ef65,0xbfebdaa1a4712459,3
+np.float64,0x3fef687a8d7ed0f6,0x3ff60cf5fef8d448,3
+np.float64,0xbfeeb2dc8afd65b9,0xbff48dda6a906cd6,3
+np.float64,0x3fdb2e28aeb65c50,0x3fdc12620655eb7a,3
+np.float64,0x3fedc1863afb830c,0x3ff31ae823315e83,3
+np.float64,0xbfe6b1bb546d6376,0xbfe93a38163e3a59,3
+np.float64,0x3fe479c78468f390,0x3fe637e5c0fc5730,3
+np.float64,0x3fbad1fade35a3f0,0x3fbade9a43ca05cf,3
+np.float64,0xbfe2d1c563e5a38b,0xbfe41e712785900c,3
+np.float64,0xbfc08c33ed211868,0xbfc09817a752d500,3
+np.float64,0xbfecce0935f99c12,0xbff1ebfe84524037,3
+np.float64,0x3fce4ef0e73c9de0,0x3fce995638a3dc48,3
+np.float64,0xbfd2fb2343a5f646,0xbfd345592517ca18,3
+np.float64,0x3fd848f7cdb091f0,0x3fd8e8bee5f7b49a,3
+np.float64,0x3fe532b7d2ea6570,0x3fe72b9ac747926a,3
+np.float64,0x3fd616aadcac2d54,0x3fd68d692c5cad42,3
+np.float64,0x3fd7720eb3aee41c,0x3fd801206a0e1e43,3
+np.float64,0x3fee835a35fd06b4,0x3ff43c7175eb7a54,3
+np.float64,0xbfe2e8f70b65d1ee,0xbfe43b2800a947a7,3
+np.float64,0xbfed38f45d7a71e9,0xbff26acd6bde7174,3
+np.float64,0xbfc0c62661218c4c,0xbfc0d28964d66120,3
+np.float64,0x3fe97940bef2f282,0x3fed76b986a74ee3,3
+np.float64,0x3fc96f7dc532def8,0x3fc99b20044c8fcf,3
+np.float64,0xbfd60201eeac0404,0xbfd677675efaaedc,3
+np.float64,0x3fe63c0867ec7810,0x3fe894f060200140,3
+np.float64,0xbfef6144b37ec289,0xbff5fa589a515ba8,3
+np.float64,0xbfde2da0c8bc5b42,0xbfdf6d0b59e3232a,3
+np.float64,0xbfd7401612ae802c,0xbfd7cb74ddd413b9,3
+np.float64,0x3fe41c012de83802,0x3fe5be9d87da3f82,3
+np.float64,0x3fdf501609bea02c,0x3fe05c1d96a2270b,3
+np.float64,0x3fcf9fa1233f3f40,0x3fcff45598e72f07,3
+np.float64,0x3fd4e3895ea9c714,0x3fd547580d8392a2,3
+np.float64,0x3fe1e8ff5fe3d1fe,0x3fe3022a0b86a2ab,3
+np.float64,0xbfe0aa55956154ab,0xbfe18768823da589,3
+np.float64,0x3fb2a0aa26254150,0x3fb2a4e1faff1c93,3
+np.float64,0x3fd3823417a70468,0x3fd3d2f808dbb167,3
+np.float64,0xbfaed323643da640,0xbfaed7e9bef69811,3
+np.float64,0x3fe661e8c4ecc3d2,0x3fe8c9c535f43c16,3
+np.float64,0xbfa429777c2852f0,0xbfa42acd38ba02a6,3
+np.float64,0x3fb5993ea22b3280,0x3fb59fd353e47397,3
+np.float64,0x3fee62d21efcc5a4,0x3ff40788f9278ade,3
+np.float64,0xbf813fb810227f80,0xbf813fc56d8f3c53,3
+np.float64,0x3fd56205deaac40c,0x3fd5cd59671ef193,3
+np.float64,0x3fd31a4de5a6349c,0x3fd365fe401b66e8,3
+np.float64,0xbfec7cc7a478f98f,0xbff190cf69703ca4,3
+np.float64,0xbf755881a02ab100,0xbf755887f52e7794,3
+np.float64,0x3fdd1c92e6ba3924,0x3fde38efb4e8605c,3
+np.float64,0x3fdf49da80be93b4,0x3fe0588af8dd4a34,3
+np.float64,0x3fe1fcdbf2e3f9b8,0x3fe31a27b9d273f2,3
+np.float64,0x3fe2a0f18be541e4,0x3fe3e23b159ce20f,3
+np.float64,0xbfed0f1561fa1e2b,0xbff23820fc0a54ca,3
+np.float64,0x3fe34a006c669400,0x3fe4b419b9ed2b83,3
+np.float64,0xbfd51be430aa37c8,0xbfd583005a4d62e7,3
+np.float64,0x3fe5ec4e336bd89c,0x3fe826caad6b0f65,3
+np.float64,0xbfdad71b1fb5ae36,0xbfdbb25bef8b53d8,3
+np.float64,0xbfe8eac2d871d586,0xbfec8f8cac7952f9,3
+np.float64,0xbfe1d5aef663ab5e,0xbfe2eae14b7ccdfd,3
+np.float64,0x3fec11d3157823a6,0x3ff11e8279506753,3
+np.float64,0xbfe67ff1166cffe2,0xbfe8f3e61c1dfd32,3
+np.float64,0xbfd101eecda203de,0xbfd136e0e9557022,3
+np.float64,0x3fde6c9e5cbcd93c,0x3fdfb48ee7efe134,3
+np.float64,0x3fec3ede9c787dbe,0x3ff14dead1e5cc1c,3
+np.float64,0x3fe7a022086f4044,0x3fea93ce2980b161,3
+np.float64,0xbfc3b2b1b7276564,0xbfc3c6d02d60bb21,3
+np.float64,0x7ff0000000000000,0x7ff8000000000000,3
+np.float64,0x3fe60b5647ec16ac,0x3fe8517ef0544b40,3
+np.float64,0xbfd20ab654a4156c,0xbfd24a2f1b8e4932,3
+np.float64,0xbfe4aa1e2f69543c,0xbfe677005cbd2646,3
+np.float64,0xbfc831cc0b306398,0xbfc8574910d0b86d,3
+np.float64,0xbfc3143495262868,0xbfc3267961b79198,3
+np.float64,0x3fc14d64c1229ac8,0x3fc15afea90a319d,3
+np.float64,0x3fc0a5a207214b48,0x3fc0b1bd2f15c1b0,3
+np.float64,0xbfc0b8351521706c,0xbfc0c4792672d6db,3
+np.float64,0xbfdc383600b8706c,0xbfdd398429e163bd,3
+np.float64,0x3fd9e17321b3c2e8,0x3fdaa4c4d140a622,3
+np.float64,0xbfd44f079ea89e10,0xbfd4aa7d6deff4ab,3
+np.float64,0xbfc3de52a927bca4,0xbfc3f2f8f65f4c3f,3
+np.float64,0x3fe7779d566eef3a,0x3fea57f8592dbaad,3
+np.float64,0xbfe309039e661207,0xbfe462f47f9a64e5,3
+np.float64,0x3fd8e06d08b1c0dc,0x3fd98cc946e440a6,3
+np.float64,0x3fdde66c9ebbccd8,0x3fdf1c68009a8dc1,3
+np.float64,0x3fd4369c6ba86d38,0x3fd490bf460a69e4,3
+np.float64,0xbfe132252fe2644a,0xbfe22775e109cc2e,3
+np.float64,0x3fee15483c7c2a90,0x3ff39111de89036f,3
+np.float64,0xbfc1d5ee8123abdc,0xbfc1e4d66c6871a5,3
+np.float64,0x3fc851c52b30a388,0x3fc877d93fb4ae1a,3
+np.float64,0x3fdaade707b55bd0,0x3fdb85001661fffe,3
+np.float64,0xbfe79fb7f96f3f70,0xbfea9330ec27ac10,3
+np.float64,0xbfe8b0f725f161ee,0xbfec3411c0e4517a,3
+np.float64,0xbfea79f5f374f3ec,0xbfef2e9dd9270488,3
+np.float64,0x3fe0b5fe5b616bfc,0x3fe19512a36a4534,3
+np.float64,0xbfad7c622c3af8c0,0xbfad808fea96a804,3
+np.float64,0xbfe3e24dbce7c49c,0xbfe574b4c1ea9818,3
+np.float64,0xbfe80b038af01607,0xbfeb33fec279576a,3
+np.float64,0xbfef69e2ea7ed3c6,0xbff610a5593a18bc,3
+np.float64,0x3fdcc0bb39b98178,0x3fddd1f8c9a46430,3
+np.float64,0xbfba39976a347330,0xbfba4563bb5369a4,3
+np.float64,0xbfebf9768ef7f2ed,0xbff10548ab725f74,3
+np.float64,0xbfec21c066f84381,0xbff12f2803ba052f,3
+np.float64,0xbfca216a6b3442d4,0xbfca50c5e1e5748e,3
+np.float64,0x3fd5e40da4abc81c,0x3fd65783f9a22946,3
+np.float64,0x3fc235ca17246b98,0x3fc245a8f453173f,3
+np.float64,0x3fecb5b867796b70,0x3ff1d046a0bfda69,3
+np.float64,0x3fcb457fef368b00,0x3fcb7b6daa8165a7,3
+np.float64,0xbfa5ed6f7c2bdae0,0xbfa5ef27244e2e42,3
+np.float64,0x3fecf618a1f9ec32,0x3ff21a86cc104542,3
+np.float64,0x3fe9d95413f3b2a8,0x3fee178dcafa11fc,3
+np.float64,0xbfe93a5357f274a7,0xbfed0f9a565da84a,3
+np.float64,0xbfeb9e45ff773c8c,0xbff0a93cab8e258d,3
+np.float64,0x3fcbd9d0bd37b3a0,0x3fcc134e87cae241,3
+np.float64,0x3fe55d4db76aba9c,0x3fe764a0e028475a,3
+np.float64,0xbfc8a6fc71314df8,0xbfc8ceaafbfc59a7,3
+np.float64,0x3fe0615fa660c2c0,0x3fe1323611c4cbc2,3
+np.float64,0x3fb965558632cab0,0x3fb9700b84de20ab,3
+np.float64,0x8000000000000000,0x8000000000000000,3
+np.float64,0x3fe76776c6eeceee,0x3fea40403e24a9f1,3
+np.float64,0x3fe3b7f672676fec,0x3fe53ece71a1a1b1,3
+np.float64,0xbfa9b82ba4337050,0xbfa9baf15394ca64,3
+np.float64,0xbfe31faf49663f5e,0xbfe47f31b1ca73dc,3
+np.float64,0xbfcc4c6beb3898d8,0xbfcc88c5f814b2c1,3
+np.float64,0x3fd481530aa902a8,0x3fd4df8df03bc155,3
+np.float64,0x3fd47593b8a8eb28,0x3fd4d327ab78a1a8,3
+np.float64,0x3fd70e6ccbae1cd8,0x3fd7962fe8b63d46,3
+np.float64,0x3fd25191f7a4a324,0x3fd2941623c88e02,3
+np.float64,0x3fd0603ef0a0c07c,0x3fd08f64e97588dc,3
+np.float64,0xbfc653bae52ca774,0xbfc6711e5e0d8ea9,3
+np.float64,0xbfd11db8fea23b72,0xbfd153b63c6e8812,3
+np.float64,0xbfea9bde25f537bc,0xbfef6b52268e139a,3
+np.float64,0x1,0x1,3
+np.float64,0xbfefd3806d7fa701,0xbff776dcef9583ca,3
+np.float64,0xbfe0fb8cfde1f71a,0xbfe1e6e2e774a8f8,3
+np.float64,0x3fea384534f4708a,0x3feebadaa389be0d,3
+np.float64,0x3feff761c97feec4,0x3ff866157b9d072d,3
+np.float64,0x3fe7131ccb6e263a,0x3fe9c58b4389f505,3
+np.float64,0x3fe9084f7872109e,0x3fecbed0355dbc8f,3
+np.float64,0x3f708e89e0211d00,0x3f708e8cd4946b9e,3
+np.float64,0xbfe39185f067230c,0xbfe50e1cd178244d,3
+np.float64,0x3fd67cc1a9acf984,0x3fd6fa514784b48c,3
+np.float64,0xbfecaef005f95de0,0xbff1c89c9c3ef94a,3
+np.float64,0xbfe12eec81e25dd9,0xbfe223a4285bba9a,3
+np.float64,0x3fbe7f9faa3cff40,0x3fbe92363525068d,3
+np.float64,0xbfe1950b2b632a16,0xbfe29d45fc1e4ce9,3
+np.float64,0x3fe45049e6e8a094,0x3fe6020de759e383,3
+np.float64,0x3fe4d10c8969a21a,0x3fe6aa1fe42cbeb9,3
+np.float64,0xbfe9d04658f3a08d,0xbfee08370a0dbf0c,3
+np.float64,0x3fe14fb314e29f66,0x3fe24a8d73663521,3
+np.float64,0xbfef4abfe4fe9580,0xbff5c2c1ff1250ca,3
+np.float64,0xbfe6162b366c2c56,0xbfe86073ac3c6243,3
+np.float64,0x3feffe781e7ffcf0,0x3ff8d2cbedd6a1b5,3
+np.float64,0xbff0000000000000,0xbff921fb54442d18,3
+np.float64,0x3fc1dc45ad23b888,0x3fc1eb3d9bddda58,3
+np.float64,0xbfe793f6fcef27ee,0xbfea81c93d65aa64,3
+np.float64,0x3fdef6d2bbbdeda4,0x3fe029079d42efb5,3
+np.float64,0xbfdf0ac479be1588,0xbfe0346dbc95963f,3
+np.float64,0xbfd33927d7a67250,0xbfd38653f90a5b73,3
+np.float64,0xbfe248b072e49161,0xbfe37631ef6572e1,3
+np.float64,0xbfc8ceb6af319d6c,0xbfc8f7288657f471,3
+np.float64,0x3fdd7277fcbae4f0,0x3fde99886e6766ef,3
+np.float64,0xbfe0d30c6561a619,0xbfe1b72f90bf53d6,3
+np.float64,0xbfcb0fe07d361fc0,0xbfcb448e2eae9542,3
+np.float64,0xbfe351f57fe6a3eb,0xbfe4be13eef250f2,3
+np.float64,0x3fe85ec02cf0bd80,0x3febb407e2e52e4c,3
+np.float64,0x3fc8bc59b53178b0,0x3fc8e470f65800ec,3
+np.float64,0xbfd278d447a4f1a8,0xbfd2bd133c9c0620,3
+np.float64,0x3feda5cfd87b4ba0,0x3ff2f5ab4324f43f,3
+np.float64,0xbfd2b32a36a56654,0xbfd2fa09c36afd34,3
+np.float64,0xbfed4a81cb7a9504,0xbff28077a4f4fff4,3
+np.float64,0x3fdf079bf9be0f38,0x3fe0329f7fb13f54,3
+np.float64,0x3fd14097f6a28130,0x3fd177e9834ec23f,3
+np.float64,0xbfaeab11843d5620,0xbfaeafc5531eb6b5,3
+np.float64,0xbfac3f8c14387f20,0xbfac433893d53360,3
+np.float64,0xbfc139d7ed2273b0,0xbfc14743adbbe660,3
+np.float64,0x3fe78cb02cef1960,0x3fea7707f76edba9,3
+np.float64,0x3fefe16b41ffc2d6,0x3ff7bff36a7aa7b8,3
+np.float64,0x3fec5260d378a4c2,0x3ff162c588b0da38,3
+np.float64,0x3fedb146f17b628e,0x3ff304f90d3a15d1,3
+np.float64,0x3fd1fd45f7a3fa8c,0x3fd23c2dc3929e20,3
+np.float64,0x3fe0898a5ee11314,0x3fe1610c63e726eb,3
+np.float64,0x3fe7719946eee332,0x3fea4f205eecb59f,3
+np.float64,0x3fe955218972aa44,0x3fed3b530c1f7651,3
+np.float64,0x3fe0ccbf4461997e,0x3fe1afc7b4587836,3
+np.float64,0xbfe9204314f24086,0xbfece5605780e346,3
+np.float64,0xbfe552017feaa403,0xbfe755773cbd74d5,3
+np.float64,0x3fd8ce4b32b19c98,0x3fd9791c8dd44eae,3
+np.float64,0x3fef89acd9ff135a,0x3ff668f78adf7ced,3
+np.float64,0x3fc9d713ad33ae28,0x3fca04da6c293bbd,3
+np.float64,0xbfe22d9c4de45b38,0xbfe3553effadcf92,3
+np.float64,0x3fa5cda38c2b9b40,0x3fa5cf53c5787482,3
+np.float64,0x3fa878ebdc30f1e0,0x3fa87b4f2bf1d4c3,3
+np.float64,0x3fe8030353700606,0x3feb27e196928789,3
+np.float64,0x3fb50607222a0c10,0x3fb50c188ce391e6,3
+np.float64,0x3fd9ba4ab4b37494,0x3fda79fa8bd40f45,3
+np.float64,0x3fb564598e2ac8b0,0x3fb56abe42d1ba13,3
+np.float64,0xbfd1177c83a22efa,0xbfd14d3d7ef30cc4,3
+np.float64,0xbfd952cec7b2a59e,0xbfda09215d17c0ac,3
+np.float64,0x3fe1d8066663b00c,0x3fe2edb35770b8dd,3
+np.float64,0xbfc89427a3312850,0xbfc8bb7a7c389497,3
+np.float64,0xbfe86ebfd3f0dd80,0xbfebccc2ba0f506c,3
+np.float64,0x3fc390578b2720b0,0x3fc3a40cb7f5f728,3
+np.float64,0xbfd122f9b8a245f4,0xbfd15929dc57a897,3
+np.float64,0x3f8d0636d03a0c80,0x3f8d06767de576df,3
+np.float64,0xbfe4b55d8b696abb,0xbfe685be537a9637,3
+np.float64,0xbfdfd51cf9bfaa3a,0xbfe0a894fcff0c76,3
+np.float64,0xbfd37c1f52a6f83e,0xbfd3cc9593c37aad,3
+np.float64,0x3fd0e8283ea1d050,0x3fd11c25c800785a,3
+np.float64,0x3fd3160784a62c10,0x3fd36183a6c2880c,3
+np.float64,0x3fd4c66e57a98cdc,0x3fd5288fe3394eff,3
+np.float64,0x3fee2f7e3afc5efc,0x3ff3b8063eb30cdc,3
+np.float64,0xbfe526773a6a4cee,0xbfe71b4364215b18,3
+np.float64,0x3fea01181e740230,0x3fee5b65eccfd130,3
+np.float64,0xbfe51c03f76a3808,0xbfe70d5919d37587,3
+np.float64,0x3fd97e1375b2fc28,0x3fda3845da40b22b,3
+np.float64,0x3fd5c14a14ab8294,0x3fd632890d07ed03,3
+np.float64,0xbfec9b474279368e,0xbff1b28f50584fe3,3
+np.float64,0x3fe0139ca860273a,0x3fe0d7fc377f001c,3
+np.float64,0x3fdb080c9db61018,0x3fdbe85056358fa0,3
+np.float64,0xbfdd72ceb1bae59e,0xbfde99ea171661eb,3
+np.float64,0xbfe64e934fec9d26,0xbfe8aec2ef24be63,3
+np.float64,0x3fd1036a93a206d4,0x3fd1386adabe01bd,3
+np.float64,0x3febc9d4a5f793aa,0x3ff0d4c069f1e67d,3
+np.float64,0xbfe547a16fea8f43,0xbfe747902fe6fb4d,3
+np.float64,0x3fc289b0f9251360,0x3fc29a709de6bdd9,3
+np.float64,0xbfe694494a6d2892,0xbfe9108f3dc133e2,3
+np.float64,0x3fd827dfe4b04fc0,0x3fd8c4fe40532b91,3
+np.float64,0xbfe8b89418f17128,0xbfec400c5a334b2e,3
+np.float64,0x3fed5605147aac0a,0x3ff28ed1f612814a,3
+np.float64,0xbfed36af31fa6d5e,0xbff26804e1f71af0,3
+np.float64,0x3fdbb01c02b76038,0x3fdca2381558bbf0,3
+np.float64,0x3fe2a951666552a2,0x3fe3ec88f780f9e6,3
+np.float64,0x3fe662defbecc5be,0x3fe8cb1dbfca98ab,3
+np.float64,0x3fd098b1b3a13164,0x3fd0c9d064e4eaf2,3
+np.float64,0x3fefa10edeff421e,0x3ff6b1c6187b18a8,3
+np.float64,0xbfec4feb7a789fd7,0xbff16021ef37a219,3
+np.float64,0x3fd8e415bbb1c82c,0x3fd990c1f8b786bd,3
+np.float64,0xbfead5a09275ab41,0xbfefd44fab5b4f6e,3
+np.float64,0xbfe8666c16f0ccd8,0xbfebbfe0c9f2a9ae,3
+np.float64,0x3fdc962132b92c44,0x3fdda2525a6f406c,3
+np.float64,0xbfe2037f03e406fe,0xbfe3222ec2a3449e,3
+np.float64,0xbfec82c27e790585,0xbff197626ea9df1e,3
+np.float64,0x3fd2b4e03ca569c0,0x3fd2fbd3c7fda23e,3
+np.float64,0xbfe9b0dee5f361be,0xbfedd34f6d3dfe8a,3
+np.float64,0x3feef45cd17de8ba,0x3ff508180687b591,3
+np.float64,0x3f82c39bf0258700,0x3f82c3ad24c3b3f1,3
+np.float64,0xbfca848cfd350918,0xbfcab612ce258546,3
+np.float64,0x3fd6442aaaac8854,0x3fd6bdea54016e48,3
+np.float64,0x3fe550799e6aa0f4,0x3fe75369c9ea5b1e,3
+np.float64,0xbfe0e9d5a361d3ac,0xbfe1d20011139d89,3
+np.float64,0x3fbfc9ff1e3f9400,0x3fbfdf0ea6885c80,3
+np.float64,0xbfa187e8b4230fd0,0xbfa188c95072092e,3
+np.float64,0x3fcd28c9533a5190,0x3fcd6ae879c21b47,3
+np.float64,0x3fc6227ec52c4500,0x3fc63f1fbb441d29,3
+np.float64,0x3fe9b7a2ed736f46,0x3feddeab49b2d176,3
+np.float64,0x3fd4aee93da95dd4,0x3fd50fb3b71e0339,3
+np.float64,0xbfe164dacf62c9b6,0xbfe263bb2f7dd5d9,3
+np.float64,0x3fec62e525f8c5ca,0x3ff17496416d9921,3
+np.float64,0x3fdd363ee0ba6c7c,0x3fde55c6a49a5f86,3
+np.float64,0x3fe65cbf75ecb97e,0x3fe8c28d31ff3ebd,3
+np.float64,0xbfe76d27ca6eda50,0xbfea4899e3661425,3
+np.float64,0xbfc305738d260ae8,0xbfc3178dcfc9d30f,3
+np.float64,0xbfd3aa2a54a75454,0xbfd3fcf1e1ce8328,3
+np.float64,0x3fd1609fc9a2c140,0x3fd1992efa539b9f,3
+np.float64,0xbfac1291bc382520,0xbfac162cc7334b4d,3
+np.float64,0xbfedb461ea7b68c4,0xbff309247850455d,3
+np.float64,0xbfe8d2adf8f1a55c,0xbfec6947be90ba92,3
+np.float64,0xbfd7128965ae2512,0xbfd79a9855bcfc5a,3
+np.float64,0x3fe8deb09471bd62,0x3fec7c56b3aee531,3
+np.float64,0xbfe5f4d329ebe9a6,0xbfe8327ea8189af8,3
+np.float64,0xbfd3b46ac9a768d6,0xbfd407b80b12ff17,3
+np.float64,0x3fec899d7cf9133a,0x3ff19ef26baca36f,3
+np.float64,0xbfec192fd5783260,0xbff126306e507fd0,3
+np.float64,0x3fe945bdaef28b7c,0x3fed222f787310bf,3
+np.float64,0xbfeff9635d7ff2c7,0xbff87d6773f318eb,3
+np.float64,0xbfd604b81cac0970,0xbfd67a4aa852559a,3
+np.float64,0x3fcd1cc9d53a3990,0x3fcd5e962e237c24,3
+np.float64,0xbfed77b0fffaef62,0xbff2b97a1c9b6483,3
+np.float64,0xbfc9c69325338d28,0xbfc9f401500402fb,3
+np.float64,0xbfdf97e246bf2fc4,0xbfe0855601ea9db3,3
+np.float64,0x3fc7e6304f2fcc60,0x3fc80a4e718504cd,3
+np.float64,0x3fec3b599e7876b4,0x3ff14a2d1b9c68e6,3
+np.float64,0xbfe98618e1f30c32,0xbfed8bfbb31c394a,3
+np.float64,0xbfe59b3c0feb3678,0xbfe7b832d6df81de,3
+np.float64,0xbfe54ce2fe6a99c6,0xbfe74e9a85be4116,3
+np.float64,0x3fc9db49cb33b690,0x3fca092737ef500a,3
+np.float64,0xbfb4a922ae295248,0xbfb4aee4e39078a9,3
+np.float64,0xbfd0e542e0a1ca86,0xbfd11925208d66af,3
+np.float64,0x3fd70543f2ae0a88,0x3fd78c5e9238a3ee,3
+np.float64,0x3fd67f7a7facfef4,0x3fd6fd3998df8545,3
+np.float64,0xbfe40b643d6816c8,0xbfe5a947e427f298,3
+np.float64,0xbfcd85f69b3b0bec,0xbfcdcaa24b75f1a3,3
+np.float64,0x3fec705fb4f8e0c0,0x3ff1833c82163ee2,3
+np.float64,0x3fb37650ea26eca0,0x3fb37b20c16fb717,3
+np.float64,0x3fe5ebfa55ebd7f4,0x3fe826578d716e70,3
+np.float64,0x3fe991dfe5f323c0,0x3fed9f8a4bf1f588,3
+np.float64,0xbfd658bd0aacb17a,0xbfd6d3dd06e54900,3
+np.float64,0xbfc24860252490c0,0xbfc258701a0b9290,3
+np.float64,0xbfefb8d763ff71af,0xbff705b6ea4a569d,3
+np.float64,0x3fb8fcb4ae31f970,0x3fb906e809e7899f,3
+np.float64,0x3fce6343cb3cc688,0x3fceae41d1629625,3
+np.float64,0xbfd43d5a11a87ab4,0xbfd497da25687e07,3
+np.float64,0xbfe9568851f2ad11,0xbfed3d9e5fe83a76,3
+np.float64,0x3fe1b66153e36cc2,0x3fe2c53c7e016271,3
+np.float64,0x3fef27452bfe4e8a,0x3ff571b3486ed416,3
+np.float64,0x3fca87c0a7350f80,0x3fcab958a7bb82d4,3
+np.float64,0xbfd8776a8fb0eed6,0xbfd91afaf2f50edf,3
+np.float64,0x3fe9522a76f2a454,0x3fed3679264e1525,3
+np.float64,0x3fea14ff2cf429fe,0x3fee7da6431cc316,3
+np.float64,0x3fe970618bf2e0c4,0x3fed68154d54dd97,3
+np.float64,0x3fd3410cfca68218,0x3fd38e9b21792240,3
+np.float64,0xbf6a8070c0350100,0xbf6a8073c7c34517,3
+np.float64,0xbfbe449de23c8938,0xbfbe56c8e5e4d98b,3
+np.float64,0x3fedbc92e27b7926,0x3ff314313216d8e6,3
+np.float64,0xbfe3be4706677c8e,0xbfe546d3ceb85aea,3
+np.float64,0x3fe30cd6d76619ae,0x3fe467b6f2664a8d,3
+np.float64,0x3fd7d69b21afad38,0x3fd86d54284d05ad,3
+np.float64,0xbfe501001fea0200,0xbfe6e978afcff4d9,3
+np.float64,0xbfe44ba3d8e89748,0xbfe5fc0a31cd1e3e,3
+np.float64,0x3fec52f7c078a5f0,0x3ff16367acb209b2,3
+np.float64,0xbfcb19efcb3633e0,0xbfcb4ed9235a7d47,3
+np.float64,0xbfab86796c370cf0,0xbfab89df7bf15710,3
+np.float64,0xbfb962feda32c600,0xbfb96db1e1679c98,3
+np.float64,0x3fe0dd14e861ba2a,0x3fe1c2fc72810567,3
+np.float64,0x3fe41bcc6de83798,0x3fe5be59b7f9003b,3
+np.float64,0x3fc82f4c4f305e98,0x3fc854bd9798939f,3
+np.float64,0xbfcd143a613a2874,0xbfcd55cbd1619d84,3
+np.float64,0xbfd52da61baa5b4c,0xbfd595d0b3543439,3
+np.float64,0xbfb71b4a8e2e3698,0xbfb7235a4ab8432f,3
+np.float64,0xbfec141a19782834,0xbff120e1e39fc856,3
+np.float64,0xbfdba9319db75264,0xbfdc9a8ca2578bb2,3
+np.float64,0xbfbce5d74639cbb0,0xbfbcf5a4878cfa51,3
+np.float64,0x3fde67f7b3bccff0,0x3fdfaf45a9f843ad,3
+np.float64,0xbfe12d87bc625b10,0xbfe221fd4476eb71,3
+np.float64,0x3fe35b8f6be6b71e,0x3fe4ca20f65179e1,3
+np.float64,0xbfdbada1d3b75b44,0xbfdc9f78b19f93d1,3
+np.float64,0xbfc60159c52c02b4,0xbfc61d79b879f598,3
+np.float64,0x3fd6b81c38ad7038,0x3fd739c27bfa16d8,3
+np.float64,0xbfd646a253ac8d44,0xbfd6c08c19612bbb,3
+np.float64,0xbfe6babef0ed757e,0xbfe94703d0bfa311,3
+np.float64,0xbfed5671f1faace4,0xbff28f5a3f3683d0,3
+np.float64,0x3fc01d1e85203a40,0x3fc02817ec0dfd38,3
+np.float64,0xbfe9188a61f23115,0xbfecd8eb5da84223,3
+np.float64,0x3fdca3bab9b94774,0x3fddb1868660c239,3
+np.float64,0xbfa255750c24aaf0,0xbfa25675f7b36343,3
+np.float64,0x3fb3602db626c060,0x3fb364ed2d5b2876,3
+np.float64,0xbfd30a14bda6142a,0xbfd354ff703b8862,3
+np.float64,0xbfe1cfe381639fc7,0xbfe2e3e720b968c8,3
+np.float64,0xbfd2af6a4fa55ed4,0xbfd2f61e190bcd1f,3
+np.float64,0xbfe93c50937278a1,0xbfed12d64bb10d73,3
+np.float64,0x3fddd8bc44bbb178,0x3fdf0ced7f9005cc,3
+np.float64,0x3fdb2bc73cb65790,0x3fdc0fc0e18e425e,3
+np.float64,0xbfd073f6aba0e7ee,0xbfd0a3cb5468a961,3
+np.float64,0x3fed4bad7b7a975a,0x3ff281ebeb75e414,3
+np.float64,0xbfdc75b50bb8eb6a,0xbfdd7e1a7631cb22,3
+np.float64,0x3fd458a90fa8b154,0x3fd4b4a5817248ce,3
+np.float64,0x3feead5db57d5abc,0x3ff484286fab55ff,3
+np.float64,0x3fb3894382271280,0x3fb38e217b4e7905,3
+np.float64,0xffefffffffffffff,0x7ff8000000000000,3
+np.float64,0xbfe428212ae85042,0xbfe5ce36f226bea8,3
+np.float64,0xbfc08b39f7211674,0xbfc0971b93ebc7ad,3
+np.float64,0xbfc2e7cf5525cfa0,0xbfc2f994eb72b623,3
+np.float64,0xbfdb0d85afb61b0c,0xbfdbee5a2de3c5db,3
+np.float64,0xfff0000000000000,0x7ff8000000000000,3
+np.float64,0xbfd0d36af7a1a6d6,0xbfd106a5f05ef6ff,3
+np.float64,0xbfc333d0912667a0,0xbfc3467162b7289a,3
+np.float64,0x3fcdababc53b5758,0x3fcdf16458c20fa8,3
+np.float64,0x3fd0821b38a10438,0x3fd0b26e3e0b9185,3
+np.float64,0x0,0x0,3
+np.float64,0x3feb7f70edf6fee2,0x3ff08ae81854bf20,3
+np.float64,0x3fe6e075716dc0ea,0x3fe97cc5254be6ff,3
+np.float64,0x3fea13b682f4276e,0x3fee7b6f18073b5b,3
diff --git a/numpy/core/tests/data/umath-validation-set-arcsinh.csv b/numpy/core/tests/data/umath-validation-set-arcsinh.csv
new file mode 100644
index 000000000..1da29c822
--- /dev/null
+++ b/numpy/core/tests/data/umath-validation-set-arcsinh.csv
@@ -0,0 +1,1429 @@
+dtype,input,output,ulperrortol
+np.float32,0xbf24142a,0xbf1a85ef,2
+np.float32,0x3e71cf91,0x3e6f9e37,2
+np.float32,0xe52a7,0xe52a7,2
+np.float32,0x3ef1e074,0x3ee9add9,2
+np.float32,0x806160ac,0x806160ac,2
+np.float32,0x7e2d59a2,0x42af4798,2
+np.float32,0xbf32cac9,0xbf26bf96,2
+np.float32,0x3f081701,0x3f026142,2
+np.float32,0x3f23cc88,0x3f1a499c,2
+np.float32,0xbf090d94,0xbf033ad0,2
+np.float32,0x803af2fc,0x803af2fc,2
+np.float32,0x807eb17e,0x807eb17e,2
+np.float32,0x5c0d8e,0x5c0d8e,2
+np.float32,0x3f7b79d2,0x3f5e6b1d,2
+np.float32,0x806feeae,0x806feeae,2
+np.float32,0x3e4b423a,0x3e49f274,2
+np.float32,0x3f49e5ac,0x3f394a41,2
+np.float32,0x3f18cd4e,0x3f10ef35,2
+np.float32,0xbed75734,0xbed17322,2
+np.float32,0x7f591151,0x42b28085,2
+np.float32,0xfefe9da6,0xc2b16f51,2
+np.float32,0xfeac90fc,0xc2b0a82a,2
+np.float32,0x805c198e,0x805c198e,2
+np.float32,0x7f66d6df,0x42b2a004,2
+np.float32,0x505438,0x505438,2
+np.float32,0xbf39a209,0xbf2c5255,2
+np.float32,0x7fa00000,0x7fe00000,2
+np.float32,0xc84cb,0xc84cb,2
+np.float32,0x7f07d6f5,0x42b19088,2
+np.float32,0x79d7e4,0x79d7e4,2
+np.float32,0xff32f6a0,0xc2b21db1,2
+np.float32,0x7c005c05,0x42a9222e,2
+np.float32,0x3ec449aa,0x3ebfc5ae,2
+np.float32,0x800ec323,0x800ec323,2
+np.float32,0xff1c904c,0xc2b1d93a,2
+np.float32,0x7f4eca52,0x42b267b0,2
+np.float32,0x3ee06540,0x3ed9c514,2
+np.float32,0x6aab4,0x6aab4,2
+np.float32,0x3e298d8c,0x3e28c99e,2
+np.float32,0xbf38d162,0xbf2ba94a,2
+np.float32,0x2d9083,0x2d9083,2
+np.float32,0x7eae5032,0x42b0ad52,2
+np.float32,0x3ead5b3c,0x3eaa3443,2
+np.float32,0x806fef66,0x806fef66,2
+np.float32,0x3f5b614e,0x3f46ca71,2
+np.float32,0xbf4c906a,0xbf3b60fc,2
+np.float32,0x8049453e,0x8049453e,2
+np.float32,0x3d305220,0x3d304432,2
+np.float32,0x2e1a89,0x2e1a89,2
+np.float32,0xbf4e74ec,0xbf3cdacf,2
+np.float32,0x807a827a,0x807a827a,2
+np.float32,0x80070745,0x80070745,2
+np.float32,0xbe1ba2fc,0xbe1b0b28,2
+np.float32,0xbe5131d0,0xbe4fc421,2
+np.float32,0x5bfd98,0x5bfd98,2
+np.float32,0xbd8e1a48,0xbd8dfd27,2
+np.float32,0x8006c160,0x8006c160,2
+np.float32,0x346490,0x346490,2
+np.float32,0xbdbdf060,0xbdbdaaf0,2
+np.float32,0x3ea9d0c4,0x3ea6d8c7,2
+np.float32,0xbf2aaa28,0xbf200916,2
+np.float32,0xbf160c26,0xbf0e9047,2
+np.float32,0x80081fd4,0x80081fd4,2
+np.float32,0x7db44283,0x42adf8b6,2
+np.float32,0xbf1983f8,0xbf118bf5,2
+np.float32,0x2c4a35,0x2c4a35,2
+np.float32,0x6165a7,0x6165a7,2
+np.float32,0xbe776b44,0xbe75129f,2
+np.float32,0xfe81841a,0xc2b0153b,2
+np.float32,0xbf7d1b2f,0xbf5f9461,2
+np.float32,0x80602d36,0x80602d36,2
+np.float32,0xfe8d5046,0xc2b041dd,2
+np.float32,0xfe5037bc,0xc2afa56d,2
+np.float32,0x4bbea6,0x4bbea6,2
+np.float32,0xfea039de,0xc2b0822d,2
+np.float32,0x7ea627a4,0x42b094c7,2
+np.float32,0x3f556198,0x3f423591,2
+np.float32,0xfedbae04,0xc2b123c1,2
+np.float32,0xbe30432c,0xbe2f6744,2
+np.float32,0x80202c77,0x80202c77,2
+np.float32,0xff335cc1,0xc2b21ed5,2
+np.float32,0x3e1e1ebe,0x3e1d7f95,2
+np.float32,0x8021c9c0,0x8021c9c0,2
+np.float32,0x7dc978,0x7dc978,2
+np.float32,0xff6cfabc,0xc2b2ad75,2
+np.float32,0x7f2bd542,0x42b208e0,2
+np.float32,0x53bf33,0x53bf33,2
+np.float32,0x804e04bb,0x804e04bb,2
+np.float32,0x3f30d2f9,0x3f2521ca,2
+np.float32,0x3dfde876,0x3dfd4316,2
+np.float32,0x46f8b1,0x46f8b1,2
+np.float32,0xbd5f9e20,0xbd5f81ba,2
+np.float32,0x807d6a22,0x807d6a22,2
+np.float32,0xff3881da,0xc2b22d50,2
+np.float32,0x1b1cb5,0x1b1cb5,2
+np.float32,0x3f75f2d0,0x3f5a7435,2
+np.float32,0xfee39c1a,0xc2b135e9,2
+np.float32,0x7f79f14a,0x42b2c8b9,2
+np.float32,0x8000e2d1,0x8000e2d1,2
+np.float32,0xab779,0xab779,2
+np.float32,0xbede6690,0xbed7f102,2
+np.float32,0x76e20d,0x76e20d,2
+np.float32,0x3ed714cb,0x3ed135e9,2
+np.float32,0xbeaa6f44,0xbea76f31,2
+np.float32,0x7f7dc8b1,0x42b2d089,2
+np.float32,0x108cb2,0x108cb2,2
+np.float32,0x7d37ba82,0x42ac9f94,2
+np.float32,0x3f31d068,0x3f25f221,2
+np.float32,0x8010a331,0x8010a331,2
+np.float32,0x3f2fdc7c,0x3f2456cd,2
+np.float32,0x7f7a9a67,0x42b2ca13,2
+np.float32,0x3f2acb31,0x3f202492,2
+np.float32,0x7f54fa94,0x42b276c9,2
+np.float32,0x3ebf8a70,0x3ebb553c,2
+np.float32,0x7f75b1a7,0x42b2bff2,2
+np.float32,0x7daebe07,0x42ade8cc,2
+np.float32,0xbd3a3ef0,0xbd3a2e86,2
+np.float32,0x8078ec9e,0x8078ec9e,2
+np.float32,0x3eda206a,0x3ed403ec,2
+np.float32,0x3f7248f2,0x3f57cd77,2
+np.float32,0x805d55ba,0x805d55ba,2
+np.float32,0xff30dc3e,0xc2b217a3,2
+np.float32,0xbe12b27c,0xbe123333,2
+np.float32,0xbf6ed9cf,0xbf554cd0,2
+np.float32,0xbed9eb5c,0xbed3d31c,2
+np.float32,0xbf1c9aea,0xbf14307b,2
+np.float32,0x3f540ac4,0x3f412de2,2
+np.float32,0x800333ac,0x800333ac,2
+np.float32,0x3f74cdb4,0x3f59a09a,2
+np.float32,0xbf41dc41,0xbf32ee6f,2
+np.float32,0xff2c7804,0xc2b20ac4,2
+np.float32,0x514493,0x514493,2
+np.float32,0xbddf1220,0xbddea1cf,2
+np.float32,0xfeaf74de,0xc2b0b0ab,2
+np.float32,0xfe5dfb30,0xc2afc633,2
+np.float32,0xbf4785c4,0xbf376bdb,2
+np.float32,0x80191cd3,0x80191cd3,2
+np.float32,0xfe44f708,0xc2af88fb,2
+np.float32,0x3d4cd8a0,0x3d4cc2ca,2
+np.float32,0x7f572eff,0x42b27c0f,2
+np.float32,0x8031bacb,0x8031bacb,2
+np.float32,0x7f2ea684,0x42b21133,2
+np.float32,0xbea1976a,0xbe9f05bb,2
+np.float32,0x3d677b41,0x3d675bc1,2
+np.float32,0x3f61bf24,0x3f4b9870,2
+np.float32,0x7ef55ddf,0x42b15c5f,2
+np.float32,0x3eabcb20,0x3ea8b91c,2
+np.float32,0xff73d9ec,0xc2b2bc18,2
+np.float32,0x77b9f5,0x77b9f5,2
+np.float32,0x4c6c6c,0x4c6c6c,2
+np.float32,0x7ed09c94,0x42b10949,2
+np.float32,0xdeeec,0xdeeec,2
+np.float32,0x7eac5858,0x42b0a782,2
+np.float32,0x7e190658,0x42af07bd,2
+np.float32,0xbe3c8980,0xbe3b7ce2,2
+np.float32,0x8059e86e,0x8059e86e,2
+np.float32,0xff201836,0xc2b1e4a5,2
+np.float32,0xbeac109c,0xbea8fafb,2
+np.float32,0x7edd1e2b,0x42b12718,2
+np.float32,0x639cd8,0x639cd8,2
+np.float32,0x3f5e4cae,0x3f490059,2
+np.float32,0x3d84c185,0x3d84a9c4,2
+np.float32,0xbe8c1130,0xbe8a605b,2
+np.float32,0x80000000,0x80000000,2
+np.float32,0x3f1da5e4,0x3f151404,2
+np.float32,0x7f75a873,0x42b2bfdf,2
+np.float32,0xbd873540,0xbd871c28,2
+np.float32,0xbe8e5e10,0xbe8c9808,2
+np.float32,0x7f004bf2,0x42b17347,2
+np.float32,0x800000,0x800000,2
+np.float32,0xbf6d6b79,0xbf544095,2
+np.float32,0x7ed7b563,0x42b11a6a,2
+np.float32,0x80693745,0x80693745,2
+np.float32,0x3ee0f608,0x3eda49a8,2
+np.float32,0xfe1285a4,0xc2aef181,2
+np.float32,0x72d946,0x72d946,2
+np.float32,0x6a0dca,0x6a0dca,2
+np.float32,0x3f5c9df6,0x3f47ba99,2
+np.float32,0xff002af6,0xc2b172c4,2
+np.float32,0x3f4ac98f,0x3f39fd0a,2
+np.float32,0x8066acf7,0x8066acf7,2
+np.float32,0xbcaa4e60,0xbcaa4b3c,2
+np.float32,0x80162813,0x80162813,2
+np.float32,0xff34b318,0xc2b222a2,2
+np.float32,0x7f1ce33c,0x42b1da49,2
+np.float32,0x3f0e55ab,0x3f07ddb0,2
+np.float32,0x7c75d996,0x42aa6eec,2
+np.float32,0xbf221bc6,0xbf18dc89,2
+np.float32,0x3f5a1a4c,0x3f45d1d4,2
+np.float32,0x7f2451b8,0x42b1f1fb,2
+np.float32,0x3ec55ca0,0x3ec0c655,2
+np.float32,0x3f752dc2,0x3f59e600,2
+np.float32,0xbe33f638,0xbe330c4d,2
+np.float32,0x3e2a9148,0x3e29c9d8,2
+np.float32,0x3f3362a1,0x3f273c01,2
+np.float32,0x5f83b3,0x5f83b3,2
+np.float32,0x3e362488,0x3e353216,2
+np.float32,0x140bcf,0x140bcf,2
+np.float32,0x7e3e96df,0x42af7822,2
+np.float32,0xbebc7082,0xbeb86ce6,2
+np.float32,0xbe92a92e,0xbe90b9d2,2
+np.float32,0xff3d8afc,0xc2b23b19,2
+np.float32,0x804125e3,0x804125e3,2
+np.float32,0x3f3675d1,0x3f29bedb,2
+np.float32,0xff70bb09,0xc2b2b57f,2
+np.float32,0x3f29681c,0x3f1efcd2,2
+np.float32,0xbdc70380,0xbdc6b3a8,2
+np.float32,0x54e0dd,0x54e0dd,2
+np.float32,0x3d545de0,0x3d54458c,2
+np.float32,0x7f800000,0x7f800000,2
+np.float32,0x8014a4c2,0x8014a4c2,2
+np.float32,0xbe93f58a,0xbe91f938,2
+np.float32,0x17de33,0x17de33,2
+np.float32,0xfefb679a,0xc2b168d2,2
+np.float32,0xbf23423e,0xbf19d511,2
+np.float32,0x7e893fa1,0x42b032ec,2
+np.float32,0x3f44fe2d,0x3f356bda,2
+np.float32,0xbebb2e78,0xbeb73e8f,2
+np.float32,0x3f5632e0,0x3f42d633,2
+np.float32,0x3ddd8698,0x3ddd1896,2
+np.float32,0x80164ea7,0x80164ea7,2
+np.float32,0x80087b37,0x80087b37,2
+np.float32,0xbf06ab1e,0xbf011f95,2
+np.float32,0x3db95524,0x3db9149f,2
+np.float32,0x7aa1fbb3,0x42a570a1,2
+np.float32,0xbd84fc48,0xbd84e467,2
+np.float32,0x3d65c6f5,0x3d65a826,2
+np.float32,0xfe987800,0xc2b068c4,2
+np.float32,0x7ec59532,0x42b0ed7a,2
+np.float32,0x3ea0232c,0x3e9da29a,2
+np.float32,0x80292a08,0x80292a08,2
+np.float32,0x734cfe,0x734cfe,2
+np.float32,0x3f3b6d63,0x3f2dc596,2
+np.float32,0x3f27bcc1,0x3f1d97e6,2
+np.float32,0xfe1da554,0xc2af16f9,2
+np.float32,0x7c91f5,0x7c91f5,2
+np.float32,0xfe4e78cc,0xc2afa11e,2
+np.float32,0x7e4b4e08,0x42af9933,2
+np.float32,0xfe0949ec,0xc2aed02e,2
+np.float32,0x7e2f057f,0x42af4c81,2
+np.float32,0xbf200ae0,0xbf171ce1,2
+np.float32,0x3ebcc244,0x3eb8b99e,2
+np.float32,0xbf68f58d,0xbf50f7aa,2
+np.float32,0x4420b1,0x4420b1,2
+np.float32,0x3f5b61bf,0x3f46cac7,2
+np.float32,0x3fec78,0x3fec78,2
+np.float32,0x7f4183c8,0x42b245b7,2
+np.float32,0xbf10587c,0xbf099ee2,2
+np.float32,0x0,0x0,2
+np.float32,0x7ec84dc3,0x42b0f47a,2
+np.float32,0x3f5fbd7b,0x3f4a166d,2
+np.float32,0xbd884eb8,0xbd883502,2
+np.float32,0xfe3f10a4,0xc2af7969,2
+np.float32,0xff3f4920,0xc2b23fc9,2
+np.float32,0x8013900f,0x8013900f,2
+np.float32,0x8003529d,0x8003529d,2
+np.float32,0xbf032384,0xbefbfb3c,2
+np.float32,0xff418c7c,0xc2b245ce,2
+np.float32,0xbec0aad0,0xbebc633b,2
+np.float32,0xfdbff178,0xc2ae18de,2
+np.float32,0x68ab15,0x68ab15,2
+np.float32,0xbdfc4a88,0xbdfba848,2
+np.float32,0xbf5adec6,0xbf466747,2
+np.float32,0x807d5dcc,0x807d5dcc,2
+np.float32,0x61d144,0x61d144,2
+np.float32,0x807e3a03,0x807e3a03,2
+np.float32,0x1872f2,0x1872f2,2
+np.float32,0x7f2a272c,0x42b203d8,2
+np.float32,0xfe7f8314,0xc2b00e3a,2
+np.float32,0xbe42aeac,0xbe418737,2
+np.float32,0x8024b614,0x8024b614,2
+np.float32,0xbe41b6b8,0xbe40939a,2
+np.float32,0xa765c,0xa765c,2
+np.float32,0x7ea74f4b,0x42b09853,2
+np.float32,0x7f7ef631,0x42b2d2e7,2
+np.float32,0x7eaef5e6,0x42b0af38,2
+np.float32,0xff733d85,0xc2b2bacf,2
+np.float32,0x537ac0,0x537ac0,2
+np.float32,0xbeca4790,0xbec55b1d,2
+np.float32,0x80117314,0x80117314,2
+np.float32,0xfe958536,0xc2b05ec5,2
+np.float32,0x8066ecc2,0x8066ecc2,2
+np.float32,0xbf56baf3,0xbf433e82,2
+np.float32,0x1f7fd7,0x1f7fd7,2
+np.float32,0x3e942104,0x3e9222fc,2
+np.float32,0xfeaffe82,0xc2b0b23c,2
+np.float32,0xfe0e02b0,0xc2aee17e,2
+np.float32,0xbf800000,0xbf61a1b3,2
+np.float32,0x800b7e49,0x800b7e49,2
+np.float32,0x6c514f,0x6c514f,2
+np.float32,0xff800000,0xff800000,2
+np.float32,0x7f7d9a45,0x42b2d02b,2
+np.float32,0x800c9c69,0x800c9c69,2
+np.float32,0x274b14,0x274b14,2
+np.float32,0xbf4b22b0,0xbf3a42e2,2
+np.float32,0x63e5ae,0x63e5ae,2
+np.float32,0xbe18facc,0xbe186a90,2
+np.float32,0x7e137351,0x42aef4bd,2
+np.float32,0x80518ffd,0x80518ffd,2
+np.float32,0xbf0a8ffc,0xbf048f0d,2
+np.float32,0x841d,0x841d,2
+np.float32,0x7edfdc9e,0x42b12d69,2
+np.float32,0xfd1092b0,0xc2ac24de,2
+np.float32,0x7e2c9bdf,0x42af4566,2
+np.float32,0x7f7fffff,0x42b2d4fc,2
+np.float32,0x3f4954a6,0x3f38d853,2
+np.float32,0xbe83efd2,0xbe8284c3,2
+np.float32,0x800e8e02,0x800e8e02,2
+np.float32,0x78ad39,0x78ad39,2
+np.float32,0x7eb0f967,0x42b0b514,2
+np.float32,0xbe39aa94,0xbe38a9ee,2
+np.float32,0x80194e7b,0x80194e7b,2
+np.float32,0x3cf3a340,0x3cf39a0f,2
+np.float32,0x3ed3117a,0x3ecd8173,2
+np.float32,0x7f530b11,0x42b2721c,2
+np.float32,0xff756ba2,0xc2b2bf60,2
+np.float32,0x15ea25,0x15ea25,2
+np.float32,0x803cbb64,0x803cbb64,2
+np.float32,0x3f34722d,0x3f281a2c,2
+np.float32,0x3ddd88e0,0x3ddd1adb,2
+np.float32,0x3f54244c,0x3f41418b,2
+np.float32,0x3e0adb98,0x3e0a6f8b,2
+np.float32,0x80800000,0x80800000,2
+np.float32,0x58902b,0x58902b,2
+np.float32,0xfe3b50b8,0xc2af6f43,2
+np.float32,0xfe0846d0,0xc2aecc64,2
+np.float32,0xbe0299d0,0xbe023fd4,2
+np.float32,0x18dde6,0x18dde6,2
+np.float32,0x8039fe8b,0x8039fe8b,2
+np.float32,0x8015d179,0x8015d179,2
+np.float32,0x3f551322,0x3f41f947,2
+np.float32,0x2ab387,0x2ab387,2
+np.float32,0xbf7e311e,0xbf6059d0,2
+np.float32,0xbdba58a8,0xbdba1713,2
+np.float32,0xbf1d008a,0xbf148724,2
+np.float32,0xbf6b9c97,0xbf52ec98,2
+np.float32,0x802acf04,0x802acf04,2
+np.float32,0x1,0x1,2
+np.float32,0xbe9e16d6,0xbe9bade3,2
+np.float32,0xbf048a14,0xbefe78c7,2
+np.float32,0x7e432ad3,0x42af8449,2
+np.float32,0xbdcc7fe0,0xbdcc2944,2
+np.float32,0x6dfc27,0x6dfc27,2
+np.float32,0xfef6eed8,0xc2b15fa1,2
+np.float32,0xbeeff6e8,0xbee7f2e4,2
+np.float32,0x7e3a6ca8,0x42af6cd2,2
+np.float32,0xff2c82e8,0xc2b20ae4,2
+np.float32,0x3e9f8d74,0x3e9d13b0,2
+np.float32,0x7ea36191,0x42b08c29,2
+np.float32,0x7f734bed,0x42b2baed,2
+np.float32,0x7f2df96d,0x42b20f37,2
+np.float32,0x5036fd,0x5036fd,2
+np.float32,0x806eab38,0x806eab38,2
+np.float32,0xbe9db90e,0xbe9b5446,2
+np.float32,0xfeef6fac,0xc2b14fd9,2
+np.float32,0xc2bf7,0xc2bf7,2
+np.float32,0xff53ec3d,0xc2b2743d,2
+np.float32,0x7e837637,0x42b01cde,2
+np.float32,0xbefb5934,0xbef23662,2
+np.float32,0x3f6cec80,0x3f53e371,2
+np.float32,0x3e86e7de,0x3e85643f,2
+np.float32,0x3f09cb42,0x3f03e1ef,2
+np.float32,0xbec3d236,0xbebf5620,2
+np.float32,0xfedef246,0xc2b12b50,2
+np.float32,0xbf08d6a8,0xbf030a62,2
+np.float32,0x8036cbf9,0x8036cbf9,2
+np.float32,0x3f74d3e3,0x3f59a512,2
+np.float32,0x6a600c,0x6a600c,2
+np.float32,0xfd1295b0,0xc2ac2bf1,2
+np.float32,0xbeb61142,0xbeb26efa,2
+np.float32,0x80216556,0x80216556,2
+np.float32,0xbf1fa0f6,0xbf16c30a,2
+np.float32,0x3e0af8e1,0x3e0a8c90,2
+np.float32,0x80434709,0x80434709,2
+np.float32,0x49efd9,0x49efd9,2
+np.float32,0x7f7cce6c,0x42b2ce8f,2
+np.float32,0x6e5450,0x6e5450,2
+np.float32,0x7f0fc115,0x42b1ad86,2
+np.float32,0x632db0,0x632db0,2
+np.float32,0x3f6f4c2a,0x3f55a064,2
+np.float32,0x7ec4f273,0x42b0ebd3,2
+np.float32,0x61ae1e,0x61ae1e,2
+np.float32,0x5f47c4,0x5f47c4,2
+np.float32,0xbf3c8f62,0xbf2eaf54,2
+np.float32,0xfca38900,0xc2ab0113,2
+np.float32,0x3ec89d52,0x3ec3ce78,2
+np.float32,0xbe0e3f70,0xbe0dcb53,2
+np.float32,0x805d3156,0x805d3156,2
+np.float32,0x3eee33f8,0x3ee65a4e,2
+np.float32,0xbeda7e9a,0xbed45a90,2
+np.float32,0x7e2fac7b,0x42af4e69,2
+np.float32,0x7efd0e28,0x42b16c2c,2
+np.float32,0x3f0c7b17,0x3f063e46,2
+np.float32,0xbf395bec,0xbf2c198f,2
+np.float32,0xfdf1c3f8,0xc2ae8f05,2
+np.float32,0xbe11f4e4,0xbe117783,2
+np.float32,0x7eddc901,0x42b128a3,2
+np.float32,0x3f4bad09,0x3f3aaf33,2
+np.float32,0xfefb5d76,0xc2b168bd,2
+np.float32,0x3ed3a4cf,0x3ece09a3,2
+np.float32,0x7ec582e4,0x42b0ed4a,2
+np.float32,0x3dc2268a,0x3dc1dc64,2
+np.float32,0x3ef9b17c,0x3ef0b9c9,2
+np.float32,0x2748ac,0x2748ac,2
+np.float32,0xfed6a602,0xc2b117e4,2
+np.float32,0xbefc9c36,0xbef35832,2
+np.float32,0x7e0476,0x7e0476,2
+np.float32,0x804be1a0,0x804be1a0,2
+np.float32,0xbefbc1c2,0xbef2943a,2
+np.float32,0xbd4698f0,0xbd46850a,2
+np.float32,0x688627,0x688627,2
+np.float32,0x3f7f7685,0x3f61406f,2
+np.float32,0x827fb,0x827fb,2
+np.float32,0x3f503264,0x3f3e34fd,2
+np.float32,0x7f5458d1,0x42b27543,2
+np.float32,0x800ac01f,0x800ac01f,2
+np.float32,0x6188dd,0x6188dd,2
+np.float32,0x806ac0ba,0x806ac0ba,2
+np.float32,0xbe14493c,0xbe13c5cc,2
+np.float32,0x3f77542c,0x3f5b72ae,2
+np.float32,0xfeaacab6,0xc2b0a2df,2
+np.float32,0x7f2893d5,0x42b1ff15,2
+np.float32,0x66b528,0x66b528,2
+np.float32,0xbf653e24,0xbf4e3573,2
+np.float32,0x801a2853,0x801a2853,2
+np.float32,0x3f3d8c98,0x3f2f7b04,2
+np.float32,0xfdffbad8,0xc2aeabc5,2
+np.float32,0x3dd50f,0x3dd50f,2
+np.float32,0x3f325a4c,0x3f266353,2
+np.float32,0xfcc48ec0,0xc2ab5f3f,2
+np.float32,0x3e6f5b9a,0x3e6d3ae5,2
+np.float32,0x3dbcd62b,0x3dbc91ee,2
+np.float32,0xbf7458d9,0xbf594c1c,2
+np.float32,0xff5adb24,0xc2b284b9,2
+np.float32,0x807b246d,0x807b246d,2
+np.float32,0x3f800000,0x3f61a1b3,2
+np.float32,0x231a28,0x231a28,2
+np.float32,0xbdc66258,0xbdc61341,2
+np.float32,0x3c84b4b4,0x3c84b338,2
+np.float32,0xbf215894,0xbf183783,2
+np.float32,0xff4ee298,0xc2b267ec,2
+np.float32,0x801ef52e,0x801ef52e,2
+np.float32,0x1040b0,0x1040b0,2
+np.float32,0xff545582,0xc2b2753b,2
+np.float32,0x3f3b9dda,0x3f2decaf,2
+np.float32,0x730f99,0x730f99,2
+np.float32,0xff7fffff,0xc2b2d4fc,2
+np.float32,0xff24cc5e,0xc2b1f379,2
+np.float32,0xbe9b456a,0xbe98fc0b,2
+np.float32,0x188fb,0x188fb,2
+np.float32,0x3f5c7ce2,0x3f47a18a,2
+np.float32,0x7fc00000,0x7fc00000,2
+np.float32,0x806ea4da,0x806ea4da,2
+np.float32,0xfe810570,0xc2b01345,2
+np.float32,0x8036af89,0x8036af89,2
+np.float32,0x8043cec6,0x8043cec6,2
+np.float32,0x80342bb3,0x80342bb3,2
+np.float32,0x1a2bd4,0x1a2bd4,2
+np.float32,0x3f6248c2,0x3f4bff9a,2
+np.float32,0x8024eb35,0x8024eb35,2
+np.float32,0x7ea55872,0x42b09247,2
+np.float32,0x806d6e56,0x806d6e56,2
+np.float32,0x25c21a,0x25c21a,2
+np.float32,0x3f4e95f3,0x3f3cf483,2
+np.float32,0x15ca38,0x15ca38,2
+np.float32,0x803f01b2,0x803f01b2,2
+np.float32,0xbe731634,0xbe70dc10,2
+np.float32,0x3e80cee4,0x3e7ef933,2
+np.float32,0x3ef6dda5,0x3eee2e7b,2
+np.float32,0x3f3dfdc2,0x3f2fd5ed,2
+np.float32,0xff0492a7,0xc2b18411,2
+np.float32,0xbf1d0adf,0xbf148ff3,2
+np.float32,0xfcf75460,0xc2abd4e3,2
+np.float32,0x3f46fca6,0x3f36ffa6,2
+np.float32,0xbe63b5c0,0xbe61dfb3,2
+np.float32,0xff019bec,0xc2b1787d,2
+np.float32,0x801f14a9,0x801f14a9,2
+np.float32,0x3f176cfa,0x3f0fc051,2
+np.float32,0x3f69d976,0x3f51a015,2
+np.float32,0x3f4917cb,0x3f38a87a,2
+np.float32,0x3b2a0bea,0x3b2a0bdd,2
+np.float32,0xbf41d857,0xbf32eb50,2
+np.float32,0xbf08841a,0xbf02c18f,2
+np.float32,0x7ec86f14,0x42b0f4d0,2
+np.float32,0xbf7d15d1,0xbf5f9090,2
+np.float32,0xbd080550,0xbd07feea,2
+np.float32,0xbf6f1bef,0xbf557d26,2
+np.float32,0xfebc282c,0xc2b0d473,2
+np.float32,0x3e68d2f5,0x3e66dd03,2
+np.float32,0x3f3ed8fe,0x3f3085d5,2
+np.float32,0xff2f78ae,0xc2b2139a,2
+np.float32,0xff647a70,0xc2b29ac1,2
+np.float32,0xfd0859a0,0xc2ac06e2,2
+np.float32,0x3ea578a8,0x3ea2b7e1,2
+np.float32,0x6c58c6,0x6c58c6,2
+np.float32,0xff23f26a,0xc2b1f0d2,2
+np.float32,0x800902a4,0x800902a4,2
+np.float32,0xfe8ba64e,0xc2b03bcd,2
+np.float32,0x3f091143,0x3f033e0f,2
+np.float32,0x8017c4bd,0x8017c4bd,2
+np.float32,0xbf708fd4,0xbf568c8c,2
+np.float32,0x3be1d8,0x3be1d8,2
+np.float32,0x80091f07,0x80091f07,2
+np.float32,0x68eabe,0x68eabe,2
+np.float32,0xfe9ab2c8,0xc2b07033,2
+np.float32,0x3eabe752,0x3ea8d3d7,2
+np.float32,0xbf7adcb2,0xbf5dfaf5,2
+np.float32,0x801ecc01,0x801ecc01,2
+np.float32,0xbf5570a9,0xbf424123,2
+np.float32,0x3e89eecd,0x3e88510e,2
+np.float32,0xfeb2feee,0xc2b0bae4,2
+np.float32,0xbeb25ec2,0xbeaef22b,2
+np.float32,0x201e49,0x201e49,2
+np.float32,0x800a35f6,0x800a35f6,2
+np.float32,0xbf02d449,0xbefb6e2a,2
+np.float32,0x3f062bea,0x3f00aef6,2
+np.float32,0x7f5219ff,0x42b26fd2,2
+np.float32,0xbd4561d0,0xbd454e47,2
+np.float32,0x3f6c4789,0x3f536a4b,2
+np.float32,0x7f58b06d,0x42b27fa1,2
+np.float32,0x7f132f39,0x42b1b999,2
+np.float32,0x3e05dcb4,0x3e057bd8,2
+np.float32,0x7f526045,0x42b2707d,2
+np.float32,0x3f6117d0,0x3f4b1adb,2
+np.float32,0xbf21f47d,0xbf18bb57,2
+np.float32,0x1a26d6,0x1a26d6,2
+np.float32,0x46b114,0x46b114,2
+np.float32,0x3eb24518,0x3eaed9ef,2
+np.float32,0xfe2139c8,0xc2af2278,2
+np.float32,0xbf7c36fb,0xbf5ef1f6,2
+np.float32,0x3f193834,0x3f114af7,2
+np.float32,0xff3ea650,0xc2b23e14,2
+np.float32,0xfeeb3bca,0xc2b146c7,2
+np.float32,0x7e8b8ca0,0x42b03b6f,2
+np.float32,0x3eed903d,0x3ee5c5d2,2
+np.float32,0xbdc73740,0xbdc6e72a,2
+np.float32,0x7e500307,0x42afa4ec,2
+np.float32,0xe003c,0xe003c,2
+np.float32,0x3e612bb4,0x3e5f64fd,2
+np.float32,0xfd81e248,0xc2ad50e6,2
+np.float32,0x766a4f,0x766a4f,2
+np.float32,0x3e8708c9,0x3e858414,2
+np.float32,0xbf206c58,0xbf176f7f,2
+np.float32,0x7e93aeb0,0x42b0586f,2
+np.float32,0xfd9d36b8,0xc2adb2ad,2
+np.float32,0xff1f4e0e,0xc2b1e21d,2
+np.float32,0x3f22bd5a,0x3f1964f8,2
+np.float32,0x7f6a517a,0x42b2a7ad,2
+np.float32,0xff6ca773,0xc2b2acc1,2
+np.float32,0x7f6bf453,0x42b2ab3d,2
+np.float32,0x3edfdd64,0x3ed9489f,2
+np.float32,0xbeafc5ba,0xbeac7daa,2
+np.float32,0x7d862039,0x42ad615b,2
+np.float32,0xbe9d2002,0xbe9ac1fc,2
+np.float32,0xbdcc54c0,0xbdcbfe5b,2
+np.float32,0xbf1bc0aa,0xbf13762a,2
+np.float32,0xbf4679ce,0xbf36984b,2
+np.float32,0x3ef45696,0x3eebe713,2
+np.float32,0xff6eb999,0xc2b2b137,2
+np.float32,0xbe4b2e4c,0xbe49dee8,2
+np.float32,0x3f498951,0x3f3901b7,2
+np.float32,0xbe9692f4,0xbe947be1,2
+np.float32,0xbf44ce26,0xbf3545c8,2
+np.float32,0x805787a8,0x805787a8,2
+np.float32,0xbf342650,0xbf27dc26,2
+np.float32,0x3edafbf0,0x3ed4cdd2,2
+np.float32,0x3f6fb858,0x3f55ef63,2
+np.float32,0xff227d0a,0xc2b1ec3f,2
+np.float32,0xfeb9a202,0xc2b0cd89,2
+np.float32,0x7f5b12c1,0x42b2853b,2
+np.float32,0x584578,0x584578,2
+np.float32,0x7ec0b76f,0x42b0e0b5,2
+np.float32,0x3f57f54b,0x3f442f10,2
+np.float32,0x7eef3620,0x42b14f5d,2
+np.float32,0x4525b5,0x4525b5,2
+np.float32,0x801bd407,0x801bd407,2
+np.float32,0xbed1f166,0xbecc7703,2
+np.float32,0x3f57e732,0x3f442449,2
+np.float32,0x80767cd5,0x80767cd5,2
+np.float32,0xbef1a7d2,0xbee97aa3,2
+np.float32,0x3dd5b1af,0x3dd54ee6,2
+np.float32,0x960c,0x960c,2
+np.float32,0x7c392d41,0x42a9ddd1,2
+np.float32,0x3f5c9a34,0x3f47b7c1,2
+np.float32,0x3f5cecee,0x3f47f667,2
+np.float32,0xbee482ce,0xbedd8899,2
+np.float32,0x8066ba7e,0x8066ba7e,2
+np.float32,0x7ed76127,0x42b119a2,2
+np.float32,0x805ca40b,0x805ca40b,2
+np.float32,0x7f5ed5d1,0x42b28df3,2
+np.float32,0xfe9e1b1e,0xc2b07b5b,2
+np.float32,0x3f0201a2,0x3ef9f6c4,2
+np.float32,0xbf2e6430,0xbf232039,2
+np.float32,0x80326b4d,0x80326b4d,2
+np.float32,0x3f11dc7c,0x3f0af06e,2
+np.float32,0xbe89c42e,0xbe8827e6,2
+np.float32,0x3f3c69f8,0x3f2e9133,2
+np.float32,0x806326a9,0x806326a9,2
+np.float32,0x3f1c5286,0x3f13f2b6,2
+np.float32,0xff5c0ead,0xc2b28786,2
+np.float32,0xff32b952,0xc2b21d01,2
+np.float32,0x7dd27c4e,0x42ae4815,2
+np.float32,0xbf7a6816,0xbf5da7a2,2
+np.float32,0xfeac72f8,0xc2b0a7d1,2
+np.float32,0x335ad7,0x335ad7,2
+np.float32,0xbe682da4,0xbe663bcc,2
+np.float32,0x3f2df244,0x3f22c208,2
+np.float32,0x80686e8e,0x80686e8e,2
+np.float32,0x7f50120f,0x42b26ad9,2
+np.float32,0x3dbc596a,0x3dbc15b3,2
+np.float32,0xbf4f2868,0xbf3d666d,2
+np.float32,0x80000001,0x80000001,2
+np.float32,0xff66c059,0xc2b29fd2,2
+np.float32,0xfe8bbcaa,0xc2b03c1f,2
+np.float32,0x3ece6a51,0x3ec93271,2
+np.float32,0x7f06cd26,0x42b18c9a,2
+np.float32,0x7e41e6dc,0x42af80f5,2
+np.float32,0x7d878334,0x42ad669f,2
+np.float32,0xfe8c5c4c,0xc2b03e67,2
+np.float32,0x337a05,0x337a05,2
+np.float32,0x3e63801d,0x3e61ab58,2
+np.float32,0x62c315,0x62c315,2
+np.float32,0x802aa888,0x802aa888,2
+np.float32,0x80038b43,0x80038b43,2
+np.float32,0xff5c1271,0xc2b2878f,2
+np.float32,0xff4184a5,0xc2b245b9,2
+np.float32,0x7ef58f4b,0x42b15cc6,2
+np.float32,0x7f42d8ac,0x42b2493a,2
+np.float32,0x806609f2,0x806609f2,2
+np.float32,0x801e763b,0x801e763b,2
+np.float32,0x7f2bc073,0x42b208a2,2
+np.float32,0x801d7d7f,0x801d7d7f,2
+np.float32,0x7d415dc1,0x42acb9c2,2
+np.float32,0xbf624ff9,0xbf4c0502,2
+np.float32,0xbf603afd,0xbf4a74e2,2
+np.float32,0x8007fe42,0x8007fe42,2
+np.float32,0x800456db,0x800456db,2
+np.float32,0x620871,0x620871,2
+np.float32,0x3e9c6c1e,0x3e9a15fa,2
+np.float32,0x4245d,0x4245d,2
+np.float32,0x8035bde9,0x8035bde9,2
+np.float32,0xbf597418,0xbf45533c,2
+np.float32,0x3c730f80,0x3c730d38,2
+np.float32,0x3f7cd8ed,0x3f5f6540,2
+np.float32,0x807e49c3,0x807e49c3,2
+np.float32,0x3d6584c0,0x3d65660c,2
+np.float32,0xff42a744,0xc2b248b8,2
+np.float32,0xfedc6f56,0xc2b12583,2
+np.float32,0x806263a4,0x806263a4,2
+np.float32,0x175a17,0x175a17,2
+np.float32,0x3f1e8537,0x3f15d208,2
+np.float32,0x4055b5,0x4055b5,2
+np.float32,0x438aa6,0x438aa6,2
+np.float32,0x8038507f,0x8038507f,2
+np.float32,0xbed75348,0xbed16f85,2
+np.float32,0x7f07b7d6,0x42b19012,2
+np.float32,0xfe8b9d30,0xc2b03bac,2
+np.float32,0x805c501c,0x805c501c,2
+np.float32,0x3ef22b1d,0x3ee9f159,2
+np.float32,0x802b6759,0x802b6759,2
+np.float32,0x45281a,0x45281a,2
+np.float32,0xbf7e9970,0xbf60a3cf,2
+np.float32,0xbf14d152,0xbf0d8062,2
+np.float32,0x3d9ff950,0x3d9fcfc8,2
+np.float32,0x7865d9,0x7865d9,2
+np.float32,0xbee67fa4,0xbedf58eb,2
+np.float32,0x7dc822d1,0x42ae2e44,2
+np.float32,0x3f3af0fe,0x3f2d612c,2
+np.float32,0xbefea106,0xbef5274e,2
+np.float32,0xbf758a3f,0xbf5a28c5,2
+np.float32,0xbf331bdd,0xbf270209,2
+np.float32,0x7f51c901,0x42b26f0d,2
+np.float32,0x3f67c33b,0x3f5014d8,2
+np.float32,0xbbc9d980,0xbbc9d92c,2
+np.float32,0xbc407540,0xbc40741e,2
+np.float32,0x7eed9a3c,0x42b14be9,2
+np.float32,0x1be0fe,0x1be0fe,2
+np.float32,0xbf6b4913,0xbf52af1f,2
+np.float32,0xbda8eba8,0xbda8bac6,2
+np.float32,0x8004bcea,0x8004bcea,2
+np.float32,0xff6f6afe,0xc2b2b2b3,2
+np.float32,0xbf205810,0xbf175e50,2
+np.float32,0x80651944,0x80651944,2
+np.float32,0xbec73016,0xbec27a3f,2
+np.float32,0x5701b9,0x5701b9,2
+np.float32,0xbf1062ce,0xbf09a7df,2
+np.float32,0x3e0306ae,0x3e02abd1,2
+np.float32,0x7bfc62,0x7bfc62,2
+np.float32,0xbf48dd3c,0xbf387a6b,2
+np.float32,0x8009573e,0x8009573e,2
+np.float32,0x660a2c,0x660a2c,2
+np.float32,0xff2280da,0xc2b1ec4b,2
+np.float32,0xbf7034fe,0xbf564a54,2
+np.float32,0xbeeb448e,0xbee3b045,2
+np.float32,0xff4e949c,0xc2b2672b,2
+np.float32,0xbf3c4486,0xbf2e7309,2
+np.float32,0x7eb086d8,0x42b0b3c8,2
+np.float32,0x7eac8aca,0x42b0a817,2
+np.float32,0xfd3d2d60,0xc2acae8b,2
+np.float32,0xbf363226,0xbf2987bd,2
+np.float32,0x7f02e524,0x42b17d8c,2
+np.float32,0x8049a148,0x8049a148,2
+np.float32,0x147202,0x147202,2
+np.float32,0x8031d3f6,0x8031d3f6,2
+np.float32,0xfe78bf68,0xc2b0007d,2
+np.float32,0x7ebd16d0,0x42b0d6fb,2
+np.float32,0xbdaed2e8,0xbdae9cbb,2
+np.float32,0x802833ae,0x802833ae,2
+np.float32,0x7f62adf6,0x42b296b5,2
+np.float32,0xff2841c0,0xc2b1fe1b,2
+np.float32,0xbeb2c47e,0xbeaf523b,2
+np.float32,0x7e42a36e,0x42af82e6,2
+np.float32,0x41ea29,0x41ea29,2
+np.float32,0xbcaaa800,0xbcaaa4d7,2
+np.float64,0x3fed71f27ebae3e5,0x3fea5c6095012ca6,2
+np.float64,0x224dc392449b9,0x224dc392449b9,2
+np.float64,0x3fdf897a7d3f12f5,0x3fde620339360992,2
+np.float64,0xbfe1f99a5123f334,0xbfe124a57cfaf556,2
+np.float64,0xbfd9725c3bb2e4b8,0xbfd8d1e3f75110c7,2
+np.float64,0x3fe38977546712ee,0x3fe27d9d37f4b91f,2
+np.float64,0xbfc36c29e526d854,0xbfc3594743ee45c4,2
+np.float64,0xbfe5cbec332b97d8,0xbfe4638802316849,2
+np.float64,0x2ff35efe5fe6d,0x2ff35efe5fe6d,2
+np.float64,0x7fd3f828e227f051,0x40862a7d4a40b1e0,2
+np.float64,0xffd06fc11620df82,0xc08628ee8f1bf6c8,2
+np.float64,0x3fe5321bf4aa6438,0x3fe3e3d9fa453199,2
+np.float64,0xffd07a323ca0f464,0xc08628f3a2930f8c,2
+np.float64,0x3fdf7abe7abef57c,0x3fde54cb193d49cb,2
+np.float64,0x40941f1881285,0x40941f1881285,2
+np.float64,0xffef18defc7e31bd,0xc0863393f2c9f061,2
+np.float64,0xbfe379f871e6f3f1,0xbfe270620cb68347,2
+np.float64,0xffec829848f90530,0xc08632e210edaa2b,2
+np.float64,0x80070c00574e1801,0x80070c00574e1801,2
+np.float64,0xffce7654b23ceca8,0xc086285291e89975,2
+np.float64,0x7fc9932daa33265a,0x408626ec6cc2b807,2
+np.float64,0x355ee98c6abde,0x355ee98c6abde,2
+np.float64,0x3fac54962c38a920,0x3fac50e40b6c19f2,2
+np.float64,0x800857984af0af31,0x800857984af0af31,2
+np.float64,0x7fea6a3d55f4d47a,0x40863245bf39f179,2
+np.float64,0x3fdb8fab33371f56,0x3fdac5ffc9e1c347,2
+np.float64,0x800a887a7bf510f5,0x800a887a7bf510f5,2
+np.float64,0xbfbdbda3c63b7b48,0xbfbdac9dd5a2d3e8,2
+np.float64,0xbfd4a2457b29448a,0xbfd44acb3b316d6d,2
+np.float64,0x7fd5329a502a6534,0x40862af789b528b5,2
+np.float64,0x3fd96a7bceb2d4f8,0x3fd8ca92104d6cd6,2
+np.float64,0x3fde6a0cd6bcd41a,0x3fdd5f4b85abf749,2
+np.float64,0xbfc7faaff32ff560,0xbfc7d7560b8c4a52,2
+np.float64,0x7fec381b2f787035,0x408632cd0e9c095c,2
+np.float64,0x1fc2eb543f85e,0x1fc2eb543f85e,2
+np.float64,0x7ac6000af58c1,0x7ac6000af58c1,2
+np.float64,0xffe060a87920c150,0xc0862e72c37d5a4e,2
+np.float64,0xbfb7d8c89e2fb190,0xbfb7cffd3c3f8e3a,2
+np.float64,0x3fd91033deb22068,0x3fd87695b067aa1e,2
+np.float64,0x3fec1aff01b835fe,0x3fe95d5cbd729af7,2
+np.float64,0x7fb97f69ec32fed3,0x4086215aaae5c697,2
+np.float64,0x7feaf1e4e5f5e3c9,0x4086326e6ca6a2bb,2
+np.float64,0x800537e44d0a6fc9,0x800537e44d0a6fc9,2
+np.float64,0x800b2a0d0d36541a,0x800b2a0d0d36541a,2
+np.float64,0x3fe2193846e43270,0x3fe140308550138e,2
+np.float64,0x5e2a0a32bc542,0x5e2a0a32bc542,2
+np.float64,0xffe5888b09eb1116,0xc08630a348783aa3,2
+np.float64,0xbfceb9b5033d736c,0xbfce701049c10435,2
+np.float64,0x7fe5d68589abad0a,0x408630c00ce63f23,2
+np.float64,0x8009b5457ff36a8b,0x8009b5457ff36a8b,2
+np.float64,0xbfb5518c2e2aa318,0xbfb54b42638ca718,2
+np.float64,0x3f9c58469838b080,0x3f9c575974fbcd7b,2
+np.float64,0x3fe8db4b4731b697,0x3fe6dc9231587966,2
+np.float64,0x8007d0f77f4fa1f0,0x8007d0f77f4fa1f0,2
+np.float64,0x7fe79eef542f3dde,0x40863160c673c67f,2
+np.float64,0xffbdc0b6163b8170,0xc0862296be4bf032,2
+np.float64,0x3fbb8d3312371a66,0x3fbb7fa76fb4cf8d,2
+np.float64,0xffd8a0eedbb141de,0xc0862c2ac6e512f0,2
+np.float64,0x7fee99d8d87d33b1,0x4086337301c4c8df,2
+np.float64,0xffe7479b552e8f36,0xc0863142fba0f0ec,2
+np.float64,0xffedf8ef4abbf1de,0xc08633488068fe69,2
+np.float64,0x895c4d9f12b8a,0x895c4d9f12b8a,2
+np.float64,0x29b4caf05369a,0x29b4caf05369a,2
+np.float64,0xbfefb90d657f721b,0xbfec01efa2425b35,2
+np.float64,0xde07c3bdbc0f9,0xde07c3bdbc0f9,2
+np.float64,0x7feae9fd02f5d3f9,0x4086326c1368ed5a,2
+np.float64,0x3feab792da756f26,0x3fe84f6e15338ed7,2
+np.float64,0xbfeff8ed72fff1db,0xbfec2f35da06daaf,2
+np.float64,0x8004b2c132896583,0x8004b2c132896583,2
+np.float64,0xbf9fcb00103f9600,0xbf9fc9b1751c569e,2
+np.float64,0x4182b72e83058,0x4182b72e83058,2
+np.float64,0x90820d812105,0x90820d812105,2
+np.float64,0xbfdec9a0ba3d9342,0xbfddb585df607ce1,2
+np.float64,0x7fdc0a69a03814d2,0x40862d347f201b63,2
+np.float64,0xbfef0708937e0e11,0xbfeb82d27f8ea97f,2
+np.float64,0xffda57e4ddb4afca,0xc0862cb49e2e0c4c,2
+np.float64,0xbfa30b9af4261730,0xbfa30a7b4a633060,2
+np.float64,0x7feb57fcc4b6aff9,0x4086328c83957a0b,2
+np.float64,0x7fe6759153eceb22,0x408630f980433963,2
+np.float64,0x7fdd3278c8ba64f1,0x40862d87445243e9,2
+np.float64,0xd3b8e6b9a771d,0xd3b8e6b9a771d,2
+np.float64,0x6267dc88c4cfc,0x6267dc88c4cfc,2
+np.float64,0x7fedd3cf00bba79d,0x4086333e91712ff5,2
+np.float64,0xffbe512ce03ca258,0xc08622bd39314cea,2
+np.float64,0xbfe71742ca6e2e86,0xbfe572ccbf2d010d,2
+np.float64,0x8002fb048c65f60a,0x8002fb048c65f60a,2
+np.float64,0x800d9d9ddf7b3b3c,0x800d9d9ddf7b3b3c,2
+np.float64,0xbfeaf6230df5ec46,0xbfe87f5d751ec3d5,2
+np.float64,0xbfe69973a42d32e8,0xbfe50c680f7002fe,2
+np.float64,0x3fe309cf87e613a0,0x3fe21048714ce1ac,2
+np.float64,0x800435d17a286ba4,0x800435d17a286ba4,2
+np.float64,0x7fefffffffffffff,0x408633ce8fb9f87e,2
+np.float64,0x3fe36ade1766d5bc,0x3fe26379fb285dde,2
+np.float64,0x3f98d8d94831b1c0,0x3f98d839885dc527,2
+np.float64,0xbfd08f7ae5211ef6,0xbfd0618ab5293e1e,2
+np.float64,0xbfcf630bd53ec618,0xbfcf14a0cd20704d,2
+np.float64,0xbfe58f0ca6eb1e1a,0xbfe4312225df8e28,2
+np.float64,0xffef4f6406be9ec7,0xc08633a1ed1d27e5,2
+np.float64,0x7fe10120b3e20240,0x40862ebfaf94e6e8,2
+np.float64,0xffe96c52fbb2d8a5,0xc08631f75d9a59a0,2
+np.float64,0xbfe448a333e89146,0xbfe31fee44c3ec43,2
+np.float64,0x80045ff4e788bfeb,0x80045ff4e788bfeb,2
+np.float64,0x7fefaa2f823f545e,0x408633b8fea29524,2
+np.float64,0xffea6b8bf234d717,0xc0863246248e5960,2
+np.float64,0xbfdb085d80b610bc,0xbfda498b15b43eec,2
+np.float64,0xbfd5e12da3abc25c,0xbfd57970e2b8aecc,2
+np.float64,0x3fcc84928a390925,0x3fcc497c417a89f3,2
+np.float64,0xbfdcb713bf396e28,0xbfdbd46c5e731fd9,2
+np.float64,0xffdf50c0453ea180,0xc0862e16b5562f25,2
+np.float64,0x800342c2f7268587,0x800342c2f7268587,2
+np.float64,0x7feb8b6d743716da,0x4086329b8248de2c,2
+np.float64,0x800a9b18b4953632,0x800a9b18b4953632,2
+np.float64,0xffedaf0d12fb5e19,0xc0863334af82de1a,2
+np.float64,0x800aebda4ab5d7b5,0x800aebda4ab5d7b5,2
+np.float64,0xbfa9f5848433eb10,0xbfa9f2ac7ac065d4,2
+np.float64,0x3fea375928f46eb2,0x3fe7ec9f10eeac7d,2
+np.float64,0x3fd6c213fead8428,0x3fd64dcc1eff5f1b,2
+np.float64,0xbfa0476f44208ee0,0xbfa046bb986007ac,2
+np.float64,0x6c8e18aed91c4,0x6c8e18aed91c4,2
+np.float64,0x8000000000000001,0x8000000000000001,2
+np.float64,0x7fea86b5ba350d6a,0x4086324e59f13027,2
+np.float64,0x2316c3b0462d9,0x2316c3b0462d9,2
+np.float64,0x3fec4e3281389c65,0x3fe983c5c9d65940,2
+np.float64,0x3fbb87c47f772,0x3fbb87c47f772,2
+np.float64,0x8004af00fdc95e03,0x8004af00fdc95e03,2
+np.float64,0xbfd316db9ba62db8,0xbfd2d12765b9d155,2
+np.float64,0x3fec1a7a99f834f6,0x3fe95cf941889b3d,2
+np.float64,0x3feff7e1477fefc3,0x3fec2e782392d4b9,2
+np.float64,0xbfc683ea042d07d4,0xbfc66698cfa5026e,2
+np.float64,0x3fdbc8aaa9b79154,0x3fdafa50e6fc3fff,2
+np.float64,0xfb3b630ff676d,0xfb3b630ff676d,2
+np.float64,0x7fe715ef8eae2bde,0x40863131d794b41f,2
+np.float64,0x7fefa06c11bf40d7,0x408633b686c7996a,2
+np.float64,0x80002a40f5205483,0x80002a40f5205483,2
+np.float64,0x7fe95f3c74b2be78,0x408631f33e37bf76,2
+np.float64,0x3fb2977b32252ef0,0x3fb2934eaf5a4be8,2
+np.float64,0x3fc0f3dbc821e7b8,0x3fc0e745288c84c3,2
+np.float64,0x3fda98da56b531b5,0x3fd9e2b19447dacc,2
+np.float64,0x3f95b9d5202b73aa,0x3f95b96a53282949,2
+np.float64,0x3fdc1ace7738359d,0x3fdb4597d31df7ff,2
+np.float64,0xffeac5bb2e358b76,0xc0863261452ab66c,2
+np.float64,0xbfefb1b78f7f636f,0xbfebfcb9be100ced,2
+np.float64,0xf5c9e191eb93c,0xf5c9e191eb93c,2
+np.float64,0x3fe83a977630752f,0x3fe65d0df90ff6ef,2
+np.float64,0x3fc317515d262ea0,0x3fc3056072b719f0,2
+np.float64,0x7fe2dcfab225b9f4,0x40862f94257c28a2,2
+np.float64,0xca2b115794562,0xca2b115794562,2
+np.float64,0x3fd495301aa92a60,0x3fd43e57108761d5,2
+np.float64,0x800ccc4293199885,0x800ccc4293199885,2
+np.float64,0xc8d3173d91a63,0xc8d3173d91a63,2
+np.float64,0xbf2541bb7e4a8,0xbf2541bb7e4a8,2
+np.float64,0xbfe9a330df334662,0xbfe779816573f5be,2
+np.float64,0xffd5e4c8252bc990,0xc0862b39b3ca5d72,2
+np.float64,0x3fe90f3a53721e75,0x3fe70585ae09531d,2
+np.float64,0xbfe2b5ddc7a56bbc,0xbfe1c7fa91a675ed,2
+np.float64,0xbf981a0360303400,0xbf9819719345073a,2
+np.float64,0x19174b0e322ea,0x19174b0e322ea,2
+np.float64,0xbfd2f71a1725ee34,0xbfd2b2b6f7cd10b1,2
+np.float64,0x80056e83236add07,0x80056e83236add07,2
+np.float64,0x7fe4bc41d9697883,0x40863055f20ce0cb,2
+np.float64,0xffe76e06c46edc0d,0xc086315024b25559,2
+np.float64,0x3fe3c4f0f96789e2,0x3fe2b04b584609bf,2
+np.float64,0x3fe6cfc533ed9f8a,0x3fe538b4d784d5ee,2
+np.float64,0x7fd234a640a4694c,0x408629bfead4f0b2,2
+np.float64,0x3fdbc49c9ab78939,0x3fdaf698a83d08e2,2
+np.float64,0x3fe4c5336ee98a66,0x3fe388c6ddb60e0a,2
+np.float64,0xf4b9497be9729,0xf4b9497be9729,2
+np.float64,0x3fb312be12262580,0x3fb30e3c847c1d16,2
+np.float64,0x3fe9554218f2aa84,0x3fe73c8b311c7a98,2
+np.float64,0xff899816a0333040,0xc08610bfb2cd8559,2
+np.float64,0x8006008ad52c0116,0x8006008ad52c0116,2
+np.float64,0x3fd7d47be4afa8f8,0x3fd74fa71ec17fd0,2
+np.float64,0x8010000000000000,0x8010000000000000,2
+np.float64,0xdf2a9943be553,0xdf2a9943be553,2
+np.float64,0xbfeb86bf1eb70d7e,0xbfe8ed797580ba5c,2
+np.float64,0x800e2c0c28bc5818,0x800e2c0c28bc5818,2
+np.float64,0xbfe2be65d4657ccc,0xbfe1cf578dec2323,2
+np.float64,0xbfedea3a5afbd475,0xbfeab490bf05e585,2
+np.float64,0xbfe04b1583a0962b,0xbfdf523dfd7be25c,2
+np.float64,0x75929bb4eb254,0x75929bb4eb254,2
+np.float64,0x3fd7b4968caf692d,0x3fd731c0938ff97c,2
+np.float64,0x60bd8fd2c17b3,0x60bd8fd2c17b3,2
+np.float64,0xbfdaf15e70b5e2bc,0xbfda345a95ce18fe,2
+np.float64,0x7fdd7c35c2baf86b,0x40862d9b5f40c6b2,2
+np.float64,0x7feeb4d2ab7d69a4,0x4086337a0c0dffaf,2
+np.float64,0xffe65b5a1decb6b4,0xc08630f024420efb,2
+np.float64,0x7feb272b30764e55,0x4086327e2e553aa2,2
+np.float64,0x3fd27513e8a4ea28,0x3fd235ea49670f6a,2
+np.float64,0x3fe6541a6aeca834,0x3fe4d3a5b69fd1b6,2
+np.float64,0xbfe0c6ca0f618d94,0xbfe017058259efdb,2
+np.float64,0x7fc1bf07b7237e0e,0x4086240000fa5a52,2
+np.float64,0x7fe96af9c0f2d5f3,0x408631f6f0f4faa2,2
+np.float64,0x3fe0728be7a0e518,0x3fdf9881a5869de9,2
+np.float64,0xffe8ea4441b1d488,0xc08631ce0685ae7e,2
+np.float64,0xffd0b973f02172e8,0xc08629121e7fdf85,2
+np.float64,0xffe37b907a26f720,0xc0862fd6529401a0,2
+np.float64,0x3fe0ee826461dd05,0x3fe03a2a424a1b40,2
+np.float64,0xbfe8073c92300e79,0xbfe6340cbd179ac1,2
+np.float64,0x800768383f8ed071,0x800768383f8ed071,2
+np.float64,0x8002e467c7c5c8d0,0x8002e467c7c5c8d0,2
+np.float64,0xbfd8d53ea5b1aa7e,0xbfd83fa7243289d7,2
+np.float64,0xffebefce2bb7df9c,0xc08632b874f4f8dc,2
+np.float64,0xffe3be9eb9277d3d,0xc0862ff1ac70ad0b,2
+np.float64,0xffe2f8a82e65f150,0xc0862f9fd9e77d86,2
+np.float64,0xbfa01d151c203a30,0xbfa01c66dc13a70a,2
+np.float64,0x800877062d30ee0d,0x800877062d30ee0d,2
+np.float64,0xaade16a755bc3,0xaade16a755bc3,2
+np.float64,0xbfeb1abc70363579,0xbfe89b52c3b003aa,2
+np.float64,0x80097d0b2ad2fa17,0x80097d0b2ad2fa17,2
+np.float64,0x8001499907429333,0x8001499907429333,2
+np.float64,0x3fe8db2aaf71b656,0x3fe6dc7873f1b235,2
+np.float64,0x5cfeadc4b9fd6,0x5cfeadc4b9fd6,2
+np.float64,0xff3f77d1fe7ef,0xff3f77d1fe7ef,2
+np.float64,0xffeecd56f9bd9aad,0xc08633806cb1163d,2
+np.float64,0xbf96f3ca582de7a0,0xbf96f34c6b8e1c85,2
+np.float64,0x7ed6b44afdad7,0x7ed6b44afdad7,2
+np.float64,0x80071808da4e3012,0x80071808da4e3012,2
+np.float64,0x3feb8aee2bf715dc,0x3fe8f0a55516615c,2
+np.float64,0x800038f62e2071ed,0x800038f62e2071ed,2
+np.float64,0x3fb13f9af2227f30,0x3fb13c456ced8e08,2
+np.float64,0xffd584d1812b09a4,0xc0862b165558ec0c,2
+np.float64,0x800b20c30fb64186,0x800b20c30fb64186,2
+np.float64,0x80024f9646e49f2d,0x80024f9646e49f2d,2
+np.float64,0xffefffffffffffff,0xc08633ce8fb9f87e,2
+np.float64,0x3fdddbcb5bbbb797,0x3fdcde981111f650,2
+np.float64,0xffed14077f3a280e,0xc086330a795ad634,2
+np.float64,0x800fec2da7ffd85b,0x800fec2da7ffd85b,2
+np.float64,0x3fe8205ffc7040c0,0x3fe6482318d217f9,2
+np.float64,0x3013e5226027d,0x3013e5226027d,2
+np.float64,0xffe4e5aad469cb55,0xc0863065dc2fb4e3,2
+np.float64,0x5cb0f7b2b9620,0x5cb0f7b2b9620,2
+np.float64,0xbfeb4537d2768a70,0xbfe8bbb2c1d3bff9,2
+np.float64,0xbfd859e297b0b3c6,0xbfd7cc807948bf9d,2
+np.float64,0x71f00b8ce3e02,0x71f00b8ce3e02,2
+np.float64,0xf5c1b875eb837,0xf5c1b875eb837,2
+np.float64,0xa0f35c8141e8,0xa0f35c8141e8,2
+np.float64,0xffe24860b42490c1,0xc0862f54222f616e,2
+np.float64,0xffcd9ae8583b35d0,0xc08628181e643a42,2
+np.float64,0x7fe9b710c7736e21,0x4086320ec033490f,2
+np.float64,0x3fd2b9ca1d257394,0x3fd277e631f0c0b3,2
+np.float64,0x23559bfc46ab4,0x23559bfc46ab4,2
+np.float64,0x8002adf75e455bef,0x8002adf75e455bef,2
+np.float64,0xbfefa4d75cbf49af,0xbfebf392e51d6a1a,2
+np.float64,0xffcfef263e3fde4c,0xc08628b336adb611,2
+np.float64,0x80061acaa8ec3596,0x80061acaa8ec3596,2
+np.float64,0x7fc1b33be0236677,0x408623faaddcc17e,2
+np.float64,0x7fe3a84083675080,0x40862fe8972e41e1,2
+np.float64,0xbfe756c1276ead82,0xbfe5a6318b061e1b,2
+np.float64,0xbfae4b71b43c96e0,0xbfae46ed0b6203a4,2
+np.float64,0x800421c6d0a8438e,0x800421c6d0a8438e,2
+np.float64,0x8009ad56fe335aae,0x8009ad56fe335aae,2
+np.float64,0xbfe71afc976e35f9,0xbfe575d21f3d7193,2
+np.float64,0x7fec0bbe4c38177c,0x408632c0710f1d8a,2
+np.float64,0x750e1daeea1c4,0x750e1daeea1c4,2
+np.float64,0x800501d4240a03a9,0x800501d4240a03a9,2
+np.float64,0x800794955cef292b,0x800794955cef292b,2
+np.float64,0x3fdf8a87f5bf1510,0x3fde62f4f00cfa19,2
+np.float64,0xbfebebdbc7f7d7b8,0xbfe939e51ba1340c,2
+np.float64,0xbfe3a16217a742c4,0xbfe292039dd08a71,2
+np.float64,0x3fed6cd04c3ad9a1,0x3fea58995973f74b,2
+np.float64,0xffcad8787335b0f0,0xc086274fbb35dd37,2
+np.float64,0x3fcb178e3d362f1c,0x3fcae4c9f3e6dddc,2
+np.float64,0xbfcadc669435b8cc,0xbfcaaae7cf075420,2
+np.float64,0x7fe0e3906321c720,0x40862eb1bacc5c43,2
+np.float64,0xff8ad5edb035abc0,0xc0861120b6404d0b,2
+np.float64,0x3fe175a21562eb44,0x3fe0b13120a46549,2
+np.float64,0xbfeb4c4a5f769895,0xbfe8c1147f1c9d8f,2
+np.float64,0x7fca22f4e63445e9,0x40862718e9b4094e,2
+np.float64,0x3fe4269d0c684d3a,0x3fe3032aa2015c53,2
+np.float64,0x3fef551c09beaa38,0x3febbabe03f49c83,2
+np.float64,0xffd843df9fb087c0,0xc0862c0c52d5e5d9,2
+np.float64,0x7fc497e2ca292fc5,0x40862530bbd9fcc7,2
+np.float64,0x3fee02919efc0523,0x3feac655588a4acd,2
+np.float64,0x7fed1e52c0fa3ca5,0x4086330d4ddd8a2c,2
+np.float64,0xba04d4ef7409b,0xba04d4ef7409b,2
+np.float64,0x3fee22d0937c45a2,0x3feaddd4ca66b447,2
+np.float64,0xffeb2558cf764ab1,0xc086327da4e84053,2
+np.float64,0xbfe103d987e207b3,0xbfe04d04818ad1ff,2
+np.float64,0x3f9fd7fed03faffe,0x3f9fd6ae9a45be84,2
+np.float64,0x800a53ec4c34a7d9,0x800a53ec4c34a7d9,2
+np.float64,0xbfe2feb17f65fd63,0xbfe206b9d33a78a2,2
+np.float64,0x989bdd613139,0x989bdd613139,2
+np.float64,0xbfdd0ad3fb3a15a8,0xbfdc20c32a530741,2
+np.float64,0xbfc4222163284444,0xbfc40d1c612784b5,2
+np.float64,0xc30cf5c78619f,0xc30cf5c78619f,2
+np.float64,0x3fe913bd6732277b,0x3fe70912f76bad71,2
+np.float64,0x98f175f531e2f,0x98f175f531e2f,2
+np.float64,0x3fed8c1f717b183f,0x3fea6f9fb3af3423,2
+np.float64,0x7fee46b085bc8d60,0x4086335d269eb7e9,2
+np.float64,0x8007480f564e901f,0x8007480f564e901f,2
+np.float64,0xc9b96e179372e,0xc9b96e179372e,2
+np.float64,0x3fe44deac4289bd6,0x3fe32463a74a69e7,2
+np.float64,0x80021d6c5c243ad9,0x80021d6c5c243ad9,2
+np.float64,0xbfebc805a6f7900b,0xbfe91edcf65a1c19,2
+np.float64,0x80044748adc88e92,0x80044748adc88e92,2
+np.float64,0x4007ee44800fe,0x4007ee44800fe,2
+np.float64,0xbfe24307a4648610,0xbfe1648ad5c47b6f,2
+np.float64,0xbfee6d3a93fcda75,0xbfeb13e1a3196e78,2
+np.float64,0x3fe49a287f293451,0x3fe364a11b9f0068,2
+np.float64,0x80052b37ceaa5670,0x80052b37ceaa5670,2
+np.float64,0xbfd42be893a857d2,0xbfd3da05dac7c286,2
+np.float64,0xffb4bbe4ac2977c8,0xc0861fb31bda6956,2
+np.float64,0xbfc732a4142e6548,0xbfc7129a4eafa399,2
+np.float64,0x7fd0696791a0d2ce,0x408628eb7756cb9c,2
+np.float64,0x3fe46c8f8d68d91f,0x3fe33e3df16187c1,2
+np.float64,0x3fe3a28f1ce7451e,0x3fe293043238d08c,2
+np.float64,0xffedc4eb723b89d6,0xc086333a92258c15,2
+np.float64,0x8000d15b4c41a2b7,0x8000d15b4c41a2b7,2
+np.float64,0xffeb73450236e689,0xc08632947b0148ab,2
+np.float64,0xffe68cf4722d19e8,0xc0863101d08d77bd,2
+np.float64,0x800c70eb4698e1d7,0x800c70eb4698e1d7,2
+np.float64,0xffa94387ff529,0xffa94387ff529,2
+np.float64,0x7fe3835d996706ba,0x40862fd985ff8e7d,2
+np.float64,0x3fe55e476feabc8e,0x3fe408a15594ec52,2
+np.float64,0xffc69672222d2ce4,0xc08625ee0c4c0f6a,2
+np.float64,0xbf9d900b883b2020,0xbf9d8efe811d36df,2
+np.float64,0xbfdb9b9755b7372e,0xbfdad0f2aa2cb110,2
+np.float64,0xffeade6073b5bcc0,0xc08632689f17a25d,2
+np.float64,0xffd1d6a6baa3ad4e,0xc086299630a93a7b,2
+np.float64,0x7fd05ba25620b744,0x408628e4be1ef845,2
+np.float64,0xbfc7d422d52fa844,0xbfc7b170a61531bf,2
+np.float64,0x3fd5196797aa32d0,0x3fd4bc0f0e7d8e1d,2
+np.float64,0x617594a4c2eb3,0x617594a4c2eb3,2
+np.float64,0x7fd779bc4caef378,0x40862bc89271b882,2
+np.float64,0xffd2fb262ba5f64c,0xc0862a15561e9524,2
+np.float64,0x72fd661ae5fad,0x72fd661ae5fad,2
+np.float64,0x3fecf441f339e884,0x3fe9ff880d584f64,2
+np.float64,0x7fc3a8968827512c,0x408624d198b05c61,2
+np.float64,0x3fe7a25c56ef44b9,0x3fe5e32509a7c32d,2
+np.float64,0x7fd117d514222fa9,0x4086293ec640d5f2,2
+np.float64,0x3fe37dfe5ee6fbfc,0x3fe273d1bcaa1ef0,2
+np.float64,0xbfed4cd19d7a99a3,0xbfea41064cba4c8b,2
+np.float64,0x8003ff12aaa7fe26,0x8003ff12aaa7fe26,2
+np.float64,0x3fcbc3d1193787a2,0x3fcb8d39e3e88264,2
+np.float64,0xe9ba1a91d3744,0xe9ba1a91d3744,2
+np.float64,0x8002ab71998556e4,0x8002ab71998556e4,2
+np.float64,0x800110057922200c,0x800110057922200c,2
+np.float64,0xbfe3b7af19a76f5e,0xbfe2a502fc0a2882,2
+np.float64,0x7fd9de9d5e33bd3a,0x40862c8f73cccabf,2
+np.float64,0xbfba0f0a86341e18,0xbfba0392f44c2771,2
+np.float64,0x8000000000000000,0x8000000000000000,2
+np.float64,0x7fe5d162e96ba2c5,0x408630be2b15e01b,2
+np.float64,0x800b7f0eac76fe1e,0x800b7f0eac76fe1e,2
+np.float64,0xff98bed150317da0,0xc086160633164f5f,2
+np.float64,0x3fef91fd70ff23fb,0x3febe629709d0ae7,2
+np.float64,0x7fe5bea7f16b7d4f,0x408630b749f445e9,2
+np.float64,0xbfe3dc428467b885,0xbfe2c41ea93fab07,2
+np.float64,0xbfeba1fbfcf743f8,0xbfe9021b52851bb9,2
+np.float64,0x7fd2fb2108a5f641,0x40862a1553f45830,2
+np.float64,0x7feb8199a4370332,0x40863298a7169dad,2
+np.float64,0x800f97ff8d7f2fff,0x800f97ff8d7f2fff,2
+np.float64,0x3fd5e20b6b2bc417,0x3fd57a42bd1c0993,2
+np.float64,0x8006b4072dad680f,0x8006b4072dad680f,2
+np.float64,0x605dccf2c0bba,0x605dccf2c0bba,2
+np.float64,0x3fc705ed142e0bda,0x3fc6e69971d86f73,2
+np.float64,0xffd2ba1aad257436,0xc08629f9bc918f8b,2
+np.float64,0x8002954e23c52a9d,0x8002954e23c52a9d,2
+np.float64,0xbfecc65da7798cbb,0xbfe9dd745be18562,2
+np.float64,0x7fc66110482cc220,0x408625db0db57ef8,2
+np.float64,0x3fcd09446d3a1289,0x3fcccaf2dd0a41ea,2
+np.float64,0x3febe7095437ce13,0x3fe93642d1e73b2a,2
+np.float64,0x8004773c7da8ee7a,0x8004773c7da8ee7a,2
+np.float64,0x8001833241230665,0x8001833241230665,2
+np.float64,0x3fe6a262db6d44c6,0x3fe513b3dab5adce,2
+np.float64,0xe6282cc1cc506,0xe6282cc1cc506,2
+np.float64,0x800b9d8553973b0b,0x800b9d8553973b0b,2
+np.float64,0x3fdfbe0c7b3f7c19,0x3fde912375d867a8,2
+np.float64,0x7fd5ac11ebab5823,0x40862b24dfc6d08e,2
+np.float64,0x800e4b7cb1fc96f9,0x800e4b7cb1fc96f9,2
+np.float64,0x3fe14706da628e0e,0x3fe0883aec2a917a,2
+np.float64,0x7fc963f97532c7f2,0x408626dd9b0cafe1,2
+np.float64,0xbfe9c250b5b384a2,0xbfe791c5eabcb05d,2
+np.float64,0x3fe8d16e6c71a2dd,0x3fe6d4c7a33a0bf4,2
+np.float64,0x3fe474ae4628e95d,0x3fe34515c93f4733,2
+np.float64,0x3fbf3257ee3e64b0,0x3fbf1eb530e126ea,2
+np.float64,0x8005f089b3abe114,0x8005f089b3abe114,2
+np.float64,0x3fece07bccf9c0f8,0x3fe9f0dc228124d5,2
+np.float64,0xbfc52521632a4a44,0xbfc50ccebdf59c2c,2
+np.float64,0x7fdf53beb13ea77c,0x40862e177918195e,2
+np.float64,0x8003d9f6ad07b3ee,0x8003d9f6ad07b3ee,2
+np.float64,0xffeacf96bbb59f2d,0xc086326436b38b1a,2
+np.float64,0xdccaea29b995e,0xdccaea29b995e,2
+np.float64,0x5948d21eb291b,0x5948d21eb291b,2
+np.float64,0x10000000000000,0x10000000000000,2
+np.float64,0x7fef6d2c543eda58,0x408633a98593cdf5,2
+np.float64,0x7feda454f47b48a9,0x40863331cb6dc9f7,2
+np.float64,0x3fdd377cecba6ef8,0x3fdc4968f74a9c83,2
+np.float64,0x800644096d4c8814,0x800644096d4c8814,2
+np.float64,0xbfe33ca15ae67942,0xbfe23be5de832bd8,2
+np.float64,0xffce9582bd3d2b04,0xc086285abdf9bf9d,2
+np.float64,0x3fe6621e86acc43d,0x3fe4df231bfa93e1,2
+np.float64,0xee7d19e9dcfa3,0xee7d19e9dcfa3,2
+np.float64,0x800be5997277cb33,0x800be5997277cb33,2
+np.float64,0x82069041040e,0x82069041040e,2
+np.float64,0x800d6efdc19addfc,0x800d6efdc19addfc,2
+np.float64,0x7fb27770ee24eee1,0x40861ec5ed91b839,2
+np.float64,0x3fd506064caa0c0d,0x3fd4a9a66353fefd,2
+np.float64,0xbfeca9b36bf95367,0xbfe9c81f03ba37b8,2
+np.float64,0xffeab1b7bab5636f,0xc086325b47f61f2b,2
+np.float64,0xffc99f5b2e333eb8,0xc08626f03b08b412,2
+np.float64,0x3fbf1a71bc3e34e3,0x3fbf06fbcaa5de58,2
+np.float64,0x3fe75015736ea02b,0x3fe5a0cd8d763d8d,2
+np.float64,0xffe6a7442fad4e88,0xc086310b20addba4,2
+np.float64,0x3fe5d62ff86bac60,0x3fe46c033195bf28,2
+np.float64,0x7fd0b1f0362163df,0x4086290e857dc1be,2
+np.float64,0xbe0353737c06b,0xbe0353737c06b,2
+np.float64,0x7fec912d8739225a,0x408632e627704635,2
+np.float64,0xded8ba2fbdb18,0xded8ba2fbdb18,2
+np.float64,0x7fec0b53fdf816a7,0x408632c052bc1bd2,2
+np.float64,0x7fe9640d12b2c819,0x408631f4c2ba54d8,2
+np.float64,0x800be714eeb7ce2a,0x800be714eeb7ce2a,2
+np.float64,0xbfcf444a793e8894,0xbfcef6c126b54853,2
+np.float64,0xffeb20cf1bf6419e,0xc086327c4e6ffe80,2
+np.float64,0xc07de22180fd,0xc07de22180fd,2
+np.float64,0xffed129d387a253a,0xc086330a15ad0adb,2
+np.float64,0x3fd9e94fedb3d2a0,0x3fd94049924706a8,2
+np.float64,0x7fe6ba488c2d7490,0x40863111d51e7861,2
+np.float64,0xbfebbdf25db77be5,0xbfe91740ad7ba521,2
+np.float64,0x7fbc6c3c4838d878,0x40862239160cb613,2
+np.float64,0xbfefa82ecebf505e,0xbfebf5f31957dffd,2
+np.float64,0x800bebeb7ad7d7d7,0x800bebeb7ad7d7d7,2
+np.float64,0x7fecccc6f8f9998d,0x408632f6c6da8aac,2
+np.float64,0xcbe4926197ca,0xcbe4926197ca,2
+np.float64,0x2c5d9fd858bb5,0x2c5d9fd858bb5,2
+np.float64,0xbfe9fb021073f604,0xbfe7bddc61f1151a,2
+np.float64,0xbfebb18572f7630b,0xbfe90ddc5002313f,2
+np.float64,0x13bb0d3227763,0x13bb0d3227763,2
+np.float64,0x3feefa5e5cbdf4bd,0x3feb79b9e8ce16bf,2
+np.float64,0x3fc97f086132fe10,0x3fc9549fc8e15ecb,2
+np.float64,0xffe70887c06e110f,0xc086312d30fd31cf,2
+np.float64,0xa00c113540182,0xa00c113540182,2
+np.float64,0x800950984772a131,0x800950984772a131,2
+np.float64,0x1,0x1,2
+np.float64,0x3fd83b4026b07680,0x3fd7afdc659d9a34,2
+np.float64,0xbfe32348fbe64692,0xbfe226292a706a1a,2
+np.float64,0x800b894dcc77129c,0x800b894dcc77129c,2
+np.float64,0xeb2ca419d6595,0xeb2ca419d6595,2
+np.float64,0xbff0000000000000,0xbfec34366179d427,2
+np.float64,0x3feb269e99f64d3d,0x3fe8a4634b927a21,2
+np.float64,0xbfe83149d7706294,0xbfe655a2b245254e,2
+np.float64,0xbfe6eef3ca6ddde8,0xbfe5521310e24d16,2
+np.float64,0x3fea89a4b7b51349,0x3fe82c1fc69edcec,2
+np.float64,0x800f2a8bf17e5518,0x800f2a8bf17e5518,2
+np.float64,0x800f71fac29ee3f6,0x800f71fac29ee3f6,2
+np.float64,0xe7cb31f1cf966,0xe7cb31f1cf966,2
+np.float64,0x3b0f8752761f2,0x3b0f8752761f2,2
+np.float64,0x3fea27dea3744fbd,0x3fe7e0a4705476b2,2
+np.float64,0xbfa97c019c32f800,0xbfa97950c1257b92,2
+np.float64,0xffeff13647ffe26c,0xc08633cadc7105ed,2
+np.float64,0x3feee162353dc2c4,0x3feb67c2da0fbce8,2
+np.float64,0x80088c0807911810,0x80088c0807911810,2
+np.float64,0x3fe936ab1db26d56,0x3fe72489bc69719d,2
+np.float64,0xa2f84bd545f0a,0xa2f84bd545f0a,2
+np.float64,0xbfed445ed27a88be,0xbfea3acac0aaf482,2
+np.float64,0x800faf3e69df5e7d,0x800faf3e69df5e7d,2
+np.float64,0x3fc145a330228b46,0x3fc13853f11b1c90,2
+np.float64,0xbfe25ec5abe4bd8c,0xbfe17c9e9b486f07,2
+np.float64,0x3fe119b160e23363,0x3fe0604b10178966,2
+np.float64,0x7fe0cbf2836197e4,0x40862ea6831e5f4a,2
+np.float64,0x3fe75dd3b4eebba8,0x3fe5abe80fd628fb,2
+np.float64,0x3f7c391000387220,0x3f7c39015d8f3a36,2
+np.float64,0x899d9cad133b4,0x899d9cad133b4,2
+np.float64,0x3fe5f0e34febe1c6,0x3fe4820cefe138fc,2
+np.float64,0x7fe060dfdba0c1bf,0x40862e72de8afcd0,2
+np.float64,0xbfae42f7103c85f0,0xbfae3e7630819c60,2
+np.float64,0x35f1f2c06be5,0x35f1f2c06be5,2
+np.float64,0xffc5194d362a329c,0xc086256266c8b7ad,2
+np.float64,0xbfda034f1b34069e,0xbfd95860a44c43ad,2
+np.float64,0x32bcebca6579e,0x32bcebca6579e,2
+np.float64,0xbfd1751ebca2ea3e,0xbfd13f79f45bf75c,2
+np.float64,0x3fee4fa1e5bc9f44,0x3feafe69e0d6c1c7,2
+np.float64,0x7f9c03cd5038079a,0x4086170459172900,2
+np.float64,0x7fc5fb6d6d2bf6da,0x408625b6651cfc73,2
+np.float64,0x7ff8000000000000,0x7ff8000000000000,2
+np.float64,0xffd1a8162ca3502c,0xc0862981333931ad,2
+np.float64,0x7fc415c198282b82,0x408624fd8c155d1b,2
+np.float64,0xffda37fbe7b46ff8,0xc0862caae7865c43,2
+np.float64,0xbfef4312257e8624,0xbfebadd89f3ee31c,2
+np.float64,0xbfec45e1fd788bc4,0xbfe97d8b14db6274,2
+np.float64,0xbfe6fdcfd26dfba0,0xbfe55e25b770d00a,2
+np.float64,0x7feb66d424f6cda7,0x40863290d9ff7ea2,2
+np.float64,0x8b08a29916115,0x8b08a29916115,2
+np.float64,0xffe12ca25c625944,0xc0862ed40d769f72,2
+np.float64,0x7ff4000000000000,0x7ffc000000000000,2
+np.float64,0x804925e100925,0x804925e100925,2
+np.float64,0xcebf3e019d9,0xcebf3e019d9,2
+np.float64,0xbfd5d75d4aabaeba,0xbfd57027671dedf7,2
+np.float64,0x800b829ecd37053e,0x800b829ecd37053e,2
+np.float64,0x800b1205daf6240c,0x800b1205daf6240c,2
+np.float64,0x3fdf7e9889befd31,0x3fde583fdff406c3,2
+np.float64,0x7ff0000000000000,0x7ff0000000000000,2
+np.float64,0x3fdc09760d3812ec,0x3fdb35b55c8090c6,2
+np.float64,0x800c4d99e4f89b34,0x800c4d99e4f89b34,2
+np.float64,0xffbaa6772e354cf0,0xc08621b535badb2f,2
+np.float64,0xbfc91188fd322310,0xbfc8e933b5d25ea7,2
+np.float64,0xffc1b947f4237290,0xc08623fd69164251,2
+np.float64,0x3fc6ab3b252d5678,0x3fc68d50bbac106d,2
+np.float64,0xffac8eb968391d70,0xc0861cb734833355,2
+np.float64,0xffe29a35c365346b,0xc0862f77a1aed6d8,2
+np.float64,0x3fde14b9543c2973,0x3fdd122697779015,2
+np.float64,0xbf10f5400021e000,0xbf10f53fffef1383,2
+np.float64,0xffe0831aa3e10635,0xc0862e838553d0ca,2
+np.float64,0x3fccbadbcf3975b8,0x3fcc7e768d0154ec,2
+np.float64,0x3fe092ef66e125df,0x3fdfd212a7116c9b,2
+np.float64,0xbfd727f039ae4fe0,0xbfd6adad040b2334,2
+np.float64,0xbfe4223b93a84477,0xbfe2ff7587364db4,2
+np.float64,0x3f4e5c3a003cb874,0x3f4e5c39b75c70f7,2
+np.float64,0x800e76b1a87ced63,0x800e76b1a87ced63,2
+np.float64,0x3fed2b7368fa56e7,0x3fea2863b9131b8c,2
+np.float64,0xffadb76ec43b6ee0,0xc0861d08ae79f20c,2
+np.float64,0x800b6a0cd1f6d41a,0x800b6a0cd1f6d41a,2
+np.float64,0xffee6aa943fcd552,0xc0863366a24250d5,2
+np.float64,0xbfe68cbc4e6d1978,0xbfe502040591aa5b,2
+np.float64,0xff859a38002b3480,0xc0860f64726235cc,2
+np.float64,0x3474d13e68e9b,0x3474d13e68e9b,2
+np.float64,0xffc11d49f6223a94,0xc08623b5c2df9712,2
+np.float64,0x800d82d019bb05a0,0x800d82d019bb05a0,2
+np.float64,0xbfe2af0192255e03,0xbfe1c20e38106388,2
+np.float64,0x3fe97d13c032fa28,0x3fe75bba11a65f86,2
+np.float64,0x7fcd457e133a8afb,0x40862800e80f5863,2
+np.float64,0x9d7254cf3ae4b,0x9d7254cf3ae4b,2
+np.float64,0x8003047675a608ee,0x8003047675a608ee,2
+np.float64,0x3fead6cd7d75ad9a,0x3fe8676138e5ff93,2
+np.float64,0x3fea6ee3b0f4ddc7,0x3fe817838a2bcbe3,2
+np.float64,0x3feed0edea7da1dc,0x3feb5bea3cb12fe2,2
+np.float64,0x88003fe510008,0x88003fe510008,2
+np.float64,0x3fe64cadc56c995c,0x3fe4cd8ead87fc79,2
+np.float64,0xaae30c5955c62,0xaae30c5955c62,2
+np.float64,0x7fc8c97cae3192f8,0x408626ac579f4fc5,2
+np.float64,0xbfc2bc0e8b25781c,0xbfc2ab188fdab7dc,2
+np.float64,0xc8f8e5e791f1d,0xc8f8e5e791f1d,2
+np.float64,0x3fecfaa5d6f9f54c,0x3fea0444dabe5a15,2
+np.float64,0xbfeb93740ff726e8,0xbfe8f71a9ab13baf,2
+np.float64,0xffd951236c32a246,0xc0862c633a4661eb,2
+np.float64,0x3fddbc5fcd3b78c0,0x3fdcc21c1a0a9246,2
+np.float64,0xbfd242443da48488,0xbfd20512d91f7924,2
+np.float64,0x2a3689b2546d2,0x2a3689b2546d2,2
+np.float64,0xffe24c67382498ce,0xc0862f55e4ea6283,2
+np.float64,0x800cbfce22197f9c,0x800cbfce22197f9c,2
+np.float64,0x8002269428044d29,0x8002269428044d29,2
+np.float64,0x7fd44babbd289756,0x40862a9e79b51c3b,2
+np.float64,0x3feea056a27d40ad,0x3feb38dcddb682f0,2
+np.float64,0xffeca8174b39502e,0xc08632ec8f88a5b2,2
+np.float64,0x7fbe0853a03c10a6,0x408622a9e8d53a9e,2
+np.float64,0xbfa9704b2432e090,0xbfa96d9dfc8c0cc2,2
+np.float64,0x800bda28fab7b452,0x800bda28fab7b452,2
+np.float64,0xbfb0ffa2f621ff48,0xbfb0fc71f405e82a,2
+np.float64,0xbfe66c04216cd808,0xbfe4e73ea3b58cf6,2
+np.float64,0x3fe336ea5d266dd5,0x3fe236ffcf078c62,2
+np.float64,0xbfe7729ae6aee536,0xbfe5bcad4b8ac62d,2
+np.float64,0x558cfc96ab1a0,0x558cfc96ab1a0,2
+np.float64,0xbfe7d792aaefaf26,0xbfe60de1b8f0279d,2
+np.float64,0xffd19ef6bda33dee,0xc086297d0ffee3c7,2
+np.float64,0x666b3ab4ccd68,0x666b3ab4ccd68,2
+np.float64,0xffa3d89e3c27b140,0xc08619cdeb2c1e49,2
+np.float64,0xbfb1728f7f62f,0xbfb1728f7f62f,2
+np.float64,0x3fc76319f32ec634,0x3fc74247bd005e20,2
+np.float64,0xbfbf1caee23e3960,0xbfbf0934c13d70e2,2
+np.float64,0x7fe79626f32f2c4d,0x4086315dcc68a5cb,2
+np.float64,0xffee78c4603cf188,0xc086336a572c05c2,2
+np.float64,0x3fce546eda3ca8de,0x3fce0d8d737fd31d,2
+np.float64,0xa223644d4446d,0xa223644d4446d,2
+np.float64,0x3fecea878b79d510,0x3fe9f850d50973f6,2
+np.float64,0x3fc20e0ea1241c1d,0x3fc1fedda87c5e75,2
+np.float64,0xffd1c5a99ca38b54,0xc086298e8e94cd47,2
+np.float64,0x7feb2c299d765852,0x4086327fa6db2808,2
+np.float64,0xcaf9d09595f3a,0xcaf9d09595f3a,2
+np.float64,0xbfe293bf21e5277e,0xbfe1aa7f6ac274ef,2
+np.float64,0xbfbaa3c8ce354790,0xbfba97891df19c01,2
+np.float64,0x3faf5784543eaf09,0x3faf5283acc7d71d,2
+np.float64,0x7fc014f8f62029f1,0x40862336531c662d,2
+np.float64,0xbfe0d9ac2d61b358,0xbfe027bce36699ca,2
+np.float64,0x8003e112ff27c227,0x8003e112ff27c227,2
+np.float64,0xffec0d4151381a82,0xc08632c0df718dd0,2
+np.float64,0x7fa2156fb0242ade,0x4086190f7587d708,2
+np.float64,0xd698358dad307,0xd698358dad307,2
+np.float64,0xbfed8d1b0efb1a36,0xbfea70588ef9ba18,2
+np.float64,0xbfd2cae6a92595ce,0xbfd28851e2185dee,2
+np.float64,0xffe7a36764ef46ce,0xc086316249c9287a,2
+np.float64,0xbfdb8ad8e5b715b2,0xbfdac19213c14315,2
+np.float64,0x3b5dba6076bc,0x3b5dba6076bc,2
+np.float64,0x800e6e8347bcdd07,0x800e6e8347bcdd07,2
+np.float64,0x800bea9f3fb7d53f,0x800bea9f3fb7d53f,2
+np.float64,0x7fb6d0e5fc2da1cb,0x4086207714c4ab85,2
+np.float64,0x0,0x0,2
+np.float64,0xbfe2aa1e1465543c,0xbfe1bdd550ef2966,2
+np.float64,0x7fd3f6a47fa7ed48,0x40862a7caea33055,2
+np.float64,0x800094e292c129c6,0x800094e292c129c6,2
+np.float64,0x800e1500ecbc2a02,0x800e1500ecbc2a02,2
+np.float64,0xbfd8ff6f97b1fee0,0xbfd866f84346ecdc,2
+np.float64,0x681457d0d028c,0x681457d0d028c,2
+np.float64,0x3feed0b5987da16b,0x3feb5bc1ab424984,2
+np.float64,0x3fdbcb34cdb79668,0x3fdafca540f32c06,2
+np.float64,0xbfdc9eacdcb93d5a,0xbfdbbe274aa8aeb0,2
+np.float64,0xffe6e35d526dc6ba,0xc08631203df38ed2,2
+np.float64,0x3fcac1cc65358398,0x3fca90de41889613,2
+np.float64,0xbfebf07a55b7e0f5,0xbfe93d6007db0c67,2
+np.float64,0xbfd7a7b1e7af4f64,0xbfd725a9081c22cb,2
+np.float64,0x800232bd7de4657c,0x800232bd7de4657c,2
+np.float64,0x7fb1dae43c23b5c7,0x40861e80f5c0a64e,2
+np.float64,0x8013ded70027c,0x8013ded70027c,2
+np.float64,0x7fc4373a59286e74,0x4086250ad60575d0,2
+np.float64,0xbfe9980fd6733020,0xbfe770d1352d0ed3,2
+np.float64,0x8008a66b8dd14cd7,0x8008a66b8dd14cd7,2
+np.float64,0xbfaebc67f83d78d0,0xbfaeb7b015848478,2
+np.float64,0xffd0c52762218a4e,0xc0862917b564afc6,2
+np.float64,0xbfd503860aaa070c,0xbfd4a74618441561,2
+np.float64,0x5bdacabcb7b5a,0x5bdacabcb7b5a,2
+np.float64,0xf3623cffe6c48,0xf3623cffe6c48,2
+np.float64,0x7fe16c6c7ea2d8d8,0x40862ef18d90201f,2
+np.float64,0x3ff0000000000000,0x3fec34366179d427,2
+np.float64,0x7fe19cbc84233978,0x40862f079dcbc169,2
+np.float64,0x3fcfd3d6933fa7ad,0x3fcf822187907f6b,2
+np.float64,0x8007d65d672facbc,0x8007d65d672facbc,2
+np.float64,0xffca6115aa34c22c,0xc086272bd7728750,2
+np.float64,0xbfe77ab1556ef562,0xbfe5c332fb55b66e,2
+np.float64,0x8001ed797c23daf4,0x8001ed797c23daf4,2
+np.float64,0x7fdd3d16cb3a7a2d,0x40862d8a2c869281,2
+np.float64,0x75f36beaebe6e,0x75f36beaebe6e,2
+np.float64,0xffda3c2798b47850,0xc0862cac2d3435df,2
+np.float64,0xbfa37cc3c426f980,0xbfa37b8f9d3ec4b7,2
+np.float64,0x80030ea8bd061d52,0x80030ea8bd061d52,2
+np.float64,0xffe41f7617683eec,0xc08630188a3e135e,2
+np.float64,0x800e40590dfc80b2,0x800e40590dfc80b2,2
+np.float64,0x3fea950d80f52a1c,0x3fe834e74481e66f,2
+np.float64,0xffec95e39a792bc6,0xc08632e779150084,2
+np.float64,0xbfd54310ecaa8622,0xbfd4e39c4d767002,2
+np.float64,0xffd40c9971a81932,0xc0862a85764eb2f4,2
+np.float64,0xb0a2230761445,0xb0a2230761445,2
+np.float64,0x80092973661252e7,0x80092973661252e7,2
+np.float64,0x7fb13b030a227605,0x40861e380aeb5549,2
+np.float64,0x3fbd5d8db23abb1b,0x3fbd4d2a0b94af36,2
+np.float64,0xbfd6cb8567ad970a,0xbfd656b19ab8fa61,2
+np.float64,0xbfe7c0fd346f81fa,0xbfe5fbc28807c794,2
+np.float64,0xffd586579eab0cb0,0xc0862b16e65c0754,2
+np.float64,0x8000e52da461ca5c,0x8000e52da461ca5c,2
+np.float64,0x3fc69d17112d3a2e,0x3fc67f63fe1fea1c,2
+np.float64,0x3fd36ba892a6d750,0x3fd3225be1fa87af,2
+np.float64,0x7fe2850598e50a0a,0x40862f6e7fcd6c1a,2
+np.float64,0x80074a4dacce949c,0x80074a4dacce949c,2
+np.float64,0x3fe25eea4d64bdd5,0x3fe17cbe5fefbd4e,2
+np.float64,0xbfe250c08be4a181,0xbfe17074c520e5de,2
+np.float64,0x8000f5665481eacd,0x8000f5665481eacd,2
+np.float64,0x7fdb3172f83662e5,0x40862cf5a46764f1,2
+np.float64,0x7fd8ed82d631db05,0x40862c4380658afa,2
+np.float64,0xffec5163feb8a2c7,0xc08632d4366aab06,2
+np.float64,0x800ff14ac6ffe296,0x800ff14ac6ffe296,2
+np.float64,0xbfc7cc7aea2f98f4,0xbfc7a9e9cb38f023,2
+np.float64,0xbfd50cdfc32a19c0,0xbfd4b0282b452fb2,2
+np.float64,0xbfec256d75b84adb,0xbfe965328c1860b2,2
+np.float64,0xffe860c4cdb0c189,0xc08631a164b7059a,2
+np.float64,0xbfe23de164247bc3,0xbfe16011bffa4651,2
+np.float64,0xcc96b39d992d7,0xcc96b39d992d7,2
+np.float64,0xbfec43acf938875a,0xbfe97be3a13b50c3,2
+np.float64,0xc4f587bb89eb1,0xc4f587bb89eb1,2
+np.float64,0xbfcd971d9a3b2e3c,0xbfcd5537ad15dab4,2
+np.float64,0xffcaf00d8035e01c,0xc0862756bf2cdf8f,2
+np.float64,0x8008c26f93f184e0,0x8008c26f93f184e0,2
+np.float64,0xfff0000000000000,0xfff0000000000000,2
+np.float64,0xbfd13552c3a26aa6,0xbfd101e5e252eb7b,2
+np.float64,0x7fe497235e292e46,0x4086304792fb423a,2
+np.float64,0x7fd6dc0192adb802,0x40862b921a5e935d,2
+np.float64,0xf16d49a1e2da9,0xf16d49a1e2da9,2
+np.float64,0xffef6b1b71bed636,0xc08633a8feed0178,2
+np.float64,0x7fe15ec62f62bd8b,0x40862eeb46b193dc,2
+np.float64,0x3fef4369ec7e86d4,0x3febae1768be52cc,2
+np.float64,0x4f84e8e89f09e,0x4f84e8e89f09e,2
+np.float64,0xbfe19e71ade33ce4,0xbfe0d4fad05e0ebc,2
+np.float64,0xbfe7e1df1defc3be,0xbfe616233e15b3d0,2
+np.float64,0x7fe9349afdb26935,0x408631e5c1c5c6cd,2
+np.float64,0xff90c35ac82186c0,0xc08612e896a06467,2
+np.float64,0xbfe88bf8807117f1,0xbfe69dc786464422,2
+np.float64,0x3feaf9ff6475f3fe,0x3fe8825132410d18,2
+np.float64,0x9ff487a33fe91,0x9ff487a33fe91,2
+np.float64,0x7fedb30159bb6602,0x40863335c0419322,2
+np.float64,0x800bddf6ed77bbee,0x800bddf6ed77bbee,2
+np.float64,0x3fd919df133233be,0x3fd87f963b9584ce,2
+np.float64,0x7fd64da3b52c9b46,0x40862b5fa9dd3b6d,2
+np.float64,0xbfce288db43c511c,0xbfcde2d953407ae8,2
+np.float64,0x3fe88bc72771178e,0x3fe69da05e9e9b4e,2
+np.float64,0x800feafe259fd5fc,0x800feafe259fd5fc,2
+np.float64,0x3febbbff4a7777ff,0x3fe915c78f6a280f,2
+np.float64,0xbfefbde4417f7bc9,0xbfec055f4fb2cd21,2
+np.float64,0xf13ca103e2794,0xf13ca103e2794,2
+np.float64,0x3fe6423884ec8471,0x3fe4c4f97eaa876a,2
+np.float64,0x800ca01c8cb94039,0x800ca01c8cb94039,2
+np.float64,0x3fbc5073f638a0e0,0x3fbc41c163ac0001,2
+np.float64,0xbfda0d83cfb41b08,0xbfd961d4cacc82cf,2
+np.float64,0x800f37b8f17e6f72,0x800f37b8f17e6f72,2
+np.float64,0x7fe0b08cd7216119,0x40862e996becb771,2
+np.float64,0xffd4222a40a84454,0xc0862a8e0c984917,2
+np.float64,0x7feb3df98ff67bf2,0x40863284e3a86ee6,2
+np.float64,0x8001d5d291e3aba6,0x8001d5d291e3aba6,2
+np.float64,0xbfd3c21629a7842c,0xbfd3750095a5894a,2
+np.float64,0xbfd069eb48a0d3d6,0xbfd03d2b1c2ae9db,2
+np.float64,0xffeb1be2973637c4,0xc086327ada954662,2
+np.float64,0x3fc659f97e2cb3f3,0x3fc63d497a451f10,2
+np.float64,0xbfeb624bc776c498,0xbfe8d1cf7c0626ca,2
+np.float64,0xffeedf26e23dbe4d,0xc08633850baab425,2
+np.float64,0xffe70da48a6e1b48,0xc086312ef75d5036,2
+np.float64,0x2b4f4830569ea,0x2b4f4830569ea,2
+np.float64,0xffe82e7fcfb05cff,0xc0863190d4771f75,2
+np.float64,0x3fcc2c1fd5385840,0x3fcbf3211ddc5123,2
+np.float64,0x7fe22ced5a6459da,0x40862f481629ee6a,2
+np.float64,0x7fe13d2895e27a50,0x40862edbbc411899,2
+np.float64,0x3fd54c4280aa9884,0x3fd4ec55a946c5d7,2
+np.float64,0xffd75b8e01aeb71c,0xc0862bbe42d76e5e,2
+np.float64,0x7f1d5376fe3ab,0x7f1d5376fe3ab,2
+np.float64,0x3fe6ec6c902dd8d9,0x3fe55004f35192bd,2
+np.float64,0x5634504aac68b,0x5634504aac68b,2
+np.float64,0x3feedb0d83bdb61b,0x3feb633467467ce6,2
+np.float64,0x3fddb1c0dcbb6380,0x3fdcb87a02daf1fa,2
+np.float64,0xbfa832da443065b0,0xbfa8308c70257209,2
+np.float64,0x87a9836b0f531,0x87a9836b0f531,2
diff --git a/numpy/core/tests/data/umath-validation-set-arctan.csv b/numpy/core/tests/data/umath-validation-set-arctan.csv
new file mode 100644
index 000000000..1e92073d3
--- /dev/null
+++ b/numpy/core/tests/data/umath-validation-set-arctan.csv
@@ -0,0 +1,1429 @@
+dtype,input,output,ulperrortol
+np.float32,0x3f338252,0x3f1c8d9c,3
+np.float32,0x7e569df2,0x3fc90fdb,3
+np.float32,0xbf347e25,0xbf1d361f,3
+np.float32,0xbf0a654e,0xbefdbfd2,3
+np.float32,0x8070968e,0x8070968e,3
+np.float32,0x803cfb27,0x803cfb27,3
+np.float32,0x8024362e,0x8024362e,3
+np.float32,0xfd55dca0,0xbfc90fdb,3
+np.float32,0x592b82,0x592b82,3
+np.float32,0x802eb8e1,0x802eb8e1,3
+np.float32,0xbc5fef40,0xbc5febae,3
+np.float32,0x3f1f6ce8,0x3f0e967c,3
+np.float32,0x20bedc,0x20bedc,3
+np.float32,0xbf058860,0xbef629c7,3
+np.float32,0x311504,0x311504,3
+np.float32,0xbd23f560,0xbd23defa,3
+np.float32,0x800ff4e8,0x800ff4e8,3
+np.float32,0x355009,0x355009,3
+np.float32,0x3f7be42e,0x3f46fdb3,3
+np.float32,0xbf225f7c,0xbf10b364,3
+np.float32,0x8074fa9e,0x8074fa9e,3
+np.float32,0xbea4b418,0xbe9f59ce,3
+np.float32,0xbe909c14,0xbe8cf045,3
+np.float32,0x80026bee,0x80026bee,3
+np.float32,0x3d789c20,0x3d784e25,3
+np.float32,0x7f56a4ba,0x3fc90fdb,3
+np.float32,0xbf70d141,0xbf413db7,3
+np.float32,0xbf2c4886,0xbf17a505,3
+np.float32,0x7e2993bf,0x3fc90fdb,3
+np.float32,0xbe2c8a30,0xbe2aef28,3
+np.float32,0x803f82d9,0x803f82d9,3
+np.float32,0x3f062fbc,0x3ef730a1,3
+np.float32,0x3f349ee0,0x3f1d4bfa,3
+np.float32,0x3eccfb69,0x3ec2f9e8,3
+np.float32,0x7e8a85dd,0x3fc90fdb,3
+np.float32,0x25331,0x25331,3
+np.float32,0x464f19,0x464f19,3
+np.float32,0x8035c818,0x8035c818,3
+np.float32,0x802e5799,0x802e5799,3
+np.float32,0x64e1c0,0x64e1c0,3
+np.float32,0x701cc2,0x701cc2,3
+np.float32,0x265c57,0x265c57,3
+np.float32,0x807a053f,0x807a053f,3
+np.float32,0x3bd2c412,0x3bd2c354,3
+np.float32,0xff28f1c8,0xbfc90fdb,3
+np.float32,0x7f08f08b,0x3fc90fdb,3
+np.float32,0x800c50e4,0x800c50e4,3
+np.float32,0x369674,0x369674,3
+np.float32,0xbf5b7db3,0xbf3571bf,3
+np.float32,0x7edcf5e2,0x3fc90fdb,3
+np.float32,0x800e5d4b,0x800e5d4b,3
+np.float32,0x80722554,0x80722554,3
+np.float32,0x693f33,0x693f33,3
+np.float32,0x800844e4,0x800844e4,3
+np.float32,0xbf111b82,0xbf0402ec,3
+np.float32,0x7df9c9ac,0x3fc90fdb,3
+np.float32,0xbf6619a6,0xbf3b6f57,3
+np.float32,0x8002fafe,0x8002fafe,3
+np.float32,0xfe1e67f8,0xbfc90fdb,3
+np.float32,0x3f7f4bf8,0x3f48b5b7,3
+np.float32,0x7f017b20,0x3fc90fdb,3
+np.float32,0x2d9b07,0x2d9b07,3
+np.float32,0x803aa174,0x803aa174,3
+np.float32,0x7d530336,0x3fc90fdb,3
+np.float32,0x80662195,0x80662195,3
+np.float32,0xfd5ebcf0,0xbfc90fdb,3
+np.float32,0xbe7b8dcc,0xbe76ab59,3
+np.float32,0x7f2bacaf,0x3fc90fdb,3
+np.float32,0x3f194fc4,0x3f0a229e,3
+np.float32,0x7ee21cdf,0x3fc90fdb,3
+np.float32,0x3f5a17fc,0x3f34a307,3
+np.float32,0x7f100c58,0x3fc90fdb,3
+np.float32,0x7e9128f5,0x3fc90fdb,3
+np.float32,0xbf2107c6,0xbf0fbdb4,3
+np.float32,0xbd29c800,0xbd29af22,3
+np.float32,0xbf5af499,0xbf3522a6,3
+np.float32,0x801bde44,0x801bde44,3
+np.float32,0xfeb4761a,0xbfc90fdb,3
+np.float32,0x3d88aa1b,0x3d887650,3
+np.float32,0x7eba5e0b,0x3fc90fdb,3
+np.float32,0x803906bd,0x803906bd,3
+np.float32,0x80101512,0x80101512,3
+np.float32,0x7e898f83,0x3fc90fdb,3
+np.float32,0x806406d3,0x806406d3,3
+np.float32,0x7ed20fc0,0x3fc90fdb,3
+np.float32,0x20827d,0x20827d,3
+np.float32,0x3f361359,0x3f1e43fe,3
+np.float32,0xfe4ef8d8,0xbfc90fdb,3
+np.float32,0x805e7d2d,0x805e7d2d,3
+np.float32,0xbe4316b0,0xbe40c745,3
+np.float32,0xbf0a1c06,0xbefd4e5a,3
+np.float32,0x3e202860,0x3e1edee1,3
+np.float32,0xbeb32a2c,0xbeac5899,3
+np.float32,0xfe528838,0xbfc90fdb,3
+np.float32,0x2f73e2,0x2f73e2,3
+np.float32,0xbe16e010,0xbe15cc27,3
+np.float32,0x3f50d6c5,0x3f2f2d75,3
+np.float32,0xbe88a6a2,0xbe8589c7,3
+np.float32,0x3ee36060,0x3ed5fb36,3
+np.float32,0x6c978b,0x6c978b,3
+np.float32,0x7f1b735f,0x3fc90fdb,3
+np.float32,0x3dad8256,0x3dad1885,3
+np.float32,0x807f5094,0x807f5094,3
+np.float32,0x65c358,0x65c358,3
+np.float32,0xff315ce4,0xbfc90fdb,3
+np.float32,0x7411a6,0x7411a6,3
+np.float32,0x80757b04,0x80757b04,3
+np.float32,0x3eec73a6,0x3edd82f4,3
+np.float32,0xfe9f69e8,0xbfc90fdb,3
+np.float32,0x801f4fa8,0x801f4fa8,3
+np.float32,0xbf6f2fae,0xbf405f79,3
+np.float32,0xfea206b6,0xbfc90fdb,3
+np.float32,0x3f257301,0x3f12e1ee,3
+np.float32,0x7ea6a506,0x3fc90fdb,3
+np.float32,0x80800000,0x80800000,3
+np.float32,0xff735c2d,0xbfc90fdb,3
+np.float32,0x80197f95,0x80197f95,3
+np.float32,0x7f4a354f,0x3fc90fdb,3
+np.float32,0xff320c00,0xbfc90fdb,3
+np.float32,0x3f2659de,0x3f138484,3
+np.float32,0xbe5451bc,0xbe515a52,3
+np.float32,0x3f6e228c,0x3f3fcf7c,3
+np.float32,0x66855a,0x66855a,3
+np.float32,0x8034b3a3,0x8034b3a3,3
+np.float32,0xbe21a2fc,0xbe20505d,3
+np.float32,0x7f79e2dc,0x3fc90fdb,3
+np.float32,0xbe19a8e0,0xbe18858c,3
+np.float32,0x10802c,0x10802c,3
+np.float32,0xfeee579e,0xbfc90fdb,3
+np.float32,0x3f3292c8,0x3f1becc0,3
+np.float32,0xbf595a71,0xbf34350a,3
+np.float32,0xbf7c3373,0xbf4725f4,3
+np.float32,0xbdd30938,0xbdd24b36,3
+np.float32,0x153a17,0x153a17,3
+np.float32,0x807282a0,0x807282a0,3
+np.float32,0xfe817322,0xbfc90fdb,3
+np.float32,0x3f1b3628,0x3f0b8771,3
+np.float32,0x41be8f,0x41be8f,3
+np.float32,0x7f4a8343,0x3fc90fdb,3
+np.float32,0x3dc4ea2b,0x3dc44fae,3
+np.float32,0x802aac25,0x802aac25,3
+np.float32,0xbf20e1d7,0xbf0fa284,3
+np.float32,0xfd91a1b0,0xbfc90fdb,3
+np.float32,0x3f0d5476,0x3f012265,3
+np.float32,0x21c916,0x21c916,3
+np.float32,0x807df399,0x807df399,3
+np.float32,0x7e207b4c,0x3fc90fdb,3
+np.float32,0x8055f8ff,0x8055f8ff,3
+np.float32,0x7edf3b01,0x3fc90fdb,3
+np.float32,0x803a8df3,0x803a8df3,3
+np.float32,0x3ce3b002,0x3ce3a101,3
+np.float32,0x3f62dd54,0x3f39a248,3
+np.float32,0xff33ae10,0xbfc90fdb,3
+np.float32,0x7e3de69d,0x3fc90fdb,3
+np.float32,0x8024581e,0x8024581e,3
+np.float32,0xbf4ac99d,0xbf2b807a,3
+np.float32,0x3f157d19,0x3f074d8c,3
+np.float32,0xfed383f4,0xbfc90fdb,3
+np.float32,0xbf5a39fa,0xbf34b6b8,3
+np.float32,0x800d757d,0x800d757d,3
+np.float32,0x807d606b,0x807d606b,3
+np.float32,0x3e828f89,0x3e7fac2d,3
+np.float32,0x7a6604,0x7a6604,3
+np.float32,0x7dc7e72b,0x3fc90fdb,3
+np.float32,0x80144146,0x80144146,3
+np.float32,0x7c2eed69,0x3fc90fdb,3
+np.float32,0x3f5b4d8c,0x3f3555fc,3
+np.float32,0xfd8b7778,0xbfc90fdb,3
+np.float32,0xfc9d9140,0xbfc90fdb,3
+np.float32,0xbea265d4,0xbe9d4232,3
+np.float32,0xbe9344d0,0xbe8f65da,3
+np.float32,0x3f71f19a,0x3f41d65b,3
+np.float32,0x804a3f59,0x804a3f59,3
+np.float32,0x3e596290,0x3e563476,3
+np.float32,0x3e994ee4,0x3e94f546,3
+np.float32,0xbc103e00,0xbc103d0c,3
+np.float32,0xbf1cd896,0xbf0cb889,3
+np.float32,0x7f52b080,0x3fc90fdb,3
+np.float32,0xff584452,0xbfc90fdb,3
+np.float32,0x58b26b,0x58b26b,3
+np.float32,0x3f23cd4c,0x3f11b799,3
+np.float32,0x707d7,0x707d7,3
+np.float32,0xff732cff,0xbfc90fdb,3
+np.float32,0x3e41c2a6,0x3e3f7f0f,3
+np.float32,0xbf7058e9,0xbf40fdcf,3
+np.float32,0x7dca9857,0x3fc90fdb,3
+np.float32,0x7f0eb44b,0x3fc90fdb,3
+np.float32,0x8000405c,0x8000405c,3
+np.float32,0x4916ab,0x4916ab,3
+np.float32,0x4811a8,0x4811a8,3
+np.float32,0x3d69bf,0x3d69bf,3
+np.float32,0xfeadcf1e,0xbfc90fdb,3
+np.float32,0x3e08dbbf,0x3e080d58,3
+np.float32,0xff031f88,0xbfc90fdb,3
+np.float32,0xbe09cab8,0xbe08f818,3
+np.float32,0x21d7cd,0x21d7cd,3
+np.float32,0x3f23230d,0x3f113ea9,3
+np.float32,0x7e8a48d4,0x3fc90fdb,3
+np.float32,0x413869,0x413869,3
+np.float32,0x7e832990,0x3fc90fdb,3
+np.float32,0x800f5c09,0x800f5c09,3
+np.float32,0x7f5893b6,0x3fc90fdb,3
+np.float32,0x7f06b5b1,0x3fc90fdb,3
+np.float32,0xbe1cbee8,0xbe1b89d6,3
+np.float32,0xbf279f14,0xbf1468a8,3
+np.float32,0xfea86060,0xbfc90fdb,3
+np.float32,0x3e828174,0x3e7f91bb,3
+np.float32,0xff682c82,0xbfc90fdb,3
+np.float32,0x4e20f3,0x4e20f3,3
+np.float32,0x7f17d7e9,0x3fc90fdb,3
+np.float32,0x80671f92,0x80671f92,3
+np.float32,0x7f6dd100,0x3fc90fdb,3
+np.float32,0x3f219a4d,0x3f102695,3
+np.float32,0x803c9808,0x803c9808,3
+np.float32,0x3c432ada,0x3c43287d,3
+np.float32,0xbd3db450,0xbd3d91a2,3
+np.float32,0x3baac135,0x3baac0d0,3
+np.float32,0xff7fffe1,0xbfc90fdb,3
+np.float32,0xfe38a6f4,0xbfc90fdb,3
+np.float32,0x3dfb0a04,0x3df9cb04,3
+np.float32,0x800b05c2,0x800b05c2,3
+np.float32,0x644163,0x644163,3
+np.float32,0xff03a025,0xbfc90fdb,3
+np.float32,0x3f7d506c,0x3f47b641,3
+np.float32,0xff0e682a,0xbfc90fdb,3
+np.float32,0x3e09b7b0,0x3e08e567,3
+np.float32,0x7f72a216,0x3fc90fdb,3
+np.float32,0x7f800000,0x3fc90fdb,3
+np.float32,0x8050a281,0x8050a281,3
+np.float32,0x7edafa2f,0x3fc90fdb,3
+np.float32,0x3f4e0df6,0x3f2d7f2f,3
+np.float32,0xbf6728e0,0xbf3c050f,3
+np.float32,0x3e904ce4,0x3e8ca6eb,3
+np.float32,0x0,0x0,3
+np.float32,0xfd215070,0xbfc90fdb,3
+np.float32,0x7e406b15,0x3fc90fdb,3
+np.float32,0xbf2803c9,0xbf14af18,3
+np.float32,0x5950c8,0x5950c8,3
+np.float32,0xbeddcec8,0xbed14faa,3
+np.float32,0xbec6457e,0xbebd2aa5,3
+np.float32,0xbf42843c,0xbf2656db,3
+np.float32,0x3ee9cba8,0x3edb5163,3
+np.float32,0xbe30c954,0xbe2f0f90,3
+np.float32,0xbeee6b44,0xbedf216f,3
+np.float32,0xbe35d818,0xbe33f7cd,3
+np.float32,0xbe47c630,0xbe454bc6,3
+np.float32,0x801b146f,0x801b146f,3
+np.float32,0x7f6788da,0x3fc90fdb,3
+np.float32,0x3eaef088,0x3ea8927d,3
+np.float32,0x3eb5983e,0x3eae81fc,3
+np.float32,0x40b51d,0x40b51d,3
+np.float32,0xfebddd04,0xbfc90fdb,3
+np.float32,0x3e591aee,0x3e55efea,3
+np.float32,0xbe2b6b48,0xbe29d81f,3
+np.float32,0xff4a8826,0xbfc90fdb,3
+np.float32,0x3e791df0,0x3e745eac,3
+np.float32,0x7c8f681f,0x3fc90fdb,3
+np.float32,0xfe7a15c4,0xbfc90fdb,3
+np.float32,0x3c8963,0x3c8963,3
+np.float32,0x3f0afa0a,0x3efea5cc,3
+np.float32,0xbf0d2680,0xbf00ff29,3
+np.float32,0x3dc306b0,0x3dc27096,3
+np.float32,0x7f4cf105,0x3fc90fdb,3
+np.float32,0xbe196060,0xbe183ea4,3
+np.float32,0x5caf1c,0x5caf1c,3
+np.float32,0x801f2852,0x801f2852,3
+np.float32,0xbe01aa0c,0xbe00fa53,3
+np.float32,0x3f0cfd32,0x3f00df7a,3
+np.float32,0x7d82038e,0x3fc90fdb,3
+np.float32,0x7f7b927f,0x3fc90fdb,3
+np.float32,0xbe93b2e4,0xbe8fcb7f,3
+np.float32,0x1ffe8c,0x1ffe8c,3
+np.float32,0x3faaf6,0x3faaf6,3
+np.float32,0x3e32b1b8,0x3e30e9ab,3
+np.float32,0x802953c0,0x802953c0,3
+np.float32,0xfe5d9844,0xbfc90fdb,3
+np.float32,0x3e1a59d0,0x3e193292,3
+np.float32,0x801c6edc,0x801c6edc,3
+np.float32,0x1ecf41,0x1ecf41,3
+np.float32,0xfe56b09c,0xbfc90fdb,3
+np.float32,0x7e878351,0x3fc90fdb,3
+np.float32,0x3f401e2c,0x3f24cfcb,3
+np.float32,0xbf204a40,0xbf0f35bb,3
+np.float32,0x3e155a98,0x3e144ee1,3
+np.float32,0xbf34f929,0xbf1d8838,3
+np.float32,0x801bbf70,0x801bbf70,3
+np.float32,0x7e7c9730,0x3fc90fdb,3
+np.float32,0x7cc23432,0x3fc90fdb,3
+np.float32,0xbf351638,0xbf1d9b97,3
+np.float32,0x80152094,0x80152094,3
+np.float32,0x3f2d731c,0x3f187219,3
+np.float32,0x804ab0b7,0x804ab0b7,3
+np.float32,0x37d6db,0x37d6db,3
+np.float32,0xbf3ccc56,0xbf22acbf,3
+np.float32,0x3e546f8c,0x3e5176e7,3
+np.float32,0xbe90e87e,0xbe8d3707,3
+np.float32,0x48256c,0x48256c,3
+np.float32,0x7e2468d0,0x3fc90fdb,3
+np.float32,0x807af47e,0x807af47e,3
+np.float32,0x3ed4b221,0x3ec996f0,3
+np.float32,0x3d3b1956,0x3d3af811,3
+np.float32,0xbe69d93c,0xbe65e7f0,3
+np.float32,0xff03ff14,0xbfc90fdb,3
+np.float32,0x801e79dc,0x801e79dc,3
+np.float32,0x3f467c53,0x3f28d63d,3
+np.float32,0x3eab6baa,0x3ea56a1c,3
+np.float32,0xbf15519c,0xbf072d1c,3
+np.float32,0x7f0bd8e8,0x3fc90fdb,3
+np.float32,0xbe1e0d1c,0xbe1cd053,3
+np.float32,0x8016edab,0x8016edab,3
+np.float32,0x7ecaa09b,0x3fc90fdb,3
+np.float32,0x3f72e6d9,0x3f4257a8,3
+np.float32,0xbefe787e,0xbeec29a4,3
+np.float32,0xbee989e8,0xbedb1af9,3
+np.float32,0xbe662db0,0xbe626a45,3
+np.float32,0x495bf7,0x495bf7,3
+np.float32,0x26c379,0x26c379,3
+np.float32,0x7f54d41a,0x3fc90fdb,3
+np.float32,0x801e7dd9,0x801e7dd9,3
+np.float32,0x80000000,0x80000000,3
+np.float32,0xfa3d3000,0xbfc90fdb,3
+np.float32,0xfa3cb800,0xbfc90fdb,3
+np.float32,0x264894,0x264894,3
+np.float32,0xff6de011,0xbfc90fdb,3
+np.float32,0x7e9045b2,0x3fc90fdb,3
+np.float32,0x3f2253a8,0x3f10aaf4,3
+np.float32,0xbd462bf0,0xbd460469,3
+np.float32,0x7f1796af,0x3fc90fdb,3
+np.float32,0x3e718858,0x3e6d3279,3
+np.float32,0xff437d7e,0xbfc90fdb,3
+np.float32,0x805ae7cb,0x805ae7cb,3
+np.float32,0x807e32e9,0x807e32e9,3
+np.float32,0x3ee0bafc,0x3ed3c453,3
+np.float32,0xbf721dee,0xbf41edc3,3
+np.float32,0xfec9f792,0xbfc90fdb,3
+np.float32,0x7f050720,0x3fc90fdb,3
+np.float32,0x182261,0x182261,3
+np.float32,0x3e39e678,0x3e37e5be,3
+np.float32,0x7e096e4b,0x3fc90fdb,3
+np.float32,0x103715,0x103715,3
+np.float32,0x3f7e7741,0x3f484ae4,3
+np.float32,0x3e29aea5,0x3e28277c,3
+np.float32,0x58c183,0x58c183,3
+np.float32,0xff72fdb2,0xbfc90fdb,3
+np.float32,0xbd9a9420,0xbd9a493c,3
+np.float32,0x7f1e07e7,0x3fc90fdb,3
+np.float32,0xff79f522,0xbfc90fdb,3
+np.float32,0x7c7d0e96,0x3fc90fdb,3
+np.float32,0xbeba9e8e,0xbeb2f504,3
+np.float32,0xfd880a80,0xbfc90fdb,3
+np.float32,0xff7f2a33,0xbfc90fdb,3
+np.float32,0x3e861ae0,0x3e83289c,3
+np.float32,0x7f0161c1,0x3fc90fdb,3
+np.float32,0xfe844ff8,0xbfc90fdb,3
+np.float32,0xbebf4b98,0xbeb7128e,3
+np.float32,0x652bee,0x652bee,3
+np.float32,0xff188a4b,0xbfc90fdb,3
+np.float32,0xbf800000,0xbf490fdb,3
+np.float32,0x80418711,0x80418711,3
+np.float32,0xbeb712d4,0xbeafd1f6,3
+np.float32,0xbf7cee28,0xbf478491,3
+np.float32,0xfe66c59c,0xbfc90fdb,3
+np.float32,0x4166a2,0x4166a2,3
+np.float32,0x3dfa1a2c,0x3df8deb5,3
+np.float32,0xbdbfbcb8,0xbdbf2e0f,3
+np.float32,0xfe60ef70,0xbfc90fdb,3
+np.float32,0xfe009444,0xbfc90fdb,3
+np.float32,0xfeb27aa0,0xbfc90fdb,3
+np.float32,0xbe99f7bc,0xbe95902b,3
+np.float32,0x8043d28d,0x8043d28d,3
+np.float32,0xfe5328c4,0xbfc90fdb,3
+np.float32,0x8017b27e,0x8017b27e,3
+np.float32,0x3ef1d2cf,0x3ee1ebd7,3
+np.float32,0x805ddd90,0x805ddd90,3
+np.float32,0xbf424263,0xbf262d17,3
+np.float32,0xfc99dde0,0xbfc90fdb,3
+np.float32,0xbf7ec13b,0xbf487015,3
+np.float32,0xbef727ea,0xbee64377,3
+np.float32,0xff15ce95,0xbfc90fdb,3
+np.float32,0x1fbba4,0x1fbba4,3
+np.float32,0x3f3b2368,0x3f2198a9,3
+np.float32,0xfefda26e,0xbfc90fdb,3
+np.float32,0x801519ad,0x801519ad,3
+np.float32,0x80473fa2,0x80473fa2,3
+np.float32,0x7e7a8bc1,0x3fc90fdb,3
+np.float32,0x3e8a9289,0x3e87548a,3
+np.float32,0x3ed68987,0x3ecb2872,3
+np.float32,0x805bca66,0x805bca66,3
+np.float32,0x8079c4e3,0x8079c4e3,3
+np.float32,0x3a2510,0x3a2510,3
+np.float32,0x7eedc598,0x3fc90fdb,3
+np.float32,0x80681956,0x80681956,3
+np.float32,0xff64c778,0xbfc90fdb,3
+np.float32,0x806bbc46,0x806bbc46,3
+np.float32,0x433643,0x433643,3
+np.float32,0x705b92,0x705b92,3
+np.float32,0xff359392,0xbfc90fdb,3
+np.float32,0xbee78672,0xbed96fa7,3
+np.float32,0x3e21717b,0x3e202010,3
+np.float32,0xfea13c34,0xbfc90fdb,3
+np.float32,0x2c8895,0x2c8895,3
+np.float32,0x3ed33290,0x3ec84f7c,3
+np.float32,0x3e63031e,0x3e5f662e,3
+np.float32,0x7e30907b,0x3fc90fdb,3
+np.float32,0xbe293708,0xbe27b310,3
+np.float32,0x3ed93738,0x3ecd6ea3,3
+np.float32,0x9db7e,0x9db7e,3
+np.float32,0x3f7cd1b8,0x3f47762c,3
+np.float32,0x3eb5143c,0x3eae0cb0,3
+np.float32,0xbe69b234,0xbe65c2d7,3
+np.float32,0x3f6e74de,0x3f3ffb97,3
+np.float32,0x5d0559,0x5d0559,3
+np.float32,0x3e1e8c30,0x3e1d4c70,3
+np.float32,0xbf2d1878,0xbf1833ef,3
+np.float32,0xff2adf82,0xbfc90fdb,3
+np.float32,0x8012e2c1,0x8012e2c1,3
+np.float32,0x7f031be3,0x3fc90fdb,3
+np.float32,0x805ff94e,0x805ff94e,3
+np.float32,0x3e9d5b27,0x3e98aa31,3
+np.float32,0x3f56d5cf,0x3f32bc9e,3
+np.float32,0x3eaa0412,0x3ea4267f,3
+np.float32,0xbe899ea4,0xbe86712f,3
+np.float32,0x800f2f48,0x800f2f48,3
+np.float32,0x3f1c2269,0x3f0c33ea,3
+np.float32,0x3f4a5f64,0x3f2b3f28,3
+np.float32,0x80739318,0x80739318,3
+np.float32,0x806e9b47,0x806e9b47,3
+np.float32,0x3c8cd300,0x3c8ccf73,3
+np.float32,0x7f39a39d,0x3fc90fdb,3
+np.float32,0x3ec95d61,0x3ebfd9dc,3
+np.float32,0xff351ff8,0xbfc90fdb,3
+np.float32,0xff3a8f58,0xbfc90fdb,3
+np.float32,0x7f313ec0,0x3fc90fdb,3
+np.float32,0x803aed13,0x803aed13,3
+np.float32,0x7f771d9b,0x3fc90fdb,3
+np.float32,0x8045a6d6,0x8045a6d6,3
+np.float32,0xbc85f280,0xbc85ef72,3
+np.float32,0x7e9c68f5,0x3fc90fdb,3
+np.float32,0xbf0f9379,0xbf02d975,3
+np.float32,0x7e97bcb1,0x3fc90fdb,3
+np.float32,0x804a07d5,0x804a07d5,3
+np.float32,0x802e6117,0x802e6117,3
+np.float32,0x7ed5e388,0x3fc90fdb,3
+np.float32,0x80750455,0x80750455,3
+np.float32,0xff4a8325,0xbfc90fdb,3
+np.float32,0xbedb6866,0xbecf497c,3
+np.float32,0x52ea3b,0x52ea3b,3
+np.float32,0xff773172,0xbfc90fdb,3
+np.float32,0xbeaa8ff0,0xbea4a46e,3
+np.float32,0x7eef2058,0x3fc90fdb,3
+np.float32,0x3f712472,0x3f4169d3,3
+np.float32,0xff6c8608,0xbfc90fdb,3
+np.float32,0xbf6eaa41,0xbf40182a,3
+np.float32,0x3eb03c24,0x3ea9bb34,3
+np.float32,0xfe118cd4,0xbfc90fdb,3
+np.float32,0x3e5b03b0,0x3e57c378,3
+np.float32,0x7f34d92d,0x3fc90fdb,3
+np.float32,0x806c3418,0x806c3418,3
+np.float32,0x7f3074e3,0x3fc90fdb,3
+np.float32,0x8002df02,0x8002df02,3
+np.float32,0x3f6df63a,0x3f3fb7b7,3
+np.float32,0xfd2b4100,0xbfc90fdb,3
+np.float32,0x80363d5c,0x80363d5c,3
+np.float32,0xbeac1f98,0xbea60bd6,3
+np.float32,0xff7fffff,0xbfc90fdb,3
+np.float32,0x80045097,0x80045097,3
+np.float32,0xfe011100,0xbfc90fdb,3
+np.float32,0x80739ef5,0x80739ef5,3
+np.float32,0xff3976ed,0xbfc90fdb,3
+np.float32,0xbe18e3a0,0xbe17c49e,3
+np.float32,0xbe289294,0xbe2712f6,3
+np.float32,0x3f1d41e7,0x3f0d050e,3
+np.float32,0x39364a,0x39364a,3
+np.float32,0x8072b77e,0x8072b77e,3
+np.float32,0x3f7cfec0,0x3f478cf6,3
+np.float32,0x2f68f6,0x2f68f6,3
+np.float32,0xbf031fb8,0xbef25c84,3
+np.float32,0xbf0b842c,0xbeff7afc,3
+np.float32,0x3f081e7e,0x3efa3676,3
+np.float32,0x7f7fffff,0x3fc90fdb,3
+np.float32,0xff15da0e,0xbfc90fdb,3
+np.float32,0x3d2001b2,0x3d1fece1,3
+np.float32,0x7f76efef,0x3fc90fdb,3
+np.float32,0x3f2405dd,0x3f11dfb7,3
+np.float32,0xa0319,0xa0319,3
+np.float32,0x3e23d2bd,0x3e227255,3
+np.float32,0xbd4d4c50,0xbd4d205e,3
+np.float32,0x382344,0x382344,3
+np.float32,0x21bbf,0x21bbf,3
+np.float32,0xbf209e82,0xbf0f7239,3
+np.float32,0xff03bf9f,0xbfc90fdb,3
+np.float32,0x7b1789,0x7b1789,3
+np.float32,0xff314944,0xbfc90fdb,3
+np.float32,0x1a63eb,0x1a63eb,3
+np.float32,0x803dc983,0x803dc983,3
+np.float32,0x3f0ff558,0x3f0323dc,3
+np.float32,0x3f544f2c,0x3f313f58,3
+np.float32,0xff032948,0xbfc90fdb,3
+np.float32,0x7f4933cc,0x3fc90fdb,3
+np.float32,0x7f14c5ed,0x3fc90fdb,3
+np.float32,0x803aeebf,0x803aeebf,3
+np.float32,0xbf0d4c0f,0xbf011bf5,3
+np.float32,0xbeaf8de2,0xbea91f57,3
+np.float32,0xff3ae030,0xbfc90fdb,3
+np.float32,0xbb362d00,0xbb362ce1,3
+np.float32,0x3d1f79e0,0x3d1f6544,3
+np.float32,0x3f56e9d9,0x3f32c860,3
+np.float32,0x3f723e5e,0x3f41fee2,3
+np.float32,0x4c0179,0x4c0179,3
+np.float32,0xfee36132,0xbfc90fdb,3
+np.float32,0x619ae6,0x619ae6,3
+np.float32,0xfde5d670,0xbfc90fdb,3
+np.float32,0xff079ac5,0xbfc90fdb,3
+np.float32,0x3e974fbd,0x3e931fae,3
+np.float32,0x8020ae6b,0x8020ae6b,3
+np.float32,0x6b5af1,0x6b5af1,3
+np.float32,0xbeb57cd6,0xbeae69a3,3
+np.float32,0x806e7eb2,0x806e7eb2,3
+np.float32,0x7e666edb,0x3fc90fdb,3
+np.float32,0xbf458c18,0xbf283ff0,3
+np.float32,0x3e50518e,0x3e4d8399,3
+np.float32,0x3e9ce224,0x3e983b98,3
+np.float32,0x3e6bc067,0x3e67b6c6,3
+np.float32,0x13783d,0x13783d,3
+np.float32,0xff3d518c,0xbfc90fdb,3
+np.float32,0xfeba5968,0xbfc90fdb,3
+np.float32,0xbf0b9f76,0xbeffa50f,3
+np.float32,0xfe174900,0xbfc90fdb,3
+np.float32,0x3f38bb0a,0x3f200527,3
+np.float32,0x7e94a77d,0x3fc90fdb,3
+np.float32,0x29d776,0x29d776,3
+np.float32,0xbf4e058d,0xbf2d7a15,3
+np.float32,0xbd94abc8,0xbd946923,3
+np.float32,0xbee62db0,0xbed85124,3
+np.float32,0x800000,0x800000,3
+np.float32,0xbef1df7e,0xbee1f636,3
+np.float32,0xbcf3cd20,0xbcf3bab5,3
+np.float32,0x80007b05,0x80007b05,3
+np.float32,0x3d9b3f2e,0x3d9af351,3
+np.float32,0xbf714a68,0xbf417dee,3
+np.float32,0xbf2a2d37,0xbf163069,3
+np.float32,0x8055104f,0x8055104f,3
+np.float32,0x7f5c40d7,0x3fc90fdb,3
+np.float32,0x1,0x1,3
+np.float32,0xff35f3a6,0xbfc90fdb,3
+np.float32,0xd9c7c,0xd9c7c,3
+np.float32,0xbf440cfc,0xbf274f22,3
+np.float32,0x8050ac43,0x8050ac43,3
+np.float32,0x63ee16,0x63ee16,3
+np.float32,0x7d90419b,0x3fc90fdb,3
+np.float32,0xfee22198,0xbfc90fdb,3
+np.float32,0xc2ead,0xc2ead,3
+np.float32,0x7f5cd6a6,0x3fc90fdb,3
+np.float32,0x3f6fab7e,0x3f40a184,3
+np.float32,0x3ecf998c,0x3ec53a73,3
+np.float32,0x7e5271f0,0x3fc90fdb,3
+np.float32,0x67c016,0x67c016,3
+np.float32,0x2189c8,0x2189c8,3
+np.float32,0x27d892,0x27d892,3
+np.float32,0x3f0d02c4,0x3f00e3c0,3
+np.float32,0xbf69ebca,0xbf3d8862,3
+np.float32,0x3e60c0d6,0x3e5d3ebb,3
+np.float32,0x3f45206c,0x3f27fc66,3
+np.float32,0xbf6b47dc,0xbf3e4592,3
+np.float32,0xfe9be2e2,0xbfc90fdb,3
+np.float32,0x7fa00000,0x7fe00000,3
+np.float32,0xff271562,0xbfc90fdb,3
+np.float32,0x3e2e5270,0x3e2caaaf,3
+np.float32,0x80222934,0x80222934,3
+np.float32,0xbd01d220,0xbd01c701,3
+np.float32,0x223aa0,0x223aa0,3
+np.float32,0x3f4b5a7e,0x3f2bd967,3
+np.float32,0x3f217d85,0x3f101200,3
+np.float32,0xbf57663a,0xbf331144,3
+np.float32,0x3f219862,0x3f102536,3
+np.float32,0x28a28c,0x28a28c,3
+np.float32,0xbf3f55f4,0xbf244f86,3
+np.float32,0xbf3de287,0xbf236092,3
+np.float32,0xbf1c1ce2,0xbf0c2fe3,3
+np.float32,0x80000001,0x80000001,3
+np.float32,0x3db695d0,0x3db61a90,3
+np.float32,0x6c39bf,0x6c39bf,3
+np.float32,0x7e33a12f,0x3fc90fdb,3
+np.float32,0x67623a,0x67623a,3
+np.float32,0x3e45dc54,0x3e4373b6,3
+np.float32,0x7f62fa68,0x3fc90fdb,3
+np.float32,0x3f0e1d01,0x3f01bbe5,3
+np.float32,0x3f13dc69,0x3f0615f5,3
+np.float32,0x246703,0x246703,3
+np.float32,0xbf1055b5,0xbf036d07,3
+np.float32,0x7f46d3d0,0x3fc90fdb,3
+np.float32,0x3d2b8086,0x3d2b66e5,3
+np.float32,0xbf03be44,0xbef35776,3
+np.float32,0x3f800000,0x3f490fdb,3
+np.float32,0xbec8d226,0xbebf613d,3
+np.float32,0x3d8faf00,0x3d8f72d4,3
+np.float32,0x170c4e,0x170c4e,3
+np.float32,0xff14c0f0,0xbfc90fdb,3
+np.float32,0xff16245d,0xbfc90fdb,3
+np.float32,0x7f44ce6d,0x3fc90fdb,3
+np.float32,0xbe8175d8,0xbe7d9aeb,3
+np.float32,0x3df7a4a1,0x3df67254,3
+np.float32,0xfe2cc46c,0xbfc90fdb,3
+np.float32,0x3f284e63,0x3f14e335,3
+np.float32,0x7e46e5d6,0x3fc90fdb,3
+np.float32,0x397be4,0x397be4,3
+np.float32,0xbf2560bc,0xbf12d50b,3
+np.float32,0x3ed9b8c1,0x3ecddc60,3
+np.float32,0xfec18c5a,0xbfc90fdb,3
+np.float32,0x64894d,0x64894d,3
+np.float32,0x36a65d,0x36a65d,3
+np.float32,0x804ffcd7,0x804ffcd7,3
+np.float32,0x800f79e4,0x800f79e4,3
+np.float32,0x5d45ac,0x5d45ac,3
+np.float32,0x6cdda0,0x6cdda0,3
+np.float32,0xbf7f2077,0xbf489fe5,3
+np.float32,0xbf152f78,0xbf0713a1,3
+np.float32,0x807bf344,0x807bf344,3
+np.float32,0x3f775023,0x3f44a4d8,3
+np.float32,0xbf3edf67,0xbf240365,3
+np.float32,0x7eed729c,0x3fc90fdb,3
+np.float32,0x14cc29,0x14cc29,3
+np.float32,0x7edd7b6b,0x3fc90fdb,3
+np.float32,0xbf3c6e2c,0xbf226fb7,3
+np.float32,0x51b9ad,0x51b9ad,3
+np.float32,0x3f617ee8,0x3f38dd7c,3
+np.float32,0xff800000,0xbfc90fdb,3
+np.float32,0x7f440ea0,0x3fc90fdb,3
+np.float32,0x3e639893,0x3e5ff49e,3
+np.float32,0xbd791bb0,0xbd78cd3c,3
+np.float32,0x8059fcbc,0x8059fcbc,3
+np.float32,0xbf7d1214,0xbf4796bd,3
+np.float32,0x3ef368fa,0x3ee33788,3
+np.float32,0xbecec0f4,0xbec48055,3
+np.float32,0xbc83d940,0xbc83d656,3
+np.float32,0xbce01220,0xbce003d4,3
+np.float32,0x803192a5,0x803192a5,3
+np.float32,0xbe40e0c0,0xbe3ea4f0,3
+np.float32,0xfb692600,0xbfc90fdb,3
+np.float32,0x3f1bec65,0x3f0c0c88,3
+np.float32,0x7f042798,0x3fc90fdb,3
+np.float32,0xbe047374,0xbe03b83b,3
+np.float32,0x7f7c6630,0x3fc90fdb,3
+np.float32,0x7f58dae3,0x3fc90fdb,3
+np.float32,0x80691c92,0x80691c92,3
+np.float32,0x7dbe76,0x7dbe76,3
+np.float32,0xbf231384,0xbf11339d,3
+np.float32,0xbef4acf8,0xbee43f8b,3
+np.float32,0x3ee9f9d0,0x3edb7793,3
+np.float32,0x3f0064f6,0x3eee04a8,3
+np.float32,0x313732,0x313732,3
+np.float32,0xfd58cf80,0xbfc90fdb,3
+np.float32,0x3f7a2bc9,0x3f461d30,3
+np.float32,0x7f7681af,0x3fc90fdb,3
+np.float32,0x7f504211,0x3fc90fdb,3
+np.float32,0xfeae0c00,0xbfc90fdb,3
+np.float32,0xbee14396,0xbed436d1,3
+np.float32,0x7fc00000,0x7fc00000,3
+np.float32,0x693406,0x693406,3
+np.float32,0x3eb4a679,0x3eadab1b,3
+np.float32,0x550505,0x550505,3
+np.float32,0xfd493d10,0xbfc90fdb,3
+np.float32,0x3f4fc907,0x3f2e8b2c,3
+np.float32,0x80799aa4,0x80799aa4,3
+np.float32,0xff1ea89b,0xbfc90fdb,3
+np.float32,0xff424510,0xbfc90fdb,3
+np.float32,0x7f68d026,0x3fc90fdb,3
+np.float32,0xbea230ca,0xbe9d1200,3
+np.float32,0x7ea585da,0x3fc90fdb,3
+np.float32,0x3f3db211,0x3f23414c,3
+np.float32,0xfea4d964,0xbfc90fdb,3
+np.float32,0xbf17fe18,0xbf092984,3
+np.float32,0x7cc8a2,0x7cc8a2,3
+np.float32,0xff0330ba,0xbfc90fdb,3
+np.float32,0x3f769835,0x3f444592,3
+np.float32,0xeb0ac,0xeb0ac,3
+np.float32,0x7f7e45de,0x3fc90fdb,3
+np.float32,0xbdb510a8,0xbdb49873,3
+np.float32,0x3ebf900b,0x3eb74e9c,3
+np.float32,0xbf21bbce,0xbf103e89,3
+np.float32,0xbf3f4682,0xbf24459d,3
+np.float32,0x7eb6e9c8,0x3fc90fdb,3
+np.float32,0xbf42532d,0xbf2637be,3
+np.float32,0xbd3b2600,0xbd3b04b4,3
+np.float32,0x3f1fa9aa,0x3f0ec23e,3
+np.float32,0x7ed6a0f1,0x3fc90fdb,3
+np.float32,0xff4759a1,0xbfc90fdb,3
+np.float32,0x6d26e3,0x6d26e3,3
+np.float32,0xfe1108e0,0xbfc90fdb,3
+np.float32,0xfdf76900,0xbfc90fdb,3
+np.float32,0xfec66f22,0xbfc90fdb,3
+np.float32,0xbf3d097f,0xbf22d458,3
+np.float32,0x3d85be25,0x3d858d99,3
+np.float32,0x7f36739f,0x3fc90fdb,3
+np.float32,0x7bc0a304,0x3fc90fdb,3
+np.float32,0xff48dd90,0xbfc90fdb,3
+np.float32,0x48cab0,0x48cab0,3
+np.float32,0x3ed3943c,0x3ec8a2ef,3
+np.float32,0xbf61488e,0xbf38bede,3
+np.float32,0x3f543df5,0x3f313525,3
+np.float32,0x5cf2ca,0x5cf2ca,3
+np.float32,0x572686,0x572686,3
+np.float32,0x80369c7c,0x80369c7c,3
+np.float32,0xbd2c1d20,0xbd2c0338,3
+np.float32,0x3e255428,0x3e23ea0b,3
+np.float32,0xbeba9ee0,0xbeb2f54c,3
+np.float32,0x8015c165,0x8015c165,3
+np.float32,0x3d31f488,0x3d31d7e6,3
+np.float32,0x3f68591c,0x3f3cac43,3
+np.float32,0xf5ed5,0xf5ed5,3
+np.float32,0xbf3b1d34,0xbf21949e,3
+np.float32,0x1f0343,0x1f0343,3
+np.float32,0x3f0e52b5,0x3f01e4ef,3
+np.float32,0x7f57c596,0x3fc90fdb,3
+np.float64,0x7fd8e333ddb1c667,0x3ff921fb54442d18,3
+np.float64,0x800bcc9cdad7993a,0x800bcc9cdad7993a,3
+np.float64,0x3fcd6f81df3adf00,0x3fcceebbafc5d55e,3
+np.float64,0x3fed7338a57ae671,0x3fe7ce3e5811fc0a,3
+np.float64,0x7fe64994fcac9329,0x3ff921fb54442d18,3
+np.float64,0xfa5a6345f4b4d,0xfa5a6345f4b4d,3
+np.float64,0xe9dcd865d3b9b,0xe9dcd865d3b9b,3
+np.float64,0x7fea6cffabf4d9fe,0x3ff921fb54442d18,3
+np.float64,0xa9e1de6153c3c,0xa9e1de6153c3c,3
+np.float64,0xab6bdc5356d7c,0xab6bdc5356d7c,3
+np.float64,0x80062864a02c50ca,0x80062864a02c50ca,3
+np.float64,0xbfdac03aa7b58076,0xbfd9569f3230128d,3
+np.float64,0xbfe61b77752c36ef,0xbfe3588f51b8be8f,3
+np.float64,0x800bc854c8d790aa,0x800bc854c8d790aa,3
+np.float64,0x3feed1a2da3da346,0x3fe887f9b8ea031f,3
+np.float64,0x3fe910d3697221a7,0x3fe54365a53d840e,3
+np.float64,0x7fe7ab4944ef5692,0x3ff921fb54442d18,3
+np.float64,0x3fa462f1a028c5e3,0x3fa460303a6a4e69,3
+np.float64,0x800794f1a3af29e4,0x800794f1a3af29e4,3
+np.float64,0x3fee6fe7fafcdfd0,0x3fe854f863816d55,3
+np.float64,0x8000000000000000,0x8000000000000000,3
+np.float64,0x7f336472fe66d,0x7f336472fe66d,3
+np.float64,0xffb1623ac822c478,0xbff921fb54442d18,3
+np.float64,0x3fbacd68ce359ad2,0x3fbab480b3638846,3
+np.float64,0xffd5c02706ab804e,0xbff921fb54442d18,3
+np.float64,0xbfd4daf03d29b5e0,0xbfd42928f069c062,3
+np.float64,0x800c6e85dbd8dd0c,0x800c6e85dbd8dd0c,3
+np.float64,0x800e3599c5bc6b34,0x800e3599c5bc6b34,3
+np.float64,0x2c0d654c581ad,0x2c0d654c581ad,3
+np.float64,0xbfdd3eb13fba7d62,0xbfdb6e8143302de7,3
+np.float64,0x800b60cb8776c197,0x800b60cb8776c197,3
+np.float64,0x80089819ad113034,0x80089819ad113034,3
+np.float64,0x29fe721453fcf,0x29fe721453fcf,3
+np.float64,0x3fe8722f4df0e45f,0x3fe4e026d9eadb4d,3
+np.float64,0xffd1fbcd01a3f79a,0xbff921fb54442d18,3
+np.float64,0x7fc74e1e982e9c3c,0x3ff921fb54442d18,3
+np.float64,0x800c09d3d15813a8,0x800c09d3d15813a8,3
+np.float64,0xbfeee4578b3dc8af,0xbfe891ab3d6c3ce4,3
+np.float64,0xffdd01a6f33a034e,0xbff921fb54442d18,3
+np.float64,0x7fcc130480382608,0x3ff921fb54442d18,3
+np.float64,0xffcbb6bd1d376d7c,0xbff921fb54442d18,3
+np.float64,0xc068a53780d15,0xc068a53780d15,3
+np.float64,0xbfc974f15532e9e4,0xbfc92100b355f3e7,3
+np.float64,0x3fe6da79442db4f3,0x3fe3d87393b082e7,3
+np.float64,0xd9d9be4db3b38,0xd9d9be4db3b38,3
+np.float64,0x5ea50a20bd4a2,0x5ea50a20bd4a2,3
+np.float64,0xbfe5597f7d2ab2ff,0xbfe2d3ccc544b52b,3
+np.float64,0x80019364e4e326cb,0x80019364e4e326cb,3
+np.float64,0x3fed2902c3fa5206,0x3fe7a5e1df07e5c1,3
+np.float64,0xbfa7b72b5c2f6e50,0xbfa7b2d545b3cc1f,3
+np.float64,0xffdb60dd43b6c1ba,0xbff921fb54442d18,3
+np.float64,0x81a65d8b034cc,0x81a65d8b034cc,3
+np.float64,0x8000c30385818608,0x8000c30385818608,3
+np.float64,0x6022f5f4c045f,0x6022f5f4c045f,3
+np.float64,0x8007a2bb810f4578,0x8007a2bb810f4578,3
+np.float64,0x7fdc68893238d111,0x3ff921fb54442d18,3
+np.float64,0x7fd443454ea8868a,0x3ff921fb54442d18,3
+np.float64,0xffe6b04209ed6084,0xbff921fb54442d18,3
+np.float64,0x7fcd9733d13b2e67,0x3ff921fb54442d18,3
+np.float64,0xf5ee80a9ebdd0,0xf5ee80a9ebdd0,3
+np.float64,0x3fe3788e8de6f11e,0x3fe17dec7e6843a0,3
+np.float64,0x3fee36f62f7c6dec,0x3fe836f832515b43,3
+np.float64,0xf6cb49aded969,0xf6cb49aded969,3
+np.float64,0x3fd2b15ea4a562bc,0x3fd22fdc09920e67,3
+np.float64,0x7fccf6aef139ed5d,0x3ff921fb54442d18,3
+np.float64,0x3fd396b8ce272d72,0x3fd3026118857bd4,3
+np.float64,0x7fe53d3c80ea7a78,0x3ff921fb54442d18,3
+np.float64,0x3feae88fc4f5d120,0x3fe65fb04b18ef7a,3
+np.float64,0x3fedc643747b8c86,0x3fe7fafa6c20e25a,3
+np.float64,0xffdb2dc0df365b82,0xbff921fb54442d18,3
+np.float64,0xbfa2af3658255e70,0xbfa2ad17348f4253,3
+np.float64,0x3f8aa77b30354ef6,0x3f8aa71892336a69,3
+np.float64,0xbfdd1b1efbba363e,0xbfdb510dcd186820,3
+np.float64,0x800f50d99c5ea1b3,0x800f50d99c5ea1b3,3
+np.float64,0xff6ed602403dac00,0xbff921fb54442d18,3
+np.float64,0x800477d71aa8efaf,0x800477d71aa8efaf,3
+np.float64,0xbfe729a9e86e5354,0xbfe40ca78d9eefcf,3
+np.float64,0x3fd81ab2d4303566,0x3fd70d7e3937ea22,3
+np.float64,0xb617cbab6c2fa,0xb617cbab6c2fa,3
+np.float64,0x7fefffffffffffff,0x3ff921fb54442d18,3
+np.float64,0xffa40933ac281260,0xbff921fb54442d18,3
+np.float64,0xbfe1ede621e3dbcc,0xbfe057bb2b341ced,3
+np.float64,0xbfec700f03b8e01e,0xbfe73fb190bc722e,3
+np.float64,0x6e28af02dc517,0x6e28af02dc517,3
+np.float64,0x3fe37ad37ae6f5a7,0x3fe17f94674818a9,3
+np.float64,0x8000cbdeeae197bf,0x8000cbdeeae197bf,3
+np.float64,0x3fe8fd1f01f1fa3e,0x3fe5372bbec5d72c,3
+np.float64,0x3f8f9229103f2452,0x3f8f918531894256,3
+np.float64,0x800536858e0a6d0c,0x800536858e0a6d0c,3
+np.float64,0x7fe82bb4f9f05769,0x3ff921fb54442d18,3
+np.float64,0xffc1c2fb592385f8,0xbff921fb54442d18,3
+np.float64,0x7f924ddfc0249bbf,0x3ff921fb54442d18,3
+np.float64,0xffd5e125c52bc24c,0xbff921fb54442d18,3
+np.float64,0xbfef0d8738be1b0e,0xbfe8a6ef17b16c10,3
+np.float64,0x3fc9c8875233910f,0x3fc9715e708503cb,3
+np.float64,0xbfe2d926f4e5b24e,0xbfe108956e61cbb3,3
+np.float64,0x7fd61c496dac3892,0x3ff921fb54442d18,3
+np.float64,0x7fed545c6b7aa8b8,0x3ff921fb54442d18,3
+np.float64,0x8003746fea86e8e1,0x8003746fea86e8e1,3
+np.float64,0x3fdf515e75bea2bd,0x3fdd201a5585caa3,3
+np.float64,0xffda87c8ee350f92,0xbff921fb54442d18,3
+np.float64,0xffc675d8e22cebb0,0xbff921fb54442d18,3
+np.float64,0xffcdc173433b82e8,0xbff921fb54442d18,3
+np.float64,0xffed9df1517b3be2,0xbff921fb54442d18,3
+np.float64,0x3fd6a2eec72d45de,0x3fd5c1f1d7dcddcf,3
+np.float64,0xffec116a66f822d4,0xbff921fb54442d18,3
+np.float64,0x8007c2a2458f8545,0x8007c2a2458f8545,3
+np.float64,0x3fe4ee80d969dd02,0x3fe2895076094668,3
+np.float64,0x3fe3cae7116795ce,0x3fe1b9c07e0d03a7,3
+np.float64,0xbfd81bf8d8b037f2,0xbfd70e9bbbb4ca57,3
+np.float64,0x800c88ccd1f9119a,0x800c88ccd1f9119a,3
+np.float64,0xffdab2aee2b5655e,0xbff921fb54442d18,3
+np.float64,0x3fe743d227ee87a4,0x3fe41dcaef186d96,3
+np.float64,0x3fb060fd0220c1fa,0x3fb05b47f56ebbb4,3
+np.float64,0xbfd3f03772a7e06e,0xbfd3541522377291,3
+np.float64,0x190a5ae03216,0x190a5ae03216,3
+np.float64,0x3fe48c71916918e4,0x3fe24442f45b3183,3
+np.float64,0x800862470590c48e,0x800862470590c48e,3
+np.float64,0x7fd3ced89d279db0,0x3ff921fb54442d18,3
+np.float64,0x3feb3d9b4ab67b37,0x3fe69140cf2623f7,3
+np.float64,0xbc3f296b787e5,0xbc3f296b787e5,3
+np.float64,0xbfed6b905dfad721,0xbfe7ca1881a8c0fd,3
+np.float64,0xbfe621c2aaac4386,0xbfe35cd1969a82db,3
+np.float64,0x8009e7b17593cf63,0x8009e7b17593cf63,3
+np.float64,0x80045f580ca8beb1,0x80045f580ca8beb1,3
+np.float64,0xbfea2e177e745c2f,0xbfe5f13971633339,3
+np.float64,0x3fee655787fccab0,0x3fe84f6b98b6de26,3
+np.float64,0x3fc9cde92f339bd0,0x3fc9768a88b2c97c,3
+np.float64,0x3fc819c3b3303388,0x3fc7d25e1526e731,3
+np.float64,0x3fd3e848d2a7d090,0x3fd34cd9e6af558f,3
+np.float64,0x3fe19dacac633b5a,0x3fe01a6b4d27adc2,3
+np.float64,0x800b190da316321c,0x800b190da316321c,3
+np.float64,0xd5c69711ab8d3,0xd5c69711ab8d3,3
+np.float64,0xbfdc31bed7b8637e,0xbfda8ea3c1309d6d,3
+np.float64,0xbfd02ba007a05740,0xbfcfad86f0d756dc,3
+np.float64,0x3fe874473d70e88e,0x3fe4e1793cd82123,3
+np.float64,0xffb465585c28cab0,0xbff921fb54442d18,3
+np.float64,0xbfb5d8e13e2bb1c0,0xbfb5cb5c7807fc4d,3
+np.float64,0xffe80f933bf01f26,0xbff921fb54442d18,3
+np.float64,0x7feea783f5fd4f07,0x3ff921fb54442d18,3
+np.float64,0xbfae6665f43cccd0,0xbfae5d45b0a6f90a,3
+np.float64,0x800bd6ef5a77addf,0x800bd6ef5a77addf,3
+np.float64,0x800d145babda28b8,0x800d145babda28b8,3
+np.float64,0x39de155473bc3,0x39de155473bc3,3
+np.float64,0x3fefbd6bb1ff7ad8,0x3fe9008e73a3296e,3
+np.float64,0x3fc40bca3d281798,0x3fc3e2710e167007,3
+np.float64,0x3fcae0918335c120,0x3fca7e09e704a678,3
+np.float64,0x51287fbea2511,0x51287fbea2511,3
+np.float64,0x7fa6bc33a82d7866,0x3ff921fb54442d18,3
+np.float64,0xe72a2bebce546,0xe72a2bebce546,3
+np.float64,0x3fe1c8fd686391fa,0x3fe03b9622aeb4e3,3
+np.float64,0x3fe2a73ac3654e76,0x3fe0e36bc1ee4ac4,3
+np.float64,0x59895218b312b,0x59895218b312b,3
+np.float64,0xc6dc25c78db85,0xc6dc25c78db85,3
+np.float64,0xbfc06cfac520d9f4,0xbfc0561f85d2c907,3
+np.float64,0xbfea912dc4f5225c,0xbfe62c3b1c01c793,3
+np.float64,0x3fb78ce89a2f19d0,0x3fb77bfcb65a67d3,3
+np.float64,0xbfece5cdea39cb9c,0xbfe78103d24099e5,3
+np.float64,0x30d3054e61a61,0x30d3054e61a61,3
+np.float64,0xbfd3fe26fba7fc4e,0xbfd360c8447c4f7a,3
+np.float64,0x800956072a92ac0f,0x800956072a92ac0f,3
+np.float64,0x7fe639b3b6ec7366,0x3ff921fb54442d18,3
+np.float64,0x800ee30240bdc605,0x800ee30240bdc605,3
+np.float64,0x7fef6af0d2bed5e1,0x3ff921fb54442d18,3
+np.float64,0xffefce8725ff9d0d,0xbff921fb54442d18,3
+np.float64,0x3fe2e311da65c624,0x3fe10ff1623089dc,3
+np.float64,0xbfe7e5cbe56fcb98,0xbfe486c3daeda67c,3
+np.float64,0x80095bc14472b783,0x80095bc14472b783,3
+np.float64,0xffef0cb4553e1968,0xbff921fb54442d18,3
+np.float64,0xe3e60567c7cc1,0xe3e60567c7cc1,3
+np.float64,0xffde919f06bd233e,0xbff921fb54442d18,3
+np.float64,0x3fe3f9632e27f2c6,0x3fe1db49ebd21c4e,3
+np.float64,0x9dee9a233bdd4,0x9dee9a233bdd4,3
+np.float64,0xbfe3bb0602e7760c,0xbfe1ae41b6d4c488,3
+np.float64,0x3fc46945a128d288,0x3fc43da54c6c6a2a,3
+np.float64,0x7fdef149ac3de292,0x3ff921fb54442d18,3
+np.float64,0x800a96c76d752d8f,0x800a96c76d752d8f,3
+np.float64,0x3f971a32382e3464,0x3f9719316b9e9baf,3
+np.float64,0x7fe97bcf15b2f79d,0x3ff921fb54442d18,3
+np.float64,0x7fea894558f5128a,0x3ff921fb54442d18,3
+np.float64,0x3fc9e3be1933c780,0x3fc98b847c3923eb,3
+np.float64,0x3f7accac40359959,0x3f7acc9330741b64,3
+np.float64,0xa80c136950183,0xa80c136950183,3
+np.float64,0x3fe408732b2810e6,0x3fe1e61e7cbc8824,3
+np.float64,0xffa775bc042eeb80,0xbff921fb54442d18,3
+np.float64,0x3fbf04bd223e0980,0x3fbede37b8fc697e,3
+np.float64,0x7fd999b34c333366,0x3ff921fb54442d18,3
+np.float64,0xe72146dfce429,0xe72146dfce429,3
+np.float64,0x4f511ee49ea24,0x4f511ee49ea24,3
+np.float64,0xffb3e6e58827cdc8,0xbff921fb54442d18,3
+np.float64,0x3fd1f180cfa3e300,0x3fd17e85b2871de2,3
+np.float64,0x97c8e45b2f91d,0x97c8e45b2f91d,3
+np.float64,0xbfeeb20e88fd641d,0xbfe8778f878440bf,3
+np.float64,0xbfe1fc6dee23f8dc,0xbfe062c815a93cde,3
+np.float64,0xab4bf71f5697f,0xab4bf71f5697f,3
+np.float64,0xa9675a2952cec,0xa9675a2952cec,3
+np.float64,0xbfef3ea4a33e7d49,0xbfe8c02743ebc1b6,3
+np.float64,0x3fe22a2eafa4545d,0x3fe08577afca52a9,3
+np.float64,0x3fe8a08daaf1411c,0x3fe4fd5a34f05305,3
+np.float64,0xbfc6cda77b2d9b50,0xbfc6910bcfa0cf4f,3
+np.float64,0x3fec398394387307,0x3fe7211dd5276500,3
+np.float64,0x3fe36c95c626d92c,0x3fe1752e5aa2357b,3
+np.float64,0xffd8b9e7073173ce,0xbff921fb54442d18,3
+np.float64,0xffe19f043ae33e08,0xbff921fb54442d18,3
+np.float64,0x800e3640709c6c81,0x800e3640709c6c81,3
+np.float64,0x3fe7d6c20aafad84,0x3fe47d1a3307d9c8,3
+np.float64,0x80093fd63b727fad,0x80093fd63b727fad,3
+np.float64,0xffe1a671a4634ce3,0xbff921fb54442d18,3
+np.float64,0xbfe53a6b386a74d6,0xbfe2be41859cb10d,3
+np.float64,0xbfed149a097a2934,0xbfe79ab7e3e93c1c,3
+np.float64,0x7fc2769a5724ed34,0x3ff921fb54442d18,3
+np.float64,0xffd01e4e99a03c9e,0xbff921fb54442d18,3
+np.float64,0xa61f38434c3e7,0xa61f38434c3e7,3
+np.float64,0x800ad4ac5195a959,0x800ad4ac5195a959,3
+np.float64,0x7ff8000000000000,0x7ff8000000000000,3
+np.float64,0x80034a45b6c6948c,0x80034a45b6c6948c,3
+np.float64,0x6350b218c6a17,0x6350b218c6a17,3
+np.float64,0xfff0000000000000,0xbff921fb54442d18,3
+np.float64,0x3fe363e759e6c7cf,0x3fe16ed58d80f9ce,3
+np.float64,0xffe3b98e59e7731c,0xbff921fb54442d18,3
+np.float64,0x3fdbf7b40337ef68,0x3fda5df7ad3c80f9,3
+np.float64,0xbfe9cdf784739bef,0xbfe5b74f346ef93d,3
+np.float64,0xbfc321bea326437c,0xbfc2fdc0d4ff7561,3
+np.float64,0xbfe40f77d2a81ef0,0xbfe1eb28c4ae4dde,3
+np.float64,0x7fe071806960e300,0x3ff921fb54442d18,3
+np.float64,0x7fd269006ea4d200,0x3ff921fb54442d18,3
+np.float64,0x80017a56e0e2f4af,0x80017a56e0e2f4af,3
+np.float64,0x8004b4ea09a969d5,0x8004b4ea09a969d5,3
+np.float64,0xbfedbb01e63b7604,0xbfe7f4f0e84297df,3
+np.float64,0x3fe44454826888a9,0x3fe210ff6d005706,3
+np.float64,0xbfe0e77e6ea1cefd,0xbfdf1a977da33402,3
+np.float64,0xbfed6d4c8c3ada99,0xbfe7cb0932093f60,3
+np.float64,0x1d74cb9e3ae9a,0x1d74cb9e3ae9a,3
+np.float64,0x80082a785d1054f1,0x80082a785d1054f1,3
+np.float64,0x3fe58393266b0726,0x3fe2f0d8e91d4887,3
+np.float64,0xffe4028899680510,0xbff921fb54442d18,3
+np.float64,0x783a2e5af0746,0x783a2e5af0746,3
+np.float64,0x7fcdce88e73b9d11,0x3ff921fb54442d18,3
+np.float64,0x3fc58672a72b0ce5,0x3fc5535e090e56e2,3
+np.float64,0x800889c839b11391,0x800889c839b11391,3
+np.float64,0xffe5e05c466bc0b8,0xbff921fb54442d18,3
+np.float64,0xbfcbef6ebe37dedc,0xbfcb810752468f49,3
+np.float64,0xffe9408563b2810a,0xbff921fb54442d18,3
+np.float64,0xbfee4738367c8e70,0xbfe83f8e5dd7602f,3
+np.float64,0xbfe4aeb587295d6b,0xbfe25c7a0c76a454,3
+np.float64,0xffc9aea0a7335d40,0xbff921fb54442d18,3
+np.float64,0xe1e02199c3c04,0xe1e02199c3c04,3
+np.float64,0xbfbd9400783b2800,0xbfbd729345d1d14f,3
+np.float64,0x7a5418bcf4a84,0x7a5418bcf4a84,3
+np.float64,0x3fdc1c2fa5b83860,0x3fda7c935965ae72,3
+np.float64,0x80076a9f58ced53f,0x80076a9f58ced53f,3
+np.float64,0x3fedc4bf957b897f,0x3fe7fa2a83148f1c,3
+np.float64,0x800981b8a9d30372,0x800981b8a9d30372,3
+np.float64,0xffe1082311621046,0xbff921fb54442d18,3
+np.float64,0xe0091f89c0124,0xe0091f89c0124,3
+np.float64,0xbfce8d674f3d1ad0,0xbfcdfdbf2ddaa0ca,3
+np.float64,0x800516e72eaa2dcf,0x800516e72eaa2dcf,3
+np.float64,0xffe61ee64c6c3dcc,0xbff921fb54442d18,3
+np.float64,0x7fed2683cafa4d07,0x3ff921fb54442d18,3
+np.float64,0xffd4faf27729f5e4,0xbff921fb54442d18,3
+np.float64,0x7fe308fa842611f4,0x3ff921fb54442d18,3
+np.float64,0x3fc612a62b2c2550,0x3fc5db9ddbd4e159,3
+np.float64,0xbfe5b01e766b603d,0xbfe30f72a875e988,3
+np.float64,0x3fc2dd8b9a25bb17,0x3fc2bb06246b9f78,3
+np.float64,0x8170908102e12,0x8170908102e12,3
+np.float64,0x800c1c8a8a583915,0x800c1c8a8a583915,3
+np.float64,0xffe5d91e8b6bb23c,0xbff921fb54442d18,3
+np.float64,0xffd140adee22815c,0xbff921fb54442d18,3
+np.float64,0xbfe2f1f5f8e5e3ec,0xbfe11afa5d749952,3
+np.float64,0xbfed6d1d587ada3b,0xbfe7caef9ecf7651,3
+np.float64,0x3fe9b85e67f370bd,0x3fe5aa3474768982,3
+np.float64,0x7fdc8932edb91265,0x3ff921fb54442d18,3
+np.float64,0x7fd136bc54a26d78,0x3ff921fb54442d18,3
+np.float64,0x800a1ea12a343d43,0x800a1ea12a343d43,3
+np.float64,0x3fec6a5c1b78d4b8,0x3fe73c82235c3f8f,3
+np.float64,0x800fbf6a00df7ed4,0x800fbf6a00df7ed4,3
+np.float64,0xbfd0e6e0cda1cdc2,0xbfd0864bf8cad294,3
+np.float64,0x3fc716df482e2dbf,0x3fc6d7fbfd4a8470,3
+np.float64,0xbfe75990936eb321,0xbfe42bffec3fa0d7,3
+np.float64,0x3fd58e54a02b1ca9,0x3fd4cace1107a5cc,3
+np.float64,0xbfc9c04136338084,0xbfc9696ad2591d54,3
+np.float64,0xdd1f0147ba3e0,0xdd1f0147ba3e0,3
+np.float64,0x5c86a940b90e,0x5c86a940b90e,3
+np.float64,0xbfecae3b8e795c77,0xbfe7624d4988c612,3
+np.float64,0xffd0370595206e0c,0xbff921fb54442d18,3
+np.float64,0xbfdc26d443384da8,0xbfda857ecd33ba9f,3
+np.float64,0xbfd1c849d9a39094,0xbfd15849449cc378,3
+np.float64,0xffee04acdb3c0959,0xbff921fb54442d18,3
+np.float64,0xbfded1056dbda20a,0xbfdcb83b30e1528c,3
+np.float64,0x7fb7b826622f704c,0x3ff921fb54442d18,3
+np.float64,0xbfee4df8ae7c9bf1,0xbfe8431df9dfd05d,3
+np.float64,0x7fe7f3670e2fe6cd,0x3ff921fb54442d18,3
+np.float64,0x8008ac9ae0d15936,0x8008ac9ae0d15936,3
+np.float64,0x800dce9f3b3b9d3f,0x800dce9f3b3b9d3f,3
+np.float64,0x7fbb19db203633b5,0x3ff921fb54442d18,3
+np.float64,0x3fe56c7f302ad8fe,0x3fe2e0eec3ad45fd,3
+np.float64,0x7fe82c05c570580b,0x3ff921fb54442d18,3
+np.float64,0xc0552b7780aa6,0xc0552b7780aa6,3
+np.float64,0x39d40e3073a83,0x39d40e3073a83,3
+np.float64,0x3fd8db54d731b6aa,0x3fd7b589b3ee9b20,3
+np.float64,0xffcdd355233ba6ac,0xbff921fb54442d18,3
+np.float64,0x3fbe97b3a43d2f67,0x3fbe72bca9be0348,3
+np.float64,0xbff0000000000000,0xbfe921fb54442d18,3
+np.float64,0xbfb4f55e6229eac0,0xbfb4e96df18a75a7,3
+np.float64,0xbfc66399ba2cc734,0xbfc62a3298bd96fc,3
+np.float64,0x3fd00988bb201311,0x3fcf6d67a9374c38,3
+np.float64,0x7fe471867d28e30c,0x3ff921fb54442d18,3
+np.float64,0xbfe38e0e64271c1d,0xbfe18d9888b7523b,3
+np.float64,0x8009dc127573b825,0x8009dc127573b825,3
+np.float64,0x800047bde4608f7d,0x800047bde4608f7d,3
+np.float64,0xffeede42c77dbc85,0xbff921fb54442d18,3
+np.float64,0xd8cf6d13b19ee,0xd8cf6d13b19ee,3
+np.float64,0xbfd08fb302a11f66,0xbfd034b1f8235e23,3
+np.float64,0x7fdb404c0b368097,0x3ff921fb54442d18,3
+np.float64,0xbfd6ba0438ad7408,0xbfd5d673e3276ec1,3
+np.float64,0xffd9568027b2ad00,0xbff921fb54442d18,3
+np.float64,0xbfb313b73e262770,0xbfb30ab4acb4fa67,3
+np.float64,0xbfe2dc1a15e5b834,0xbfe10ac5f8f3acd3,3
+np.float64,0xbfee426bf4bc84d8,0xbfe83d061df91edd,3
+np.float64,0xd9142c2fb2286,0xd9142c2fb2286,3
+np.float64,0x7feb0d11dff61a23,0x3ff921fb54442d18,3
+np.float64,0x800fea5b509fd4b7,0x800fea5b509fd4b7,3
+np.float64,0x3fe1a8818da35103,0x3fe022ba1bdf366e,3
+np.float64,0x8010000000000000,0x8010000000000000,3
+np.float64,0xbfd8fc6de6b1f8dc,0xbfd7d24726ed8dcc,3
+np.float64,0xf4b3dc2de967c,0xf4b3dc2de967c,3
+np.float64,0x8af0409b15e08,0x8af0409b15e08,3
+np.float64,0x3fb21e6934243cd2,0x3fb216b065f8709a,3
+np.float64,0x3fc53069392a60d2,0x3fc4ffa931211fb9,3
+np.float64,0xffc955812c32ab04,0xbff921fb54442d18,3
+np.float64,0xbfe3de42b1a7bc86,0xbfe1c7bd1324de75,3
+np.float64,0x1dc149a03b82a,0x1dc149a03b82a,3
+np.float64,0x8001bc5a24a378b5,0x8001bc5a24a378b5,3
+np.float64,0x3da14c407b44,0x3da14c407b44,3
+np.float64,0x80025e8da924bd1c,0x80025e8da924bd1c,3
+np.float64,0xbfcb0141c9360284,0xbfca9d572ea5e1f3,3
+np.float64,0xc90036fd92007,0xc90036fd92007,3
+np.float64,0x138312c427063,0x138312c427063,3
+np.float64,0x800dda3a963bb475,0x800dda3a963bb475,3
+np.float64,0x3fe9339934f26732,0x3fe558e723291f78,3
+np.float64,0xbfea8357027506ae,0xbfe6240826faaf48,3
+np.float64,0x7fe04735cae08e6b,0x3ff921fb54442d18,3
+np.float64,0x3fe29aca3c653594,0x3fe0da214c8bc6a4,3
+np.float64,0x3fbe1f09a03c3e13,0x3fbdfbbefef0155b,3
+np.float64,0x816ee4ad02ddd,0x816ee4ad02ddd,3
+np.float64,0xffddd1b31d3ba366,0xbff921fb54442d18,3
+np.float64,0x3fe2e01e0625c03c,0x3fe10dc0bd6677c2,3
+np.float64,0x3fec6bcf1978d79e,0x3fe73d518cddeb7c,3
+np.float64,0x7fe01aaaf8603555,0x3ff921fb54442d18,3
+np.float64,0xdf300cc5be602,0xdf300cc5be602,3
+np.float64,0xbfe71c01a36e3804,0xbfe403af80ce47b8,3
+np.float64,0xffa5be00ac2b7c00,0xbff921fb54442d18,3
+np.float64,0xbfda9ba711b5374e,0xbfd93775e3ac6bda,3
+np.float64,0xbfe56d8a27eadb14,0xbfe2e1a7185e8e6d,3
+np.float64,0x800f1bc937be3792,0x800f1bc937be3792,3
+np.float64,0x800a61d93c74c3b3,0x800a61d93c74c3b3,3
+np.float64,0x7fe71a52fcae34a5,0x3ff921fb54442d18,3
+np.float64,0x7fb4aef256295de4,0x3ff921fb54442d18,3
+np.float64,0x3fe6c1e861ed83d1,0x3fe3c828f281a7ef,3
+np.float64,0x3fba128402342508,0x3fb9fb94cf141860,3
+np.float64,0x3fee55a7ecfcab50,0x3fe8472a9af893ee,3
+np.float64,0x3fe586f31b2b0de6,0x3fe2f32bce9e91bc,3
+np.float64,0xbfbb1d1442363a28,0xbfbb034c7729d5f2,3
+np.float64,0xc78b4d3f8f16a,0xc78b4d3f8f16a,3
+np.float64,0x7fdbc277d4b784ef,0x3ff921fb54442d18,3
+np.float64,0xbfa728ca2c2e5190,0xbfa724c04e73ccbd,3
+np.float64,0x7fefc7b2143f8f63,0x3ff921fb54442d18,3
+np.float64,0x3fd153a3dda2a748,0x3fd0ebccd33a4dca,3
+np.float64,0xbfe18a6eace314de,0xbfe00ba32ec89d30,3
+np.float64,0x7feef518537dea30,0x3ff921fb54442d18,3
+np.float64,0x8005f007cd4be010,0x8005f007cd4be010,3
+np.float64,0x7fd890b840b12170,0x3ff921fb54442d18,3
+np.float64,0x7feed0582ebda0af,0x3ff921fb54442d18,3
+np.float64,0x1013f53220280,0x1013f53220280,3
+np.float64,0xbfe77273986ee4e7,0xbfe43c375a8bf6de,3
+np.float64,0x7fe3ab8918675711,0x3ff921fb54442d18,3
+np.float64,0xbfc6ad515b2d5aa4,0xbfc671b2f7f86624,3
+np.float64,0x7fcd86231d3b0c45,0x3ff921fb54442d18,3
+np.float64,0xffe2523299a4a464,0xbff921fb54442d18,3
+np.float64,0x7fcadc5a1b35b8b3,0x3ff921fb54442d18,3
+np.float64,0x3fe5e020c4ebc042,0x3fe330418eec75bd,3
+np.float64,0x7fe332a9dc266553,0x3ff921fb54442d18,3
+np.float64,0xfa11dc21f425,0xfa11dc21f425,3
+np.float64,0xbec800177d900,0xbec800177d900,3
+np.float64,0x3fcadd057835ba0b,0x3fca7aa42face8bc,3
+np.float64,0xbfe6b9a206ad7344,0xbfe3c2a9719803de,3
+np.float64,0x3fbb4250b63684a0,0x3fbb281e9cefc519,3
+np.float64,0x7fef8787517f0f0e,0x3ff921fb54442d18,3
+np.float64,0x8001315c2d6262b9,0x8001315c2d6262b9,3
+np.float64,0xbfd94e3cf2b29c7a,0xbfd819257d36f56c,3
+np.float64,0xf1f325abe3e65,0xf1f325abe3e65,3
+np.float64,0x7fd6c07079ad80e0,0x3ff921fb54442d18,3
+np.float64,0x7fe328b075a65160,0x3ff921fb54442d18,3
+np.float64,0x7fe7998f812f331e,0x3ff921fb54442d18,3
+np.float64,0xffe026bb65604d76,0xbff921fb54442d18,3
+np.float64,0xffd6c06de8ad80dc,0xbff921fb54442d18,3
+np.float64,0x3fcd5a37bf3ab46f,0x3fccda82935d98ce,3
+np.float64,0xffc3e5a45227cb48,0xbff921fb54442d18,3
+np.float64,0x3febf7dd8177efbc,0x3fe6fc0bb999883e,3
+np.float64,0x7fd7047ea92e08fc,0x3ff921fb54442d18,3
+np.float64,0x35b3fc406b680,0x35b3fc406b680,3
+np.float64,0x7fd52e97632a5d2e,0x3ff921fb54442d18,3
+np.float64,0x3fd464d401a8c9a8,0x3fd3be2967fc97c3,3
+np.float64,0x800e815b2ebd02b6,0x800e815b2ebd02b6,3
+np.float64,0x3fca8428af350850,0x3fca257b466b8970,3
+np.float64,0x8007b7526f6f6ea6,0x8007b7526f6f6ea6,3
+np.float64,0x82f60a8f05ec2,0x82f60a8f05ec2,3
+np.float64,0x3fb71a5d0a2e34c0,0x3fb70a629ef8e2a2,3
+np.float64,0x7fc8570c7d30ae18,0x3ff921fb54442d18,3
+np.float64,0x7fe5528e77eaa51c,0x3ff921fb54442d18,3
+np.float64,0xffc20dbbf1241b78,0xbff921fb54442d18,3
+np.float64,0xeb13368fd6267,0xeb13368fd6267,3
+np.float64,0x7fe7d529056faa51,0x3ff921fb54442d18,3
+np.float64,0x3fecd02eabf9a05d,0x3fe77516f0ba1ac4,3
+np.float64,0x800fcba6a09f974d,0x800fcba6a09f974d,3
+np.float64,0x7fe7e8e015afd1bf,0x3ff921fb54442d18,3
+np.float64,0xbfd271a382a4e348,0xbfd1f513a191c595,3
+np.float64,0x9f1014013e21,0x9f1014013e21,3
+np.float64,0x3fc05da47f20bb49,0x3fc04708a13a3a47,3
+np.float64,0x3fe0f427dda1e850,0x3fdf2e60ba8678b9,3
+np.float64,0xbfecb29fa539653f,0xbfe764bc791c45dd,3
+np.float64,0x45881ec68b104,0x45881ec68b104,3
+np.float64,0x8000000000000001,0x8000000000000001,3
+np.float64,0x3fe9c67ee1338cfe,0x3fe5b2c7b3df6ce8,3
+np.float64,0x7fedb8fef6bb71fd,0x3ff921fb54442d18,3
+np.float64,0x3fe54f6aaaea9ed6,0x3fe2ccd1df2abaa9,3
+np.float64,0x7feff58a1bbfeb13,0x3ff921fb54442d18,3
+np.float64,0x7fe3b62827276c4f,0x3ff921fb54442d18,3
+np.float64,0x3fe5feb682ebfd6d,0x3fe345105bc6d980,3
+np.float64,0x3fe49f38d9693e72,0x3fe2518b2824757f,3
+np.float64,0x8006bfd27c6d7fa6,0x8006bfd27c6d7fa6,3
+np.float64,0x3fc13409e2226814,0x3fc119ce0c01a5a2,3
+np.float64,0x95f8c7212bf19,0x95f8c7212bf19,3
+np.float64,0x3fd9f0fa6133e1f5,0x3fd8a567515edecf,3
+np.float64,0x3fef95cbe5ff2b98,0x3fe8ec88c768ba0b,3
+np.float64,0x3fbed28bba3da510,0x3fbeacbf136e51c2,3
+np.float64,0xbfd3987aeca730f6,0xbfd303fca58e3e60,3
+np.float64,0xbfed0f90cbfa1f22,0xbfe797f59249410d,3
+np.float64,0xffe55d8cbf2abb19,0xbff921fb54442d18,3
+np.float64,0x3feb4d9fc6769b40,0x3fe69a88131a1f1f,3
+np.float64,0x80085569acd0aad4,0x80085569acd0aad4,3
+np.float64,0x20557a6e40ab0,0x20557a6e40ab0,3
+np.float64,0x3fead2fd5df5a5fb,0x3fe653091f33b27f,3
+np.float64,0x3fe7b9983eaf7330,0x3fe46a50c4b5235e,3
+np.float64,0xffdad237ffb5a470,0xbff921fb54442d18,3
+np.float64,0xbfe5cc39a4eb9874,0xbfe322ad3a903f93,3
+np.float64,0x800ad6eecb35adde,0x800ad6eecb35adde,3
+np.float64,0xffec620f6438c41e,0xbff921fb54442d18,3
+np.float64,0xbfe5ef29122bde52,0xbfe33a7dfcc255e2,3
+np.float64,0x3fd451e7d0a8a3d0,0x3fd3acfa4939af10,3
+np.float64,0x8003ea93c127d528,0x8003ea93c127d528,3
+np.float64,0x800b48d37c9691a7,0x800b48d37c9691a7,3
+np.float64,0x3fe7e202acafc405,0x3fe484558246069b,3
+np.float64,0x80070c9b686e1938,0x80070c9b686e1938,3
+np.float64,0xbfda90bbc6352178,0xbfd92e25fcd12288,3
+np.float64,0x800e1ffebb1c3ffe,0x800e1ffebb1c3ffe,3
+np.float64,0x3ff0000000000000,0x3fe921fb54442d18,3
+np.float64,0xffd8cfdd46319fba,0xbff921fb54442d18,3
+np.float64,0x7fd8cd4182319a82,0x3ff921fb54442d18,3
+np.float64,0x3fed8bb778bb176f,0x3fe7db7c77c4c694,3
+np.float64,0x3fc74a70302e94e0,0x3fc709e95d6defec,3
+np.float64,0x3fe87269d070e4d4,0x3fe4e04bcc4a2137,3
+np.float64,0x7fb48223f6290447,0x3ff921fb54442d18,3
+np.float64,0xffe8ec444b71d888,0xbff921fb54442d18,3
+np.float64,0x7fde17d280bc2fa4,0x3ff921fb54442d18,3
+np.float64,0x3fd1cbde01a397bc,0x3fd15b9bb7b3147b,3
+np.float64,0x800883a64451074d,0x800883a64451074d,3
+np.float64,0x7fe3160a3f262c13,0x3ff921fb54442d18,3
+np.float64,0xbfe051d4d9a0a3aa,0xbfde2ecf14dc75fb,3
+np.float64,0xbfd89de689b13bce,0xbfd780176d1a28a3,3
+np.float64,0x3fecde2bf779bc58,0x3fe77ccf10bdd8e2,3
+np.float64,0xffe75774dc6eaee9,0xbff921fb54442d18,3
+np.float64,0x7fe834414d706882,0x3ff921fb54442d18,3
+np.float64,0x1,0x1,3
+np.float64,0xbfea5e4e4a74bc9c,0xbfe60e0601711835,3
+np.float64,0xffec248d4cb8491a,0xbff921fb54442d18,3
+np.float64,0xffd9942c2c332858,0xbff921fb54442d18,3
+np.float64,0xa9db36a553b67,0xa9db36a553b67,3
+np.float64,0x7fec630718b8c60d,0x3ff921fb54442d18,3
+np.float64,0xbfd062188f20c432,0xbfd009ecd652be89,3
+np.float64,0x8001b84e3023709d,0x8001b84e3023709d,3
+np.float64,0xbfe9e26d7cb3c4db,0xbfe5c3b157ecf668,3
+np.float64,0xbfef66ddf33ecdbc,0xbfe8d4b1f6410a24,3
+np.float64,0x3fd8d7109431ae21,0x3fd7b1d4860719a2,3
+np.float64,0xffee0f53107c1ea5,0xbff921fb54442d18,3
+np.float64,0x80000b4fd60016a0,0x80000b4fd60016a0,3
+np.float64,0xbfd99ff6e5333fee,0xbfd85fb3cbdaa049,3
+np.float64,0xbfe9cfd268339fa5,0xbfe5b86ef021a1b1,3
+np.float64,0xe32eace1c65d6,0xe32eace1c65d6,3
+np.float64,0xffc81f6627303ecc,0xbff921fb54442d18,3
+np.float64,0x7fe98dadde331b5b,0x3ff921fb54442d18,3
+np.float64,0xbfbcebd11e39d7a0,0xbfbccc8ec47883c7,3
+np.float64,0x7fe164880f22c90f,0x3ff921fb54442d18,3
+np.float64,0x800467c0cae8cf82,0x800467c0cae8cf82,3
+np.float64,0x800071e4b140e3ca,0x800071e4b140e3ca,3
+np.float64,0xbfc87a7eae30f4fc,0xbfc82fbc55bb0f24,3
+np.float64,0xffb2e0e23225c1c8,0xbff921fb54442d18,3
+np.float64,0x20ef338041df,0x20ef338041df,3
+np.float64,0x7fe6de71ca6dbce3,0x3ff921fb54442d18,3
+np.float64,0x5d1fa026ba3f5,0x5d1fa026ba3f5,3
+np.float64,0xffd112a9ce222554,0xbff921fb54442d18,3
+np.float64,0x3fb351f66626a3ed,0x3fb3489ab578c452,3
+np.float64,0x7fef7b2bd3bef657,0x3ff921fb54442d18,3
+np.float64,0xffe144f5d4e289eb,0xbff921fb54442d18,3
+np.float64,0xffd63a6750ac74ce,0xbff921fb54442d18,3
+np.float64,0x7fd2d8bb25a5b175,0x3ff921fb54442d18,3
+np.float64,0x3fec5920a078b242,0x3fe732dcffcf6521,3
+np.float64,0x80009a8b7f813518,0x80009a8b7f813518,3
+np.float64,0x3fdea220893d4441,0x3fdc921edf6bf3d8,3
+np.float64,0x8006cee2208d9dc5,0x8006cee2208d9dc5,3
+np.float64,0xdd0b0081ba17,0xdd0b0081ba17,3
+np.float64,0x7ff4000000000000,0x7ffc000000000000,3
+np.float64,0xbfdac33955358672,0xbfd9592bce7daf1f,3
+np.float64,0x7fe8301d7170603a,0x3ff921fb54442d18,3
+np.float64,0xbfc1d34d8523a69c,0xbfc1b62449af9684,3
+np.float64,0x800c62239458c447,0x800c62239458c447,3
+np.float64,0xffd398c009a73180,0xbff921fb54442d18,3
+np.float64,0xbfe0c6d9ee218db4,0xbfdee777557f4401,3
+np.float64,0x3feccdd373799ba7,0x3fe773c9c2263f89,3
+np.float64,0xbfd21898bda43132,0xbfd1a2be8545fcc5,3
+np.float64,0x3fd77019b62ee033,0x3fd67793cabdf267,3
+np.float64,0x7fa609cad42c1395,0x3ff921fb54442d18,3
+np.float64,0x7fb4eaea5a29d5d4,0x3ff921fb54442d18,3
+np.float64,0x3fc570dc9a2ae1b9,0x3fc53e5f6218a799,3
+np.float64,0x800344ae8466895e,0x800344ae8466895e,3
+np.float64,0xbfc7c985252f930c,0xbfc784d60fa27bac,3
+np.float64,0xffaa2929fc345250,0xbff921fb54442d18,3
+np.float64,0xffe63e5ee9ac7cbe,0xbff921fb54442d18,3
+np.float64,0x73f0280ce7e06,0x73f0280ce7e06,3
+np.float64,0xffc525f8822a4bf0,0xbff921fb54442d18,3
+np.float64,0x7fd744d00aae899f,0x3ff921fb54442d18,3
+np.float64,0xbfe0fe590761fcb2,0xbfdf3e493e8b1f32,3
+np.float64,0xfae04ae7f5c0a,0xfae04ae7f5c0a,3
+np.float64,0xef821939df043,0xef821939df043,3
+np.float64,0x7fef6135843ec26a,0x3ff921fb54442d18,3
+np.float64,0xbfebf34dcbf7e69c,0xbfe6f97588a8f911,3
+np.float64,0xbfeec0b498fd8169,0xbfe87f2eceeead12,3
+np.float64,0x7fb67161b42ce2c2,0x3ff921fb54442d18,3
+np.float64,0x3fdcfd998639fb33,0x3fdb38934927c096,3
+np.float64,0xffda5960bc34b2c2,0xbff921fb54442d18,3
+np.float64,0xbfe11f8c71223f19,0xbfdf71fe770c96ab,3
+np.float64,0x3fe4ac1bab695838,0x3fe25aa4517b8322,3
+np.float64,0x3f730458a02608b1,0x3f73044fabb5e999,3
+np.float64,0x3fdb14ffcdb62a00,0x3fd99ea6c241a3ed,3
+np.float64,0xbfc93208cd326410,0xbfc8e09d78b6d4db,3
+np.float64,0x19e734dc33ce8,0x19e734dc33ce8,3
+np.float64,0x3fe5e98428abd308,0x3fe336a6a085eb55,3
+np.float64,0x7fec672a1378ce53,0x3ff921fb54442d18,3
+np.float64,0x800f8bd8d4ff17b2,0x800f8bd8d4ff17b2,3
+np.float64,0xbfe5a12e4e6b425c,0xbfe30533f99d5d06,3
+np.float64,0x75a34cb0eb46a,0x75a34cb0eb46a,3
+np.float64,0x7fe1d21d16a3a439,0x3ff921fb54442d18,3
+np.float64,0x7ff0000000000000,0x3ff921fb54442d18,3
+np.float64,0xffe0f50db261ea1b,0xbff921fb54442d18,3
+np.float64,0xbfd9dc22feb3b846,0xbfd8937ec965a501,3
+np.float64,0x8009d68e48d3ad1d,0x8009d68e48d3ad1d,3
+np.float64,0xbfe2eba620e5d74c,0xbfe1164d7d273c60,3
+np.float64,0x992efa09325e0,0x992efa09325e0,3
+np.float64,0x3fdab640ea356c82,0x3fd94e20cab88db2,3
+np.float64,0x69a6f04ad34df,0x69a6f04ad34df,3
+np.float64,0x3fe397df25272fbe,0x3fe194bd1a3a6192,3
+np.float64,0xebcce9fdd799d,0xebcce9fdd799d,3
+np.float64,0x3fbb49490c369292,0x3fbb2f02eccc497d,3
+np.float64,0xffd871f980b0e3f4,0xbff921fb54442d18,3
+np.float64,0x800348f6966691ee,0x800348f6966691ee,3
+np.float64,0xbfebc270a7f784e1,0xbfe6dda8d0d80f26,3
+np.float64,0xffd6d559b1adaab4,0xbff921fb54442d18,3
+np.float64,0x3fec3635c0b86c6c,0x3fe71f420256e43e,3
+np.float64,0x7fbc82ad7039055a,0x3ff921fb54442d18,3
+np.float64,0x7f873050602e60a0,0x3ff921fb54442d18,3
+np.float64,0x3fca44b8c3348970,0x3fc9e8a1a1a2d96e,3
+np.float64,0x3fe0fc308fe1f861,0x3fdf3aeb469ea225,3
+np.float64,0x7fefc27de8bf84fb,0x3ff921fb54442d18,3
+np.float64,0x8005f3f3916be7e8,0x8005f3f3916be7e8,3
+np.float64,0xbfd4278c7c284f18,0xbfd38678988873b6,3
+np.float64,0x435eafc486bd7,0x435eafc486bd7,3
+np.float64,0xbfd01f5199203ea4,0xbfcf96631f2108a3,3
+np.float64,0xffd5ee9185abdd24,0xbff921fb54442d18,3
+np.float64,0xffedb363257b66c5,0xbff921fb54442d18,3
+np.float64,0x800d68e6e11ad1ce,0x800d68e6e11ad1ce,3
+np.float64,0xbfcf687f8e3ed100,0xbfceccb771b0d39a,3
+np.float64,0x7feb3b9ef2f6773d,0x3ff921fb54442d18,3
+np.float64,0x3fe15ec5ca62bd8c,0x3fdfd3fab9d96f81,3
+np.float64,0x10000000000000,0x10000000000000,3
+np.float64,0xd2386f81a470e,0xd2386f81a470e,3
+np.float64,0xb9feed4573fde,0xb9feed4573fde,3
+np.float64,0x3fe7ed25c9efda4c,0x3fe48b7b72db4014,3
+np.float64,0xbfe01478726028f1,0xbfddcd1f5a2efc59,3
+np.float64,0x9946d02f328da,0x9946d02f328da,3
+np.float64,0xbfe3bb67f06776d0,0xbfe1ae88aa81c5a6,3
+np.float64,0xbfd3fd8a4c27fb14,0xbfd3603982e3b78d,3
+np.float64,0xffd5c3ab912b8758,0xbff921fb54442d18,3
+np.float64,0xffd5f502b12bea06,0xbff921fb54442d18,3
+np.float64,0xbfc64981ec2c9304,0xbfc610e0382b1fa6,3
+np.float64,0xffec42e3413885c6,0xbff921fb54442d18,3
+np.float64,0x80084eb4ed109d6a,0x80084eb4ed109d6a,3
+np.float64,0xbfd17cac9fa2f95a,0xbfd112020588a4b3,3
+np.float64,0xbfd06c1359a0d826,0xbfd0134a28aa9a66,3
+np.float64,0x7fdc3d7c03b87af7,0x3ff921fb54442d18,3
+np.float64,0x7bdf5aaaf7bec,0x7bdf5aaaf7bec,3
+np.float64,0xbfee3cd966fc79b3,0xbfe83a14bc07ac3b,3
+np.float64,0x7fec910da3f9221a,0x3ff921fb54442d18,3
+np.float64,0xffb4ea667029d4d0,0xbff921fb54442d18,3
+np.float64,0x800103d7cce207b0,0x800103d7cce207b0,3
+np.float64,0x7fbb229a6c364534,0x3ff921fb54442d18,3
+np.float64,0x0,0x0,3
+np.float64,0xffd8fccd0331f99a,0xbff921fb54442d18,3
+np.float64,0xbfd0784ae1a0f096,0xbfd01ebff62e39ad,3
+np.float64,0xbfed2ec9b3ba5d93,0xbfe7a9099410bc76,3
+np.float64,0x800690b8d16d2172,0x800690b8d16d2172,3
+np.float64,0x7fc061b26520c364,0x3ff921fb54442d18,3
+np.float64,0x8007ec47054fd88f,0x8007ec47054fd88f,3
+np.float64,0x775546b6eeaa9,0x775546b6eeaa9,3
+np.float64,0x8005e00fb56bc020,0x8005e00fb56bc020,3
+np.float64,0xbfe510f8d0ea21f2,0xbfe2a16862b5a37f,3
+np.float64,0xffd87a6bf3b0f4d8,0xbff921fb54442d18,3
+np.float64,0x800906e3d0520dc8,0x800906e3d0520dc8,3
+np.float64,0x2296f000452f,0x2296f000452f,3
+np.float64,0xbfe3189fa2e63140,0xbfe1378c0e005be4,3
+np.float64,0xb4d2447f69a49,0xb4d2447f69a49,3
+np.float64,0xffd056a24a20ad44,0xbff921fb54442d18,3
+np.float64,0xbfe3b23fe4e76480,0xbfe1a7e5840fcbeb,3
+np.float64,0x80018ee270831dc6,0x80018ee270831dc6,3
+np.float64,0x800df89f245bf13e,0x800df89f245bf13e,3
+np.float64,0x3fee1409d7bc2814,0x3fe824779d133232,3
+np.float64,0xbfef8d81667f1b03,0xbfe8e85523620368,3
+np.float64,0xffd8a6519b314ca4,0xbff921fb54442d18,3
+np.float64,0x7fc7bc86f32f790d,0x3ff921fb54442d18,3
+np.float64,0xffea6159e674c2b3,0xbff921fb54442d18,3
+np.float64,0x3fe153c3fba2a788,0x3fdfc2f74769d300,3
+np.float64,0xffc4261ef3284c3c,0xbff921fb54442d18,3
+np.float64,0x7fe8a8961ff1512b,0x3ff921fb54442d18,3
+np.float64,0xbfe3fb1fd167f640,0xbfe1dc89dcb7ecdf,3
+np.float64,0x3fd88577c2b10af0,0x3fd76acc09660704,3
+np.float64,0x3fe128ec27e251d8,0x3fdf808fc7ebcd8f,3
+np.float64,0xbfed6ca7c4fad950,0xbfe7caafe9a3e213,3
+np.float64,0xbf9a3912b8347220,0xbf9a379b3349352e,3
+np.float64,0xbfd724d7bcae49b0,0xbfd6351efa2a5fc5,3
+np.float64,0xbfed59700a7ab2e0,0xbfe7c043014c694c,3
+np.float64,0x8002ad435bc55a87,0x8002ad435bc55a87,3
+np.float64,0xffe46ed345a8dda6,0xbff921fb54442d18,3
+np.float64,0x7fd2f1d1d825e3a3,0x3ff921fb54442d18,3
+np.float64,0xbfea0265e23404cc,0xbfe5d6fb3fd30464,3
+np.float64,0xbfd17e049122fc0a,0xbfd113421078bbae,3
+np.float64,0xffea03b986b40772,0xbff921fb54442d18,3
+np.float64,0x800b55331a16aa67,0x800b55331a16aa67,3
+np.float64,0xbfc6fcafbf2df960,0xbfc6be9ecd0ebc1f,3
+np.float64,0xd6a36017ad46c,0xd6a36017ad46c,3
+np.float64,0xbfe9ba86dfb3750e,0xbfe5ab840cb0ef86,3
+np.float64,0x75c4a108eb895,0x75c4a108eb895,3
+np.float64,0x8008d6bc8051ad79,0x8008d6bc8051ad79,3
+np.float64,0xbfd3dc5984a7b8b4,0xbfd341f78e0528ec,3
+np.float64,0xffe1cbb01aa39760,0xbff921fb54442d18,3
+np.float64,0x3fc7e292f52fc526,0x3fc79d0ce9365767,3
+np.float64,0xbfcbeae2bd37d5c4,0xbfcb7cb034f82467,3
+np.float64,0x8000f0c62e21e18d,0x8000f0c62e21e18d,3
+np.float64,0xbfe23d8bc6247b18,0xbfe09418ee35c3c7,3
+np.float64,0x717394bae2e73,0x717394bae2e73,3
+np.float64,0xffa2ef1cc425de40,0xbff921fb54442d18,3
+np.float64,0x3fd938c229b27184,0x3fd806900735c99d,3
+np.float64,0x800bf3ec8a77e7d9,0x800bf3ec8a77e7d9,3
+np.float64,0xffeef41dd57de83b,0xbff921fb54442d18,3
+np.float64,0x8008df97e5b1bf30,0x8008df97e5b1bf30,3
+np.float64,0xffe9ab9d0db35739,0xbff921fb54442d18,3
+np.float64,0x99ff391333fe7,0x99ff391333fe7,3
+np.float64,0x3fb864b4a630c969,0x3fb851e883ea2cf9,3
+np.float64,0x22c1230a45825,0x22c1230a45825,3
+np.float64,0xff2336fbfe467,0xff2336fbfe467,3
+np.float64,0xbfd488f4cea911ea,0xbfd3def0490f5414,3
+np.float64,0x3fa379c78426f38f,0x3fa377607370800b,3
+np.float64,0xbfb0873302210e68,0xbfb08155b78dfd53,3
+np.float64,0xbfdf9ff7c2bf3ff0,0xbfdd5f658e357ad2,3
+np.float64,0x800978719192f0e4,0x800978719192f0e4,3
+np.float64,0xbfba8759ea350eb0,0xbfba6f325013b9e5,3
+np.float64,0xbfdd3e6b06ba7cd6,0xbfdb6e472b6091b0,3
+np.float64,0x7fe0c334a7a18668,0x3ff921fb54442d18,3
+np.float64,0xbfeb971feb772e40,0xbfe6c4e0f61404d1,3
+np.float64,0x3fe2a50968e54a13,0x3fe0e1c8b8d96e85,3
+np.float64,0x800fa9c5515f538b,0x800fa9c5515f538b,3
+np.float64,0x800f8532fbbf0a66,0x800f8532fbbf0a66,3
+np.float64,0x167d6f1e2cfaf,0x167d6f1e2cfaf,3
+np.float64,0xffee88e769fd11ce,0xbff921fb54442d18,3
+np.float64,0xbfeecc8529fd990a,0xbfe885520cdad8ea,3
+np.float64,0xffefffffffffffff,0xbff921fb54442d18,3
+np.float64,0xbfef6a566afed4ad,0xbfe8d6767b4c4235,3
+np.float64,0xffec12415af82482,0xbff921fb54442d18,3
+np.float64,0x3678a20a6cf15,0x3678a20a6cf15,3
+np.float64,0xffe468d54ee8d1aa,0xbff921fb54442d18,3
+np.float64,0x800ad6006795ac01,0x800ad6006795ac01,3
+np.float64,0x8001d5b61063ab6d,0x8001d5b61063ab6d,3
+np.float64,0x800dfcd1863bf9a3,0x800dfcd1863bf9a3,3
+np.float64,0xc9fbff6f93f80,0xc9fbff6f93f80,3
+np.float64,0xffe55c20f9eab842,0xbff921fb54442d18,3
+np.float64,0xbfcb596b6536b2d8,0xbfcaf1b339c5c615,3
+np.float64,0xbfe092689ea124d1,0xbfde94fa58946e51,3
+np.float64,0x3fe9ec733af3d8e6,0x3fe5c9bf5dee2623,3
+np.float64,0x3fe30f3d83261e7b,0x3fe1309fd6620e03,3
+np.float64,0xffd31d7f84263b00,0xbff921fb54442d18,3
+np.float64,0xbfe88d2d3e711a5a,0xbfe4f12b5a136178,3
+np.float64,0xffc81e4ce1303c98,0xbff921fb54442d18,3
+np.float64,0xffe5b96ebfab72dd,0xbff921fb54442d18,3
+np.float64,0x512f0502a25e1,0x512f0502a25e1,3
+np.float64,0x7fa3a376982746ec,0x3ff921fb54442d18,3
+np.float64,0x80005b5f2f60b6bf,0x80005b5f2f60b6bf,3
+np.float64,0xc337cc69866fa,0xc337cc69866fa,3
+np.float64,0x3fe7719c4caee339,0x3fe43bab42b19e64,3
+np.float64,0x7fde7ec1d93cfd83,0x3ff921fb54442d18,3
+np.float64,0x3fd2f38f3825e71e,0x3fd26cc7b1dd0acb,3
+np.float64,0x7fce298b993c5316,0x3ff921fb54442d18,3
+np.float64,0x56ae3b2cad5c8,0x56ae3b2cad5c8,3
+np.float64,0x3fe9299f2bf2533e,0x3fe552bddd999e72,3
+np.float64,0x7feff3a4823fe748,0x3ff921fb54442d18,3
+np.float64,0xbfd05c670aa0b8ce,0xbfd00494d78e9e97,3
+np.float64,0xffe745323eae8a64,0xbff921fb54442d18,3
diff --git a/numpy/core/tests/data/umath-validation-set-arctanh.csv b/numpy/core/tests/data/umath-validation-set-arctanh.csv
new file mode 100644
index 000000000..a655269d0
--- /dev/null
+++ b/numpy/core/tests/data/umath-validation-set-arctanh.csv
@@ -0,0 +1,1429 @@
+dtype,input,output,ulperrortol
+np.float32,0x3ee82930,0x3efa60fd,2
+np.float32,0x3f0aa640,0x3f1b3e13,2
+np.float32,0x3ec1a21c,0x3ecbbf8d,2
+np.float32,0x3cdb1740,0x3cdb24a1,2
+np.float32,0xbf28b6f3,0xbf4a86ac,2
+np.float32,0xbe490dcc,0xbe4bb2eb,2
+np.float32,0x80000001,0x80000001,2
+np.float32,0xbf44f9dd,0xbf826ce1,2
+np.float32,0xbf1d66c4,0xbf37786b,2
+np.float32,0x3f0ad26a,0x3f1b7c9b,2
+np.float32,0x3f7b6c54,0x4016aab0,2
+np.float32,0xbf715bb8,0xbfe1a0bc,2
+np.float32,0xbee8a562,0xbefafd6a,2
+np.float32,0x3db94d00,0x3db9cf16,2
+np.float32,0x3ee2970c,0x3ef368b3,2
+np.float32,0x3f3f8614,0x3f77fdca,2
+np.float32,0xbf1fb5f0,0xbf3b3789,2
+np.float32,0x3f798dc0,0x400b96bb,2
+np.float32,0x3e975d64,0x3e9c0573,2
+np.float32,0xbe3f1908,0xbe415d1f,2
+np.float32,0x3f2cea38,0x3f52192e,2
+np.float32,0x3e82f1ac,0x3e85eaa1,2
+np.float32,0x3eab6b30,0x3eb24acd,2
+np.float32,0xbe9bb90c,0xbea0cf5f,2
+np.float32,0xbf43e847,0xbf81202f,2
+np.float32,0xbd232fa0,0xbd2345c0,2
+np.float32,0xbbabbc00,0xbbabbc67,2
+np.float32,0xbf0b2975,0xbf1bf808,2
+np.float32,0xbef5ab0a,0xbf05d305,2
+np.float32,0x3f2cad16,0x3f51a8e2,2
+np.float32,0xbef75940,0xbf06eb08,2
+np.float32,0xbf0c1216,0xbf1d4325,2
+np.float32,0x3e7bdc08,0x3e8090c2,2
+np.float32,0x3da14e10,0x3da1a3c5,2
+np.float32,0x3f627412,0x3fb2bf21,2
+np.float32,0xbd6d08c0,0xbd6d4ca0,2
+np.float32,0x3f3e2368,0x3f74df8b,2
+np.float32,0xbe0df104,0xbe0edc77,2
+np.float32,0x3e8a265c,0x3e8da833,2
+np.float32,0xbdccdbb0,0xbdcd8ba8,2
+np.float32,0x3eb080c4,0x3eb80a44,2
+np.float32,0x3e627800,0x3e6645fe,2
+np.float32,0xbd8be0b0,0xbd8c1886,2
+np.float32,0xbf3282ac,0xbf5cae8c,2
+np.float32,0xbe515910,0xbe545707,2
+np.float32,0xbf2e64ac,0xbf54d637,2
+np.float32,0x3e0fc230,0x3e10b6de,2
+np.float32,0x3eb13ca0,0x3eb8df94,2
+np.float32,0x3f07a3ca,0x3f170572,2
+np.float32,0x3f2c7026,0x3f513935,2
+np.float32,0x3f3c4ec8,0x3f70d67c,2
+np.float32,0xbee9cce8,0xbefc724f,2
+np.float32,0xbe53ca60,0xbe56e3f3,2
+np.float32,0x3dd9e9a0,0x3ddabd98,2
+np.float32,0x3f38b8d4,0x3f69319b,2
+np.float32,0xbe176dc4,0xbe188c1d,2
+np.float32,0xbf322f2e,0xbf5c0c51,2
+np.float32,0xbe9b8676,0xbea097a2,2
+np.float32,0xbca44280,0xbca44823,2
+np.float32,0xbe2b0248,0xbe2ca036,2
+np.float32,0x3d101e80,0x3d102dbd,2
+np.float32,0xbf4eb610,0xbf8f526d,2
+np.float32,0xbec32a50,0xbecd89d1,2
+np.float32,0x3d549100,0x3d54c1ee,2
+np.float32,0x3f78e55e,0x40087025,2
+np.float32,0x3e592798,0x3e5c802d,2
+np.float32,0x3de045d0,0x3de12cfb,2
+np.float32,0xbdad28e0,0xbdad92f7,2
+np.float32,0x3e9a69e0,0x3e9f5e59,2
+np.float32,0x3e809778,0x3e836716,2
+np.float32,0xbf3278d9,0xbf5c9b6d,2
+np.float32,0x3f39fa00,0x3f6bd4a5,2
+np.float32,0xbec8143c,0xbed34ffa,2
+np.float32,0x3ddb7f40,0x3ddc57e6,2
+np.float32,0x3f0e8342,0x3f20c634,2
+np.float32,0x3f353dda,0x3f6213a4,2
+np.float32,0xbe96b400,0xbe9b4bea,2
+np.float32,0x3e626580,0x3e66328a,2
+np.float32,0xbde091c8,0xbde179df,2
+np.float32,0x3eb47b5c,0x3ebc91ca,2
+np.float32,0xbf282182,0xbf497f2f,2
+np.float32,0x3ea9f64c,0x3eb0a748,2
+np.float32,0x3f28dd4e,0x3f4aca86,2
+np.float32,0xbf71de18,0xbfe3f587,2
+np.float32,0x7fa00000,0x7fe00000,2
+np.float32,0xbf6696a6,0xbfbcf11a,2
+np.float32,0xbc853ae0,0xbc853de2,2
+np.float32,0xbeced246,0xbedb51b8,2
+np.float32,0x3f3472a4,0x3f607e00,2
+np.float32,0xbee90124,0xbefb7117,2
+np.float32,0x3eb45b90,0x3ebc6d7c,2
+np.float32,0xbe53ead0,0xbe5705d6,2
+np.float32,0x3f630c80,0x3fb420e2,2
+np.float32,0xbf408cd0,0xbf7a56a2,2
+np.float32,0x3dda4ed0,0x3ddb23f1,2
+np.float32,0xbf37ae88,0xbf67096b,2
+np.float32,0xbdd48c28,0xbdd550c9,2
+np.float32,0xbf5745b0,0xbf9cb4a4,2
+np.float32,0xbf44e6fc,0xbf8255c1,2
+np.float32,0x3f5c8e6a,0x3fa65020,2
+np.float32,0xbea45fe8,0xbeaa6630,2
+np.float32,0x3f08bdee,0x3f188ef5,2
+np.float32,0x3ec77e74,0x3ed29f4b,2
+np.float32,0xbf1a1d3c,0xbf324029,2
+np.float32,0x3cad7340,0x3cad79e3,2
+np.float32,0xbf4fac2e,0xbf90b72a,2
+np.float32,0x3f58516e,0x3f9e8330,2
+np.float32,0x3f442008,0x3f816391,2
+np.float32,0xbf6e0c6c,0xbfd42854,2
+np.float32,0xbf266f7a,0xbf4689b2,2
+np.float32,0x3eb7e2f0,0x3ec077ba,2
+np.float32,0xbf320fd0,0xbf5bcf83,2
+np.float32,0xbf6a76b9,0xbfc80a11,2
+np.float32,0xbf2a91b4,0xbf4dd526,2
+np.float32,0x3f176e30,0x3f2e150e,2
+np.float32,0xbdcccad0,0xbdcd7a9c,2
+np.float32,0x3f60a8a4,0x3faebbf7,2
+np.float32,0x3d9706f0,0x3d974d40,2
+np.float32,0x3ef3cd34,0x3f049d58,2
+np.float32,0xbf73c615,0xbfed79fe,2
+np.float32,0x3df1b170,0x3df2d31b,2
+np.float32,0x3f632a46,0x3fb466c7,2
+np.float32,0xbf3ea18e,0xbf75f9ce,2
+np.float32,0xbf3ea05c,0xbf75f71f,2
+np.float32,0xbdd76750,0xbdd83403,2
+np.float32,0xbca830c0,0xbca836cd,2
+np.float32,0x3f1d4162,0x3f373c59,2
+np.float32,0x3c115700,0x3c1157fa,2
+np.float32,0x3dae8ab0,0x3daef758,2
+np.float32,0xbcad5020,0xbcad56bf,2
+np.float32,0x3ee299c4,0x3ef36c15,2
+np.float32,0xbf7f566c,0xc054c3bd,2
+np.float32,0x3f0cc698,0x3f1e4557,2
+np.float32,0xbe75c648,0xbe7aaa04,2
+np.float32,0x3ea29238,0x3ea86417,2
+np.float32,0x3f09d9c0,0x3f1a1d61,2
+np.float32,0x3f67275c,0x3fbe74b3,2
+np.float32,0x3e1a4e18,0x3e1b7d3a,2
+np.float32,0xbef6e3fc,0xbf069e98,2
+np.float32,0xbf6038ac,0xbfadc9fd,2
+np.float32,0xbe46bdd4,0xbe494b7f,2
+np.float32,0xbf4df1f4,0xbf8e3a98,2
+np.float32,0x3d094dc0,0x3d095aed,2
+np.float32,0x3f44c7d2,0x3f822fa3,2
+np.float32,0xbea30816,0xbea8e737,2
+np.float32,0xbe3c27c4,0xbe3e511b,2
+np.float32,0x3f3bb47c,0x3f6f8789,2
+np.float32,0xbe423760,0xbe4498c3,2
+np.float32,0x3ece1a74,0x3eda7634,2
+np.float32,0x3f14d1f6,0x3f2a1a89,2
+np.float32,0xbf4d9e8f,0xbf8dc4c1,2
+np.float32,0xbe92968e,0xbe96cd7f,2
+np.float32,0x3e99e6c0,0x3e9ece26,2
+np.float32,0xbf397361,0xbf6ab878,2
+np.float32,0xbf4fcea4,0xbf90e99f,2
+np.float32,0x3de37640,0x3de46779,2
+np.float32,0x3eb1b604,0x3eb9698c,2
+np.float32,0xbf52d0a2,0xbf957361,2
+np.float32,0xbe20435c,0xbe21975a,2
+np.float32,0x3f437a58,0x3f809bf1,2
+np.float32,0x3f27d1cc,0x3f48f335,2
+np.float32,0x3f7d4ff2,0x4027d1e2,2
+np.float32,0xbef732e4,0xbf06d205,2
+np.float32,0x3f4a0ae6,0x3f88e18e,2
+np.float32,0x3f800000,0x7f800000,2
+np.float32,0x3e3e56a0,0x3e4093ba,2
+np.float32,0xbed2fcfa,0xbee0517d,2
+np.float32,0xbe0e0114,0xbe0eecd7,2
+np.float32,0xbe808574,0xbe8353db,2
+np.float32,0x3f572e2a,0x3f9c8c86,2
+np.float32,0x80800000,0x80800000,2
+np.float32,0x3f3f3c82,0x3f775703,2
+np.float32,0xbf6e2482,0xbfd4818b,2
+np.float32,0xbf3943b0,0xbf6a5439,2
+np.float32,0x3f6e42ac,0x3fd4f1ea,2
+np.float32,0x3eb676c4,0x3ebed619,2
+np.float32,0xbe5e56c4,0xbe61ef6c,2
+np.float32,0x3eea200c,0x3efcdb65,2
+np.float32,0x3e3d2c78,0x3e3f5ef8,2
+np.float32,0xbdfd8fb0,0xbdfede71,2
+np.float32,0xbee69c8a,0xbef86e89,2
+np.float32,0x3e9efca0,0x3ea46a1c,2
+np.float32,0x3e4c2498,0x3e4ee9ee,2
+np.float32,0xbf3cc93c,0xbf71e21d,2
+np.float32,0x3ee0d77c,0x3ef13d2b,2
+np.float32,0xbefbcd2a,0xbf09d6a3,2
+np.float32,0x3f6dbe5c,0x3fd30a3e,2
+np.float32,0x3dae63e0,0x3daed03f,2
+np.float32,0xbd5001e0,0xbd502fb9,2
+np.float32,0x3f59632a,0x3fa067c8,2
+np.float32,0x3f0d355a,0x3f1ee452,2
+np.float32,0x3f2cbe5c,0x3f51c896,2
+np.float32,0x3c5e6e80,0x3c5e7200,2
+np.float32,0xbe8ac49c,0xbe8e52f0,2
+np.float32,0x3f54e576,0x3f98c0e6,2
+np.float32,0xbeaa0762,0xbeb0ba7c,2
+np.float32,0x3ec81e88,0x3ed35c21,2
+np.float32,0x3f5a6738,0x3fa23fb6,2
+np.float32,0xbf24a682,0xbf43784a,2
+np.float32,0x1,0x1,2
+np.float32,0x3ee6bc24,0x3ef89630,2
+np.float32,0x3f19444a,0x3f30ecf5,2
+np.float32,0x3ec1fc70,0x3ecc28fc,2
+np.float32,0xbf706e14,0xbfdd92fb,2
+np.float32,0x3eccb630,0x3ed8cd98,2
+np.float32,0xbcdf7aa0,0xbcdf88d3,2
+np.float32,0xbe450da8,0xbe478a8e,2
+np.float32,0x3ec9c210,0x3ed54c0b,2
+np.float32,0xbf3b86ca,0xbf6f24d1,2
+np.float32,0x3edcc7a0,0x3eec3a5c,2
+np.float32,0x3f075d5c,0x3f16a39a,2
+np.float32,0xbf5719ce,0xbf9c69de,2
+np.float32,0x3f62cb22,0x3fb3885a,2
+np.float32,0x3f639216,0x3fb55c93,2
+np.float32,0xbf473ee7,0xbf85413a,2
+np.float32,0xbf01b66c,0xbf0eea86,2
+np.float32,0x3e872d80,0x3e8a74f8,2
+np.float32,0xbf60957e,0xbfae925c,2
+np.float32,0xbf6847b2,0xbfc1929b,2
+np.float32,0x3f78bb94,0x4007b363,2
+np.float32,0xbf47efdb,0xbf8622db,2
+np.float32,0xbe1f2308,0xbe206fd6,2
+np.float32,0xbf414926,0xbf7c0a7e,2
+np.float32,0x3eecc268,0x3f00194d,2
+np.float32,0x3eb086d0,0x3eb81120,2
+np.float32,0xbef1af80,0xbf033ff5,2
+np.float32,0xbf454e56,0xbf82d4aa,2
+np.float32,0x3e622560,0x3e65ef20,2
+np.float32,0x3f50d2b2,0x3f926a83,2
+np.float32,0x3eb2c45c,0x3eba9d2c,2
+np.float32,0x3e42d1a0,0x3e4538c9,2
+np.float32,0xbf24cc5c,0xbf43b8e3,2
+np.float32,0x3e8c6464,0x3e90141a,2
+np.float32,0xbf3abff2,0xbf6d79c5,2
+np.float32,0xbec8f2e6,0xbed456fa,2
+np.float32,0xbf787b38,0xc00698b4,2
+np.float32,0xbf58d5cd,0xbf9f6c03,2
+np.float32,0x3df4ee20,0x3df61ba8,2
+np.float32,0xbf34581e,0xbf604951,2
+np.float32,0xbeba5cf4,0xbec35119,2
+np.float32,0xbf76c22d,0xbfffc51c,2
+np.float32,0x3ef63b2c,0x3f0630b4,2
+np.float32,0x3eeadb64,0x3efdc877,2
+np.float32,0x3dfd8c70,0x3dfedb24,2
+np.float32,0x3f441600,0x3f81576d,2
+np.float32,0x3f23a0d8,0x3f41bbf6,2
+np.float32,0x3cb84d40,0x3cb85536,2
+np.float32,0xbf25cb5c,0xbf456e38,2
+np.float32,0xbc108540,0xbc108636,2
+np.float32,0xbc5b9140,0xbc5b949e,2
+np.float32,0xbf62ff40,0xbfb401dd,2
+np.float32,0x3e8e0710,0x3e91d93e,2
+np.float32,0x3f1b6ae0,0x3f344dfd,2
+np.float32,0xbf4dbbbe,0xbf8dedea,2
+np.float32,0x3f1a5fb2,0x3f32a880,2
+np.float32,0xbe56bd00,0xbe59f8cb,2
+np.float32,0xbf490a5c,0xbf87902d,2
+np.float32,0xbf513072,0xbf92f717,2
+np.float32,0x3e73ee28,0x3e78b542,2
+np.float32,0x3f0a4c7a,0x3f1abf2c,2
+np.float32,0x3e10d5c8,0x3e11d00b,2
+np.float32,0xbf771aac,0xc001207e,2
+np.float32,0x3efe2f54,0x3f0b6a46,2
+np.float32,0xbea5f3ea,0xbeac291f,2
+np.float32,0xbf1a73e8,0xbf32c845,2
+np.float32,0x3ebcc82c,0x3ec61c4f,2
+np.float32,0xbf24f492,0xbf43fd9a,2
+np.float32,0x3ecbd908,0x3ed7c691,2
+np.float32,0x3f461c5e,0x3f83d3f0,2
+np.float32,0x3eed0524,0x3f0043c1,2
+np.float32,0x3d06e840,0x3d06f4bf,2
+np.float32,0x3eb6c974,0x3ebf34d7,2
+np.float32,0xbf1c85e1,0xbf36100f,2
+np.float32,0x3ed697d0,0x3ee4ad04,2
+np.float32,0x3eab0484,0x3eb1d733,2
+np.float32,0xbf3b02f2,0xbf6e0935,2
+np.float32,0xbeeab154,0xbefd9334,2
+np.float32,0xbf695372,0xbfc49881,2
+np.float32,0x3e8aaa7c,0x3e8e36be,2
+np.float32,0xbf208754,0xbf3c8f7b,2
+np.float32,0xbe0dbf28,0xbe0ea9a1,2
+np.float32,0x3ca780c0,0x3ca786ba,2
+np.float32,0xbeb320b4,0xbebb065e,2
+np.float32,0x3f13c698,0x3f288821,2
+np.float32,0xbe8cbbec,0xbe9072c4,2
+np.float32,0x3f1ed534,0x3f39c8df,2
+np.float32,0x3e1ca450,0x3e1de190,2
+np.float32,0x3f54be1c,0x3f988134,2
+np.float32,0x3f34e4ee,0x3f6161b4,2
+np.float32,0xbf7e6913,0xc038b246,2
+np.float32,0x3d3c3f20,0x3d3c6119,2
+np.float32,0x3ca9dc80,0x3ca9e2bc,2
+np.float32,0xbf577ea2,0xbf9d161a,2
+np.float32,0xbedb22c8,0xbeea3644,2
+np.float32,0x3f22a044,0x3f400bfa,2
+np.float32,0xbe214b8c,0xbe22a637,2
+np.float32,0x3e8cd300,0x3e908bbc,2
+np.float32,0xbec4d214,0xbecf7a58,2
+np.float32,0x3e9399a4,0x3e97e7e4,2
+np.float32,0xbee6a1a2,0xbef874ed,2
+np.float32,0xbf323742,0xbf5c1bfd,2
+np.float32,0x3f48b882,0x3f8725ac,2
+np.float32,0xbf4d4dba,0xbf8d532e,2
+np.float32,0xbf59640a,0xbfa0695a,2
+np.float32,0xbf2ad562,0xbf4e4f03,2
+np.float32,0x3e317d98,0x3e334d03,2
+np.float32,0xbf6a5b71,0xbfc7b5a2,2
+np.float32,0x3e87b434,0x3e8b05cf,2
+np.float32,0xbf1c344c,0xbf358dee,2
+np.float32,0x3e449428,0x3e470c65,2
+np.float32,0xbf2c0f2f,0xbf508808,2
+np.float32,0xbec5b5ac,0xbed0859c,2
+np.float32,0xbf4aa956,0xbf89b4b1,2
+np.float32,0x3f6dd374,0x3fd35717,2
+np.float32,0x3f45f76c,0x3f83a5ef,2
+np.float32,0xbed1fba8,0xbedf1bd5,2
+np.float32,0xbd26b2d0,0xbd26ca66,2
+np.float32,0xbe9817c2,0xbe9cd1c3,2
+np.float32,0x3e725988,0x3e770875,2
+np.float32,0xbf1a8ded,0xbf32f132,2
+np.float32,0xbe695860,0xbe6d83d3,2
+np.float32,0x3d8cecd0,0x3d8d25ea,2
+np.float32,0x3f574706,0x3f9cb6ec,2
+np.float32,0xbf5c5a1f,0xbfa5eaf3,2
+np.float32,0x3e7a7c88,0x3e7fab83,2
+np.float32,0xff800000,0xffc00000,2
+np.float32,0x3f66396a,0x3fbbfbb0,2
+np.float32,0x3ed6e588,0x3ee50b53,2
+np.float32,0xbb56d500,0xbb56d532,2
+np.float32,0x3ebd23fc,0x3ec6869a,2
+np.float32,0xbf70d490,0xbfdf4af5,2
+np.float32,0x3e514f88,0x3e544d15,2
+np.float32,0x3e660f98,0x3e6a0dac,2
+np.float32,0xbf034da1,0xbf1110bb,2
+np.float32,0xbf60d9be,0xbfaf2714,2
+np.float32,0x3df67b10,0x3df7ae64,2
+np.float32,0xbeeedc0a,0xbf017010,2
+np.float32,0xbe149224,0xbe15a072,2
+np.float32,0x3f455084,0x3f82d759,2
+np.float32,0x3f210f9e,0x3f3d7093,2
+np.float32,0xbeaea3e0,0xbeb5edd3,2
+np.float32,0x3e0724b0,0x3e07efad,2
+np.float32,0x3f09a784,0x3f19d6ac,2
+np.float32,0xbf044340,0xbf125ee8,2
+np.float32,0xbf71adc9,0xbfe315fe,2
+np.float32,0x3efd3870,0x3f0ac6a8,2
+np.float32,0xbf53c7a6,0xbf96f6df,2
+np.float32,0xbf3cf784,0xbf7247af,2
+np.float32,0x3e0ce9e0,0x3e0dd035,2
+np.float32,0xbd3051a0,0xbd306d89,2
+np.float32,0x3ecab804,0x3ed66f77,2
+np.float32,0x3e984350,0x3e9d0189,2
+np.float32,0x3edd1c00,0x3eeca20b,2
+np.float32,0xbe8e22a0,0xbe91f71b,2
+np.float32,0x3ebebc18,0x3ec85fd6,2
+np.float32,0xba275c00,0xba275c01,2
+np.float32,0x3f1d8190,0x3f37a385,2
+np.float32,0x3f17343e,0x3f2dbbfe,2
+np.float32,0x3caa8000,0x3caa864e,2
+np.float32,0x3e7a7308,0x3e7fa168,2
+np.float32,0x3f7359a6,0x3feb3e1a,2
+np.float32,0xbf7ad15a,0xc012a743,2
+np.float32,0xbf122efb,0xbf262812,2
+np.float32,0xbf03ba04,0xbf11a3fa,2
+np.float32,0x3ed7a90c,0x3ee5f8d4,2
+np.float32,0xbe23e318,0xbe254eed,2
+np.float32,0xbe2866f4,0xbe29f20a,2
+np.float32,0xbeaedff2,0xbeb631d0,2
+np.float32,0x0,0x0,2
+np.float32,0x3ef2a034,0x3f03dafd,2
+np.float32,0x3f35806c,0x3f62994e,2
+np.float32,0xbf655e19,0xbfb9c718,2
+np.float32,0x3f5d54ce,0x3fa7d4f4,2
+np.float32,0x3f33e64a,0x3f5f67e3,2
+np.float32,0x3ebf4010,0x3ec8f923,2
+np.float32,0xbe050dc8,0xbe05cf70,2
+np.float32,0x3f61693e,0x3fb063b0,2
+np.float32,0xbd94ac00,0xbd94ef12,2
+np.float32,0x3e9de008,0x3ea32f61,2
+np.float32,0xbe3d042c,0xbe3f3540,2
+np.float32,0x3e8fdfc0,0x3e93d9e4,2
+np.float32,0x3f28bc48,0x3f4a9019,2
+np.float32,0x3edea928,0x3eee8b09,2
+np.float32,0xbf05f673,0xbf14b362,2
+np.float32,0xbf360730,0xbf63a914,2
+np.float32,0xbe3fb454,0xbe41fe0a,2
+np.float32,0x3f6d99a8,0x3fd28552,2
+np.float32,0xbf3ae866,0xbf6dd052,2
+np.float32,0x3f5b1164,0x3fa37aec,2
+np.float32,0xbf64a451,0xbfb7f61b,2
+np.float32,0xbdd79bd0,0xbdd86919,2
+np.float32,0x3e89fc00,0x3e8d7a85,2
+np.float32,0x3f4bf690,0x3f8b77ea,2
+np.float32,0x3cbdf280,0x3cbdfb38,2
+np.float32,0x3f138f98,0x3f2835b4,2
+np.float32,0xbe33967c,0xbe3576bc,2
+np.float32,0xbf298164,0xbf4bedda,2
+np.float32,0x3e9955cc,0x3e9e2edb,2
+np.float32,0xbf79b383,0xc00c56c0,2
+np.float32,0x3ea0834c,0x3ea61aea,2
+np.float32,0xbf511184,0xbf92c89a,2
+np.float32,0x3f4d9fba,0x3f8dc666,2
+np.float32,0x3f3387c2,0x3f5ead80,2
+np.float32,0x3e3f7360,0x3e41babb,2
+np.float32,0xbf3cc4d6,0xbf71d879,2
+np.float32,0x3f2e4402,0x3f54994e,2
+np.float32,0x3e6a7118,0x3e6eabff,2
+np.float32,0xbf05d83e,0xbf1489cc,2
+np.float32,0xbdce4fd8,0xbdcf039a,2
+np.float32,0xbf03e2f4,0xbf11dbaf,2
+np.float32,0x3f1ea0a0,0x3f397375,2
+np.float32,0x3f7aff54,0x4013cb1b,2
+np.float32,0x3f5ef158,0x3fab1801,2
+np.float32,0xbe33bcc8,0xbe359e40,2
+np.float32,0xbf04dd0e,0xbf133111,2
+np.float32,0xbf14f887,0xbf2a54d1,2
+np.float32,0x3f75c37a,0x3ff9196e,2
+np.float32,0x3f35c3c8,0x3f6320f2,2
+np.float32,0x3f53bb94,0x3f96e3c3,2
+np.float32,0x3f4d473e,0x3f8d4a19,2
+np.float32,0xbdfe19e0,0xbdff6ac9,2
+np.float32,0xbf7f0cc4,0xc049342d,2
+np.float32,0xbdbfc778,0xbdc057bb,2
+np.float32,0xbf7575b7,0xbff73067,2
+np.float32,0xbe9df488,0xbea34609,2
+np.float32,0xbefbd3c6,0xbf09daff,2
+np.float32,0x3f19962c,0x3f316cbd,2
+np.float32,0x3f7acec6,0x40129732,2
+np.float32,0xbf5db7de,0xbfa89a21,2
+np.float32,0x3f62f444,0x3fb3e830,2
+np.float32,0xbf522adb,0xbf94737f,2
+np.float32,0xbef6ceb2,0xbf0690ba,2
+np.float32,0xbf57c41e,0xbf9d8db0,2
+np.float32,0x3eb3360c,0x3ebb1eb0,2
+np.float32,0x3f29327e,0x3f4b618e,2
+np.float32,0xbf08d099,0xbf18a916,2
+np.float32,0x3ea21014,0x3ea7d369,2
+np.float32,0x3f39e516,0x3f6ba861,2
+np.float32,0x3e7c4f28,0x3e80ce08,2
+np.float32,0xbec5a7f8,0xbed07582,2
+np.float32,0xbf0b1b46,0xbf1be3e7,2
+np.float32,0xbef0e0ec,0xbf02bb2e,2
+np.float32,0x3d835a30,0x3d838869,2
+np.float32,0x3f08aa40,0x3f18736e,2
+np.float32,0x3eb0e4c8,0x3eb87bcd,2
+np.float32,0x3eb3821c,0x3ebb7564,2
+np.float32,0xbe3a7320,0xbe3c8d5a,2
+np.float32,0x3e43f8c0,0x3e466b10,2
+np.float32,0x3e914288,0x3e955b69,2
+np.float32,0x3ec7d800,0x3ed308e7,2
+np.float32,0x3e603df8,0x3e63eef2,2
+np.float32,0x3f225cac,0x3f3f9ac6,2
+np.float32,0x3e3db8f0,0x3e3ff06b,2
+np.float32,0x3f358d78,0x3f62b38c,2
+np.float32,0xbed9bd64,0xbee88158,2
+np.float32,0x800000,0x800000,2
+np.float32,0x3f1adfce,0x3f337230,2
+np.float32,0xbefdc346,0xbf0b229d,2
+np.float32,0xbf091018,0xbf190208,2
+np.float32,0xbf800000,0xff800000,2
+np.float32,0x3f27c2c4,0x3f48d8db,2
+np.float32,0x3ef59c80,0x3f05c993,2
+np.float32,0x3e18a340,0x3e19c893,2
+np.float32,0x3f209610,0x3f3ca7c5,2
+np.float32,0x3f69cc22,0x3fc60087,2
+np.float32,0xbf66cf07,0xbfbd8721,2
+np.float32,0xbf768098,0xbffdfcc4,2
+np.float32,0x3df27a40,0x3df39ec4,2
+np.float32,0x3daf5bd0,0x3dafca02,2
+np.float32,0x3f53f2be,0x3f973b41,2
+np.float32,0xbf7edcbc,0xc0436ce3,2
+np.float32,0xbdf61db8,0xbdf74fae,2
+np.float32,0x3e2c9328,0x3e2e3cb2,2
+np.float32,0x3f1a4570,0x3f327f41,2
+np.float32,0xbf766306,0xbffd32f1,2
+np.float32,0xbf468b9d,0xbf845f0f,2
+np.float32,0x3e398970,0x3e3b9bb1,2
+np.float32,0xbbefa900,0xbbefaa18,2
+np.float32,0xbf54c989,0xbf9893ad,2
+np.float32,0x3f262cf6,0x3f46169d,2
+np.float32,0x3f638a8a,0x3fb54a98,2
+np.float32,0xbeb36c78,0xbebb5cb8,2
+np.float32,0xbeac4d42,0xbeb34993,2
+np.float32,0x3f1d1942,0x3f36fbf2,2
+np.float32,0xbf5d49ba,0xbfa7bf07,2
+np.float32,0xbf182b5c,0xbf2f38d0,2
+np.float32,0x3f41a742,0x3f7ce5ef,2
+np.float32,0x3f0b9a6c,0x3f1c9898,2
+np.float32,0x3e847494,0x3e8788f3,2
+np.float32,0xbde41608,0xbde50941,2
+np.float32,0x3f693944,0x3fc44b5a,2
+np.float32,0x3f0386b2,0x3f115e37,2
+np.float32,0x3f3a08b0,0x3f6bf3c1,2
+np.float32,0xbf78ee64,0xc0089977,2
+np.float32,0xbf013a11,0xbf0e436e,2
+np.float32,0x3f00668e,0x3f0d2836,2
+np.float32,0x3e6d9850,0x3e720081,2
+np.float32,0x3eacf578,0x3eb4075d,2
+np.float32,0x3f18aef8,0x3f3004b4,2
+np.float32,0x3de342f0,0x3de43385,2
+np.float32,0x3e56cee8,0x3e5a0b85,2
+np.float32,0xbf287912,0xbf4a1966,2
+np.float32,0x3e92c948,0x3e9704c2,2
+np.float32,0x3c07d080,0x3c07d14c,2
+np.float32,0xbe90f6a0,0xbe9508e0,2
+np.float32,0x3e8b4f28,0x3e8ee884,2
+np.float32,0xbf35b56c,0xbf6303ff,2
+np.float32,0xbef512b8,0xbf057027,2
+np.float32,0x3e36c630,0x3e38c0cd,2
+np.float32,0x3f0b3ca8,0x3f1c134a,2
+np.float32,0x3e4cd610,0x3e4fa2c5,2
+np.float32,0xbf5a8372,0xbfa273a3,2
+np.float32,0xbecaad3c,0xbed662ae,2
+np.float32,0xbec372d2,0xbecddeac,2
+np.float32,0x3f6fb2b2,0x3fda8a22,2
+np.float32,0x3f365f28,0x3f645b5a,2
+np.float32,0xbecd00fa,0xbed926a4,2
+np.float32,0xbebafa32,0xbec40672,2
+np.float32,0xbf235b73,0xbf4146c4,2
+np.float32,0x3f7a4658,0x400f6e2c,2
+np.float32,0x3f35e824,0x3f636a54,2
+np.float32,0x3cb87640,0x3cb87e3c,2
+np.float32,0xbf296288,0xbf4bb6ee,2
+np.float32,0x7f800000,0xffc00000,2
+np.float32,0xbf4de86e,0xbf8e2d1a,2
+np.float32,0xbf4ace12,0xbf89e5f3,2
+np.float32,0x3d65a300,0x3d65e0b5,2
+np.float32,0xbe10c534,0xbe11bf21,2
+np.float32,0xbeba3c1c,0xbec32b3e,2
+np.float32,0x3e87eaf8,0x3e8b40b8,2
+np.float32,0x3d5c3bc0,0x3d5c722d,2
+np.float32,0x3e8c14b8,0x3e8fbdf8,2
+np.float32,0xbf06c6f0,0xbf15d327,2
+np.float32,0xbe0f1e30,0xbe100f96,2
+np.float32,0xbee244b0,0xbef30251,2
+np.float32,0x3f2a21b0,0x3f4d0c1d,2
+np.float32,0xbf5f7f81,0xbfac408e,2
+np.float32,0xbe3dba2c,0xbe3ff1b2,2
+np.float32,0x3f3ffc22,0x3f790abf,2
+np.float32,0x3edc3dac,0x3eeb90fd,2
+np.float32,0x7f7fffff,0xffc00000,2
+np.float32,0x3ecfaaac,0x3edc5485,2
+np.float32,0x3f0affbe,0x3f1bbcd9,2
+np.float32,0x3f5f2264,0x3fab7dca,2
+np.float32,0x3f37394c,0x3f66186c,2
+np.float32,0xbe6b2f6c,0xbe6f74e3,2
+np.float32,0x3f284772,0x3f49c1f1,2
+np.float32,0xbdf27bc8,0xbdf3a051,2
+np.float32,0xbc8b14e0,0xbc8b184c,2
+np.float32,0x3f6a867c,0x3fc83b07,2
+np.float32,0x3f1ec876,0x3f39b429,2
+np.float32,0x3f6fd9a8,0x3fdb28d6,2
+np.float32,0xbf473cca,0xbf853e8c,2
+np.float32,0x3e23eff8,0x3e255c23,2
+np.float32,0x3ebefdfc,0x3ec8ac5d,2
+np.float32,0x3f6c8c22,0x3fced2b1,2
+np.float32,0x3f168388,0x3f2cad44,2
+np.float32,0xbece2410,0xbeda81ac,2
+np.float32,0x3f5532f0,0x3f993eea,2
+np.float32,0x3ef1938c,0x3f032dfa,2
+np.float32,0xbef05268,0xbf025fba,2
+np.float32,0x3f552e4a,0x3f993754,2
+np.float32,0x3e9ed068,0x3ea4392d,2
+np.float32,0xbe1a0c24,0xbe1b39be,2
+np.float32,0xbf2623aa,0xbf46068c,2
+np.float32,0xbe1cc300,0xbe1e00fc,2
+np.float32,0xbe9c0576,0xbea12397,2
+np.float32,0xbd827338,0xbd82a07e,2
+np.float32,0x3f0fc31a,0x3f229786,2
+np.float32,0x3e577810,0x3e5abc7d,2
+np.float32,0x3e0e1cb8,0x3e0f0906,2
+np.float32,0x3e84d344,0x3e87ee73,2
+np.float32,0xbf39c45e,0xbf6b6337,2
+np.float32,0x3edfb25c,0x3eefd273,2
+np.float32,0x3e016398,0x3e021596,2
+np.float32,0xbefeb1be,0xbf0bc0de,2
+np.float32,0x3f37e104,0x3f677196,2
+np.float32,0x3f545316,0x3f97d500,2
+np.float32,0xbefc165a,0xbf0a06ed,2
+np.float32,0xbf0923e6,0xbf191dcd,2
+np.float32,0xbf386508,0xbf68831f,2
+np.float32,0xbf3d4630,0xbf72f4e1,2
+np.float32,0x3f3dbe82,0x3f73ff13,2
+np.float32,0xbf703de4,0xbfdcc7e2,2
+np.float32,0xbf531482,0xbf95dd1a,2
+np.float32,0xbf0af1b6,0xbf1ba8f4,2
+np.float32,0xbec8fd9c,0xbed463a4,2
+np.float32,0xbe230320,0xbe24691a,2
+np.float32,0xbf7de541,0xc02faf38,2
+np.float32,0x3efd2360,0x3f0ab8b7,2
+np.float32,0x3db7f350,0x3db87291,2
+np.float32,0x3e74c510,0x3e799924,2
+np.float32,0x3da549c0,0x3da5a5fc,2
+np.float32,0x3e8a3bc4,0x3e8dbf4a,2
+np.float32,0xbf69f086,0xbfc66e84,2
+np.float32,0x3f323f8e,0x3f5c2c17,2
+np.float32,0x3ec0ae3c,0x3ecaa334,2
+np.float32,0xbebe8966,0xbec824fc,2
+np.float32,0x3f34691e,0x3f606b13,2
+np.float32,0x3f13790e,0x3f2813f5,2
+np.float32,0xbf61c027,0xbfb12618,2
+np.float32,0x3e90c690,0x3e94d4a1,2
+np.float32,0xbefce8f0,0xbf0a920e,2
+np.float32,0xbf5c0e8a,0xbfa559a7,2
+np.float32,0x3f374f60,0x3f6645b6,2
+np.float32,0x3f25f6fa,0x3f45b967,2
+np.float32,0x3f2421aa,0x3f42963a,2
+np.float32,0x3ebfa328,0x3ec96c57,2
+np.float32,0x3e3bef28,0x3e3e1685,2
+np.float32,0x3ea3fa3c,0x3ea9f4dd,2
+np.float32,0x3f362b8e,0x3f63f2b2,2
+np.float32,0xbedcef18,0xbeec6ada,2
+np.float32,0xbdd29c88,0xbdd35bd0,2
+np.float32,0x3f261aea,0x3f45f76f,2
+np.float32,0xbe62c470,0xbe66965e,2
+np.float32,0x7fc00000,0x7fc00000,2
+np.float32,0xbee991aa,0xbefc277b,2
+np.float32,0xbf571960,0xbf9c6923,2
+np.float32,0xbe6fb410,0xbe743b41,2
+np.float32,0x3eb1bed0,0x3eb9738d,2
+np.float32,0x80000000,0x80000000,2
+np.float32,0x3eddcbe4,0x3eed7a69,2
+np.float32,0xbf2a81ba,0xbf4db86d,2
+np.float32,0x3f74da54,0x3ff38737,2
+np.float32,0xbeb6bff4,0xbebf29f4,2
+np.float32,0x3f445752,0x3f81a698,2
+np.float32,0x3ed081b4,0x3edd5618,2
+np.float32,0xbee73802,0xbef931b4,2
+np.float32,0xbd13f2a0,0xbd14031c,2
+np.float32,0xbb4d1200,0xbb4d122c,2
+np.float32,0xbee8777a,0xbefac393,2
+np.float32,0x3f42047c,0x3f7dc06c,2
+np.float32,0xbd089270,0xbd089f67,2
+np.float32,0xbf628c16,0xbfb2f66b,2
+np.float32,0x3e72e098,0x3e77978d,2
+np.float32,0x3ed967cc,0x3ee818e4,2
+np.float32,0x3e284c80,0x3e29d6d9,2
+np.float32,0x3f74e8ba,0x3ff3dbef,2
+np.float32,0x3f013e86,0x3f0e4969,2
+np.float32,0xbf610d4f,0xbfaf983c,2
+np.float32,0xbf3c8d36,0xbf715eba,2
+np.float32,0xbedbc756,0xbeeaffdb,2
+np.float32,0x3e143ec8,0x3e154b4c,2
+np.float32,0xbe1c9808,0xbe1dd4fc,2
+np.float32,0xbe887a1e,0xbe8bdac5,2
+np.float32,0xbe85c4bc,0xbe88f17a,2
+np.float32,0x3f35967e,0x3f62c5b4,2
+np.float32,0x3ea2c4a4,0x3ea89c2d,2
+np.float32,0xbc8703c0,0xbc8706e1,2
+np.float32,0xbf13d52c,0xbf289dff,2
+np.float32,0xbf63bb56,0xbfb5bf29,2
+np.float32,0xbf61c5ef,0xbfb13319,2
+np.float32,0xbf128410,0xbf26a675,2
+np.float32,0x3f03fcf2,0x3f11ff13,2
+np.float32,0xbe49c924,0xbe4c75cd,2
+np.float32,0xbf211a9c,0xbf3d82c5,2
+np.float32,0x3f7e9d52,0x403d1b42,2
+np.float32,0x3edfefd4,0x3ef01e71,2
+np.float32,0x3ebc5bd8,0x3ec59efb,2
+np.float32,0x3d7b02e0,0x3d7b537f,2
+np.float32,0xbf1163ba,0xbf24fb43,2
+np.float32,0x3f5072f2,0x3f91dbf1,2
+np.float32,0xbee700ce,0xbef8ec60,2
+np.float32,0x3f534168,0x3f962359,2
+np.float32,0x3e6d6c40,0x3e71d1ef,2
+np.float32,0x3def9d70,0x3df0b7a8,2
+np.float32,0x3e89cf80,0x3e8d4a8a,2
+np.float32,0xbf687ca7,0xbfc2290f,2
+np.float32,0x3f35e134,0x3f635c51,2
+np.float32,0x3e59eef8,0x3e5d50fa,2
+np.float32,0xbf65c9e1,0xbfbada61,2
+np.float32,0xbf759292,0xbff7e43d,2
+np.float32,0x3f4635a0,0x3f83f372,2
+np.float32,0x3f29baaa,0x3f4c53f1,2
+np.float32,0x3f6b15a6,0x3fc9fe04,2
+np.float32,0x3edabc88,0x3ee9b922,2
+np.float32,0x3ef382e0,0x3f046d4d,2
+np.float32,0xbe351310,0xbe36ff7f,2
+np.float32,0xbf05c935,0xbf14751c,2
+np.float32,0xbf0e7c50,0xbf20bc24,2
+np.float32,0xbf69bc94,0xbfc5d1b8,2
+np.float32,0xbed41aca,0xbee1aa23,2
+np.float32,0x3f518c08,0x3f938162,2
+np.float32,0xbf3d7974,0xbf73661a,2
+np.float32,0x3f1951a6,0x3f3101c9,2
+np.float32,0xbeb3f436,0xbebbf787,2
+np.float32,0xbf77a190,0xc0031d43,2
+np.float32,0x3eb5b3cc,0x3ebdf6e7,2
+np.float32,0xbed534b4,0xbee2fed2,2
+np.float32,0xbe53e1b8,0xbe56fc56,2
+np.float32,0x3f679e20,0x3fbfb91c,2
+np.float32,0xff7fffff,0xffc00000,2
+np.float32,0xbf7b9bcb,0xc0180073,2
+np.float32,0xbf5635e8,0xbf9aea15,2
+np.float32,0xbe5a3318,0xbe5d9856,2
+np.float32,0xbe003284,0xbe00df9a,2
+np.float32,0x3eb119a4,0x3eb8b7d6,2
+np.float32,0xbf3bccf8,0xbf6fbc84,2
+np.float32,0x3f36f600,0x3f658ea8,2
+np.float32,0x3f1ea834,0x3f397fc2,2
+np.float32,0xbe7cfb54,0xbe8129b3,2
+np.float32,0xbe9b3746,0xbea0406a,2
+np.float32,0x3edc0f90,0x3eeb586c,2
+np.float32,0x3e1842e8,0x3e19660c,2
+np.float32,0xbd8f10b0,0xbd8f4c70,2
+np.float32,0xbf064aca,0xbf1527a2,2
+np.float32,0x3e632e58,0x3e6705be,2
+np.float32,0xbef28ba4,0xbf03cdbb,2
+np.float32,0x3f27b21e,0x3f48bbaf,2
+np.float32,0xbe6f30d4,0xbe73b06e,2
+np.float32,0x3f3e6cb0,0x3f75834b,2
+np.float32,0xbf264aa5,0xbf4649f0,2
+np.float32,0xbf690775,0xbfc3b978,2
+np.float32,0xbf3e4a38,0xbf753632,2
+np.float64,0x3fe12bbe8c62577e,0x3fe32de8e5f961b0,2
+np.float64,0x3fc9b8909b337120,0x3fca1366da00efff,2
+np.float64,0x3feaee4245f5dc84,0x3ff3a011ea0432f3,2
+np.float64,0xbfe892c000f12580,0xbff03e5adaed6f0c,2
+np.float64,0xbf9be8de4837d1c0,0xbf9beaa367756bd1,2
+np.float64,0x3fe632e58fec65cc,0x3feb5ccc5114ca38,2
+np.float64,0x3fe78a0ef7ef141e,0x3fee1b4521d8eb6c,2
+np.float64,0x3feec27a65fd84f4,0x3fff643c8318e81e,2
+np.float64,0x3fbed6efce3dade0,0x3fbefd76cff00111,2
+np.float64,0xbfe3a05fab6740c0,0xbfe6db078aeeb0ca,2
+np.float64,0x3fdca11a56b94234,0x3fdece9e6eacff1b,2
+np.float64,0x3fe0fb15aae1f62c,0x3fe2e9e095ec2089,2
+np.float64,0x3fede12abf7bc256,0x3ffafd0ff4142807,2
+np.float64,0x3feb919edcf7233e,0x3ff4c9aa0bc2432f,2
+np.float64,0x3fd39633b5a72c68,0x3fd43c2e6d5f441c,2
+np.float64,0x3fd9efcbfeb3df98,0x3fdb83f03e58f91c,2
+np.float64,0x3fe2867a36650cf4,0x3fe525858c8ce72e,2
+np.float64,0x3fdacbb8f3b59770,0x3fdc8cd431b6e3ff,2
+np.float64,0x3fcc120503382408,0x3fcc88a8fa43e1c6,2
+np.float64,0xbfd99ff4eab33fea,0xbfdb24a20ae3687d,2
+np.float64,0xbfe8caf0157195e0,0xbff083b8dd0941d3,2
+np.float64,0x3fddc9bf92bb9380,0x3fe022aac0f761d5,2
+np.float64,0x3fe2dbb66e65b76c,0x3fe5a6e7caf3f1f2,2
+np.float64,0x3fe95f5c4a72beb8,0x3ff1444697e96138,2
+np.float64,0xbfc6b163d92d62c8,0xbfc6ef6e006658a1,2
+np.float64,0x3fdf1b2616be364c,0x3fe0fcbd2848c9e8,2
+np.float64,0xbfdca1ccf7b9439a,0xbfdecf7dc0eaa663,2
+np.float64,0x3fe078d6a260f1ae,0x3fe236a7c66ef6c2,2
+np.float64,0x3fdf471bb9be8e38,0x3fe11990ec74e704,2
+np.float64,0xbfe417626be82ec5,0xbfe79c9aa5ed2e2f,2
+np.float64,0xbfeb9cf5677739eb,0xbff4dfc24c012c90,2
+np.float64,0x3f8d9142b03b2280,0x3f8d91c9559d4779,2
+np.float64,0x3fb052c67220a590,0x3fb05873c90d1cd6,2
+np.float64,0x3fd742e2c7ae85c4,0x3fd860128947d15d,2
+np.float64,0x3fec2e2a2bf85c54,0x3ff60eb554bb8d71,2
+np.float64,0xbfeb2b8bc8f65718,0xbff40b734679497a,2
+np.float64,0x3fe25f8e0d64bf1c,0x3fe4eb381d077803,2
+np.float64,0x3fe56426256ac84c,0x3fe9dafbe79370f0,2
+np.float64,0x3feecc1e5d7d983c,0x3fffa49bedc7aa25,2
+np.float64,0xbfc88ce94b3119d4,0xbfc8dbba0fdee2d2,2
+np.float64,0xbfabcf51ac379ea0,0xbfabd6552aa63da3,2
+np.float64,0xbfccc8b849399170,0xbfcd48d6ff057a4d,2
+np.float64,0x3fd2f831e8a5f064,0x3fd38e67b0dda905,2
+np.float64,0x3fcafdcd6135fb98,0x3fcb670ae2ef4d36,2
+np.float64,0x3feda6042efb4c08,0x3ffa219442ac4ea5,2
+np.float64,0x3fed382b157a7056,0x3ff8bc01bc6d10bc,2
+np.float64,0x3fed858a50fb0b14,0x3ff9b1c05cb6cc0f,2
+np.float64,0x3fcc3960653872c0,0x3fccb2045373a3d1,2
+np.float64,0xbfec5177e478a2f0,0xbff65eb4557d94eb,2
+np.float64,0x3feafe0d5e75fc1a,0x3ff3bb4a260a0dcb,2
+np.float64,0x3fe08bc87ee11790,0x3fe25078aac99d31,2
+np.float64,0xffefffffffffffff,0xfff8000000000000,2
+np.float64,0x3f79985ce0333100,0x3f799872b591d1cb,2
+np.float64,0xbfd4001cf9a8003a,0xbfd4b14b9035b94f,2
+np.float64,0x3fe54a17e6ea9430,0x3fe9ac0f18682343,2
+np.float64,0xbfb4e07fea29c100,0xbfb4ec6520dd0689,2
+np.float64,0xbfed2b6659fa56cd,0xbff895ed57dc1450,2
+np.float64,0xbfe81fc8b5f03f92,0xbfef6b95e72a7a7c,2
+np.float64,0xbfe6aced16ed59da,0xbfec4ce131ee3704,2
+np.float64,0xbfe599f30ceb33e6,0xbfea3d07c1cd78e2,2
+np.float64,0xbfe0ff278b61fe4f,0xbfe2ef8b5efa89ed,2
+np.float64,0xbfe3e9406467d281,0xbfe750e43e841736,2
+np.float64,0x3fcc6b52cf38d6a8,0x3fcce688f4fb2cf1,2
+np.float64,0xbfc890e8133121d0,0xbfc8dfdfee72d258,2
+np.float64,0x3fe46e81dbe8dd04,0x3fe82e09783811a8,2
+np.float64,0x3fd94455e5b288ac,0x3fdab7cef2de0b1f,2
+np.float64,0xbfe82151fff042a4,0xbfef6f254c9696ca,2
+np.float64,0x3fcee1ac1d3dc358,0x3fcf80a6ed07070a,2
+np.float64,0x3fcce8f90939d1f0,0x3fcd6ad18d34f8b5,2
+np.float64,0x3fd6afe56fad5fcc,0x3fd7b7567526b1fb,2
+np.float64,0x3fb1a77092234ee0,0x3fb1ae9fe0d176fc,2
+np.float64,0xbfeb758b0d76eb16,0xbff493d105652edc,2
+np.float64,0xbfb857c24e30af88,0xbfb86aa4da3be53f,2
+np.float64,0x3fe89064eff120ca,0x3ff03b7c5b3339a8,2
+np.float64,0xbfc1bd2fef237a60,0xbfc1da99893473ed,2
+np.float64,0xbfe5ad6e2eeb5adc,0xbfea60ed181b5c05,2
+np.float64,0x3fd5a66358ab4cc8,0x3fd6899e640aeb1f,2
+np.float64,0xbfe198e832e331d0,0xbfe3c8c9496d0de5,2
+np.float64,0xbfdaa5c0d7b54b82,0xbfdc5ed7d3c5ce49,2
+np.float64,0x3fcceccb6939d998,0x3fcd6ed88c2dd3a5,2
+np.float64,0xbfe44413eae88828,0xbfe7e6cd32b34046,2
+np.float64,0xbfc7cbeccf2f97d8,0xbfc8139a2626edae,2
+np.float64,0x3fbf31e4fa3e63d0,0x3fbf59c6e863255e,2
+np.float64,0x3fdf03fa05be07f4,0x3fe0ed953f7989ad,2
+np.float64,0x3fe7f4eaceefe9d6,0x3fef092ca7e2ac39,2
+np.float64,0xbfc084e9d92109d4,0xbfc09ca10fd6aaea,2
+np.float64,0xbf88cfbf70319f80,0xbf88d00effa6d897,2
+np.float64,0x7ff4000000000000,0x7ffc000000000000,2
+np.float64,0xbfa0176e9c202ee0,0xbfa018ca0a6ceef3,2
+np.float64,0xbfd88d0815b11a10,0xbfd9dfc6c6bcbe4e,2
+np.float64,0x3fe89f7730713eee,0x3ff04de52fb536f3,2
+np.float64,0xbfedc9707bfb92e1,0xbffaa25fcf9dd6da,2
+np.float64,0x3fe936d1a6726da4,0x3ff10e40c2d94bc9,2
+np.float64,0x3fdb64aec7b6c95c,0x3fdd473177317b3f,2
+np.float64,0xbfee4f9aaefc9f35,0xbffcdd212667003c,2
+np.float64,0x3fe3730067e6e600,0x3fe692b0a0babf5f,2
+np.float64,0xbfc257e58924afcc,0xbfc27871f8c218d7,2
+np.float64,0x3fe62db12dec5b62,0x3feb52c61b97d9f6,2
+np.float64,0xbfe3ff491367fe92,0xbfe774f1b3a96fd6,2
+np.float64,0x3fea43255274864a,0x3ff28b0c4b7b8d21,2
+np.float64,0xbfea37923c746f24,0xbff27962159f2072,2
+np.float64,0x3fcd0ac3c73a1588,0x3fcd8e6f8de41755,2
+np.float64,0xbfdccafde6b995fc,0xbfdf030fea8a0630,2
+np.float64,0x3fdba35268b746a4,0x3fdd94094f6f50c1,2
+np.float64,0x3fc68ea1d92d1d40,0x3fc6cb8d07cbb0e4,2
+np.float64,0xbfb88b1f6e311640,0xbfb89e7af4e58778,2
+np.float64,0xbfedc7cadffb8f96,0xbffa9c3766227956,2
+np.float64,0x3fe7928d3eef251a,0x3fee2dcf2ac7961b,2
+np.float64,0xbfeff42ede7fe85e,0xc00cef6b0f1e8323,2
+np.float64,0xbfebf07fa477e0ff,0xbff5893f99e15236,2
+np.float64,0x3fe3002ab9660056,0x3fe5defba550c583,2
+np.float64,0x3feb8f4307f71e86,0x3ff4c517ec8d6de9,2
+np.float64,0x3fd3c16f49a782e0,0x3fd46becaacf74da,2
+np.float64,0x3fc7613df12ec278,0x3fc7a52b2a3c3368,2
+np.float64,0xbfe33af560e675eb,0xbfe63a6528ff1587,2
+np.float64,0xbfde86495abd0c92,0xbfe09bd7ba05b461,2
+np.float64,0x3fe1e7fb4ee3cff6,0x3fe43b04311c0ab6,2
+np.float64,0xbfc528b6bd2a516c,0xbfc55ae0a0c184c8,2
+np.float64,0xbfd81025beb0204c,0xbfd94dd72d804613,2
+np.float64,0x10000000000000,0x10000000000000,2
+np.float64,0x3fc1151c47222a38,0x3fc12f5aad80a6bf,2
+np.float64,0x3feafa136775f426,0x3ff3b46854da0b3a,2
+np.float64,0x3fed2da0747a5b40,0x3ff89c85b658459e,2
+np.float64,0x3fda2a4b51b45498,0x3fdbca0d908ddbbd,2
+np.float64,0xbfd04cf518a099ea,0xbfd0aae0033b9e4c,2
+np.float64,0xbfb9065586320ca8,0xbfb91adb7e31f322,2
+np.float64,0xbfd830b428b06168,0xbfd973ca3c484d8d,2
+np.float64,0x3fc952f7ed32a5f0,0x3fc9a9994561fc1a,2
+np.float64,0xbfeb06c83c760d90,0xbff3ca77b326df20,2
+np.float64,0xbfeb1c98ac763931,0xbff3f0d0900f6149,2
+np.float64,0x3fdf061dbebe0c3c,0x3fe0eefb32b48d17,2
+np.float64,0xbf9acbaf28359760,0xbf9acd4024be9fec,2
+np.float64,0x3fec0adde2f815bc,0x3ff5c1628423794d,2
+np.float64,0xbfc4bc750d2978ec,0xbfc4eba43f590b94,2
+np.float64,0x3fdbe47878b7c8f0,0x3fdde44a2b500d73,2
+np.float64,0x3fe160d18162c1a4,0x3fe378cff08f18f0,2
+np.float64,0x3fc3b58dfd276b18,0x3fc3de01d3802de9,2
+np.float64,0x3fa860343430c060,0x3fa864ecd07ec962,2
+np.float64,0x3fcaebfb4b35d7f8,0x3fcb546512d1b4c7,2
+np.float64,0x3fe3fda558e7fb4a,0x3fe772412e5776de,2
+np.float64,0xbfe8169f2c702d3e,0xbfef5666c9a10f6d,2
+np.float64,0x3feda78e9efb4f1e,0x3ffa270712ded769,2
+np.float64,0xbfda483161b49062,0xbfdbedfbf2e850ba,2
+np.float64,0x3fd7407cf3ae80f8,0x3fd85d4f52622743,2
+np.float64,0xbfd63de4d4ac7bca,0xbfd73550a33e3c32,2
+np.float64,0xbfd9c30b90b38618,0xbfdb4e7695c856f3,2
+np.float64,0x3fcd70c00b3ae180,0x3fcdfa0969e0a119,2
+np.float64,0x3feb4f127f769e24,0x3ff44bf42514e0f4,2
+np.float64,0xbfec1db44af83b69,0xbff5ea54aed1f8e9,2
+np.float64,0x3fd68ff051ad1fe0,0x3fd792d0ed6d6122,2
+np.float64,0x3fe0a048a5614092,0x3fe26c80a826b2a2,2
+np.float64,0x3fd59f3742ab3e70,0x3fd6818563fcaf80,2
+np.float64,0x3fca26ecf9344dd8,0x3fca867ceb5d7ba8,2
+np.float64,0x3fdc1d547ab83aa8,0x3fde2a9cea866484,2
+np.float64,0xbfc78df6312f1bec,0xbfc7d3719b698a39,2
+np.float64,0x3fe754e72b6ea9ce,0x3feda89ea844a2e5,2
+np.float64,0x3fe740c1a4ee8184,0x3fed7dc56ec0c425,2
+np.float64,0x3fe77566a9eeeace,0x3fedee6f408df6de,2
+np.float64,0xbfbbf5bf8e37eb80,0xbfbc126a223781b4,2
+np.float64,0xbfe0acb297615965,0xbfe27d86681ca2b5,2
+np.float64,0xbfc20a0487241408,0xbfc228f5f7d52ce8,2
+np.float64,0xfff0000000000000,0xfff8000000000000,2
+np.float64,0x3fef98a4dbff314a,0x40043cfb60bd46fa,2
+np.float64,0x3fd059102ca0b220,0x3fd0b7d2be6d7822,2
+np.float64,0x3fe89f18a1f13e32,0x3ff04d714bbbf400,2
+np.float64,0x3fd45b6275a8b6c4,0x3fd516a44a276a4b,2
+np.float64,0xbfe04463e86088c8,0xbfe1ef9dfc9f9a53,2
+np.float64,0xbfe086e279610dc5,0xbfe249c9c1040a13,2
+np.float64,0x3f89c9b110339380,0x3f89ca0a641454b5,2
+np.float64,0xbfb5f5b4322beb68,0xbfb6038dc3fd1516,2
+np.float64,0x3fe6eae76f6dd5ce,0x3feccabae04d5c14,2
+np.float64,0x3fa9ef6c9c33dee0,0x3fa9f51c9a8c8a2f,2
+np.float64,0xbfe171b45f62e368,0xbfe390ccc4c01bf6,2
+np.float64,0x3fb2999442253330,0x3fb2a1fc006804b5,2
+np.float64,0x3fd124bf04a24980,0x3fd1927abb92472d,2
+np.float64,0xbfe6e05938edc0b2,0xbfecb519ba78114f,2
+np.float64,0x3fed466ee6fa8cde,0x3ff8e75405b50490,2
+np.float64,0xbfb999aa92333358,0xbfb9afa4f19f80a2,2
+np.float64,0xbfe98969ed7312d4,0xbff17d887b0303e7,2
+np.float64,0x3fe782843e6f0508,0x3fee0adbeebe3486,2
+np.float64,0xbfe232fcc26465fa,0xbfe4a90a68d46040,2
+np.float64,0x3fd190a90fa32154,0x3fd206f56ffcdca2,2
+np.float64,0xbfc4f8b75929f170,0xbfc5298b2d4e7740,2
+np.float64,0xbfba3a63d63474c8,0xbfba520835c2fdc2,2
+np.float64,0xbfb7708eea2ee120,0xbfb781695ec17846,2
+np.float64,0x3fed9fb7a5fb3f70,0x3ffa0b717bcd1609,2
+np.float64,0xbfc1b158cd2362b0,0xbfc1ce87345f3473,2
+np.float64,0x3f963478082c6900,0x3f96355c3000953b,2
+np.float64,0x3fc5050e532a0a20,0x3fc536397f38f616,2
+np.float64,0x3fe239f9eee473f4,0x3fe4b360da3b2faa,2
+np.float64,0xbfd66bd80eacd7b0,0xbfd769a29fd784c0,2
+np.float64,0x3fc57cdad52af9b8,0x3fc5b16b937f5f72,2
+np.float64,0xbfd3c36a0aa786d4,0xbfd46e1cd0b4eddc,2
+np.float64,0x3feff433487fe866,0x400cf0ea1def3161,2
+np.float64,0xbfed5577807aaaef,0xbff915e8f6bfdf22,2
+np.float64,0xbfca0dd3eb341ba8,0xbfca6c4d11836cb6,2
+np.float64,0x7ff8000000000000,0x7ff8000000000000,2
+np.float64,0xbf974deaa82e9be0,0xbf974ef26a3130d1,2
+np.float64,0xbfe7f425e1efe84c,0xbfef076cb00d649d,2
+np.float64,0xbfe4413605e8826c,0xbfe7e20448b8a4b1,2
+np.float64,0xbfdfad202cbf5a40,0xbfe15cd9eb2be707,2
+np.float64,0xbfe43261ee6864c4,0xbfe7c952c951fe33,2
+np.float64,0xbfec141225782824,0xbff5d54d33861d98,2
+np.float64,0x3fd0f47abaa1e8f4,0x3fd15e8691a7f1c2,2
+np.float64,0x3fd378f0baa6f1e0,0x3fd41bea4a599081,2
+np.float64,0xbfb52523462a4a48,0xbfb5317fa7f436e2,2
+np.float64,0x3fcb30797d3660f0,0x3fcb9c174ea401ff,2
+np.float64,0xbfd48480dea90902,0xbfd5446e02c8b329,2
+np.float64,0xbfee4ae3ab7c95c7,0xbffcc650340ba274,2
+np.float64,0xbfeab086d075610e,0xbff3387f4e83ae26,2
+np.float64,0x3fa17cddf422f9c0,0x3fa17e9bf1b25736,2
+np.float64,0xbfe3064536e60c8a,0xbfe5e86aa5244319,2
+np.float64,0x3feb2882c5765106,0x3ff40604c7d97d44,2
+np.float64,0xbfa6923ff42d2480,0xbfa695ff57b2fc3f,2
+np.float64,0xbfa8bdbdcc317b80,0xbfa8c2ada0d94aa7,2
+np.float64,0x3fe7f16b8e6fe2d8,0x3fef013948c391a6,2
+np.float64,0x3fe4e7169f69ce2e,0x3fe8fceef835050a,2
+np.float64,0x3fed877638fb0eec,0x3ff9b83694127959,2
+np.float64,0xbfe0cc9ecf61993e,0xbfe2a978234cbde5,2
+np.float64,0xbfe977e79672efcf,0xbff16589ea494a38,2
+np.float64,0xbfe240130ae48026,0xbfe4bc69113e0d7f,2
+np.float64,0x3feb1e9b70763d36,0x3ff3f4615938a491,2
+np.float64,0xbfdf197dfcbe32fc,0xbfe0fba78a0fc816,2
+np.float64,0xbfee0f8543fc1f0a,0xbffbb9d9a4ee5387,2
+np.float64,0x3fe88d2191f11a44,0x3ff037843b5b6313,2
+np.float64,0xbfd11bb850a23770,0xbfd188c1cef40007,2
+np.float64,0xbfa1b36e9c2366e0,0xbfa1b53d1d8a8bc4,2
+np.float64,0xbfea2d70d9f45ae2,0xbff26a0629e36b3e,2
+np.float64,0xbfd9188703b2310e,0xbfda83f9ddc18348,2
+np.float64,0xbfee194894fc3291,0xbffbe3c83b61e7cb,2
+np.float64,0xbfe093b4a9e1276a,0xbfe25b4ad6f8f83d,2
+np.float64,0x3fea031489f4062a,0x3ff22accc000082e,2
+np.float64,0xbfc6c0827b2d8104,0xbfc6ff0a94326381,2
+np.float64,0x3fef5cd340feb9a6,0x4002659c5a1b34af,2
+np.float64,0x8010000000000000,0x8010000000000000,2
+np.float64,0x3fd97cb533b2f96c,0x3fdafab28aaae8e3,2
+np.float64,0x3fe2123334642466,0x3fe478bd83a8ce02,2
+np.float64,0xbfd9a69637b34d2c,0xbfdb2c87c6b6fb8c,2
+np.float64,0x3fc58def7f2b1be0,0x3fc5c2ff724a9f61,2
+np.float64,0xbfedd5da1f7babb4,0xbffad15949b7fb22,2
+np.float64,0x3fe90e92a0721d26,0x3ff0d9b64323efb8,2
+np.float64,0x3fd34b9442a69728,0x3fd3e9f8fe80654e,2
+np.float64,0xbfc5f509ab2bea14,0xbfc62d2ad325c59f,2
+np.float64,0x3feb245634f648ac,0x3ff3fe91a46acbe1,2
+np.float64,0x3fd101e539a203cc,0x3fd16cf52ae6d203,2
+np.float64,0xbfc51e9ba72a3d38,0xbfc5507d00521ba3,2
+np.float64,0x3fe5fe1683ebfc2e,0x3feaf7dd8b1f92b0,2
+np.float64,0x3fc362e59126c5c8,0x3fc389601814170b,2
+np.float64,0x3fea34dbd77469b8,0x3ff27542eb721e7e,2
+np.float64,0xbfc13ed241227da4,0xbfc159d42c0a35a9,2
+np.float64,0xbfe6df118cedbe23,0xbfecb27bb5d3f784,2
+np.float64,0x3fd92895f6b2512c,0x3fda96f5f94b625e,2
+np.float64,0xbfe7ea3aa76fd476,0xbfeef0e93939086e,2
+np.float64,0xbfc855498330aa94,0xbfc8a1ff690c9533,2
+np.float64,0x3fd9f27b3ab3e4f8,0x3fdb8726979afc3b,2
+np.float64,0x3fc65d52232cbaa8,0x3fc698ac4367afba,2
+np.float64,0x3fd1271dd0a24e3c,0x3fd195087649d54e,2
+np.float64,0xbfe983445df30689,0xbff175158b773b90,2
+np.float64,0xbfe0d9b13261b362,0xbfe2bb8908fc9e6e,2
+np.float64,0x3fd7671f2aaece40,0x3fd889dccbf21629,2
+np.float64,0x3fe748aebfee915e,0x3fed8e970d94c17d,2
+np.float64,0x3fea756e4e74eadc,0x3ff2d947ef3a54f4,2
+np.float64,0x3fde22311cbc4464,0x3fe05b4ce9df1fdd,2
+np.float64,0x3fe2b55ec1e56abe,0x3fe56c6849e3985a,2
+np.float64,0x3fed7b47437af68e,0x3ff98f8e82de99a0,2
+np.float64,0x3fec8184b179030a,0x3ff6d03aaf0135ba,2
+np.float64,0x3fc9ea825533d508,0x3fca4776d7190e71,2
+np.float64,0xbfe8ddd58b71bbab,0xbff09b770ed7bc9a,2
+np.float64,0xbfed41741bfa82e8,0xbff8d81c2a9fc615,2
+np.float64,0x3fe0a73888e14e72,0x3fe27602ad9a3726,2
+np.float64,0xbfe9d0a565f3a14b,0xbff1e1897b628f66,2
+np.float64,0x3fda12b381b42568,0x3fdbadbec22fbd5a,2
+np.float64,0x3fef0081187e0102,0x4000949eff8313c2,2
+np.float64,0x3fef6942b67ed286,0x4002b7913eb1ee76,2
+np.float64,0x3fda10f882b421f0,0x3fdbababa2d6659d,2
+np.float64,0x3fe5828971eb0512,0x3fea122b5088315a,2
+np.float64,0x3fe9d4b53ff3a96a,0x3ff1e75c148bda01,2
+np.float64,0x3fe95d246bf2ba48,0x3ff1414a61a136ec,2
+np.float64,0x3f9e575eb83caec0,0x3f9e59a4f17179e3,2
+np.float64,0x3fdb0a20b5b61440,0x3fdcd8a56178a17f,2
+np.float64,0xbfdef425e3bde84c,0xbfe0e33eeacf3861,2
+np.float64,0x3fd6afcf6bad5fa0,0x3fd7b73d47288347,2
+np.float64,0x3fe89256367124ac,0x3ff03dd9f36ce40e,2
+np.float64,0x3fe7e560fcefcac2,0x3feee5ef8688b60b,2
+np.float64,0x3fedef55e1fbdeac,0x3ffb350ee1df986b,2
+np.float64,0xbfe44b926de89725,0xbfe7f3539910c41f,2
+np.float64,0x3fc58310f32b0620,0x3fc5b7cfdba15bd0,2
+np.float64,0x3f736d256026da00,0x3f736d2eebe91a90,2
+np.float64,0x3feb012d2076025a,0x3ff3c0b5d21a7259,2
+np.float64,0xbfe466a6c468cd4e,0xbfe820c9c197601f,2
+np.float64,0x3fe1aba8aa635752,0x3fe3e3b73920f64c,2
+np.float64,0x3fe5597c336ab2f8,0x3fe9c7bc4b765b15,2
+np.float64,0x3fe1004ac5e20096,0x3fe2f12116e99821,2
+np.float64,0x3fecbc67477978ce,0x3ff76377434dbdad,2
+np.float64,0x3fe0e64515e1cc8a,0x3fe2ccf5447c1579,2
+np.float64,0x3febcfa874f79f50,0x3ff54528f0822144,2
+np.float64,0x3fc36915ed26d228,0x3fc38fb5b28d3f72,2
+np.float64,0xbfe01213e5e02428,0xbfe1ac0e1e7418f1,2
+np.float64,0x3fcd97875b3b2f10,0x3fce22fe3fc98702,2
+np.float64,0xbfe30383c5e60708,0xbfe5e427e62cc957,2
+np.float64,0xbfde339bf9bc6738,0xbfe0667f337924f5,2
+np.float64,0xbfda7c1c49b4f838,0xbfdc2c8801ce654a,2
+np.float64,0x3fb6b3489e2d6690,0x3fb6c29650387b92,2
+np.float64,0xbfe1fd4d76e3fa9b,0xbfe45a1f60077678,2
+np.float64,0xbf67c5e0402f8c00,0xbf67c5e49fce115a,2
+np.float64,0xbfd4f9aa2da9f354,0xbfd5c759603d0b9b,2
+np.float64,0x3fe83c227bf07844,0x3fefada9f1bd7fa9,2
+np.float64,0xbf97f717982fee20,0xbf97f836701a8cd5,2
+np.float64,0x3fe9688a2472d114,0x3ff150aa575e7d51,2
+np.float64,0xbfc5a9779d2b52f0,0xbfc5df56509c48b1,2
+np.float64,0xbfe958d5f472b1ac,0xbff13b813f9bee20,2
+np.float64,0xbfd7b3b944af6772,0xbfd8e276c2b2920f,2
+np.float64,0x3fed10198e7a2034,0x3ff8469c817572f0,2
+np.float64,0xbfeeecc4517dd989,0xc000472b1f858be3,2
+np.float64,0xbfdbcce47eb799c8,0xbfddc734aa67812b,2
+np.float64,0xbfd013ee24a027dc,0xbfd06df3089384ca,2
+np.float64,0xbfd215f2bfa42be6,0xbfd29774ffe26a74,2
+np.float64,0x3fdfd0ae67bfa15c,0x3fe1746e3a963a9f,2
+np.float64,0xbfc84aa10b309544,0xbfc896f0d25b723a,2
+np.float64,0xbfcd0c627d3a18c4,0xbfcd9024c73747a9,2
+np.float64,0x3fd87df6dbb0fbec,0x3fd9ce1dde757f31,2
+np.float64,0xbfdad85e05b5b0bc,0xbfdc9c2addb6ce47,2
+np.float64,0xbfee4f8977fc9f13,0xbffcdccd68e514b3,2
+np.float64,0x3fa5c290542b8520,0x3fa5c5ebdf09ca70,2
+np.float64,0xbfd7e401d2afc804,0xbfd91a7e4eb5a026,2
+np.float64,0xbfe33ff73b667fee,0xbfe6423cc6eb07d7,2
+np.float64,0x3fdfb7d6c4bf6fac,0x3fe163f2e8175177,2
+np.float64,0xbfd515d69eaa2bae,0xbfd5e6eedd6a1598,2
+np.float64,0x3fb322232e264440,0x3fb32b49d91c3cbe,2
+np.float64,0xbfe20ac39e641587,0xbfe46dd4b3803f19,2
+np.float64,0x3fe282dc18e505b8,0x3fe520152120c297,2
+np.float64,0xbfc905a4cd320b48,0xbfc95929b74865fb,2
+np.float64,0x3fe0ae3b83615c78,0x3fe27fa1dafc825b,2
+np.float64,0xbfc1bfed0f237fdc,0xbfc1dd6466225cdf,2
+np.float64,0xbfeca4d47d7949a9,0xbff72761a34fb682,2
+np.float64,0xbfe8cf8c48f19f18,0xbff0897ebc003626,2
+np.float64,0xbfe1aaf0a36355e2,0xbfe3e2ae7b17a286,2
+np.float64,0x3fe2ca442e659488,0x3fe58c3a2fb4f14a,2
+np.float64,0xbfda3c2deeb4785c,0xbfdbdf89fe96a243,2
+np.float64,0xbfdc12bfecb82580,0xbfde1d81dea3c221,2
+np.float64,0xbfe2d6d877e5adb1,0xbfe59f73e22c1fc7,2
+np.float64,0x3fe5f930636bf260,0x3feaee96a462e4de,2
+np.float64,0x3fcf3c0ea53e7820,0x3fcfe0b0f92be7e9,2
+np.float64,0xbfa5bb90f42b7720,0xbfa5bee9424004cc,2
+np.float64,0xbfe2fb3a3265f674,0xbfe5d75b988bb279,2
+np.float64,0x3fcaec7aab35d8f8,0x3fcb54ea582fff6f,2
+np.float64,0xbfd8d3228db1a646,0xbfda322297747fbc,2
+np.float64,0x3fedd2e0ad7ba5c2,0x3ffac6002b65c424,2
+np.float64,0xbfd9edeca2b3dbda,0xbfdb81b2b7785e33,2
+np.float64,0xbfef5febb17ebfd7,0xc002796b15950960,2
+np.float64,0x3fde22f787bc45f0,0x3fe05bcc624b9ba2,2
+np.float64,0xbfc716a4ab2e2d48,0xbfc758073839dd44,2
+np.float64,0xbf9bed852837db00,0xbf9bef4b2a3f3bdc,2
+np.float64,0x3fef8f88507f1f10,0x4003e5e566444571,2
+np.float64,0xbfdc1bbed6b8377e,0xbfde28a64e174e60,2
+np.float64,0x3fe02d30eae05a62,0x3fe1d064ec027cd3,2
+np.float64,0x3fd9dbb500b3b76c,0x3fdb6bea40162279,2
+np.float64,0x3fe353ff1d66a7fe,0x3fe661b3358c925e,2
+np.float64,0x3fac3ebfb4387d80,0x3fac4618effff2b0,2
+np.float64,0x3fe63cf0ba6c79e2,0x3feb7030cff5f434,2
+np.float64,0x3fd0e915f8a1d22c,0x3fd152464597b510,2
+np.float64,0xbfd36987cda6d310,0xbfd40af049d7621e,2
+np.float64,0xbfdc5b4dc7b8b69c,0xbfde7790a35da2bc,2
+np.float64,0x3feee7ff4a7dcffe,0x40003545989e07c7,2
+np.float64,0xbfeb2c8308765906,0xbff40d2e6469249e,2
+np.float64,0x3fe535a894ea6b52,0x3fe98781648550d0,2
+np.float64,0xbfef168eb9fe2d1d,0xc000f274ed3cd312,2
+np.float64,0x3fc3e2d98927c5b0,0x3fc40c6991b8900c,2
+np.float64,0xbfcd8fe3e73b1fc8,0xbfce1aec7f9b7f7d,2
+np.float64,0xbfd55d8c3aaabb18,0xbfd6378132ee4892,2
+np.float64,0xbfe424a66168494d,0xbfe7b289d72c98b3,2
+np.float64,0x3fd81af13eb035e4,0x3fd95a6a9696ab45,2
+np.float64,0xbfe3016722e602ce,0xbfe5e0e46db228cd,2
+np.float64,0x3fe9a20beff34418,0x3ff19faca17fc468,2
+np.float64,0xbfe2124bc7e42498,0xbfe478e19927e723,2
+np.float64,0x3fd96f8622b2df0c,0x3fdaeb08da6b08ae,2
+np.float64,0x3fecd6796579acf2,0x3ff7a7d02159e181,2
+np.float64,0x3fe60015df6c002c,0x3feafba6f2682a61,2
+np.float64,0x3fc7181cf72e3038,0x3fc7598c2cc3c3b4,2
+np.float64,0xbfce6e2e0b3cdc5c,0xbfcf0621b3e37115,2
+np.float64,0xbfe52a829e6a5505,0xbfe973a785980af9,2
+np.float64,0x3fed4bbac37a9776,0x3ff8f7a0e68a2bbe,2
+np.float64,0x3fabdfaacc37bf60,0x3fabe6bab42bd246,2
+np.float64,0xbfcd9598cb3b2b30,0xbfce20f3c4c2c261,2
+np.float64,0x3fd717d859ae2fb0,0x3fd82e88eca09ab1,2
+np.float64,0x3fe28ccb18e51996,0x3fe52f071d2694fd,2
+np.float64,0xbfe43f064ae87e0c,0xbfe7de5eab36b5b9,2
+np.float64,0x7fefffffffffffff,0xfff8000000000000,2
+np.float64,0xbfb39b045a273608,0xbfb3a4dd3395fdd5,2
+np.float64,0xbfb3358bae266b18,0xbfb33ece5e95970a,2
+np.float64,0xbfeeafb6717d5f6d,0xbffeec3f9695b575,2
+np.float64,0xbfe7a321afef4644,0xbfee522dd80f41f4,2
+np.float64,0x3fe3a17e5be742fc,0x3fe6dcd32af51e92,2
+np.float64,0xbfc61694bd2c2d28,0xbfc64fbbd835f6e7,2
+np.float64,0xbfd795906faf2b20,0xbfd8bf89b370655c,2
+np.float64,0xbfe4b39b59e96736,0xbfe8a3c5c645b6e3,2
+np.float64,0x3fd310af3ba62160,0x3fd3a9442e825e1c,2
+np.float64,0xbfd45198a6a8a332,0xbfd50bc10311a0a3,2
+np.float64,0x3fd0017eaaa002fc,0x3fd05a472a837999,2
+np.float64,0xbfea974d98752e9b,0xbff30f67f1835183,2
+np.float64,0xbf978f60582f1ec0,0xbf979070e1c2b59d,2
+np.float64,0x3fe1c715d4e38e2c,0x3fe40b479e1241a2,2
+np.float64,0xbfccb965cd3972cc,0xbfcd38b40c4a352d,2
+np.float64,0xbfd9897048b312e0,0xbfdb09d55624c2a3,2
+np.float64,0x3fe7f5de4befebbc,0x3fef0b56be259f9c,2
+np.float64,0x3fcc6c6d4338d8d8,0x3fcce7b20ed68a78,2
+np.float64,0xbfe63884046c7108,0xbfeb67a3b945c3ee,2
+np.float64,0xbfce64e2ad3cc9c4,0xbfcefc47fae2e81f,2
+np.float64,0x3fefeb57b27fd6b0,0x400ab2eac6321cfb,2
+np.float64,0x3fe679627e6cf2c4,0x3febe6451b6ee0c4,2
+np.float64,0x3fc5f710172bee20,0x3fc62f40f85cb040,2
+np.float64,0x3fc34975e52692e8,0x3fc36f58588c7fa2,2
+np.float64,0x3fe8a3784cf146f0,0x3ff052ced9bb9406,2
+np.float64,0x3fd11a607ca234c0,0x3fd1874f876233fe,2
+np.float64,0x3fb2d653f625aca0,0x3fb2df0f4c9633f3,2
+np.float64,0x3fe555f39eeaabe8,0x3fe9c15ee962a28c,2
+np.float64,0xbfea297e3bf452fc,0xbff264107117f709,2
+np.float64,0x3fe1581cdde2b03a,0x3fe36c79acedf99c,2
+np.float64,0x3fd4567063a8ace0,0x3fd51123dbd9106f,2
+np.float64,0x3fa3883aec271080,0x3fa38aa86ec71218,2
+np.float64,0x3fe40e5d7de81cba,0x3fe78dbb9b568850,2
+np.float64,0xbfe9a2f7347345ee,0xbff1a0f4faa05041,2
+np.float64,0x3f9eef03a83dde00,0x3f9ef16caa0c1478,2
+np.float64,0xbfcb4641d1368c84,0xbfcbb2e7ff8c266d,2
+np.float64,0xbfa8403b2c308070,0xbfa844e148b735b7,2
+np.float64,0xbfe1875cd6e30eba,0xbfe3afadc08369f5,2
+np.float64,0xbfdd3c3d26ba787a,0xbfdf919b3e296766,2
+np.float64,0x3fcd6c4c853ad898,0x3fcdf55647b518b8,2
+np.float64,0xbfe360a173e6c143,0xbfe6759eb3a08cf2,2
+np.float64,0x3fe5a13147eb4262,0x3fea4a5a060f5adb,2
+np.float64,0x3feb3cdd7af679ba,0x3ff42aae0cf61234,2
+np.float64,0x3fe5205128ea40a2,0x3fe9618f3d0c54af,2
+np.float64,0x3fce35343f3c6a68,0x3fcec9c4e612b050,2
+np.float64,0xbfc345724d268ae4,0xbfc36b3ce6338e6a,2
+np.float64,0x3fedc4fc0e7b89f8,0x3ffa91c1d775c1f7,2
+np.float64,0x3fe41fbf21683f7e,0x3fe7aa6c174a0e65,2
+np.float64,0xbfc7a1a5d32f434c,0xbfc7e7d27a4c5241,2
+np.float64,0x3fd3e33eaca7c67c,0x3fd4915264441e2f,2
+np.float64,0x3feb3f02f6f67e06,0x3ff42e942249e596,2
+np.float64,0x3fdb75fcb0b6ebf8,0x3fdd5c63f98b6275,2
+np.float64,0x3fd6476603ac8ecc,0x3fd74020b164cf38,2
+np.float64,0x3fed535372faa6a6,0x3ff90f3791821841,2
+np.float64,0x3fe8648ead70c91e,0x3ff006a62befd7ed,2
+np.float64,0x3fd0f90760a1f210,0x3fd1636b39bb1525,2
+np.float64,0xbfca052443340a48,0xbfca633d6e777ae0,2
+np.float64,0xbfa6a5e3342d4bc0,0xbfa6a9ac6a488f5f,2
+np.float64,0x3fd5598038aab300,0x3fd632f35c0c3d52,2
+np.float64,0xbfdf66218fbecc44,0xbfe12df83b19f300,2
+np.float64,0x3fe78e15b56f1c2c,0x3fee240d12489cd1,2
+np.float64,0x3fe3d6a7b3e7ad50,0x3fe7329dcf7401e2,2
+np.float64,0xbfddb8e97bbb71d2,0xbfe017ed6d55a673,2
+np.float64,0xbfd57afd55aaf5fa,0xbfd658a9607c3370,2
+np.float64,0xbfdba4c9abb74994,0xbfdd95d69e5e8814,2
+np.float64,0xbfe71d8090ee3b01,0xbfed3390be6d2eef,2
+np.float64,0xbfc738ac0f2e7158,0xbfc77b3553b7c026,2
+np.float64,0x3f873656302e6c80,0x3f873697556ae011,2
+np.float64,0x3fe559491d6ab292,0x3fe9c7603b12c608,2
+np.float64,0xbfe262776864c4ef,0xbfe4ef905dda8599,2
+np.float64,0x3fe59d8917eb3b12,0x3fea439f44b7573f,2
+np.float64,0xbfd4b5afb5a96b60,0xbfd57b4e3df4dbc8,2
+np.float64,0x3fe81158447022b0,0x3fef4a3cea3eb6a9,2
+np.float64,0xbfeb023441f60468,0xbff3c27f0fc1a4dc,2
+np.float64,0x3fefb212eaff6426,0x40055fc6d949cf44,2
+np.float64,0xbfe1300ac1e26016,0xbfe333f297a1260e,2
+np.float64,0xbfeae0a2f575c146,0xbff388d58c380b8c,2
+np.float64,0xbfeddd8e55fbbb1d,0xbffaef045b2e21d9,2
+np.float64,0x3fec7c6c1d78f8d8,0x3ff6c3ebb019a8e5,2
+np.float64,0xbfe27e071f64fc0e,0xbfe518d2ff630f33,2
+np.float64,0x8000000000000001,0x8000000000000001,2
+np.float64,0x3fc5872abf2b0e58,0x3fc5bc083105db76,2
+np.float64,0x3fe65114baeca22a,0x3feb9745b82ef15a,2
+np.float64,0xbfc783abe52f0758,0xbfc7c8cb23f93e79,2
+np.float64,0x3fe4b7a5dd696f4c,0x3fe8aab9d492f0ca,2
+np.float64,0xbf91a8e8a82351e0,0xbf91a95b6ae806f1,2
+np.float64,0xbfee482eb77c905d,0xbffcb952830e715a,2
+np.float64,0x3fba0eee2a341de0,0x3fba261d495e3a1b,2
+np.float64,0xbfeb8876ae7710ed,0xbff4b7f7f4343506,2
+np.float64,0xbfe4d29e46e9a53c,0xbfe8d9547a601ba7,2
+np.float64,0xbfe12413b8e24828,0xbfe3232656541d10,2
+np.float64,0x3fc0bd8f61217b20,0x3fc0d63f937f0aa4,2
+np.float64,0xbfd3debafda7bd76,0xbfd48c534e5329e4,2
+np.float64,0x3fc0f92de921f258,0x3fc112eb7d47349b,2
+np.float64,0xbfe576b95f6aed72,0xbfe9fca859239b3c,2
+np.float64,0x3fd10e520da21ca4,0x3fd17a546e4152f7,2
+np.float64,0x3fcef917eb3df230,0x3fcf998677a8fa8f,2
+np.float64,0x3fdfcf863abf9f0c,0x3fe173a98af1cb13,2
+np.float64,0x3fc28c4b4f251898,0x3fc2adf43792e917,2
+np.float64,0x3fceb837ad3d7070,0x3fcf54a63b7d8c5c,2
+np.float64,0x3fc0140a05202818,0x3fc029e4f75330cb,2
+np.float64,0xbfd76c3362aed866,0xbfd88fb9e790b4e8,2
+np.float64,0xbfe475300868ea60,0xbfe8395334623e1f,2
+np.float64,0x3fea70b9b4f4e174,0x3ff2d1dad92173ba,2
+np.float64,0xbfe2edbd4965db7a,0xbfe5c29449a9365d,2
+np.float64,0xbfddf86f66bbf0de,0xbfe0408439cada9b,2
+np.float64,0xbfb443cdfa288798,0xbfb44eae796ad3ea,2
+np.float64,0xbf96a8a0482d5140,0xbf96a992b6ef073b,2
+np.float64,0xbfd279db2fa4f3b6,0xbfd3043db6acbd9e,2
+np.float64,0x3fe5d99088ebb322,0x3feab30be14e1605,2
+np.float64,0xbfe1a917abe35230,0xbfe3e0063d0f5f63,2
+np.float64,0x3fc77272f52ee4e8,0x3fc7b6f8ab6f4591,2
+np.float64,0x3fd6b62146ad6c44,0x3fd7be77eef8390a,2
+np.float64,0xbfe39fd9bc673fb4,0xbfe6da30dc4eadde,2
+np.float64,0x3fe35545c066aa8c,0x3fe663b5873e4d4b,2
+np.float64,0xbfcbbeffb3377e00,0xbfcc317edf7f6992,2
+np.float64,0xbfe28a58366514b0,0xbfe52b5734579ffa,2
+np.float64,0xbfbf0c87023e1910,0xbfbf33d970a0dfa5,2
+np.float64,0xbfd31144cba6228a,0xbfd3a9e84f9168f9,2
+np.float64,0xbfe5c044056b8088,0xbfea83d607c1a88a,2
+np.float64,0x3fdaabdf18b557c0,0x3fdc663ee8eddc83,2
+np.float64,0xbfeb883006f71060,0xbff4b76feff615be,2
+np.float64,0xbfebaef41d775de8,0xbff5034111440754,2
+np.float64,0x3fd9b6eb3bb36dd8,0x3fdb3fff5071dacf,2
+np.float64,0x3fe4e33c45e9c678,0x3fe8f637779ddedf,2
+np.float64,0x3fe52213a06a4428,0x3fe964adeff5c14e,2
+np.float64,0x3fe799254cef324a,0x3fee3c3ecfd3cdc5,2
+np.float64,0x3fd0533f35a0a680,0x3fd0b19a003469d3,2
+np.float64,0x3fec7ef5c7f8fdec,0x3ff6ca0abe055048,2
+np.float64,0xbfd1b5da82a36bb6,0xbfd22f357acbee79,2
+np.float64,0xbfd8f9c652b1f38c,0xbfda5faacbce9cf9,2
+np.float64,0x3fc8fc818b31f900,0x3fc94fa9a6aa53c8,2
+np.float64,0x3fcf42cc613e8598,0x3fcfe7dc128f33f2,2
+np.float64,0x3fd393a995a72754,0x3fd4396127b19305,2
+np.float64,0x3fec7b7df9f8f6fc,0x3ff6c1ae51753ef2,2
+np.float64,0x3fc07f175b20fe30,0x3fc096b55c11568c,2
+np.float64,0xbf979170082f22e0,0xbf979280d9555f44,2
+np.float64,0xbfb9d110c633a220,0xbfb9e79ba19b3c4a,2
+np.float64,0x3fedcd7d417b9afa,0x3ffab19734e86d58,2
+np.float64,0xbfec116f27f822de,0xbff5cf9425cb415b,2
+np.float64,0xbfec4fa0bef89f42,0xbff65a771982c920,2
+np.float64,0x3f94d4452829a880,0x3f94d501789ad11c,2
+np.float64,0xbfefe5ede27fcbdc,0xc009c440d3c2a4ce,2
+np.float64,0xbfe7e5f7b5efcbf0,0xbfeee74449aee1db,2
+np.float64,0xbfeb71dc8976e3b9,0xbff48cd84ea54ed2,2
+np.float64,0xbfe4cdb65f699b6c,0xbfe8d0d3bce901ef,2
+np.float64,0x3fb78ef1ee2f1de0,0x3fb7a00e7d183c48,2
+np.float64,0x3fb681864a2d0310,0x3fb6906fe64b4cd7,2
+np.float64,0xbfd2ad3b31a55a76,0xbfd33c57b5985399,2
+np.float64,0x3fdcdaaa95b9b554,0x3fdf16b99628db1e,2
+np.float64,0x3fa4780b7428f020,0x3fa47ad6ce9b8081,2
+np.float64,0x3fc546b0ad2a8d60,0x3fc579b361b3b18f,2
+np.float64,0x3feaf98dd6f5f31c,0x3ff3b38189c3539c,2
+np.float64,0x3feb0b2eca76165e,0x3ff3d22797083f9a,2
+np.float64,0xbfdc02ae3ab8055c,0xbfde099ecb5dbacf,2
+np.float64,0x3fd248bf17a49180,0x3fd2ceb77b346d1d,2
+np.float64,0x3fe349d666e693ac,0x3fe651b9933a8853,2
+np.float64,0xbfca526fc534a4e0,0xbfcab3e83f0d9b93,2
+np.float64,0x3fc156421722ac88,0x3fc171b38826563b,2
+np.float64,0xbfe4244569e8488b,0xbfe7b1e93e7d4f92,2
+np.float64,0x3fe010faabe021f6,0x3fe1aa961338886d,2
+np.float64,0xbfc52dacb72a5b58,0xbfc55ffa50eba380,2
+np.float64,0x8000000000000000,0x8000000000000000,2
+np.float64,0x3fea1d4865f43a90,0x3ff251b839eb4817,2
+np.float64,0xbfa0f65c8421ecc0,0xbfa0f7f37c91be01,2
+np.float64,0x3fcab29c0b356538,0x3fcb1863edbee184,2
+np.float64,0x3fe7949162ef2922,0x3fee323821958b88,2
+np.float64,0x3fdaf9288ab5f250,0x3fdcc400190a4839,2
+np.float64,0xbfe13ece6be27d9d,0xbfe348ba07553179,2
+np.float64,0x3f8a0c4fd0341880,0x3f8a0cabdf710185,2
+np.float64,0x3fdd0442a2ba0884,0x3fdf4b016c4da452,2
+np.float64,0xbfaf06d2343e0da0,0xbfaf1090b1600422,2
+np.float64,0xbfd3b65225a76ca4,0xbfd45fa49ae76cca,2
+np.float64,0x3fef5d75fefebaec,0x400269a5e7c11891,2
+np.float64,0xbfe048e35ce091c6,0xbfe1f5af45dd64f8,2
+np.float64,0xbfe27d4599e4fa8b,0xbfe517b07843d04c,2
+np.float64,0xbfe6f2a637ede54c,0xbfecdaa730462576,2
+np.float64,0x3fc63fbb752c7f78,0x3fc67a2854974109,2
+np.float64,0x3fedda6bfbfbb4d8,0x3ffae2e6131f3475,2
+np.float64,0x3fe7a6f5286f4dea,0x3fee5a9b1ef46016,2
+np.float64,0xbfd4ea8bcea9d518,0xbfd5b66ab7e5cf00,2
+np.float64,0x3fdc116568b822cc,0x3fde1bd4d0d9fd6c,2
+np.float64,0x3fdc45cb1bb88b98,0x3fde5cd1d2751032,2
+np.float64,0x3feabd932f757b26,0x3ff34e06e56a62a1,2
+np.float64,0xbfae5dbe0c3cbb80,0xbfae66e062ac0d65,2
+np.float64,0xbfdb385a00b670b4,0xbfdd10fedf3a58a7,2
+np.float64,0xbfebb14755f7628f,0xbff507e123a2b47c,2
+np.float64,0x3fe6de2fdfedbc60,0x3fecb0ae6e131da2,2
+np.float64,0xbfd86de640b0dbcc,0xbfd9bb4dbf0bf6af,2
+np.float64,0x3fe39e86d9e73d0e,0x3fe6d811c858d5d9,2
+np.float64,0x7ff0000000000000,0xfff8000000000000,2
+np.float64,0x3fa8101684302020,0x3fa814a12176e937,2
+np.float64,0x3fefdd5ad37fbab6,0x4008a08c0b76fbb5,2
+np.float64,0x3fe645c727ec8b8e,0x3feb814ebc470940,2
+np.float64,0x3fe3ba79dce774f4,0x3fe70500db564cb6,2
+np.float64,0xbfe0e5a254e1cb44,0xbfe2cc13940c6d9a,2
+np.float64,0x3fe2cac62465958c,0x3fe58d008c5e31f8,2
+np.float64,0xbfd3ffb531a7ff6a,0xbfd4b0d88cff2040,2
+np.float64,0x3fe0929104612522,0x3fe259bc42dce788,2
+np.float64,0x1,0x1,2
+np.float64,0xbfe7db77e6efb6f0,0xbfeecf93e8a61cb3,2
+np.float64,0xbfe37e9559e6fd2a,0xbfe6a514e29cb7aa,2
+np.float64,0xbfc53a843f2a7508,0xbfc56d2e9ad8b716,2
+np.float64,0xbfedb04485fb6089,0xbffa4615d4334ec3,2
+np.float64,0xbfc44349b1288694,0xbfc46f484b6f1cd6,2
+np.float64,0xbfe265188264ca31,0xbfe4f37d61cd9e17,2
+np.float64,0xbfd030351da0606a,0xbfd08c2537287ee1,2
+np.float64,0x3fd8fb131db1f628,0x3fda613363ca601e,2
+np.float64,0xbff0000000000000,0xfff0000000000000,2
+np.float64,0xbfe48d9a60691b35,0xbfe862c02d8fec1e,2
+np.float64,0x3fd185e050a30bc0,0x3fd1fb4c614ddb07,2
+np.float64,0xbfe4a5807e694b01,0xbfe88b8ff2d6caa7,2
+np.float64,0xbfc934d7ad3269b0,0xbfc98a405d25a666,2
+np.float64,0xbfea0e3c62741c79,0xbff23b4bd3a7b15d,2
+np.float64,0x3fe7244071ee4880,0x3fed41b27ba6bb22,2
+np.float64,0xbfd419f81ba833f0,0xbfd4cdf71b4533a3,2
+np.float64,0xbfe1e73a34e3ce74,0xbfe439eb15fa6baf,2
+np.float64,0x3fcdd9a63f3bb350,0x3fce68e1c401eff0,2
+np.float64,0x3fd1b5960ba36b2c,0x3fd22eeb566f1976,2
+np.float64,0x3fe9ad18e0735a32,0x3ff1af23c534260d,2
+np.float64,0xbfd537918aaa6f24,0xbfd60ccc8df0962b,2
+np.float64,0x3fcba3d3c73747a8,0x3fcc14fd5e5c49ad,2
+np.float64,0x3fd367e3c0a6cfc8,0x3fd40921b14e288e,2
+np.float64,0x3fe94303c6f28608,0x3ff11e62db2db6ac,2
+np.float64,0xbfcc5f77fd38bef0,0xbfccda110c087519,2
+np.float64,0xbfd63b74d7ac76ea,0xbfd7328af9f37402,2
+np.float64,0xbfe5321289ea6425,0xbfe9811ce96609ad,2
+np.float64,0xbfde910879bd2210,0xbfe0a2cd0ed1d368,2
+np.float64,0xbfcc9d9bad393b38,0xbfcd1b722a0b1371,2
+np.float64,0xbfe6dd39e16dba74,0xbfecaeb7c8c069f6,2
+np.float64,0xbfe98316eff3062e,0xbff174d7347d48bf,2
+np.float64,0xbfda88f8d1b511f2,0xbfdc3c0e75dad903,2
+np.float64,0x3fd400d8c2a801b0,0x3fd4b21bacff1f5d,2
+np.float64,0xbfe1ed335863da66,0xbfe4429e45e99779,2
+np.float64,0xbf3423a200284800,0xbf3423a20acb0342,2
+np.float64,0xbfe97bc59672f78b,0xbff16ad1adc44a33,2
+np.float64,0xbfeeca60d7fd94c2,0xbfff98d7f18f7728,2
+np.float64,0x3fd1eb13b2a3d628,0x3fd268e6ff4d56ce,2
+np.float64,0xbfa5594c242ab2a0,0xbfa55c77d6740a39,2
+np.float64,0x3fe72662006e4cc4,0x3fed462a9dedbfee,2
+np.float64,0x3fef4bb221fe9764,0x4001fe4f4cdfedb2,2
+np.float64,0xbfe938d417f271a8,0xbff110e78724ca2b,2
+np.float64,0xbfcc29ab2f385358,0xbfcca182140ef541,2
+np.float64,0x3fe18cd42c6319a8,0x3fe3b77e018165e7,2
+np.float64,0xbfec6c5cae78d8b9,0xbff69d8e01309b48,2
+np.float64,0xbfd5723da7aae47c,0xbfd64ecde17da471,2
+np.float64,0xbfe3096722e612ce,0xbfe5ed43634f37ff,2
+np.float64,0xbfdacaceb1b5959e,0xbfdc8bb826bbed39,2
+np.float64,0x3fc59a57cb2b34b0,0x3fc5cfc4a7c9bac8,2
+np.float64,0x3f84adce10295b80,0x3f84adfc1f1f6e97,2
+np.float64,0x3fdd5b28bbbab650,0x3fdfb8b906d77df4,2
+np.float64,0x3fdebf94c6bd7f28,0x3fe0c10188e1bc7c,2
+np.float64,0x3fdb30c612b6618c,0x3fdd07bf18597821,2
+np.float64,0x3fe7eeb3176fdd66,0x3feefb0be694b855,2
+np.float64,0x0,0x0,2
+np.float64,0xbfe10057e9e200b0,0xbfe2f13365e5b1c9,2
+np.float64,0xbfeb61a82376c350,0xbff46e665d3a60f5,2
+np.float64,0xbfe7f54aec6fea96,0xbfef0a0759f726dc,2
+np.float64,0xbfe4f6da3de9edb4,0xbfe9187d85bd1ab5,2
+np.float64,0xbfeb8be1b3f717c4,0xbff4be8efaab2e75,2
+np.float64,0x3fed40bc31fa8178,0x3ff8d5ec4a7f3e9b,2
+np.float64,0xbfe40f8711681f0e,0xbfe78fa5c62b191b,2
+np.float64,0x3fd1034d94a2069c,0x3fd16e78e9efb85b,2
+np.float64,0x3fc74db15b2e9b60,0x3fc790f26e894098,2
+np.float64,0x3fd912a88cb22550,0x3fda7d0ab3b21308,2
+np.float64,0x3fd8948a3bb12914,0x3fd9e8950c7874c8,2
+np.float64,0xbfa7ada5242f5b50,0xbfa7b1f8db50c104,2
+np.float64,0x3feeb2e1c27d65c4,0x3fff000b7d09c9b7,2
+np.float64,0x3fe9d46cbbf3a8da,0x3ff1e6f405265a6e,2
+np.float64,0xbfe2480b77e49017,0xbfe4c83b9b37bf0c,2
+np.float64,0x3fe950ea9372a1d6,0x3ff130e62468bf2c,2
+np.float64,0x3fefa7272a7f4e4e,0x4004d8c9bf31ab58,2
+np.float64,0xbfe7309209ee6124,0xbfed5b94acef917a,2
+np.float64,0x3fd05e8c64a0bd18,0x3fd0bdb11e0903c6,2
+np.float64,0x3fd9236043b246c0,0x3fda90ccbe4bab1e,2
+np.float64,0xbfdc3d6805b87ad0,0xbfde5266e17154c3,2
+np.float64,0x3fe5e6bad76bcd76,0x3feacbc306c63445,2
+np.float64,0x3ff0000000000000,0x7ff0000000000000,2
+np.float64,0xbfde3d7390bc7ae8,0xbfe06cd480bd0196,2
+np.float64,0xbfd3e2e3c0a7c5c8,0xbfd490edc0a45e26,2
+np.float64,0x3fe39871d76730e4,0x3fe6ce54d1719953,2
+np.float64,0x3fdff00ebcbfe01c,0x3fe1894b6655a6d0,2
+np.float64,0x3f91b7ad58236f40,0x3f91b8213bcb8b0b,2
+np.float64,0xbfd99f48f7b33e92,0xbfdb23d544f62591,2
+np.float64,0x3fae3512cc3c6a20,0x3fae3e10939fd7b5,2
+np.float64,0x3fcc4cf3db3899e8,0x3fccc698a15176d6,2
+np.float64,0xbfd0927e39a124fc,0xbfd0f5522e2bc030,2
+np.float64,0x3fcee859633dd0b0,0x3fcf87bdef7a1e82,2
+np.float64,0xbfe2a8b69565516d,0xbfe5593437b6659a,2
+np.float64,0x3fecf61e20f9ec3c,0x3ff7fda16b0209d4,2
+np.float64,0xbfbf37571e3e6eb0,0xbfbf5f4e1379a64c,2
+np.float64,0xbfd54e1b75aa9c36,0xbfd626223b68971a,2
+np.float64,0x3fe1035a56e206b4,0x3fe2f5651ca0f4b0,2
+np.float64,0x3fe4992989e93254,0x3fe876751afa70dc,2
+np.float64,0x3fc8c313d3318628,0x3fc913faf15d1562,2
+np.float64,0x3f99f6ba8833ed80,0x3f99f8274fb94828,2
+np.float64,0xbfd4a58af0a94b16,0xbfd56947c276e04f,2
+np.float64,0x3fc66f8c872cdf18,0x3fc6ab7a14372a73,2
+np.float64,0x3fc41eee0d283de0,0x3fc449ff1ff0e7a6,2
+np.float64,0x3fefd04d287fa09a,0x4007585010cfa9b0,2
+np.float64,0x3fce9e746f3d3ce8,0x3fcf39514bbe5070,2
+np.float64,0xbfe8056f72700adf,0xbfef2ee2c13e67ba,2
+np.float64,0x3fdd6b1ec0bad63c,0x3fdfccf2ba144fa8,2
+np.float64,0x3fd92ee432b25dc8,0x3fda9e6b96b2b142,2
+np.float64,0xbfc4d18f9529a320,0xbfc50150fb4de0cc,2
+np.float64,0xbfe09939a7613274,0xbfe262d703c317af,2
+np.float64,0xbfd130b132a26162,0xbfd19f5a00ae29c4,2
+np.float64,0x3fa06e21d420dc40,0x3fa06f93aba415fb,2
+np.float64,0x3fc5c48fbd2b8920,0x3fc5fb3bfad3bf55,2
+np.float64,0xbfdfa2bacbbf4576,0xbfe155f839825308,2
+np.float64,0x3fe3e1fa0f67c3f4,0x3fe745081dd4fd03,2
+np.float64,0x3fdae58289b5cb04,0x3fdcac1f6789130a,2
+np.float64,0xbf8ed3ba103da780,0xbf8ed452a9cc1442,2
+np.float64,0xbfec06b46f780d69,0xbff5b86f30d70908,2
+np.float64,0xbfe990c13b732182,0xbff187a90ae611f8,2
+np.float64,0xbfdd46c738ba8d8e,0xbfdf9eee0a113230,2
+np.float64,0x3fe08b83f3611708,0x3fe2501b1c77035c,2
+np.float64,0xbfd501b65baa036c,0xbfd5d05de3fceac8,2
+np.float64,0xbfcf4fa21f3e9f44,0xbfcff5829582c0b6,2
+np.float64,0xbfefbc0bfbff7818,0xc005eca1a2c56b38,2
+np.float64,0xbfe1ba6959e374d2,0xbfe3f8f88d128ce5,2
+np.float64,0xbfd4e74ee3a9ce9e,0xbfd5b2cabeb45e6c,2
+np.float64,0xbfe77c38eaeef872,0xbfedfd332d6f1c75,2
+np.float64,0x3fa9b5e4fc336bc0,0x3fa9bb6f6b80b4af,2
+np.float64,0xbfecba63917974c7,0xbff75e44df7f8e81,2
+np.float64,0x3fd6cf17b2ad9e30,0x3fd7db0b93b7f2b5,2
diff --git a/numpy/core/tests/data/umath-validation-set-cbrt.csv b/numpy/core/tests/data/umath-validation-set-cbrt.csv
new file mode 100644
index 000000000..ad141cb4f
--- /dev/null
+++ b/numpy/core/tests/data/umath-validation-set-cbrt.csv
@@ -0,0 +1,1429 @@
+dtype,input,output,ulperrortol
+np.float32,0x3ee7054c,0x3f4459ea,2
+np.float32,0x7d1e2489,0x54095925,2
+np.float32,0x7ee5edf5,0x549b992b,2
+np.float32,0x380607,0x2a425e72,2
+np.float32,0x34a8f3,0x2a3e6603,2
+np.float32,0x3eee2844,0x3f465a45,2
+np.float32,0x59e49c,0x2a638d0a,2
+np.float32,0xbf72c77a,0xbf7b83d4,2
+np.float32,0x7f2517b4,0x54af8bf0,2
+np.float32,0x80068a69,0xa9bdfe8b,2
+np.float32,0xbe8e3578,0xbf270775,2
+np.float32,0xbe4224dc,0xbf131119,2
+np.float32,0xbe0053b8,0xbf001be2,2
+np.float32,0x70e8d,0x29c2ddc5,2
+np.float32,0xff63f7b5,0xd4c37b7f,2
+np.float32,0x3f00bbed,0x3f4b9335,2
+np.float32,0x3f135f4e,0x3f54f5d4,2
+np.float32,0xbe13a488,0xbf063d13,2
+np.float32,0x3f14ec78,0x3f55b478,2
+np.float32,0x7ec35cfb,0x54935fbf,2
+np.float32,0x7d41c589,0x5412f904,2
+np.float32,0x3ef8a16e,0x3f4937f7,2
+np.float32,0x3f5d8464,0x3f73f279,2
+np.float32,0xbeec85ac,0xbf45e5cb,2
+np.float32,0x7f11f722,0x54a87cb1,2
+np.float32,0x8032c085,0xaa3c1219,2
+np.float32,0x80544bac,0xaa5eb9f2,2
+np.float32,0x3e944a10,0x3f296065,2
+np.float32,0xbf29fe50,0xbf5f5796,2
+np.float32,0x7e204d8d,0x545b03d5,2
+np.float32,0xfe1d0254,0xd4598127,2
+np.float32,0x80523129,0xaa5cdba9,2
+np.float32,0x806315fa,0xaa6b0eaf,2
+np.float32,0x3ed3d2a4,0x3f3ec117,2
+np.float32,0x7ee15007,0x549a8cc0,2
+np.float32,0x801ffb5e,0xaa213d4f,2
+np.float32,0x807f9f4a,0xaa7fbf76,2
+np.float32,0xbe45e854,0xbf1402d3,2
+np.float32,0x3d9e2e70,0x3eda0b64,2
+np.float32,0x51f404,0x2a5ca4d7,2
+np.float32,0xbe26a8b0,0xbf0bc54d,2
+np.float32,0x22c99a,0x2a25d2a7,2
+np.float32,0xbf71248b,0xbf7af2d5,2
+np.float32,0x7219fe,0x2a76608e,2
+np.float32,0x7f16fd7d,0x54aa6610,2
+np.float32,0x80716faa,0xaa75e5b9,2
+np.float32,0xbe24f9a4,0xbf0b4c65,2
+np.float32,0x800000,0x2a800000,2
+np.float32,0x80747456,0xaa780f27,2
+np.float32,0x68f9e8,0x2a6fa035,2
+np.float32,0x3f6a297e,0x3f7880d8,2
+np.float32,0x3f28b973,0x3f5ec8f6,2
+np.float32,0x7f58c577,0x54c03a70,2
+np.float32,0x804befcc,0xaa571b4f,2
+np.float32,0x3e2be027,0x3f0d36cf,2
+np.float32,0xfe7e80a4,0xd47f7ff7,2
+np.float32,0xfe9d444a,0xd489181b,2
+np.float32,0x3db3e790,0x3ee399d6,2
+np.float32,0xbf154c3e,0xbf55e23e,2
+np.float32,0x3d1096b7,0x3ea7f4aa,2
+np.float32,0x7fc00000,0x7fc00000,2
+np.float32,0x804e2521,0xaa592c06,2
+np.float32,0xbeda2f00,0xbf40a513,2
+np.float32,0x3f191788,0x3f57ae30,2
+np.float32,0x3ed24ade,0x3f3e4b34,2
+np.float32,0x807fadb4,0xaa7fc917,2
+np.float32,0xbe0a06dc,0xbf034234,2
+np.float32,0x3f250bba,0x3f5d276d,2
+np.float32,0x7e948b00,0x548682c8,2
+np.float32,0xfe65ecdc,0xd476fed2,2
+np.float32,0x6fdbdd,0x2a74c095,2
+np.float32,0x800112de,0xa9500fa6,2
+np.float32,0xfe63225c,0xd475fdee,2
+np.float32,0x7f3d9acd,0x54b7d648,2
+np.float32,0xfc46f480,0xd3bacf87,2
+np.float32,0xfe5deaac,0xd47417ff,2
+np.float32,0x60ce53,0x2a693d93,2
+np.float32,0x6a6e2f,0x2a70ba2c,2
+np.float32,0x7f43f0f1,0x54b9dcd0,2
+np.float32,0xbf6170c9,0xbf756104,2
+np.float32,0xbe5c9f74,0xbf197852,2
+np.float32,0xff1502b0,0xd4a9a693,2
+np.float32,0x8064f6af,0xaa6c886e,2
+np.float32,0xbf380564,0xbf6552e5,2
+np.float32,0xfeb9b7dc,0xd490e85f,2
+np.float32,0x7f34f941,0x54b5010d,2
+np.float32,0xbe9d4ca0,0xbf2cbd5f,2
+np.float32,0x3f6e43d2,0x3f79f240,2
+np.float32,0xbdad0530,0xbee0a8f2,2
+np.float32,0x3da18459,0x3edb9105,2
+np.float32,0xfd968340,0xd42a3808,2
+np.float32,0x3ea03e64,0x3f2dcf96,2
+np.float32,0x801d2f5b,0xaa1c6525,2
+np.float32,0xbf47d92d,0xbf6bb7e9,2
+np.float32,0x55a6b9,0x2a5fe9fb,2
+np.float32,0x77a7c2,0x2a7a4fb8,2
+np.float32,0xfebbc16e,0xd4916f88,2
+np.float32,0x3f5d3d6e,0x3f73d86a,2
+np.float32,0xfccd2b60,0xd3edcacb,2
+np.float32,0xbd026460,0xbea244b0,2
+np.float32,0x3e55bd,0x2a4968e4,2
+np.float32,0xbe7b5708,0xbf20490d,2
+np.float32,0xfe413cf4,0xd469171f,2
+np.float32,0x7710e3,0x2a79e657,2
+np.float32,0xfc932520,0xd3d4d9ca,2
+np.float32,0xbf764a1b,0xbf7cb8aa,2
+np.float32,0x6b1923,0x2a713aca,2
+np.float32,0xfe4dcd04,0xd46e092d,2
+np.float32,0xff3085ac,0xd4b381f8,2
+np.float32,0x3f72c438,0x3f7b82b4,2
+np.float32,0xbf6f0c6e,0xbf7a3852,2
+np.float32,0x801d2b1b,0xaa1c5d8d,2
+np.float32,0x3e9db91e,0x3f2ce50d,2
+np.float32,0x3f684f9d,0x3f77d8c5,2
+np.float32,0x7dc784,0x2a7e82cc,2
+np.float32,0x7d2c88e9,0x540d64f8,2
+np.float32,0x807fb708,0xaa7fcf51,2
+np.float32,0x8003c49a,0xa99e16e0,2
+np.float32,0x3ee4f5b8,0x3f43c3ff,2
+np.float32,0xfe992c5e,0xd487e4ec,2
+np.float32,0x4b4dfa,0x2a568216,2
+np.float32,0x3d374c80,0x3eb5c6a8,2
+np.float32,0xbd3a4700,0xbeb6c15c,2
+np.float32,0xbf13cb80,0xbf5529e5,2
+np.float32,0xbe7306d4,0xbf1e7f91,2
+np.float32,0xbf800000,0xbf800000,2
+np.float32,0xbea42efe,0xbf2f394e,2
+np.float32,0x3e1981d0,0x3f07fe2c,2
+np.float32,0x3f17ea1d,0x3f572047,2
+np.float32,0x7dc1e0,0x2a7e7efe,2
+np.float32,0x80169c08,0xaa0fa320,2
+np.float32,0x3f3e1972,0x3f67d248,2
+np.float32,0xfe5d3c88,0xd473d815,2
+np.float32,0xbf677448,0xbf778aac,2
+np.float32,0x7e799b7d,0x547dd9e4,2
+np.float32,0x3f00bb2c,0x3f4b92cf,2
+np.float32,0xbeb29f9c,0xbf343798,2
+np.float32,0xbd6b7830,0xbec59a86,2
+np.float32,0x807a524a,0xaa7c282a,2
+np.float32,0xbe0a7a04,0xbf0366ab,2
+np.float32,0x80237470,0xaa26e061,2
+np.float32,0x3ccbc0f6,0x3e95744f,2
+np.float32,0x3edec6bc,0x3f41fcb6,2
+np.float32,0x3f635198,0x3f760efa,2
+np.float32,0x800eca4f,0xa9f960d8,2
+np.float32,0x3f800000,0x3f800000,2
+np.float32,0xff4eeb9e,0xd4bd456a,2
+np.float32,0x56f4e,0x29b29e70,2
+np.float32,0xff5383a0,0xd4bea95c,2
+np.float32,0x3f4c3a77,0x3f6d6d94,2
+np.float32,0x3f6c324a,0x3f79388c,2
+np.float32,0xbebdc092,0xbf37e27c,2
+np.float32,0xff258956,0xd4afb42e,2
+np.float32,0xdc78c,0x29f39012,2
+np.float32,0xbf2db06a,0xbf60f2f5,2
+np.float32,0xbe3c5808,0xbf119660,2
+np.float32,0xbf1ba866,0xbf58e0f4,2
+np.float32,0x80377640,0xaa41b79d,2
+np.float32,0x4fdc4d,0x2a5abfea,2
+np.float32,0x7f5e7560,0x54c1e516,2
+np.float32,0xfeb4d3f2,0xd48f9fde,2
+np.float32,0x3f12a622,0x3f549c7d,2
+np.float32,0x7f737ed7,0x54c7d2dc,2
+np.float32,0xa0ddc,0x29db456d,2
+np.float32,0xfe006740,0xd44b6689,2
+np.float32,0x3f17dfd4,0x3f571b6c,2
+np.float32,0x67546e,0x2a6e5dd1,2
+np.float32,0xff0d0f11,0xd4a693e2,2
+np.float32,0xbd170090,0xbeaa6738,2
+np.float32,0x5274a0,0x2a5d1806,2
+np.float32,0x3e154fe0,0x3f06be1a,2
+np.float32,0x7ddb302e,0x5440f0a7,2
+np.float32,0x3f579d10,0x3f71c2af,2
+np.float32,0xff2bc5bb,0xd4b1e20c,2
+np.float32,0xfee8fa6a,0xd49c4872,2
+np.float32,0xbea551b0,0xbf2fa07b,2
+np.float32,0xfeabc75c,0xd48d3004,2
+np.float32,0x7f50a5a8,0x54bdcbd1,2
+np.float32,0x50354b,0x2a5b110d,2
+np.float32,0x7d139f13,0x54063b6b,2
+np.float32,0xbeee1b08,0xbf465699,2
+np.float32,0xfe5e1650,0xd47427fe,2
+np.float32,0x7f7fffff,0x54cb2ff5,2
+np.float32,0xbf52ede8,0xbf6fff35,2
+np.float32,0x804bba81,0xaa56e8f1,2
+np.float32,0x6609e2,0x2a6d5e94,2
+np.float32,0x692621,0x2a6fc1d6,2
+np.float32,0xbf288bb6,0xbf5eb4d3,2
+np.float32,0x804f28c4,0xaa5a1b82,2
+np.float32,0xbdaad2a8,0xbedfb46e,2
+np.float32,0x5e04f8,0x2a66fb13,2
+np.float32,0x804c10da,0xaa573a81,2
+np.float32,0xbe412764,0xbf12d0fd,2
+np.float32,0x801c35cc,0xaa1aa250,2
+np.float32,0x6364d4,0x2a6b4cf9,2
+np.float32,0xbf6d3cea,0xbf79962f,2
+np.float32,0x7e5a9935,0x5472defb,2
+np.float32,0xbe73a38c,0xbf1ea19c,2
+np.float32,0xbd35e950,0xbeb550f2,2
+np.float32,0x46cc16,0x2a5223d6,2
+np.float32,0x3f005288,0x3f4b5b97,2
+np.float32,0x8034e8b7,0xaa3eb2be,2
+np.float32,0xbea775fc,0xbf3061cf,2
+np.float32,0xea0e9,0x29f87751,2
+np.float32,0xbf38faaf,0xbf65b89d,2
+np.float32,0xbedf3184,0xbf421bb0,2
+np.float32,0xbe04250c,0xbf015def,2
+np.float32,0x7f56dae8,0x54bfa901,2
+np.float32,0xfebe3e04,0xd492132e,2
+np.float32,0x3e4dc326,0x3f15f19e,2
+np.float32,0x803da197,0xaa48a621,2
+np.float32,0x7eeb35aa,0x549cc7c6,2
+np.float32,0xfebb3eb6,0xd4914dc0,2
+np.float32,0xfed17478,0xd496d5e2,2
+np.float32,0x80243694,0xaa280ed2,2
+np.float32,0x8017e666,0xaa1251d3,2
+np.float32,0xbf07e942,0xbf4f4a3e,2
+np.float32,0xbf578fa6,0xbf71bdab,2
+np.float32,0x7ed8d80f,0x549896b6,2
+np.float32,0x3f2277ae,0x3f5bff11,2
+np.float32,0x7e6f195b,0x547a3cd4,2
+np.float32,0xbf441559,0xbf6a3a91,2
+np.float32,0x7f1fb427,0x54ad9d8d,2
+np.float32,0x71695f,0x2a75e12d,2
+np.float32,0xbd859588,0xbece19a1,2
+np.float32,0x7f5702fc,0x54bfb4eb,2
+np.float32,0x3f040008,0x3f4d4842,2
+np.float32,0x3de00ca5,0x3ef4df89,2
+np.float32,0x3eeabb03,0x3f45658c,2
+np.float32,0x3dfe5e65,0x3eff7480,2
+np.float32,0x1,0x26a14518,2
+np.float32,0x8065e400,0xaa6d4130,2
+np.float32,0xff50e1bb,0xd4bdde07,2
+np.float32,0xbe88635a,0xbf24b7e9,2
+np.float32,0x3f46bfab,0x3f6b4908,2
+np.float32,0xbd85c3c8,0xbece3168,2
+np.float32,0xbe633f64,0xbf1afdb1,2
+np.float32,0xff2c7706,0xd4b21f2a,2
+np.float32,0xbf02816c,0xbf4c812a,2
+np.float32,0x80653aeb,0xaa6cbdab,2
+np.float32,0x3eef1d10,0x3f469e24,2
+np.float32,0x3d9944bf,0x3ed7c36a,2
+np.float32,0x1b03d4,0x2a186b2b,2
+np.float32,0x3f251b7c,0x3f5d2e76,2
+np.float32,0x3edebab0,0x3f41f937,2
+np.float32,0xfefc2148,0xd4a073ff,2
+np.float32,0x7448ee,0x2a77f051,2
+np.float32,0x3bb8a400,0x3e3637ee,2
+np.float32,0x57df36,0x2a61d527,2
+np.float32,0xfd8b9098,0xd425fccb,2
+np.float32,0x7f67627e,0x54c4744d,2
+np.float32,0x801165d7,0xaa039fba,2
+np.float32,0x53aae5,0x2a5e2bfd,2
+np.float32,0x8014012b,0xaa09e4f1,2
+np.float32,0x3f7a2d53,0x3f7e0b4b,2
+np.float32,0x3f5fb700,0x3f74c052,2
+np.float32,0x7f192a06,0x54ab366c,2
+np.float32,0x3f569611,0x3f71603b,2
+np.float32,0x25e2dc,0x2a2a9b65,2
+np.float32,0x8036465e,0xaa405342,2
+np.float32,0x804118e1,0xaa4c5785,2
+np.float32,0xbef08d3e,0xbf4703e1,2
+np.float32,0x3447e2,0x2a3df0be,2
+np.float32,0xbf2a350b,0xbf5f6f8c,2
+np.float32,0xbec87e3e,0xbf3b4a73,2
+np.float32,0xbe99a4a8,0xbf2b6412,2
+np.float32,0x2ea2ae,0x2a36d77e,2
+np.float32,0xfcb69600,0xd3e4b9e3,2
+np.float32,0x717700,0x2a75eb06,2
+np.float32,0xbf4e81ce,0xbf6e4ecc,2
+np.float32,0xbe2021ac,0xbf09ebee,2
+np.float32,0xfef94eee,0xd49fda31,2
+np.float32,0x8563e,0x29ce0015,2
+np.float32,0x7f5d0ca5,0x54c17c0f,2
+np.float32,0x3f16459a,0x3f56590f,2
+np.float32,0xbe12f7bc,0xbf0608a0,2
+np.float32,0x3f10fd3d,0x3f53ce5f,2
+np.float32,0x3ca5e1b0,0x3e8b8d96,2
+np.float32,0xbe5288e0,0xbf17181f,2
+np.float32,0xbf7360f6,0xbf7bb8c9,2
+np.float32,0x7e989d33,0x5487ba88,2
+np.float32,0x3ea7b5dc,0x3f307839,2
+np.float32,0x7e8da0c9,0x548463f0,2
+np.float32,0xfeaf7888,0xd48e3122,2
+np.float32,0x7d90402d,0x5427d321,2
+np.float32,0x72e309,0x2a76f0ee,2
+np.float32,0xbe1faa34,0xbf09c998,2
+np.float32,0xbf2b1652,0xbf5fd1f4,2
+np.float32,0x8051eb0c,0xaa5c9cca,2
+np.float32,0x7edf02bf,0x549a058e,2
+np.float32,0x7fa00000,0x7fe00000,2
+np.float32,0x3f67f873,0x3f77b9c1,2
+np.float32,0x3f276b63,0x3f5e358c,2
+np.float32,0x7eeb4bf2,0x549cccb9,2
+np.float32,0x3bfa2c,0x2a46d675,2
+np.float32,0x3e133c50,0x3f061d75,2
+np.float32,0x3ca302c0,0x3e8abe4a,2
+np.float32,0x802e152e,0xaa361dd5,2
+np.float32,0x3f504810,0x3f6efd0a,2
+np.float32,0xbf43e0b5,0xbf6a2599,2
+np.float32,0x80800000,0xaa800000,2
+np.float32,0x3f1c0980,0x3f590e03,2
+np.float32,0xbf0084f6,0xbf4b7638,2
+np.float32,0xfee72d32,0xd49be10d,2
+np.float32,0x3f3c00ed,0x3f66f763,2
+np.float32,0x80511e81,0xaa5be492,2
+np.float32,0xfdd1b8a0,0xd43e1f0d,2
+np.float32,0x7d877474,0x54245785,2
+np.float32,0x7f110bfe,0x54a82207,2
+np.float32,0xff800000,0xff800000,2
+np.float32,0x6b6a2,0x29bfa706,2
+np.float32,0xbf5bdfd9,0xbf7357b7,2
+np.float32,0x8025bfa3,0xaa2a6676,2
+np.float32,0x3a3581,0x2a44dd3a,2
+np.float32,0x542c2a,0x2a5e9e2f,2
+np.float32,0xbe1d5650,0xbf091d57,2
+np.float32,0x3e97760d,0x3f2a935e,2
+np.float32,0x7f5dcde2,0x54c1b460,2
+np.float32,0x800bde1e,0xa9e7bbaf,2
+np.float32,0x3e6b9e61,0x3f1cdf07,2
+np.float32,0x7d46c003,0x54143884,2
+np.float32,0x80073fbb,0xa9c49e67,2
+np.float32,0x503c23,0x2a5b1748,2
+np.float32,0x7eb7b070,0x549060c8,2
+np.float32,0xe9d8f,0x29f86456,2
+np.float32,0xbeedd4f0,0xbf464320,2
+np.float32,0x3f40d5d6,0x3f68eda1,2
+np.float32,0xff201f28,0xd4adc44b,2
+np.float32,0xbdf61e98,0xbefca9c7,2
+np.float32,0x3e8a0dc9,0x3f2562e3,2
+np.float32,0xbc0c0c80,0xbe515f61,2
+np.float32,0x2b3c15,0x2a3248e3,2
+np.float32,0x42a7bb,0x2a4df592,2
+np.float32,0x7f337947,0x54b480af,2
+np.float32,0xfec21db4,0xd4930f4b,2
+np.float32,0x7f4fdbf3,0x54bd8e94,2
+np.float32,0x1e2253,0x2a1e1286,2
+np.float32,0x800c4c80,0xa9ea819e,2
+np.float32,0x7e96f5b7,0x54873c88,2
+np.float32,0x7ce4e131,0x53f69ed4,2
+np.float32,0xbead8372,0xbf327b63,2
+np.float32,0x3e15ca7e,0x3f06e2f3,2
+np.float32,0xbf63e17b,0xbf7642da,2
+np.float32,0xff5bdbdb,0xd4c122f9,2
+np.float32,0x3f44411e,0x3f6a4bfd,2
+np.float32,0xfd007da0,0xd40029d2,2
+np.float32,0xbe940168,0xbf2944b7,2
+np.float32,0x80000000,0x80000000,2
+np.float32,0x3d28e356,0x3eb0e1b8,2
+np.float32,0x3eb9fcd8,0x3f36a918,2
+np.float32,0x4f6410,0x2a5a51eb,2
+np.float32,0xbdf18e30,0xbefb1775,2
+np.float32,0x32edbd,0x2a3c49e3,2
+np.float32,0x801f70a5,0xaa2052da,2
+np.float32,0x8045a045,0xaa50f98c,2
+np.float32,0xbdd6cb00,0xbef17412,2
+np.float32,0x3f118f2c,0x3f541557,2
+np.float32,0xbe65c378,0xbf1b8f95,2
+np.float32,0xfd9a9060,0xd42bbb8b,2
+np.float32,0x3f04244f,0x3f4d5b0f,2
+np.float32,0xff05214b,0xd4a3656f,2
+np.float32,0xfe342cd0,0xd463b706,2
+np.float32,0x3f3409a8,0x3f63a836,2
+np.float32,0x80205db2,0xaa21e1e5,2
+np.float32,0xbf37c982,0xbf653a03,2
+np.float32,0x3f36ce8f,0x3f64d17e,2
+np.float32,0x36ffda,0x2a412d61,2
+np.float32,0xff569752,0xd4bf94e6,2
+np.float32,0x802fdb0f,0xaa386c3a,2
+np.float32,0x7ec55a87,0x5493df71,2
+np.float32,0x7f2234c7,0x54ae847e,2
+np.float32,0xbf02df76,0xbf4cb23d,2
+np.float32,0x3d68731a,0x3ec4c156,2
+np.float32,0x8146,0x2921cd8e,2
+np.float32,0x80119364,0xaa041235,2
+np.float32,0xfe6c1c00,0xd47930b5,2
+np.float32,0x8070da44,0xaa757996,2
+np.float32,0xfefbf50c,0xd4a06a9d,2
+np.float32,0xbf01b6a8,0xbf4c170a,2
+np.float32,0x110702,0x2a02aedb,2
+np.float32,0xbf063cd4,0xbf4e6f87,2
+np.float32,0x3f1ff178,0x3f5ad9dd,2
+np.float32,0xbf76dcd4,0xbf7cead0,2
+np.float32,0x80527281,0xaa5d1620,2
+np.float32,0xfea96df8,0xd48c8a7f,2
+np.float32,0x68db02,0x2a6f88b0,2
+np.float32,0x62d971,0x2a6adec7,2
+np.float32,0x3e816fe0,0x3f21df04,2
+np.float32,0x3f586379,0x3f720cc0,2
+np.float32,0x804a3718,0xaa5577ff,2
+np.float32,0x2e2506,0x2a3632b2,2
+np.float32,0x3f297d,0x2a4a4bf3,2
+np.float32,0xbe37aba8,0xbf105f88,2
+np.float32,0xbf18b264,0xbf577ea7,2
+np.float32,0x7f50d02d,0x54bdd8b5,2
+np.float32,0xfee296dc,0xd49ad757,2
+np.float32,0x7ec5137e,0x5493cdb1,2
+np.float32,0x3f4811f4,0x3f6bce3a,2
+np.float32,0xfdff32a0,0xd44af991,2
+np.float32,0x3f6ef140,0x3f7a2ed6,2
+np.float32,0x250838,0x2a2950b5,2
+np.float32,0x25c28e,0x2a2a6ada,2
+np.float32,0xbe875e50,0xbf244e90,2
+np.float32,0x3e3bdff8,0x3f11776a,2
+np.float32,0x3e9fe493,0x3f2daf17,2
+np.float32,0x804d8599,0xaa5897d9,2
+np.float32,0x3f0533da,0x3f4de759,2
+np.float32,0xbe63023c,0xbf1aefc8,2
+np.float32,0x80636e5e,0xaa6b547f,2
+np.float32,0xff112958,0xd4a82d5d,2
+np.float32,0x3e924112,0x3f28991f,2
+np.float32,0xbe996ffc,0xbf2b507a,2
+np.float32,0x802a7cda,0xaa314081,2
+np.float32,0x8022b524,0xaa25b21e,2
+np.float32,0x3f0808c8,0x3f4f5a43,2
+np.float32,0xbef0ec2a,0xbf471e0b,2
+np.float32,0xff4c2345,0xd4bc6b3c,2
+np.float32,0x25ccc8,0x2a2a7a3b,2
+np.float32,0x7f4467d6,0x54ba0260,2
+np.float32,0x7f506539,0x54bdb846,2
+np.float32,0x412ab4,0x2a4c6a2a,2
+np.float32,0x80672c4a,0xaa6e3ef0,2
+np.float32,0xbddfb7f8,0xbef4c0ac,2
+np.float32,0xbf250bb9,0xbf5d276c,2
+np.float32,0x807dca65,0xaa7e84bd,2
+np.float32,0xbf63b8e0,0xbf763438,2
+np.float32,0xbeed1b0c,0xbf460f6b,2
+np.float32,0x8021594f,0xaa238136,2
+np.float32,0xbebc74c8,0xbf377710,2
+np.float32,0x3e9f8e3b,0x3f2d8fce,2
+np.float32,0x7f50ca09,0x54bdd6d8,2
+np.float32,0x805797c1,0xaa6197df,2
+np.float32,0x3de198f9,0x3ef56f98,2
+np.float32,0xf154d,0x29fb0392,2
+np.float32,0xff7fffff,0xd4cb2ff5,2
+np.float32,0xfed22fa8,0xd49702c4,2
+np.float32,0xbf733736,0xbf7baa64,2
+np.float32,0xbf206a8a,0xbf5b1108,2
+np.float32,0xbca49680,0xbe8b3078,2
+np.float32,0xfecba794,0xd4956e1a,2
+np.float32,0x80126582,0xaa061886,2
+np.float32,0xfee5cc82,0xd49b919f,2
+np.float32,0xbf7ad6ae,0xbf7e4491,2
+np.float32,0x7ea88c81,0x548c4c0c,2
+np.float32,0xbf493a0d,0xbf6c4255,2
+np.float32,0xbf06dda0,0xbf4ec1d4,2
+np.float32,0xff3f6e84,0xd4b86cf6,2
+np.float32,0x3e4fe093,0x3f1674b0,2
+np.float32,0x8048ad60,0xaa53fbde,2
+np.float32,0x7ebb7112,0x54915ac5,2
+np.float32,0x5bd191,0x2a652a0d,2
+np.float32,0xfe3121d0,0xd4626cfb,2
+np.float32,0x7e4421c6,0x546a3f83,2
+np.float32,0x19975b,0x2a15b14f,2
+np.float32,0x801c8087,0xaa1b2a64,2
+np.float32,0xfdf6e950,0xd448c0f6,2
+np.float32,0x74e711,0x2a786083,2
+np.float32,0xbf2b2f2e,0xbf5fdccb,2
+np.float32,0x7ed19ece,0x5496e00b,2
+np.float32,0x7f6f8322,0x54c6ba63,2
+np.float32,0x3e90316d,0x3f27cd69,2
+np.float32,0x7ecb42ce,0x54955571,2
+np.float32,0x3f6d49be,0x3f799aaf,2
+np.float32,0x8053d327,0xaa5e4f9a,2
+np.float32,0x7ebd7361,0x5491df3e,2
+np.float32,0xfdb6eed0,0xd435a7aa,2
+np.float32,0x7f3e79f4,0x54b81e4b,2
+np.float32,0xfe83afa6,0xd4813794,2
+np.float32,0x37c443,0x2a421246,2
+np.float32,0xff075a10,0xd4a44cd8,2
+np.float32,0x3ebc5fe0,0x3f377047,2
+np.float32,0x739694,0x2a77714e,2
+np.float32,0xfe832946,0xd4810b91,2
+np.float32,0x7f2638e6,0x54aff235,2
+np.float32,0xfe87f7a6,0xd4829a3f,2
+np.float32,0x3f50f3f8,0x3f6f3eb8,2
+np.float32,0x3eafa3d0,0x3f333548,2
+np.float32,0xbec26ee6,0xbf39626f,2
+np.float32,0x7e6f924f,0x547a66ff,2
+np.float32,0x7f0baa46,0x54a606f8,2
+np.float32,0xbf6dfc49,0xbf79d939,2
+np.float32,0x7f005709,0x54a1699d,2
+np.float32,0x7ee3d7ef,0x549b2057,2
+np.float32,0x803709a4,0xaa4138d7,2
+np.float32,0x3f7bf49a,0x3f7ea509,2
+np.float32,0x509db7,0x2a5b6ff5,2
+np.float32,0x7eb1b0d4,0x548ec9ff,2
+np.float32,0x7eb996ec,0x5490dfce,2
+np.float32,0xbf1fcbaa,0xbf5ac89e,2
+np.float32,0x3e2c9a98,0x3f0d69cc,2
+np.float32,0x3ea77994,0x3f306312,2
+np.float32,0x3f3cbfe4,0x3f67457c,2
+np.float32,0x8422a,0x29cd5a30,2
+np.float32,0xbd974558,0xbed6d264,2
+np.float32,0xfecee77a,0xd496387f,2
+np.float32,0x3f51876b,0x3f6f76f1,2
+np.float32,0x3b1a25,0x2a45ddad,2
+np.float32,0xfe9912f0,0xd487dd67,2
+np.float32,0x3f3ab13d,0x3f666d99,2
+np.float32,0xbf35565a,0xbf64341b,2
+np.float32,0x7d4e84aa,0x54162091,2
+np.float32,0x4c2570,0x2a574dea,2
+np.float32,0x7e82dca6,0x5480f26b,2
+np.float32,0x7f5503e7,0x54bf1c8d,2
+np.float32,0xbeb85034,0xbf361c59,2
+np.float32,0x80460a69,0xaa516387,2
+np.float32,0x805fbbab,0xaa68602c,2
+np.float32,0x7d4b4c1b,0x541557b8,2
+np.float32,0xbefa9a0a,0xbf49bfbc,2
+np.float32,0x3dbd233f,0x3ee76e09,2
+np.float32,0x58b6df,0x2a628d50,2
+np.float32,0xfcdcc180,0xd3f3aad9,2
+np.float32,0x423a37,0x2a4d8487,2
+np.float32,0xbed8b32a,0xbf403507,2
+np.float32,0x3f68e85d,0x3f780f0b,2
+np.float32,0x7ee13c4b,0x549a883d,2
+np.float32,0xff2ed4c5,0xd4b2eec1,2
+np.float32,0xbf54dadc,0xbf70b99a,2
+np.float32,0x3f78b0af,0x3f7d8a32,2
+np.float32,0x3f377372,0x3f651635,2
+np.float32,0xfdaa6178,0xd43166bc,2
+np.float32,0x8060c337,0xaa6934a6,2
+np.float32,0x7ec752c2,0x54945cf6,2
+np.float32,0xbd01a760,0xbea1f624,2
+np.float32,0x6f6599,0x2a746a35,2
+np.float32,0x3f6315b0,0x3f75f95b,2
+np.float32,0x7f2baf32,0x54b1da44,2
+np.float32,0x3e400353,0x3f1286d8,2
+np.float32,0x40d3bf,0x2a4c0f15,2
+np.float32,0x7f733aca,0x54c7c03d,2
+np.float32,0x7e5c5407,0x5473828b,2
+np.float32,0x80191703,0xaa14b56a,2
+np.float32,0xbf4fc144,0xbf6ec970,2
+np.float32,0xbf1137a7,0xbf53eacd,2
+np.float32,0x80575410,0xaa615db3,2
+np.float32,0xbd0911d0,0xbea4fe07,2
+np.float32,0x3e98534a,0x3f2ae643,2
+np.float32,0x3f3b089a,0x3f669185,2
+np.float32,0x4fc752,0x2a5aacc1,2
+np.float32,0xbef44ddc,0xbf480b6e,2
+np.float32,0x80464217,0xaa519af4,2
+np.float32,0x80445fae,0xaa4fb6de,2
+np.float32,0x80771cf4,0xaa79eec8,2
+np.float32,0xfd9182e8,0xd4284fed,2
+np.float32,0xff0a5d16,0xd4a58288,2
+np.float32,0x3f33e169,0x3f63973e,2
+np.float32,0x8021a247,0xaa23f820,2
+np.float32,0xbf362522,0xbf648ab8,2
+np.float32,0x3f457cd7,0x3f6ac95e,2
+np.float32,0xbcadf400,0xbe8dc7e2,2
+np.float32,0x80237210,0xaa26dca7,2
+np.float32,0xbf1293c9,0xbf54939f,2
+np.float32,0xbc5e73c0,0xbe744a37,2
+np.float32,0x3c03f980,0x3e4d44df,2
+np.float32,0x7da46f,0x2a7e6b20,2
+np.float32,0x5d4570,0x2a665dd0,2
+np.float32,0x3e93fbac,0x3f294287,2
+np.float32,0x7e6808fd,0x5477bfa4,2
+np.float32,0xff5aa9a6,0xd4c0c925,2
+np.float32,0xbf5206ba,0xbf6fa767,2
+np.float32,0xbf6e513e,0xbf79f6f1,2
+np.float32,0x3ed01c0f,0x3f3da20f,2
+np.float32,0xff47d93d,0xd4bb1704,2
+np.float32,0x7f466cfd,0x54baa514,2
+np.float32,0x665e10,0x2a6d9fc8,2
+np.float32,0x804d0629,0xaa5820e8,2
+np.float32,0x7e0beaa0,0x54514e7e,2
+np.float32,0xbf7fcb6c,0xbf7fee78,2
+np.float32,0x3f6c5b03,0x3f7946dd,2
+np.float32,0x3e941504,0x3f294c30,2
+np.float32,0xbf2749ad,0xbf5e26a1,2
+np.float32,0xfec2a00a,0xd493302d,2
+np.float32,0x3f15a358,0x3f560bce,2
+np.float32,0x3f15c4e7,0x3f561bcd,2
+np.float32,0xfedc8692,0xd499728c,2
+np.float32,0x7e8f6902,0x5484f180,2
+np.float32,0x7f663d62,0x54c42136,2
+np.float32,0x8027ea62,0xaa2d99b4,2
+np.float32,0x3f3d093d,0x3f67636d,2
+np.float32,0x7f118c33,0x54a85382,2
+np.float32,0x803e866a,0xaa499d43,2
+np.float32,0x80053632,0xa9b02407,2
+np.float32,0xbf36dd66,0xbf64d7af,2
+np.float32,0xbf560358,0xbf71292b,2
+np.float32,0x139a8,0x29596bc0,2
+np.float32,0xbe04f75c,0xbf01a26c,2
+np.float32,0xfe1c3268,0xd45920fa,2
+np.float32,0x7ec77f72,0x5494680c,2
+np.float32,0xbedde724,0xbf41bbba,2
+np.float32,0x3e81dbe0,0x3f220bfd,2
+np.float32,0x800373ac,0xa99989d4,2
+np.float32,0x3f7f859a,0x3f7fd72d,2
+np.float32,0x3eb9dc7e,0x3f369e80,2
+np.float32,0xff5f8eb7,0xd4c236b1,2
+np.float32,0xff1c03cb,0xd4ac44ac,2
+np.float32,0x18cfe1,0x2a14285b,2
+np.float32,0x7f21b075,0x54ae54fd,2
+np.float32,0xff490bd8,0xd4bb7680,2
+np.float32,0xbf15dc22,0xbf5626de,2
+np.float32,0xfe1d5a10,0xd459a9a3,2
+np.float32,0x750544,0x2a7875e4,2
+np.float32,0x8023d5df,0xaa2778b3,2
+np.float32,0x3e42aa08,0x3f1332b2,2
+np.float32,0x3ecaa751,0x3f3bf60d,2
+np.float32,0x0,0x0,2
+np.float32,0x80416da6,0xaa4cb011,2
+np.float32,0x3f4ea9ae,0x3f6e5e22,2
+np.float32,0x2113f4,0x2a230f8e,2
+np.float32,0x3f35c2e6,0x3f64619a,2
+np.float32,0xbf50db8a,0xbf6f3564,2
+np.float32,0xff4d5cea,0xd4bccb8a,2
+np.float32,0x7ee54420,0x549b72d2,2
+np.float32,0x64ee68,0x2a6c81f7,2
+np.float32,0x5330da,0x2a5dbfc2,2
+np.float32,0x80047f88,0xa9a7b467,2
+np.float32,0xbda01078,0xbedae800,2
+np.float32,0xfe96d05a,0xd487315f,2
+np.float32,0x8003cc10,0xa99e7ef4,2
+np.float32,0x8007b4ac,0xa9c8aa3d,2
+np.float32,0x5d4bcf,0x2a66630e,2
+np.float32,0xfdd0c0b0,0xd43dd403,2
+np.float32,0xbf7a1d82,0xbf7e05f0,2
+np.float32,0x74ca33,0x2a784c0f,2
+np.float32,0x804f45e5,0xaa5a3640,2
+np.float32,0x7e6d16aa,0x547988c4,2
+np.float32,0x807d5762,0xaa7e3714,2
+np.float32,0xfecf93d0,0xd4966229,2
+np.float32,0xfecbd25c,0xd4957890,2
+np.float32,0xff7db31c,0xd4ca93b0,2
+np.float32,0x3dac9e18,0x3ee07c4a,2
+np.float32,0xbf4b2d28,0xbf6d0509,2
+np.float32,0xbd4f4c50,0xbebd62e0,2
+np.float32,0xbd2eac40,0xbeb2e0ee,2
+np.float32,0x3d01b69b,0x3ea1fc7b,2
+np.float32,0x7ec63902,0x549416ed,2
+np.float32,0xfcc47700,0xd3ea616d,2
+np.float32,0xbf5ddec2,0xbf7413a1,2
+np.float32,0xff6a6110,0xd4c54c52,2
+np.float32,0xfdfae2a0,0xd449d335,2
+np.float32,0x7e54868c,0x547099cd,2
+np.float32,0x802b5b88,0xaa327413,2
+np.float32,0x80440e72,0xaa4f647a,2
+np.float32,0x3e313c94,0x3f0eaad5,2
+np.float32,0x3ebb492a,0x3f3715a2,2
+np.float32,0xbef56286,0xbf4856d5,2
+np.float32,0x3f0154ba,0x3f4be3a0,2
+np.float32,0xff2df86c,0xd4b2a376,2
+np.float32,0x3ef6a850,0x3f48af57,2
+np.float32,0x3d8d33e1,0x3ed1f22d,2
+np.float32,0x4dd9b9,0x2a58e615,2
+np.float32,0x7f1caf83,0x54ac83c9,2
+np.float32,0xbf7286b3,0xbf7b6d73,2
+np.float32,0x80064f88,0xa9bbbd9f,2
+np.float32,0xbf1f55fa,0xbf5a92db,2
+np.float32,0x546a81,0x2a5ed516,2
+np.float32,0xbe912880,0xbf282d0a,2
+np.float32,0x5df587,0x2a66ee6e,2
+np.float32,0x801f706c,0xaa205279,2
+np.float32,0x58cb6d,0x2a629ece,2
+np.float32,0xfe754f8c,0xd47c62da,2
+np.float32,0xbefb6f4c,0xbf49f8e7,2
+np.float32,0x80000001,0xa6a14518,2
+np.float32,0xbf067837,0xbf4e8df4,2
+np.float32,0x3e8e715c,0x3f271ee4,2
+np.float32,0x8009de9b,0xa9d9ebc8,2
+np.float32,0xbf371ff1,0xbf64f36e,2
+np.float32,0x7f5ce661,0x54c170e4,2
+np.float32,0x3f3c47d1,0x3f671467,2
+np.float32,0xfea5e5a6,0xd48b8eb2,2
+np.float32,0xff62b17f,0xd4c31e15,2
+np.float32,0xff315932,0xd4b3c98f,2
+np.float32,0xbf1c3ca8,0xbf5925b9,2
+np.float32,0x7f800000,0x7f800000,2
+np.float32,0xfdf20868,0xd4476c3b,2
+np.float32,0x5b790e,0x2a64e052,2
+np.float32,0x3f5ddf4e,0x3f7413d4,2
+np.float32,0x7f1a3182,0x54ab9861,2
+np.float32,0x3f4b906e,0x3f6d2b9d,2
+np.float32,0x7ebac760,0x54912edb,2
+np.float32,0x7f626d3f,0x54c30a7e,2
+np.float32,0x3e27b058,0x3f0c0edc,2
+np.float32,0x8041e69c,0xaa4d2de8,2
+np.float32,0x3f42cee0,0x3f69b84a,2
+np.float32,0x7ec5fe83,0x5494085b,2
+np.float32,0x9d3e6,0x29d99cde,2
+np.float32,0x3edc50c0,0x3f41452d,2
+np.float32,0xbf2c463a,0xbf60562c,2
+np.float32,0x800bfa33,0xa9e871e8,2
+np.float32,0x7c9f2c,0x2a7dba4d,2
+np.float32,0x7f2ef9fd,0x54b2fb73,2
+np.float32,0x80741847,0xaa77cdb9,2
+np.float32,0x7e9c462a,0x5488ce1b,2
+np.float32,0x3ea47ec1,0x3f2f55a9,2
+np.float32,0x7f311c43,0x54b3b4f5,2
+np.float32,0x3d8f4c73,0x3ed2facd,2
+np.float32,0x806d7bd2,0xaa7301ef,2
+np.float32,0xbf633d24,0xbf760799,2
+np.float32,0xff4f9a3f,0xd4bd7a99,2
+np.float32,0x3f6021ca,0x3f74e73d,2
+np.float32,0x7e447015,0x546a5eac,2
+np.float32,0x6bff3c,0x2a71e711,2
+np.float32,0xe9c9f,0x29f85f06,2
+np.float32,0x8009fe14,0xa9dad277,2
+np.float32,0x807cf79c,0xaa7df644,2
+np.float32,0xff440e1b,0xd4b9e608,2
+np.float32,0xbddf9a50,0xbef4b5db,2
+np.float32,0x7f3b1c39,0x54b706fc,2
+np.float32,0x3c7471a0,0x3e7c16a7,2
+np.float32,0x8065b02b,0xaa6d18ee,2
+np.float32,0x7f63a3b2,0x54c36379,2
+np.float32,0xbe9c9d92,0xbf2c7d33,2
+np.float32,0x3d93aad3,0x3ed51a2e,2
+np.float32,0xbf41b040,0xbf694571,2
+np.float32,0x80396b9e,0xaa43f899,2
+np.float64,0x800fa025695f404b,0xaaa4000ff64bb00c,2
+np.float64,0xbfecc00198f98003,0xbfeee0b623fbd94b,2
+np.float64,0x7f9eeb60b03dd6c0,0x55291bf8554bb303,2
+np.float64,0x3fba74485634e890,0x3fde08710bdb148d,2
+np.float64,0xbfdd9a75193b34ea,0xbfe8bf711660a2f5,2
+np.float64,0xbfcf92e17a3f25c4,0xbfe4119eda6f3773,2
+np.float64,0xbfe359e2ba66b3c6,0xbfeb0f7ae97ea142,2
+np.float64,0x20791a5640f24,0x2a9441f13d262bed,2
+np.float64,0x3fe455fbfae8abf8,0x3feb830d63e1022c,2
+np.float64,0xbd112b7b7a226,0x2aa238c097ec269a,2
+np.float64,0x93349ba126694,0x2aa0c363cd74465a,2
+np.float64,0x20300cd440602,0x2a9432b4f4081209,2
+np.float64,0x3fdcfae677b9f5cc,0x3fe892a9ee56fe8d,2
+np.float64,0xbfefaae3f7bf55c8,0xbfefe388066132c4,2
+np.float64,0x1a7d6eb634faf,0x2a92ed9851d29ab5,2
+np.float64,0x7fd5308d39aa6119,0x553be444e30326c6,2
+np.float64,0xff811c7390223900,0xd5205cb404952fa7,2
+np.float64,0x80083d24aff07a4a,0xaaa0285cf764d898,2
+np.float64,0x800633810ccc6703,0xaa9d65341419586b,2
+np.float64,0x800ff456223fe8ac,0xaaa423bbcc24dff1,2
+np.float64,0x7fde5c99aebcb932,0x553f71be7d6d9daa,2
+np.float64,0x3fed961c4b3b2c39,0x3fef2ca146270cac,2
+np.float64,0x7fe744d30c6e89a5,0x554220a4cdc78e62,2
+np.float64,0x3fd8f527c7b1ea50,0x3fe76101085be1cb,2
+np.float64,0xbfc96a14b232d428,0xbfe2ab1a8962606c,2
+np.float64,0xffe85f540cf0bea7,0xd54268dff964519a,2
+np.float64,0x800e3be0fe7c77c2,0xaaa3634efd7f020b,2
+np.float64,0x3feb90d032f721a0,0x3fee72a4579e8b12,2
+np.float64,0xffe05674aaa0ace9,0xd5401c9e3fb4abcf,2
+np.float64,0x3fefc2e32c3f85c6,0x3fefeb940924bf42,2
+np.float64,0xbfecfd89e9f9fb14,0xbfeef6addf73ee49,2
+np.float64,0xf5862717eb0c5,0x2aa3e1428780382d,2
+np.float64,0xffc3003b32260078,0xd53558f92202dcdb,2
+np.float64,0x3feb4c152c36982a,0x3fee5940f7da0825,2
+np.float64,0x3fe7147b002e28f6,0x3fecb2948f46d1e3,2
+np.float64,0x7fe00ad9b4a015b2,0x5540039d15e1da54,2
+np.float64,0x8010000000000000,0xaaa428a2f98d728b,2
+np.float64,0xbfd3a41bfea74838,0xbfe595ab45b1be91,2
+np.float64,0x7fdbfd6e5537fadc,0x553e9a6e1107b8d0,2
+np.float64,0x800151d9d9a2a3b4,0xaa918cd8fb63f40f,2
+np.float64,0x7fe6828401ad0507,0x5541eda05dcd1fcf,2
+np.float64,0x3fdae1e7a1b5c3d0,0x3fe7f711e72ecc35,2
+np.float64,0x7fdf4936133e926b,0x553fc29c8d5edea3,2
+np.float64,0x80079de12d4f3bc3,0xaa9f7b06a9286da4,2
+np.float64,0x3fe1261cade24c39,0x3fe9fe09488e417a,2
+np.float64,0xbfc20dce21241b9c,0xbfe0a842fb207a28,2
+np.float64,0x3fe3285dfa2650bc,0x3feaf85215f59ef9,2
+np.float64,0x7fe42b93aea85726,0x554148c3c3bb35e3,2
+np.float64,0xffe6c74e7f6d8e9c,0xd541ffd13fa36dbd,2
+np.float64,0x3fe73ea139ee7d42,0x3fecc402242ab7d3,2
+np.float64,0xffbd4b46be3a9690,0xd53392de917c72e4,2
+np.float64,0x800caed8df395db2,0xaaa2a811a02e6be4,2
+np.float64,0x800aacdb6c9559b7,0xaaa19d6fbc8feebf,2
+np.float64,0x839fb4eb073f7,0x2aa0264b98327c12,2
+np.float64,0xffd0157ba9a02af8,0xd5397157a11c0d05,2
+np.float64,0x7fddc8ff173b91fd,0x553f3e7663fb2ac7,2
+np.float64,0x67b365facf66d,0x2a9dd4d838b0d853,2
+np.float64,0xffe12e7fc7225cff,0xd5406272a83a8e1b,2
+np.float64,0x7fea5b19a034b632,0x5542e567658b3e36,2
+np.float64,0x124989d824932,0x2a90ba8dc7a39532,2
+np.float64,0xffe12ef098225de0,0xd54062968450a078,2
+np.float64,0x3fea2f44a3f45e8a,0x3fedee3c461f4716,2
+np.float64,0x3fe6b033e66d6068,0x3fec88c8035e06b1,2
+np.float64,0x3fe928a2ccf25146,0x3fed88d4cde7a700,2
+np.float64,0x3feead27e97d5a50,0x3fef8d7537d82e60,2
+np.float64,0x8003ab80b6875702,0xaa98adfedd7715a9,2
+np.float64,0x45a405828b481,0x2a9a1fa99a4eff1e,2
+np.float64,0x8002ddebad85bbd8,0xaa96babfda4e0031,2
+np.float64,0x3fc278c32824f186,0x3fe0c8e7c979fbd5,2
+np.float64,0x2e10fffc5c221,0x2a96c30a766d06fa,2
+np.float64,0xffd6ba8c2ead7518,0xd53c8d1d92bc2788,2
+np.float64,0xbfeb5ec3a036bd87,0xbfee602bbf0a0d01,2
+np.float64,0x3fed5bd58f7ab7ab,0x3fef181bf591a4a7,2
+np.float64,0x7feb5274a5b6a4e8,0x55431fcf81876218,2
+np.float64,0xaf8fd6cf5f1fb,0x2aa1c6edbb1e2aaf,2
+np.float64,0x7fece718f179ce31,0x55437c74efb90933,2
+np.float64,0xbfa3c42d0c278860,0xbfd5a16407c77e73,2
+np.float64,0x800b5cff0576b9fe,0xaaa1fc4ecb0dec4f,2
+np.float64,0x800be89ae557d136,0xaaa244d115fc0963,2
+np.float64,0x800d2578f5ba4af2,0xaaa2e18a3a3fc134,2
+np.float64,0x80090ff93e321ff3,0xaaa0add578e3cc3c,2
+np.float64,0x28c5a240518c,0x2a81587cccd7e202,2
+np.float64,0x7fec066929780cd1,0x55434971435d1069,2
+np.float64,0x7fc84d4d15309a99,0x55372c204515694f,2
+np.float64,0xffe070a75de0e14e,0xd54025365046dad2,2
+np.float64,0x7fe5b27cc36b64f9,0x5541b5b822f0b6ca,2
+np.float64,0x3fdea35ac8bd46b6,0x3fe9086a0fb792c2,2
+np.float64,0xbfe79996f7af332e,0xbfece9571d37a5b3,2
+np.float64,0xffdfb47f943f6900,0xd53fe6c14c3366db,2
+np.float64,0xc015cf63802ba,0x2aa2517164d075f4,2
+np.float64,0x7feba98948375312,0x5543340b5b1f1181,2
+np.float64,0x8008678e6550cf1d,0xaaa043e7cea90da5,2
+np.float64,0x3fb11b92fa223726,0x3fd9f8b53be4d90b,2
+np.float64,0x7fc9b18cf0336319,0x55379b42da882047,2
+np.float64,0xbfe5043e736a087d,0xbfebd0c67db7a8e3,2
+np.float64,0x7fde88546a3d10a8,0x553f80cfe5bcf5fe,2
+np.float64,0x8006a6c82dcd4d91,0xaa9e171d182ba049,2
+np.float64,0xbfa0f707ac21ee10,0xbfd48e5d3faa1699,2
+np.float64,0xbfe7716bffaee2d8,0xbfecd8e6abfb8964,2
+np.float64,0x9511ccab2a23a,0x2aa0d56d748f0313,2
+np.float64,0x8003ddb9b847bb74,0xaa991ca06fd9d308,2
+np.float64,0x80030710fac60e23,0xaa9725845ac95fe8,2
+np.float64,0xffece5bbaeb9cb76,0xd5437c2670f894f4,2
+np.float64,0x3fd9be5c72b37cb9,0x3fe79f2e932a5708,2
+np.float64,0x1f050cca3e0a3,0x2a93f36499fe5228,2
+np.float64,0x3fd5422becaa8458,0x3fe6295d6150df58,2
+np.float64,0xffd72c050e2e580a,0xd53cbc52d73b495f,2
+np.float64,0xbfe66d5235ecdaa4,0xbfec6ca27e60bf23,2
+np.float64,0x17ac49a42f58a,0x2a923b5b757087a0,2
+np.float64,0xffd39edc40273db8,0xd53b2f7bb99b96bf,2
+np.float64,0x7fde6cf009bcd9df,0x553f77614eb30d75,2
+np.float64,0x80042b4c3fa85699,0xaa99c05fbdd057db,2
+np.float64,0xbfde5547f8bcaa90,0xbfe8f3147d67a940,2
+np.float64,0xbfdd02f9bf3a05f4,0xbfe894f2048aa3fe,2
+np.float64,0xbfa20ec82c241d90,0xbfd4fd02ee55aac7,2
+np.float64,0x8002f670f8c5ece3,0xaa96fad7e53dd479,2
+np.float64,0x80059f24d7eb3e4a,0xaa9c7312dae0d7bc,2
+np.float64,0x7fe6ae7423ad5ce7,0x5541f9430be53062,2
+np.float64,0xe135ea79c26be,0x2aa350d8f8c526e1,2
+np.float64,0x3fec188ce4f8311a,0x3feea44d21c23f68,2
+np.float64,0x800355688286aad2,0xaa97e6ca51eb8357,2
+np.float64,0xa2d6530b45acb,0x2aa15635bbd366e8,2
+np.float64,0x600e0150c01c1,0x2a9d1456ea6c239c,2
+np.float64,0x8009c30863338611,0xaaa118f94b188bcf,2
+np.float64,0x3fe7e4c0dfefc982,0x3fed07e8480b8c07,2
+np.float64,0xbfddac6407bb58c8,0xbfe8c46f63a50225,2
+np.float64,0xbc85e977790bd,0x2aa2344636ed713d,2
+np.float64,0xfff0000000000000,0xfff0000000000000,2
+np.float64,0xffcd1570303a2ae0,0xd5389a27d5148701,2
+np.float64,0xbf937334d026e660,0xbfd113762e4e29a7,2
+np.float64,0x3fdbfdaa9b37fb55,0x3fe84a425fdff7df,2
+np.float64,0xffc10800f5221000,0xd5349535ffe12030,2
+np.float64,0xaf40f3755e81f,0x2aa1c443af16cd27,2
+np.float64,0x800f7da34f7efb47,0xaaa3f14bf25fc89f,2
+np.float64,0xffe4a60125a94c02,0xd5416b764a294128,2
+np.float64,0xbf8e25aa903c4b40,0xbfcf5ebc275b4789,2
+np.float64,0x3fca681bbb34d038,0x3fe2e882bcaee320,2
+np.float64,0xbfd0f3c9c1a1e794,0xbfe48d0df7b47572,2
+np.float64,0xffeb99b49d373368,0xd5433060dc641910,2
+np.float64,0x3fe554fb916aa9f8,0x3febf437cf30bd67,2
+np.float64,0x80079518d0af2a32,0xaa9f6ee87044745a,2
+np.float64,0x5e01a8a0bc036,0x2a9cdf0badf222c3,2
+np.float64,0xbfea9831b3f53064,0xbfee1601ee953ab3,2
+np.float64,0xbfc369d1a826d3a4,0xbfe110b675c311e0,2
+np.float64,0xa82e640d505cd,0x2aa1863d4e523b9c,2
+np.float64,0x3fe506d70a2a0dae,0x3febd1eba3aa83fa,2
+np.float64,0xcbacba7197598,0x2aa2adeb9927f1f2,2
+np.float64,0xc112d6038225b,0x2aa25978f12038b0,2
+np.float64,0xffa7f5f44c2febf0,0xd52d0ede02d4e18b,2
+np.float64,0x8006f218e34de433,0xaa9e870cf373b4eb,2
+np.float64,0xffe6d9a5d06db34b,0xd54204a4adc608c7,2
+np.float64,0x7fe717210eae2e41,0x554214bf3e2b5228,2
+np.float64,0xbfdd4b45cdba968c,0xbfe8a94c7f225f8e,2
+np.float64,0x883356571066b,0x2aa055ab0b2a8833,2
+np.float64,0x3fe307fc02a60ff8,0x3feae9175053288f,2
+np.float64,0x3fefa985f77f530c,0x3fefe31289446615,2
+np.float64,0x8005698a98aad316,0xaa9c17814ff7d630,2
+np.float64,0x3fea77333c74ee66,0x3fee098ba70e10fd,2
+np.float64,0xbfd1d00b0023a016,0xbfe4e497fd1cbea1,2
+np.float64,0x80009b0c39813619,0xaa8b130a6909cc3f,2
+np.float64,0x3fdbeb896fb7d714,0x3fe84502ba5437f8,2
+np.float64,0x3fb6e7e3562dcfc7,0x3fdca00d35c389ad,2
+np.float64,0xb2d46ebf65a8e,0x2aa1e2fe158d0838,2
+np.float64,0xbfd5453266aa8a64,0xbfe62a6a74c8ef6e,2
+np.float64,0x7fe993aa07732753,0x5542b5438bf31cb7,2
+np.float64,0xbfda5a098cb4b414,0xbfe7ce6d4d606203,2
+np.float64,0xbfe40c3ce068187a,0xbfeb61a32c57a6d0,2
+np.float64,0x3fcf17671d3e2ed0,0x3fe3f753170ab686,2
+np.float64,0xbfe4f814b6e9f02a,0xbfebcb67c60b7b08,2
+np.float64,0x800efedf59fdfdbf,0xaaa3ba4ed44ad45a,2
+np.float64,0x800420b556e8416b,0xaa99aa7fb14edeab,2
+np.float64,0xbf6e4ae6403c9600,0xbfc3cb2b29923989,2
+np.float64,0x3fda5c760a34b8ec,0x3fe7cf2821c52391,2
+np.float64,0x7f898faac0331f55,0x5522b44a01408188,2
+np.float64,0x3fd55af4b7aab5e9,0x3fe631f6d19503b3,2
+np.float64,0xbfa30a255c261450,0xbfd55caf0826361d,2
+np.float64,0x7fdfb801343f7001,0x553fe7ee50b9199a,2
+np.float64,0x7fa89ee91c313dd1,0x552d528ca2a4d659,2
+np.float64,0xffea72921d34e524,0xd542eb01af2e470d,2
+np.float64,0x3feddf0f33fbbe1e,0x3fef462b67fc0a91,2
+np.float64,0x3fe36700b566ce01,0x3feb1596caa8eff7,2
+np.float64,0x7fe6284a25ac5093,0x5541d58be3956601,2
+np.float64,0xffda16f7c8b42df0,0xd53de4f722485205,2
+np.float64,0x7f9355b94026ab72,0x552578cdeb41d2ca,2
+np.float64,0xffd3a9b022275360,0xd53b347b02dcea21,2
+np.float64,0x3fcb7f4f4a36fe9f,0x3fe32a40e9f6c1aa,2
+np.float64,0x7fdb958836372b0f,0x553e746103f92111,2
+np.float64,0x3fd37761c0a6eec4,0x3fe5853c5654027e,2
+np.float64,0x3fe449f1a2e893e4,0x3feb7d9e4eacc356,2
+np.float64,0x80077dfbef0efbf9,0xaa9f4ed788d2fadd,2
+np.float64,0x4823aa7890476,0x2a9a6eb4b653bad5,2
+np.float64,0xbfede01a373bc034,0xbfef468895fbcd29,2
+np.float64,0xbfe2bac5f125758c,0xbfeac4811c4dd66f,2
+np.float64,0x3fec10373af8206e,0x3feea14529e0f178,2
+np.float64,0x3fe305e30ca60bc6,0x3feae81a2f9d0302,2
+np.float64,0xa9668c5f52cd2,0x2aa1910e3a8f2113,2
+np.float64,0xbfd98b1717b3162e,0xbfe78f75995335d2,2
+np.float64,0x800fa649c35f4c94,0xaaa402ae79026a8f,2
+np.float64,0xbfb07dacf620fb58,0xbfd9a7d33d93a30f,2
+np.float64,0x80015812f382b027,0xaa91a843e9c85c0e,2
+np.float64,0x3fc687d96c2d0fb3,0x3fe1ef0ac16319c5,2
+np.float64,0xbfecad2ecd795a5e,0xbfeed9f786697af0,2
+np.float64,0x1608c1242c119,0x2a91cd11e9b4ccd2,2
+np.float64,0x6df775e8dbeef,0x2a9e6ba8c71130eb,2
+np.float64,0xffe96e9332b2dd26,0xd542ac342d06299b,2
+np.float64,0x7fecb6a3b8396d46,0x5543718af8162472,2
+np.float64,0x800d379f893a6f3f,0xaaa2ea36bbcb9308,2
+np.float64,0x3f924cdb202499b6,0x3fd0bb90af8d1f79,2
+np.float64,0x0,0x0,2
+np.float64,0x7feaf3b365f5e766,0x5543099a160e2427,2
+np.float64,0x3fea169ed0742d3e,0x3fede4d526e404f8,2
+np.float64,0x7feaf5f2f775ebe5,0x55430a2196c5f35a,2
+np.float64,0xbfc80d4429301a88,0xbfe2541f2ddd3334,2
+np.float64,0xffc75203b32ea408,0xd536db2837068689,2
+np.float64,0xffed2850e63a50a1,0xd5438b1217b72b8a,2
+np.float64,0x7fc16b0e7f22d61c,0x5534bcd0bfddb6f0,2
+np.float64,0x7feee8ed09fdd1d9,0x5543ed5b3ca483ab,2
+np.float64,0x7fb6c7ee662d8fdc,0x5531fffb5d46dafb,2
+np.float64,0x3fd77cebf8aef9d8,0x3fe6e9242e2bd29d,2
+np.float64,0x3f81c33f70238680,0x3fca4c7f3c9848f7,2
+np.float64,0x3fd59fea92ab3fd5,0x3fe649c1558cadd5,2
+np.float64,0xffeba82d4bf7505a,0xd54333bad387f7bd,2
+np.float64,0xffd37630e1a6ec62,0xd53b1ca62818c670,2
+np.float64,0xffec2c1e70b8583c,0xd5435213dcd27c22,2
+np.float64,0x7fec206971f840d2,0x55434f6660a8ae41,2
+np.float64,0x3fed2964adba52c9,0x3fef0642fe72e894,2
+np.float64,0xffd08e30d6211c62,0xd539b060e0ae02da,2
+np.float64,0x3e5f976c7cbf4,0x2a992e6ff991a122,2
+np.float64,0xffe6eee761adddce,0xd5420a393c67182f,2
+np.float64,0xbfe8ec9a31f1d934,0xbfed714426f58147,2
+np.float64,0x7fefffffffffffff,0x554428a2f98d728b,2
+np.float64,0x3fb3ae8b2c275d16,0x3fdb36b81b18a546,2
+np.float64,0x800f73df4dfee7bf,0xaaa3ed1a3e2cf49c,2
+np.float64,0xffd0c8873b21910e,0xd539ce6a3eab5dfd,2
+np.float64,0x3facd6c49439ad80,0x3fd8886f46335df1,2
+np.float64,0x3935859c726b2,0x2a98775f6438dbb1,2
+np.float64,0x7feed879fbfdb0f3,0x5543e9d1ac239469,2
+np.float64,0xbfe84dd990f09bb3,0xbfed323af09543b1,2
+np.float64,0xbfe767cc5a6ecf98,0xbfecd4f39aedbacb,2
+np.float64,0xffd8bd91d5b17b24,0xd53d5eb3734a2609,2
+np.float64,0xbfe13edeb2a27dbe,0xbfea0a856f0b9656,2
+np.float64,0xd933dd53b267c,0x2aa3158784e428c9,2
+np.float64,0xbfef6fef987edfdf,0xbfefcfb1c160462b,2
+np.float64,0x8009eeda4893ddb5,0xaaa13268a41045b1,2
+np.float64,0xab48c7a156919,0x2aa1a1a9c124c87d,2
+np.float64,0xa997931d532f3,0x2aa192bfe5b7bbb4,2
+np.float64,0xffe39ce8b1e739d1,0xd5411fa1c5c2cbd8,2
+np.float64,0x7e7ac2f6fcf59,0x2a9fdf6f263a9e9f,2
+np.float64,0xbfee1e35a6fc3c6b,0xbfef5c25d32b4047,2
+np.float64,0xffe5589c626ab138,0xd5419d220cc9a6da,2
+np.float64,0x7fe12509bf224a12,0x55405f7036dc5932,2
+np.float64,0xa6f15ba94de2c,0x2aa17b3367b1fc1b,2
+np.float64,0x3fca8adbfa3515b8,0x3fe2f0ca775749e5,2
+np.float64,0xbfcb03aa21360754,0xbfe30d5b90ca41f7,2
+np.float64,0x3fefafb2da7f5f66,0x3fefe5251aead4e7,2
+np.float64,0xffd90a59d23214b4,0xd53d7cf63a644f0e,2
+np.float64,0x3fba499988349333,0x3fddf84154fab7e5,2
+np.float64,0x800a76a0bc54ed42,0xaaa17f68cf67f2fa,2
+np.float64,0x3fea33d15bb467a3,0x3fedeff7f445b2ff,2
+np.float64,0x8005d9b0726bb362,0xaa9cd48624afeca9,2
+np.float64,0x7febf42e9a77e85c,0x55434541d8073376,2
+np.float64,0xbfedfc4469bbf889,0xbfef505989f7ee7d,2
+np.float64,0x8001211f1422423f,0xaa90a9889d865349,2
+np.float64,0x800e852f7fdd0a5f,0xaaa3845f11917f8e,2
+np.float64,0xffefd613c87fac27,0xd5441fd17ec669b4,2
+np.float64,0x7fed2a74543a54e8,0x55438b8c637da8b8,2
+np.float64,0xb83d50ff707aa,0x2aa210b4fc11e4b2,2
+np.float64,0x10000000000000,0x2aa428a2f98d728b,2
+np.float64,0x474ad9208e97,0x2a84e5a31530368a,2
+np.float64,0xffd0c5498ea18a94,0xd539ccc0e5cb425e,2
+np.float64,0x8001a8e9c82351d4,0xaa92f1aee6ca5b7c,2
+np.float64,0xd28db1e5a51b6,0x2aa2e328c0788f4a,2
+np.float64,0x3bf734ac77ee7,0x2a98da65c014b761,2
+np.float64,0x3fe56e17c96adc30,0x3febff2b6b829b7a,2
+np.float64,0x7783113eef063,0x2a9f46c3f09eb42c,2
+np.float64,0x3fd69d4e42ad3a9d,0x3fe69f83a21679f4,2
+np.float64,0x3fd34f4841a69e90,0x3fe5766b3c771616,2
+np.float64,0x3febb49895b76931,0x3fee7fcb603416c9,2
+np.float64,0x7fe8d6cb55f1ad96,0x554286c3b3bf4313,2
+np.float64,0xbfe67c6ba36cf8d8,0xbfec730218f2e284,2
+np.float64,0xffef9d97723f3b2e,0xd54413e38b6c29be,2
+np.float64,0x12d8cd2a25b1b,0x2a90e5ccd37b8563,2
+np.float64,0x81fe019103fc0,0x2aa01524155e73c5,2
+np.float64,0x7fe95d546f72baa8,0x5542a7fabfd425ff,2
+np.float64,0x800e742f1f9ce85e,0xaaa37cbe09e1f874,2
+np.float64,0xffd96bd3a732d7a8,0xd53da3086071264a,2
+np.float64,0x4ef2691e9de4e,0x2a9b3d316047fd6d,2
+np.float64,0x1a91684c3522e,0x2a92f25913c213de,2
+np.float64,0x3d5151b87aa2b,0x2a9909dbd9a44a84,2
+np.float64,0x800d9049435b2093,0xaaa31424e32d94a2,2
+np.float64,0xffe5b25fcc2b64bf,0xd541b5b0416b40b5,2
+np.float64,0xffe0eb784c21d6f0,0xd5404d083c3d6bc6,2
+np.float64,0x8007ceefbf0f9de0,0xaa9fbe0d739368b4,2
+np.float64,0xb78529416f0b,0x2a8ca3b29b5b3f18,2
+np.float64,0x7fba61130034c225,0x5532e6d4ca0f2918,2
+np.float64,0x3fba8d67ae351acf,0x3fde11efd6239b09,2
+np.float64,0x3fe7f24c576fe498,0x3fed0d63947a854d,2
+np.float64,0x2bb58dec576b3,0x2a965de7fca12aff,2
+np.float64,0xbfe86ceec4f0d9de,0xbfed3ea7f1d084e2,2
+np.float64,0x7fd1a7f7bca34fee,0x553a3f01b67fad2a,2
+np.float64,0x3fd9a43acfb34874,0x3fe7972dc5d8dfd6,2
+np.float64,0x7fd9861acdb30c35,0x553dad3b1bbb3b4d,2
+np.float64,0xffecc0c388398186,0xd54373d3b903deec,2
+np.float64,0x3fa6f86e9c2df0e0,0x3fd6bdbe40fcf710,2
+np.float64,0x800ddd99815bbb33,0xaaa33820d2f889bb,2
+np.float64,0x7fe087089b610e10,0x55402c868348a6d3,2
+np.float64,0x3fdf43d249be87a5,0x3fe933d29fbf7c23,2
+np.float64,0x7fe4f734c7a9ee69,0x5541822e56c40725,2
+np.float64,0x3feb39a9d3b67354,0x3fee526bf1f69f0e,2
+np.float64,0x3fe61454a0ec28a9,0x3fec46d7c36f7566,2
+np.float64,0xbfeafaa0a375f541,0xbfee3af2e49d457a,2
+np.float64,0x3fda7378e1b4e6f0,0x3fe7d613a3f92c40,2
+np.float64,0xe3e31c5fc7c64,0x2aa3645c12e26171,2
+np.float64,0xbfe97a556df2f4ab,0xbfeda8aa84cf3544,2
+np.float64,0xff612f9c80225f00,0xd514a51e5a2a8a97,2
+np.float64,0x800c51c8a0f8a391,0xaaa279fe7d40b50b,2
+np.float64,0xffd6f9d2312df3a4,0xd53ca783a5f8d110,2
+np.float64,0xbfead48bd7f5a918,0xbfee2cb2f89c5e57,2
+np.float64,0x800f5949e89eb294,0xaaa3e1a67a10cfef,2
+np.float64,0x800faf292b7f5e52,0xaaa40675e0c96cfd,2
+np.float64,0xbfedc238453b8470,0xbfef3c179d2d0209,2
+np.float64,0x3feb0443c5760888,0x3fee3e8bf29089c2,2
+np.float64,0xb26f69e164ded,0x2aa1df9f3dd7d765,2
+np.float64,0x3fcacdc053359b80,0x3fe300a67765b667,2
+np.float64,0x3fe8b274647164e8,0x3fed5a4cd4da8155,2
+np.float64,0x291e6782523ce,0x2a95ea7ac1b13a68,2
+np.float64,0xbfc4fc094e29f814,0xbfe1838671fc8513,2
+np.float64,0x3fbf1301f23e2600,0x3fdfb03a6f13e597,2
+np.float64,0xffeb36554ab66caa,0xd543193d8181e4f9,2
+np.float64,0xbfd969a52db2d34a,0xbfe78528ae61f16d,2
+np.float64,0x800cccd04d3999a1,0xaaa2b6b7a2d2d2d6,2
+np.float64,0x808eb4cb011d7,0x2aa005effecb2b4a,2
+np.float64,0x7fe839b3f9b07367,0x55425f61e344cd6d,2
+np.float64,0xbfeb25b6ed764b6e,0xbfee4b0234fee365,2
+np.float64,0xffefffffffffffff,0xd54428a2f98d728b,2
+np.float64,0xbfe01305da60260c,0xbfe9700b784af7e9,2
+np.float64,0xffcbf36b0a37e6d8,0xd538474b1d74ffe1,2
+np.float64,0xffaeebe3e83dd7c0,0xd52fa2e8dabf7209,2
+np.float64,0xbfd9913bf0b32278,0xbfe7915907aab13c,2
+np.float64,0xbfe7d125d9efa24c,0xbfecfff563177706,2
+np.float64,0xbfee98d23cbd31a4,0xbfef867ae393e446,2
+np.float64,0x3fe30efb67e61df6,0x3feaec6344633d11,2
+np.float64,0x1,0x2990000000000000,2
+np.float64,0x7fd5524fd3aaa49f,0x553bf30d18ab877e,2
+np.float64,0xc98b403f93168,0x2aa29d2fadb13c07,2
+np.float64,0xffe57080046ae100,0xd541a3b1b687360e,2
+np.float64,0x7fe20bade5e4175b,0x5540a79b94294f40,2
+np.float64,0x3fe155400a22aa80,0x3fea15c45f5b5837,2
+np.float64,0x7fe428dc8f6851b8,0x554147fd2ce93cc1,2
+np.float64,0xffefb77eb67f6efc,0xd544195dcaff4980,2
+np.float64,0x3fe49e733b293ce6,0x3feba394b833452a,2
+np.float64,0x38e01e3e71c05,0x2a986b2c955bad21,2
+np.float64,0x7fe735eb376e6bd5,0x55421cc51290d92d,2
+np.float64,0xbfd81d8644b03b0c,0xbfe71ce6d6fbd51a,2
+np.float64,0x8009a32325134647,0xaaa10645d0e6b0d7,2
+np.float64,0x56031ab8ac064,0x2a9c074be40b1f80,2
+np.float64,0xff8989aa30331340,0xd522b2d319a0ac6e,2
+np.float64,0xbfd6c183082d8306,0xbfe6ab8ffb3a8293,2
+np.float64,0x7ff8000000000000,0x7ff8000000000000,2
+np.float64,0xbfe17b68b1e2f6d2,0xbfea28dac8e0c457,2
+np.float64,0x3fbb50e42236a1c8,0x3fde5b090d51e3bd,2
+np.float64,0xffc2bb7cbf2576f8,0xd5353f1b3571c17f,2
+np.float64,0xbfe7576bca6eaed8,0xbfecce388241f47c,2
+np.float64,0x3fe7b52b04ef6a56,0x3fecf495bef99e7e,2
+np.float64,0xffe5511af82aa236,0xd5419b11524e8350,2
+np.float64,0xbfe66d5edf2cdabe,0xbfec6ca7d7b5be8c,2
+np.float64,0xc84a0ba790942,0x2aa29346f16a2cb4,2
+np.float64,0x6db5e7a0db6be,0x2a9e659c0e8244a0,2
+np.float64,0x7fef8f7b647f1ef6,0x554410e67af75d27,2
+np.float64,0xbfe2b4ada7e5695c,0xbfeac1997ec5a064,2
+np.float64,0xbfe99372e03326e6,0xbfedb2662b287543,2
+np.float64,0x3fa45d352428ba6a,0x3fd5d8a895423abb,2
+np.float64,0x3fa029695c2052d3,0x3fd439f858998886,2
+np.float64,0xffe0a9bd3261537a,0xd54037d0cd8bfcda,2
+np.float64,0xbfef83e09a7f07c1,0xbfefd66a4070ce73,2
+np.float64,0x7fee3dcc31fc7b97,0x5543c8503869407e,2
+np.float64,0xffbd16f1603a2de0,0xd533872fa5be978b,2
+np.float64,0xbfe8173141b02e62,0xbfed1c478614c6f4,2
+np.float64,0xbfef57aa277eaf54,0xbfefc77fdab27771,2
+np.float64,0x7fe883a02f31073f,0x554271ff0e3208da,2
+np.float64,0xe3adb63bc75b7,0x2aa362d833d0e41c,2
+np.float64,0x8001c430bac38862,0xaa93575026d26510,2
+np.float64,0x12fb347225f67,0x2a90f00eb9edb3fe,2
+np.float64,0x3fe53f83cbaa7f08,0x3febead40de452c2,2
+np.float64,0xbfe7f67227efece4,0xbfed0f10e32ad220,2
+np.float64,0xb8c5b45d718b7,0x2aa2152912cda86d,2
+np.float64,0x3fd23bb734a4776e,0x3fe50e5d3008c095,2
+np.float64,0x8001fd558ee3faac,0xaa941faa1f7ed450,2
+np.float64,0xffe6bbeda9ed77db,0xd541fcd185a63afa,2
+np.float64,0x4361d79086c3c,0x2a99d692237c30b7,2
+np.float64,0xbfd012f004a025e0,0xbfe43093e290fd0d,2
+np.float64,0xffe1d8850423b10a,0xd54097cf79d8d01e,2
+np.float64,0x3fccf4df7939e9bf,0x3fe37f8cf8be6436,2
+np.float64,0x8000546bc6c0a8d8,0xaa861bb3588556f2,2
+np.float64,0xbfecb4d6ba7969ae,0xbfeedcb6239135fe,2
+np.float64,0xbfaeb425cc3d6850,0xbfd90cfc103bb896,2
+np.float64,0x800ec037ec7d8070,0xaaa39eae8bde9774,2
+np.float64,0xbfeeaf863dfd5f0c,0xbfef8e4514772a8a,2
+np.float64,0xffec67c6c4b8cf8d,0xd5435fad89f900cf,2
+np.float64,0x3fda4498da348932,0x3fe7c7f6b3f84048,2
+np.float64,0xbfd05fd3dea0bfa8,0xbfe4509265a9b65f,2
+np.float64,0x3fe42cc713a8598e,0x3feb706ba9cd533c,2
+np.float64,0xec22d4d7d845b,0x2aa39f8cccb9711c,2
+np.float64,0x7fda30606c3460c0,0x553deea865065196,2
+np.float64,0xbfd58cba8bab1976,0xbfe64327ce32d611,2
+np.float64,0xadd521c75baa4,0x2aa1b7efce201a98,2
+np.float64,0x7fed43c1027a8781,0x55439131832b6429,2
+np.float64,0x800bee278fb7dc4f,0xaaa247a71e776db4,2
+np.float64,0xbfe9be5dd2737cbc,0xbfedc2f9501755b0,2
+np.float64,0x8003f4854447e90b,0xaa994d9b5372b13b,2
+np.float64,0xbfe5d0f867eba1f1,0xbfec29f8dd8b33a4,2
+np.float64,0x3fd79102d5af2206,0x3fe6efaa7a1efddb,2
+np.float64,0xbfeae783c835cf08,0xbfee33cdb4a44e81,2
+np.float64,0x3fcf1713e83e2e28,0x3fe3f7414753ddfb,2
+np.float64,0xffe5ab3cff2b567a,0xd541b3bf0213274a,2
+np.float64,0x7fe0fc65d8a1f8cb,0x554052761ac96386,2
+np.float64,0x7e81292efd026,0x2a9fdff8c01ae86f,2
+np.float64,0x80091176039222ec,0xaaa0aebf0565dfa6,2
+np.float64,0x800d2bf5ab5a57ec,0xaaa2e4a4c31e7e29,2
+np.float64,0xffd1912ea923225e,0xd53a33b2856726ab,2
+np.float64,0x800869918ed0d323,0xaaa0453408e1295d,2
+np.float64,0xffba0898fa341130,0xd532d19b202a9646,2
+np.float64,0xbfe09fac29613f58,0xbfe9b9687b5811a1,2
+np.float64,0xbfbd4ae82e3a95d0,0xbfdf1220f6f0fdfa,2
+np.float64,0xffea11d27bb423a4,0xd542d3d3e1522474,2
+np.float64,0xbfe6b05705ad60ae,0xbfec88d6bcab2683,2
+np.float64,0x3fe624a3f2ec4948,0x3fec4dcc78ddf871,2
+np.float64,0x53483018a6907,0x2a9bba8f92006b69,2
+np.float64,0xbfec0a6eeb7814de,0xbfee9f2a741248d7,2
+np.float64,0x3fe8c8ce6371919d,0x3fed63250c643482,2
+np.float64,0xbfe26b0ef964d61e,0xbfea9e511db83437,2
+np.float64,0xffa0408784208110,0xd52987f62c369ae9,2
+np.float64,0xffc153abc322a758,0xd534b384b5c5fe63,2
+np.float64,0xbfbdce88a63b9d10,0xbfdf4065ef0b01d4,2
+np.float64,0xffed4a4136fa9482,0xd54392a450f8b0af,2
+np.float64,0x8007aa18748f5432,0xaa9f8bd2226d4299,2
+np.float64,0xbfdab4d3e8b569a8,0xbfe7e9a5402540e5,2
+np.float64,0x7fe68914f92d1229,0x5541ef5e78fa35de,2
+np.float64,0x800a538bb1b4a718,0xaaa16bc487711295,2
+np.float64,0xffe02edbc8605db7,0xd5400f8f713df890,2
+np.float64,0xffe8968053712d00,0xd54276b9cc7f460a,2
+np.float64,0x800a4ce211d499c5,0xaaa1680491deb40c,2
+np.float64,0x3f988080f8310102,0x3fd2713691e99329,2
+np.float64,0xf64e42a7ec9c9,0x2aa3e6a7af780878,2
+np.float64,0xff73cc7100279900,0xd51b4478c3409618,2
+np.float64,0x71e6722ce3ccf,0x2a9ec76ddf296ce0,2
+np.float64,0x8006ca16ab0d942e,0xaa9e4bfd862af570,2
+np.float64,0x8000000000000000,0x8000000000000000,2
+np.float64,0xbfed373e02ba6e7c,0xbfef0b2b7bb767b3,2
+np.float64,0xa6cb0f694d962,0x2aa179dd16b0242b,2
+np.float64,0x7fec14626cf828c4,0x55434ca55b7c85d5,2
+np.float64,0x3fcda404513b4808,0x3fe3a68e8d977752,2
+np.float64,0xbfeb94995f772933,0xbfee74091d288b81,2
+np.float64,0x3fce2299a13c4530,0x3fe3c2603f28d23b,2
+np.float64,0xffd07f4534a0fe8a,0xd539a8a6ebc5a603,2
+np.float64,0x7fdb1c651e3638c9,0x553e478a6385c86b,2
+np.float64,0x3fec758336f8eb06,0x3feec5f3b92c8b28,2
+np.float64,0x796fc87cf2dfa,0x2a9f7184a4ad8c49,2
+np.float64,0x3fef9ba866ff3750,0x3fefde6a446fc2cd,2
+np.float64,0x964d26c72c9a5,0x2aa0e143f1820179,2
+np.float64,0xbfef6af750bed5ef,0xbfefce04870a97bd,2
+np.float64,0x3fe2f3961aa5e72c,0x3feadf769321a3ff,2
+np.float64,0xbfd6b706e9ad6e0e,0xbfe6a8141c5c3b5d,2
+np.float64,0x7fe0ecc40a21d987,0x55404d72c2b46a82,2
+np.float64,0xbfe560d19deac1a3,0xbfebf962681a42a4,2
+np.float64,0xbfea37170ab46e2e,0xbfedf136ee9df02b,2
+np.float64,0xbfebf78947b7ef12,0xbfee9847ef160257,2
+np.float64,0x800551f8312aa3f1,0xaa9bee7d3aa5491b,2
+np.float64,0xffed2513897a4a26,0xd5438a58c4ae28ec,2
+np.float64,0x7fd962d75cb2c5ae,0x553d9f8a0c2016f3,2
+np.float64,0x3fefdd8512bfbb0a,0x3feff47d8da7424d,2
+np.float64,0xbfefa5b43bff4b68,0xbfefe1ca42867af0,2
+np.float64,0xbfc8a2853531450c,0xbfe279bb7b965729,2
+np.float64,0x800c8843bc391088,0xaaa2951344e7b29b,2
+np.float64,0x7fe22587bae44b0e,0x5540af8bb58cfe86,2
+np.float64,0xbfe159fae822b3f6,0xbfea182394eafd8d,2
+np.float64,0xbfe6fdfd50edfbfa,0xbfeca93f2a3597d0,2
+np.float64,0xbfe5cd5afaeb9ab6,0xbfec286a8ce0470f,2
+np.float64,0xbfc84bb97f309774,0xbfe263ef0f8f1f6e,2
+np.float64,0x7fd9c1e548b383ca,0x553dc4556874ecb9,2
+np.float64,0x7fda43d33bb487a5,0x553df60f61532fc0,2
+np.float64,0xbfe774bd25eee97a,0xbfecda42e8578c1f,2
+np.float64,0x800df1f5ab9be3ec,0xaaa34184712e69db,2
+np.float64,0xbff0000000000000,0xbff0000000000000,2
+np.float64,0x3fe14ec21b629d84,0x3fea128244215713,2
+np.float64,0x7fc1ce7843239cf0,0x5534e3fa8285b7b8,2
+np.float64,0xbfe922b204724564,0xbfed86818687d649,2
+np.float64,0x3fc58924fb2b1248,0x3fe1aa715ff6ebbf,2
+np.float64,0x8008b637e4d16c70,0xaaa0760b53abcf46,2
+np.float64,0xffbf55bd4c3eab78,0xd53404a23091a842,2
+np.float64,0x9f6b4a753ed6a,0x2aa136ef9fef9596,2
+np.float64,0xbfd11da7f8a23b50,0xbfe49deb493710d8,2
+np.float64,0x800a2f07fcd45e10,0xaaa157237c98b4f6,2
+np.float64,0x3fdd4defa4ba9bdf,0x3fe8aa0bcf895f4f,2
+np.float64,0x7fe9b0ab05f36155,0x5542bc5335414473,2
+np.float64,0x3fe89c97de313930,0x3fed51a1189b8982,2
+np.float64,0x3fdd45c8773a8b91,0x3fe8a7c2096fbf5a,2
+np.float64,0xbfeb6f64daf6deca,0xbfee665167ef43ad,2
+np.float64,0xffdf9da1c4bf3b44,0xd53fdf141944a983,2
+np.float64,0x3fde092ed0bc125c,0x3fe8de25bfbfc2db,2
+np.float64,0xbfcb21f96b3643f4,0xbfe3147904c258cf,2
+np.float64,0x800c9c934f993927,0xaaa29f17c43f021b,2
+np.float64,0x9b91814d37230,0x2aa11329e59bf6b0,2
+np.float64,0x3fe28a7e0b6514fc,0x3feaad6d23e2eadd,2
+np.float64,0xffecf38395f9e706,0xd5437f3ee1cd61e4,2
+np.float64,0x3fcade92a935bd25,0x3fe3049f4c1da1d0,2
+np.float64,0x800ab25d95d564bc,0xaaa1a076d7c66e04,2
+np.float64,0xffc0989e1e21313c,0xd53467f3b8158298,2
+np.float64,0x3fd81523eeb02a48,0x3fe71a38d2da8a82,2
+np.float64,0x7fe5b9dd402b73ba,0x5541b7b9b8631010,2
+np.float64,0x2c160d94582c3,0x2a966e51b503a3d1,2
+np.float64,0x2c416ffa5882f,0x2a9675aaef8b29c4,2
+np.float64,0x7fefe2ff01bfc5fd,0x55442289faf22b86,2
+np.float64,0xbfd469bf5d28d37e,0xbfe5dd239ffdc7eb,2
+np.float64,0xbfdd56f3eabaade8,0xbfe8ac93244ca17b,2
+np.float64,0xbfe057b89160af71,0xbfe9941557340bb3,2
+np.float64,0x800c50e140b8a1c3,0xaaa2798ace9097ee,2
+np.float64,0xbfda5a8984b4b514,0xbfe7ce93d65a56b0,2
+np.float64,0xbfcd6458323ac8b0,0xbfe39872514127bf,2
+np.float64,0x3fefb1f5ebff63ec,0x3fefe5e761b49b89,2
+np.float64,0x3fea3abc1df47578,0x3fedf29a1c997863,2
+np.float64,0x7fcb4a528e3694a4,0x553815f169667213,2
+np.float64,0x8c77da7b18efc,0x2aa080e52bdedb54,2
+np.float64,0x800e5dde4c5cbbbd,0xaaa372b16fd8b1ad,2
+np.float64,0x3fd2976038a52ec0,0x3fe5316b4f79fdbc,2
+np.float64,0x69413a0ed2828,0x2a9dfacd9cb44286,2
+np.float64,0xbfebbac0bdb77582,0xbfee820d9288b631,2
+np.float64,0x1a12aa7c34256,0x2a92d407e073bbfe,2
+np.float64,0xbfc41a27c3283450,0xbfe143c8665b0d3c,2
+np.float64,0xffe4faa41369f548,0xd54183230e0ce613,2
+np.float64,0xbfdeae81f23d5d04,0xbfe90b734bf35b68,2
+np.float64,0x3fc984ba58330975,0x3fe2b19e9052008e,2
+np.float64,0x7fe6e51b8d2dca36,0x554207a74ae2bb39,2
+np.float64,0x80081a58a81034b2,0xaaa0117d4aff11c8,2
+np.float64,0x7fde3fddfe3c7fbb,0x553f67d0082acc67,2
+np.float64,0x3fac7c999038f933,0x3fd86ec2f5dc3aa4,2
+np.float64,0x7fa26b4c4c24d698,0x552a9e6ea8545c18,2
+np.float64,0x3fdacd06e6b59a0e,0x3fe7f0dc0e8f9c6d,2
+np.float64,0x80064b62cbec96c6,0xaa9d8ac0506fdd05,2
+np.float64,0xb858116170b1,0x2a8caea703d9ccc8,2
+np.float64,0xbfe8d94ccef1b29a,0xbfed69a8782cbf3d,2
+np.float64,0x8005607d6a6ac0fc,0xaa9c07cf8620b037,2
+np.float64,0xbfe66a52daacd4a6,0xbfec6b5e403e6864,2
+np.float64,0x7fc398c2e0273185,0x5535918245894606,2
+np.float64,0x74b2d7dce965c,0x2a9f077020defdbc,2
+np.float64,0x7fe8f7a4d9b1ef49,0x55428eeae210e8eb,2
+np.float64,0x80027deddc84fbdc,0xaa95b11ff9089745,2
+np.float64,0xffeba2a94e774552,0xd5433273f6568902,2
+np.float64,0x80002f8259405f05,0xaa8240b68d7b9dc4,2
+np.float64,0xbfdf0d84883e1b0a,0xbfe92532c69c5802,2
+np.float64,0xbfcdfa7b6b3bf4f8,0xbfe3b997a84d0914,2
+np.float64,0x800c18b04e183161,0xaaa25d46d60b15c6,2
+np.float64,0xffeaf1e37c35e3c6,0xd543092cd929ac19,2
+np.float64,0xbfc5aa07752b5410,0xbfe1b36ab5ec741f,2
+np.float64,0x3fe5c491d1eb8924,0x3fec24a1c3f6a178,2
+np.float64,0xbfeb736937f6e6d2,0xbfee67cd296e6fa9,2
+np.float64,0xffec3d5718787aad,0xd5435602e1a2cc43,2
+np.float64,0x7fe71e1da86e3c3a,0x55421691ead882cb,2
+np.float64,0x3fdd6ed0c93adda2,0x3fe8b341d066c43c,2
+np.float64,0x7fbe3d7a203c7af3,0x5533c83e53283430,2
+np.float64,0x3fdc20cb56384197,0x3fe854676360aba9,2
+np.float64,0xb7a1ac636f436,0x2aa20b9d40d66e78,2
+np.float64,0x3fb1491bb8229237,0x3fda0fabad1738ee,2
+np.float64,0xbfdf9c0ce73f381a,0xbfe94b716dbe35ee,2
+np.float64,0xbfbd4f0ad23a9e18,0xbfdf1397329a2dce,2
+np.float64,0xbfe4e0caac69c196,0xbfebc119b8a181cd,2
+np.float64,0x5753641aaea6d,0x2a9c2ba3e92b0cd2,2
+np.float64,0x72bb814ae5771,0x2a9eda92fada66de,2
+np.float64,0x57ed8f5aafdb3,0x2a9c3c2e1d42e609,2
+np.float64,0xffec33359c38666a,0xd54353b2acd0daf1,2
+np.float64,0x3fa5fe6e8c2bfce0,0x3fd66a0b3bf2720a,2
+np.float64,0xffe2dc8d7ca5b91a,0xd540e6ebc097d601,2
+np.float64,0x7fd99d260eb33a4b,0x553db626c9c75f78,2
+np.float64,0xbfe2dd73e425bae8,0xbfead4fc4b93a727,2
+np.float64,0xdcd4a583b9a95,0x2aa33094c9a17ad7,2
+np.float64,0x7fb0af6422215ec7,0x553039a606e8e64f,2
+np.float64,0x7fdfab6227bf56c3,0x553fe3b26164aeda,2
+np.float64,0x1e4d265e3c9a6,0x2a93cba8a1a8ae6d,2
+np.float64,0xbfdc7d097238fa12,0xbfe86ee2f24fd473,2
+np.float64,0x7fe5d35d29eba6b9,0x5541bea5878bce2b,2
+np.float64,0xffcb886a903710d4,0xd53828281710aab5,2
+np.float64,0xffe058c7ffe0b190,0xd5401d61e9a7cbcf,2
+np.float64,0x3ff0000000000000,0x3ff0000000000000,2
+np.float64,0xffd5b1c1132b6382,0xd53c1c839c098340,2
+np.float64,0x3fe2e7956725cf2b,0x3fead9c907b9d041,2
+np.float64,0x800a8ee293951dc6,0xaaa18ce3f079f118,2
+np.float64,0x7febcd3085b79a60,0x55433c47e1f822ad,2
+np.float64,0x3feb0e14cd761c2a,0x3fee423542102546,2
+np.float64,0x3fb45e6d0628bcda,0x3fdb86db67d0c992,2
+np.float64,0x7fa836e740306dce,0x552d2907cb8118b2,2
+np.float64,0x3fd15ba25b22b745,0x3fe4b6b018409d78,2
+np.float64,0xbfb59980ce2b3300,0xbfdc1206274cb51d,2
+np.float64,0x3fdef1b87fbde371,0x3fe91dafc62124a1,2
+np.float64,0x7fed37a4337a6f47,0x55438e7e0b50ae37,2
+np.float64,0xffe6c87633ad90ec,0xd542001f216ab448,2
+np.float64,0x8008d2548ab1a4a9,0xaaa087ad272d8e17,2
+np.float64,0xbfd1d6744da3ace8,0xbfe4e71965adda74,2
+np.float64,0xbfb27f751224fee8,0xbfdaa82132775406,2
+np.float64,0x3fe2b336ae65666d,0x3feac0e6b13ec2d2,2
+np.float64,0xffc6bac2262d7584,0xd536a951a2eecb49,2
+np.float64,0x7fdb661321b6cc25,0x553e62dfd7fcd3f3,2
+np.float64,0xffe83567d5706acf,0xd5425e4bb5027568,2
+np.float64,0xbf7f0693e03e0d00,0xbfc9235314d53f82,2
+np.float64,0x3feb32b218766564,0x3fee4fd5847f3722,2
+np.float64,0x3fec25d33df84ba6,0x3feea91fcd4aebab,2
+np.float64,0x7fe17abecb22f57d,0x55407a8ba661207c,2
+np.float64,0xbfe5674b1eeace96,0xbfebfc351708dc70,2
+np.float64,0xbfe51a2d2f6a345a,0xbfebda702c9d302a,2
+np.float64,0x3fec05584af80ab0,0x3fee9d502a7bf54d,2
+np.float64,0xffda8871dcb510e4,0xd53e10105f0365b5,2
+np.float64,0xbfc279c31824f388,0xbfe0c9354d871484,2
+np.float64,0x1cbed61e397dc,0x2a937364712cd518,2
+np.float64,0x800787d198af0fa4,0xaa9f5c847affa1d2,2
+np.float64,0x80079f6d65af3edc,0xaa9f7d2863368bbd,2
+np.float64,0xb942f1e97285e,0x2aa2193e0c513b7f,2
+np.float64,0x7fe9078263320f04,0x554292d85dee2c18,2
+np.float64,0xbfe4de0761a9bc0f,0xbfebbfe04116b829,2
+np.float64,0xbfdbe6f3fc37cde8,0xbfe843aea59a0749,2
+np.float64,0xffcb6c0de136d81c,0xd5381fd9c525b813,2
+np.float64,0x9b6bda9336d7c,0x2aa111c924c35386,2
+np.float64,0x3fe17eece422fdda,0x3fea2a9bacd78607,2
+np.float64,0xd8011c49b0024,0x2aa30c87574fc0c6,2
+np.float64,0xbfc0a08b3f214118,0xbfe034d48f0d8dc0,2
+np.float64,0x3fd60adb1eac15b8,0x3fe66e42e4e7e6b5,2
+np.float64,0x80011d68ea023ad3,0xaa909733befbb962,2
+np.float64,0xffb35ac32426b588,0xd5310c4be1c37270,2
+np.float64,0x3fee8b56c9bd16ae,0x3fef81d8d15f6939,2
+np.float64,0x3fdc10a45e382149,0x3fe84fbe4cf11e68,2
+np.float64,0xbfc85dc45e30bb88,0xbfe2687b5518abde,2
+np.float64,0x3fd53b85212a770a,0x3fe6270d6d920d0f,2
+np.float64,0x800fc158927f82b1,0xaaa40e303239586f,2
+np.float64,0x11af5e98235ed,0x2a908b04a790083f,2
+np.float64,0xbfe2a097afe54130,0xbfeab80269eece99,2
+np.float64,0xbfd74ac588ae958c,0xbfe6d8ca3828d0b8,2
+np.float64,0xffea18ab2ef43156,0xd542d579ab31df1e,2
+np.float64,0xbfecda7058f9b4e1,0xbfeeea29c33b7913,2
+np.float64,0x3fc4ac56ed2958b0,0x3fe16d3e2bd7806d,2
+np.float64,0x3feccc898cb99913,0x3feee531f217dcfa,2
+np.float64,0xffeb3a64c5b674c9,0xd5431a30a41f0905,2
+np.float64,0x3fe5a7ee212b4fdc,0x3fec1844af9076fc,2
+np.float64,0x80080fdb52301fb7,0xaaa00a8b4274db67,2
+np.float64,0x800b3e7e47d67cfd,0xaaa1ec2876959852,2
+np.float64,0x80063fb8ee2c7f73,0xaa9d7875c9f20d6f,2
+np.float64,0x7fdacf80d0b59f01,0x553e2acede4c62a8,2
+np.float64,0x401e9b24803d4,0x2a996a0a75d0e093,2
+np.float64,0x3fe6c29505ed852a,0x3fec907a6d8c10af,2
+np.float64,0x8005c04ee2cb809f,0xaa9caa9813faef46,2
+np.float64,0xbfe1360f21e26c1e,0xbfea06155d6985b6,2
+np.float64,0xffc70606682e0c0c,0xd536c239b9d4be0a,2
+np.float64,0x800e639afefcc736,0xaaa37547d0229a26,2
+np.float64,0x3fe5589290aab125,0x3febf5c925c4e6db,2
+np.float64,0x8003b59330276b27,0xaa98c47e44524335,2
+np.float64,0x800d67ec22dacfd8,0xaaa301251b6a730a,2
+np.float64,0x7fdaeb5025b5d69f,0x553e35397dfe87eb,2
+np.float64,0x3fdae32a24b5c654,0x3fe7f771bc108f6c,2
+np.float64,0xffe6c1fc93ad83f8,0xd541fe6a6a716756,2
+np.float64,0xbfd7b9c1d32f7384,0xbfe6fcdae563d638,2
+np.float64,0x800e1bea06fc37d4,0xaaa354c0bf61449c,2
+np.float64,0xbfd78f097aaf1e12,0xbfe6ef068329bdf4,2
+np.float64,0x7fea6a400874d47f,0x5542e905978ad722,2
+np.float64,0x8008b4377cb1686f,0xaaa074c87eee29f9,2
+np.float64,0x8002f3fb8d45e7f8,0xaa96f47ac539b614,2
+np.float64,0xbfcf2b3fd13e5680,0xbfe3fb91c0cc66ad,2
+np.float64,0xffecca2f5279945e,0xd54375f361075927,2
+np.float64,0x7ff0000000000000,0x7ff0000000000000,2
+np.float64,0x7f84d5a5a029ab4a,0x552178d1d4e8640e,2
+np.float64,0x3fea8a4b64351497,0x3fee10c332440eb2,2
+np.float64,0x800fe01ac1dfc036,0xaaa41b34d91a4bee,2
+np.float64,0x3fc0b3d8872167b1,0x3fe03b178d354f8d,2
+np.float64,0x5ee8b0acbdd17,0x2a9cf69f2e317729,2
+np.float64,0x8006ef0407adde09,0xaa9e82888f3dd83e,2
+np.float64,0x7fdbb08a07b76113,0x553e7e4e35b938b9,2
+np.float64,0x49663f9c92cc9,0x2a9a95e0affe5108,2
+np.float64,0x7fd9b87e79b370fc,0x553dc0b5cff3dc7d,2
+np.float64,0xbfd86ae657b0d5cc,0xbfe73584d02bdd2b,2
+np.float64,0x3fd4d4a13729a942,0x3fe6030a962aaaf8,2
+np.float64,0x7fcc246bcb3848d7,0x5538557309449bba,2
+np.float64,0xbfdc86a7d5b90d50,0xbfe871a2983c2a29,2
+np.float64,0xd2a6e995a54dd,0x2aa2e3e9c0fdd6c0,2
+np.float64,0x3f92eb447825d680,0x3fd0eb4fd2ba16d2,2
+np.float64,0x800d4001697a8003,0xaaa2ee358661b75c,2
+np.float64,0x3fd3705fd1a6e0c0,0x3fe582a6f321d7d6,2
+np.float64,0xbfcfdf51533fbea4,0xbfe421c3bdd9f2a3,2
+np.float64,0x3fe268e87964d1d1,0x3fea9d47e08aad8a,2
+np.float64,0x24b8901e49713,0x2a951adeefe7b31b,2
+np.float64,0x3fedb35d687b66bb,0x3fef36e440850bf8,2
+np.float64,0x3fb7ab5cbe2f56c0,0x3fdcf097380721c6,2
+np.float64,0x3f8c4eaa10389d54,0x3fceb7ecb605b73b,2
+np.float64,0xbfed831ed6fb063e,0xbfef25f462a336f1,2
+np.float64,0x7fd8c52112318a41,0x553d61b0ee609f58,2
+np.float64,0xbfe71c4ff76e38a0,0xbfecb5d32e789771,2
+np.float64,0xbfe35fb7b166bf70,0xbfeb12328e75ee6b,2
+np.float64,0x458e1a3a8b1c4,0x2a9a1cebadc81342,2
+np.float64,0x8003c1b3ad478368,0xaa98df5ed060b28c,2
+np.float64,0x7ff4000000000000,0x7ffc000000000000,2
+np.float64,0x7fe17098c162e131,0x5540775a9a3a104f,2
+np.float64,0xbfd95cb71732b96e,0xbfe7812acf7ea511,2
+np.float64,0x8000000000000001,0xa990000000000000,2
+np.float64,0xbfde0e7d9ebc1cfc,0xbfe8df9ca9e49a5b,2
+np.float64,0xffef4f67143e9ecd,0xd5440348a6a2f231,2
+np.float64,0x7fe37d23c826fa47,0x5541165de17caa03,2
+np.float64,0xbfcc0e5f85381cc0,0xbfe34b44b0deefe9,2
+np.float64,0x3fe858f1c470b1e4,0x3fed36ab90557d89,2
+np.float64,0x800e857278fd0ae5,0xaaa3847d13220545,2
+np.float64,0x3febd31a66f7a635,0x3fee8af90e66b043,2
+np.float64,0x7fd3fde1b127fbc2,0x553b5b186a49b968,2
+np.float64,0x3fd3dabb8b27b577,0x3fe5a99b446bed26,2
+np.float64,0xffeb4500f1768a01,0xd5431cab828e254a,2
+np.float64,0xffccca8fc6399520,0xd53884f8b505e79e,2
+np.float64,0xffeee9406b7dd280,0xd543ed6d27a1a899,2
+np.float64,0xffecdde0f0f9bbc1,0xd5437a6258b14092,2
+np.float64,0xe6b54005cd6a8,0x2aa378c25938dfda,2
+np.float64,0x7fe610f1022c21e1,0x5541cf460b972925,2
+np.float64,0xbfe5a170ec6b42e2,0xbfec1576081e3232,2
diff --git a/numpy/core/tests/data/umath-validation-set-cos b/numpy/core/tests/data/umath-validation-set-cos
deleted file mode 100644
index 2e75f044c..000000000
--- a/numpy/core/tests/data/umath-validation-set-cos
+++ /dev/null
@@ -1,665 +0,0 @@
-dtype,input,output,ulperrortol
-## +ve denormals ##
-np.float32,0x004b4716,0x3f800000,2
-np.float32,0x007b2490,0x3f800000,2
-np.float32,0x007c99fa,0x3f800000,2
-np.float32,0x00734a0c,0x3f800000,2
-np.float32,0x0070de24,0x3f800000,2
-np.float32,0x007fffff,0x3f800000,2
-np.float32,0x00000001,0x3f800000,2
-## -ve denormals ##
-np.float32,0x80495d65,0x3f800000,2
-np.float32,0x806894f6,0x3f800000,2
-np.float32,0x80555a76,0x3f800000,2
-np.float32,0x804e1fb8,0x3f800000,2
-np.float32,0x80687de9,0x3f800000,2
-np.float32,0x807fffff,0x3f800000,2
-np.float32,0x80000001,0x3f800000,2
-## +/-0.0f, +/-FLT_MIN +/-FLT_MAX ##
-np.float32,0x00000000,0x3f800000,2
-np.float32,0x80000000,0x3f800000,2
-np.float32,0x00800000,0x3f800000,2
-np.float32,0x80800000,0x3f800000,2
-## 1.00f + 0x00000001 ##
-np.float32,0x3f800000,0x3f0a5140,2
-np.float32,0x3f800001,0x3f0a513f,2
-np.float32,0x3f800002,0x3f0a513d,2
-np.float32,0xc090a8b0,0xbe4332ce,2
-np.float32,0x41ce3184,0x3f4d1de1,2
-np.float32,0xc1d85848,0xbeaa8980,2
-np.float32,0x402b8820,0xbf653aa3,2
-np.float32,0x42b4e454,0xbf4a338b,2
-np.float32,0x42a67a60,0x3c58202e,2
-np.float32,0x41d92388,0xbed987c7,2
-np.float32,0x422dd66c,0x3f5dcab3,2
-np.float32,0xc28f5be6,0xbf5688d8,2
-np.float32,0x41ab2674,0xbf53aa3b,2
-np.float32,0x3f490fdb,0x3f3504f3,2
-np.float32,0xbf490fdb,0x3f3504f3,2
-np.float32,0x3fc90fdb,0xb33bbd2e,2
-np.float32,0xbfc90fdb,0xb33bbd2e,2
-np.float32,0x40490fdb,0xbf800000,2
-np.float32,0xc0490fdb,0xbf800000,2
-np.float32,0x3fc90fdb,0xb33bbd2e,2
-np.float32,0xbfc90fdb,0xb33bbd2e,2
-np.float32,0x40490fdb,0xbf800000,2
-np.float32,0xc0490fdb,0xbf800000,2
-np.float32,0x40c90fdb,0x3f800000,2
-np.float32,0xc0c90fdb,0x3f800000,2
-np.float32,0x4016cbe4,0xbf3504f3,2
-np.float32,0xc016cbe4,0xbf3504f3,2
-np.float32,0x4096cbe4,0x324cde2e,2
-np.float32,0xc096cbe4,0x324cde2e,2
-np.float32,0x4116cbe4,0xbf800000,2
-np.float32,0xc116cbe4,0xbf800000,2
-np.float32,0x40490fdb,0xbf800000,2
-np.float32,0xc0490fdb,0xbf800000,2
-np.float32,0x40c90fdb,0x3f800000,2
-np.float32,0xc0c90fdb,0x3f800000,2
-np.float32,0x41490fdb,0x3f800000,2
-np.float32,0xc1490fdb,0x3f800000,2
-np.float32,0x407b53d2,0xbf3504f1,2
-np.float32,0xc07b53d2,0xbf3504f1,2
-np.float32,0x40fb53d2,0xb4b5563d,2
-np.float32,0xc0fb53d2,0xb4b5563d,2
-np.float32,0x417b53d2,0xbf800000,2
-np.float32,0xc17b53d2,0xbf800000,2
-np.float32,0x4096cbe4,0x324cde2e,2
-np.float32,0xc096cbe4,0x324cde2e,2
-np.float32,0x4116cbe4,0xbf800000,2
-np.float32,0xc116cbe4,0xbf800000,2
-np.float32,0x4196cbe4,0x3f800000,2
-np.float32,0xc196cbe4,0x3f800000,2
-np.float32,0x40afede0,0x3f3504f7,2
-np.float32,0xc0afede0,0x3f3504f7,2
-np.float32,0x412fede0,0x353222c4,2
-np.float32,0xc12fede0,0x353222c4,2
-np.float32,0x41afede0,0xbf800000,2
-np.float32,0xc1afede0,0xbf800000,2
-np.float32,0x40c90fdb,0x3f800000,2
-np.float32,0xc0c90fdb,0x3f800000,2
-np.float32,0x41490fdb,0x3f800000,2
-np.float32,0xc1490fdb,0x3f800000,2
-np.float32,0x41c90fdb,0x3f800000,2
-np.float32,0xc1c90fdb,0x3f800000,2
-np.float32,0x40e231d6,0x3f3504f3,2
-np.float32,0xc0e231d6,0x3f3504f3,2
-np.float32,0x416231d6,0xb319a6a2,2
-np.float32,0xc16231d6,0xb319a6a2,2
-np.float32,0x41e231d6,0xbf800000,2
-np.float32,0xc1e231d6,0xbf800000,2
-np.float32,0x40fb53d2,0xb4b5563d,2
-np.float32,0xc0fb53d2,0xb4b5563d,2
-np.float32,0x417b53d2,0xbf800000,2
-np.float32,0xc17b53d2,0xbf800000,2
-np.float32,0x41fb53d2,0x3f800000,2
-np.float32,0xc1fb53d2,0x3f800000,2
-np.float32,0x410a3ae7,0xbf3504fb,2
-np.float32,0xc10a3ae7,0xbf3504fb,2
-np.float32,0x418a3ae7,0x35b08908,2
-np.float32,0xc18a3ae7,0x35b08908,2
-np.float32,0x420a3ae7,0xbf800000,2
-np.float32,0xc20a3ae7,0xbf800000,2
-np.float32,0x4116cbe4,0xbf800000,2
-np.float32,0xc116cbe4,0xbf800000,2
-np.float32,0x4196cbe4,0x3f800000,2
-np.float32,0xc196cbe4,0x3f800000,2
-np.float32,0x4216cbe4,0x3f800000,2
-np.float32,0xc216cbe4,0x3f800000,2
-np.float32,0x41235ce2,0xbf3504ef,2
-np.float32,0xc1235ce2,0xbf3504ef,2
-np.float32,0x41a35ce2,0xb53889b6,2
-np.float32,0xc1a35ce2,0xb53889b6,2
-np.float32,0x42235ce2,0xbf800000,2
-np.float32,0xc2235ce2,0xbf800000,2
-np.float32,0x412fede0,0x353222c4,2
-np.float32,0xc12fede0,0x353222c4,2
-np.float32,0x41afede0,0xbf800000,2
-np.float32,0xc1afede0,0xbf800000,2
-np.float32,0x422fede0,0x3f800000,2
-np.float32,0xc22fede0,0x3f800000,2
-np.float32,0x413c7edd,0x3f3504f4,2
-np.float32,0xc13c7edd,0x3f3504f4,2
-np.float32,0x41bc7edd,0x33800add,2
-np.float32,0xc1bc7edd,0x33800add,2
-np.float32,0x423c7edd,0xbf800000,2
-np.float32,0xc23c7edd,0xbf800000,2
-np.float32,0x41490fdb,0x3f800000,2
-np.float32,0xc1490fdb,0x3f800000,2
-np.float32,0x41c90fdb,0x3f800000,2
-np.float32,0xc1c90fdb,0x3f800000,2
-np.float32,0x42490fdb,0x3f800000,2
-np.float32,0xc2490fdb,0x3f800000,2
-np.float32,0x4155a0d9,0x3f3504eb,2
-np.float32,0xc155a0d9,0x3f3504eb,2
-np.float32,0x41d5a0d9,0xb5b3bc81,2
-np.float32,0xc1d5a0d9,0xb5b3bc81,2
-np.float32,0x4255a0d9,0xbf800000,2
-np.float32,0xc255a0d9,0xbf800000,2
-np.float32,0x416231d6,0xb319a6a2,2
-np.float32,0xc16231d6,0xb319a6a2,2
-np.float32,0x41e231d6,0xbf800000,2
-np.float32,0xc1e231d6,0xbf800000,2
-np.float32,0x426231d6,0x3f800000,2
-np.float32,0xc26231d6,0x3f800000,2
-np.float32,0x416ec2d4,0xbf3504f7,2
-np.float32,0xc16ec2d4,0xbf3504f7,2
-np.float32,0x41eec2d4,0x353ef0a7,2
-np.float32,0xc1eec2d4,0x353ef0a7,2
-np.float32,0x426ec2d4,0xbf800000,2
-np.float32,0xc26ec2d4,0xbf800000,2
-np.float32,0x417b53d2,0xbf800000,2
-np.float32,0xc17b53d2,0xbf800000,2
-np.float32,0x41fb53d2,0x3f800000,2
-np.float32,0xc1fb53d2,0x3f800000,2
-np.float32,0x427b53d2,0x3f800000,2
-np.float32,0xc27b53d2,0x3f800000,2
-np.float32,0x4183f268,0xbf3504e7,2
-np.float32,0xc183f268,0xbf3504e7,2
-np.float32,0x4203f268,0xb6059a13,2
-np.float32,0xc203f268,0xb6059a13,2
-np.float32,0x4283f268,0xbf800000,2
-np.float32,0xc283f268,0xbf800000,2
-np.float32,0x418a3ae7,0x35b08908,2
-np.float32,0xc18a3ae7,0x35b08908,2
-np.float32,0x420a3ae7,0xbf800000,2
-np.float32,0xc20a3ae7,0xbf800000,2
-np.float32,0x428a3ae7,0x3f800000,2
-np.float32,0xc28a3ae7,0x3f800000,2
-np.float32,0x41908365,0x3f3504f0,2
-np.float32,0xc1908365,0x3f3504f0,2
-np.float32,0x42108365,0xb512200d,2
-np.float32,0xc2108365,0xb512200d,2
-np.float32,0x42908365,0xbf800000,2
-np.float32,0xc2908365,0xbf800000,2
-np.float32,0x4196cbe4,0x3f800000,2
-np.float32,0xc196cbe4,0x3f800000,2
-np.float32,0x4216cbe4,0x3f800000,2
-np.float32,0xc216cbe4,0x3f800000,2
-np.float32,0x4296cbe4,0x3f800000,2
-np.float32,0xc296cbe4,0x3f800000,2
-np.float32,0x419d1463,0x3f3504ef,2
-np.float32,0xc19d1463,0x3f3504ef,2
-np.float32,0x421d1463,0xb5455799,2
-np.float32,0xc21d1463,0xb5455799,2
-np.float32,0x429d1463,0xbf800000,2
-np.float32,0xc29d1463,0xbf800000,2
-np.float32,0x41a35ce2,0xb53889b6,2
-np.float32,0xc1a35ce2,0xb53889b6,2
-np.float32,0x42235ce2,0xbf800000,2
-np.float32,0xc2235ce2,0xbf800000,2
-np.float32,0x42a35ce2,0x3f800000,2
-np.float32,0xc2a35ce2,0x3f800000,2
-np.float32,0x41a9a561,0xbf3504ff,2
-np.float32,0xc1a9a561,0xbf3504ff,2
-np.float32,0x4229a561,0x360733d0,2
-np.float32,0xc229a561,0x360733d0,2
-np.float32,0x42a9a561,0xbf800000,2
-np.float32,0xc2a9a561,0xbf800000,2
-np.float32,0x41afede0,0xbf800000,2
-np.float32,0xc1afede0,0xbf800000,2
-np.float32,0x422fede0,0x3f800000,2
-np.float32,0xc22fede0,0x3f800000,2
-np.float32,0x42afede0,0x3f800000,2
-np.float32,0xc2afede0,0x3f800000,2
-np.float32,0x41b6365e,0xbf3504f6,2
-np.float32,0xc1b6365e,0xbf3504f6,2
-np.float32,0x4236365e,0x350bb91c,2
-np.float32,0xc236365e,0x350bb91c,2
-np.float32,0x42b6365e,0xbf800000,2
-np.float32,0xc2b6365e,0xbf800000,2
-np.float32,0x41bc7edd,0x33800add,2
-np.float32,0xc1bc7edd,0x33800add,2
-np.float32,0x423c7edd,0xbf800000,2
-np.float32,0xc23c7edd,0xbf800000,2
-np.float32,0x42bc7edd,0x3f800000,2
-np.float32,0xc2bc7edd,0x3f800000,2
-np.float32,0x41c2c75c,0x3f3504f8,2
-np.float32,0xc1c2c75c,0x3f3504f8,2
-np.float32,0x4242c75c,0x354bbe8a,2
-np.float32,0xc242c75c,0x354bbe8a,2
-np.float32,0x42c2c75c,0xbf800000,2
-np.float32,0xc2c2c75c,0xbf800000,2
-np.float32,0x41c90fdb,0x3f800000,2
-np.float32,0xc1c90fdb,0x3f800000,2
-np.float32,0x42490fdb,0x3f800000,2
-np.float32,0xc2490fdb,0x3f800000,2
-np.float32,0x42c90fdb,0x3f800000,2
-np.float32,0xc2c90fdb,0x3f800000,2
-np.float32,0x41cf585a,0x3f3504e7,2
-np.float32,0xc1cf585a,0x3f3504e7,2
-np.float32,0x424f585a,0xb608cd8c,2
-np.float32,0xc24f585a,0xb608cd8c,2
-np.float32,0x42cf585a,0xbf800000,2
-np.float32,0xc2cf585a,0xbf800000,2
-np.float32,0x41d5a0d9,0xb5b3bc81,2
-np.float32,0xc1d5a0d9,0xb5b3bc81,2
-np.float32,0x4255a0d9,0xbf800000,2
-np.float32,0xc255a0d9,0xbf800000,2
-np.float32,0x42d5a0d9,0x3f800000,2
-np.float32,0xc2d5a0d9,0x3f800000,2
-np.float32,0x41dbe958,0xbf350507,2
-np.float32,0xc1dbe958,0xbf350507,2
-np.float32,0x425be958,0x365eab75,2
-np.float32,0xc25be958,0x365eab75,2
-np.float32,0x42dbe958,0xbf800000,2
-np.float32,0xc2dbe958,0xbf800000,2
-np.float32,0x41e231d6,0xbf800000,2
-np.float32,0xc1e231d6,0xbf800000,2
-np.float32,0x426231d6,0x3f800000,2
-np.float32,0xc26231d6,0x3f800000,2
-np.float32,0x42e231d6,0x3f800000,2
-np.float32,0xc2e231d6,0x3f800000,2
-np.float32,0x41e87a55,0xbf3504ef,2
-np.float32,0xc1e87a55,0xbf3504ef,2
-np.float32,0x42687a55,0xb552257b,2
-np.float32,0xc2687a55,0xb552257b,2
-np.float32,0x42e87a55,0xbf800000,2
-np.float32,0xc2e87a55,0xbf800000,2
-np.float32,0x41eec2d4,0x353ef0a7,2
-np.float32,0xc1eec2d4,0x353ef0a7,2
-np.float32,0x426ec2d4,0xbf800000,2
-np.float32,0xc26ec2d4,0xbf800000,2
-np.float32,0x42eec2d4,0x3f800000,2
-np.float32,0xc2eec2d4,0x3f800000,2
-np.float32,0x41f50b53,0x3f3504ff,2
-np.float32,0xc1f50b53,0x3f3504ff,2
-np.float32,0x42750b53,0x360a6748,2
-np.float32,0xc2750b53,0x360a6748,2
-np.float32,0x42f50b53,0xbf800000,2
-np.float32,0xc2f50b53,0xbf800000,2
-np.float32,0x41fb53d2,0x3f800000,2
-np.float32,0xc1fb53d2,0x3f800000,2
-np.float32,0x427b53d2,0x3f800000,2
-np.float32,0xc27b53d2,0x3f800000,2
-np.float32,0x42fb53d2,0x3f800000,2
-np.float32,0xc2fb53d2,0x3f800000,2
-np.float32,0x4200ce28,0x3f3504f6,2
-np.float32,0xc200ce28,0x3f3504f6,2
-np.float32,0x4280ce28,0x34fdd672,2
-np.float32,0xc280ce28,0x34fdd672,2
-np.float32,0x4300ce28,0xbf800000,2
-np.float32,0xc300ce28,0xbf800000,2
-np.float32,0x4203f268,0xb6059a13,2
-np.float32,0xc203f268,0xb6059a13,2
-np.float32,0x4283f268,0xbf800000,2
-np.float32,0xc283f268,0xbf800000,2
-np.float32,0x4303f268,0x3f800000,2
-np.float32,0xc303f268,0x3f800000,2
-np.float32,0x420716a7,0xbf3504f8,2
-np.float32,0xc20716a7,0xbf3504f8,2
-np.float32,0x428716a7,0x35588c6d,2
-np.float32,0xc28716a7,0x35588c6d,2
-np.float32,0x430716a7,0xbf800000,2
-np.float32,0xc30716a7,0xbf800000,2
-np.float32,0x420a3ae7,0xbf800000,2
-np.float32,0xc20a3ae7,0xbf800000,2
-np.float32,0x428a3ae7,0x3f800000,2
-np.float32,0xc28a3ae7,0x3f800000,2
-np.float32,0x430a3ae7,0x3f800000,2
-np.float32,0xc30a3ae7,0x3f800000,2
-np.float32,0x420d5f26,0xbf3504e7,2
-np.float32,0xc20d5f26,0xbf3504e7,2
-np.float32,0x428d5f26,0xb60c0105,2
-np.float32,0xc28d5f26,0xb60c0105,2
-np.float32,0x430d5f26,0xbf800000,2
-np.float32,0xc30d5f26,0xbf800000,2
-np.float32,0x42108365,0xb512200d,2
-np.float32,0xc2108365,0xb512200d,2
-np.float32,0x42908365,0xbf800000,2
-np.float32,0xc2908365,0xbf800000,2
-np.float32,0x43108365,0x3f800000,2
-np.float32,0xc3108365,0x3f800000,2
-np.float32,0x4213a7a5,0x3f350507,2
-np.float32,0xc213a7a5,0x3f350507,2
-np.float32,0x4293a7a5,0x3661deee,2
-np.float32,0xc293a7a5,0x3661deee,2
-np.float32,0x4313a7a5,0xbf800000,2
-np.float32,0xc313a7a5,0xbf800000,2
-np.float32,0x4216cbe4,0x3f800000,2
-np.float32,0xc216cbe4,0x3f800000,2
-np.float32,0x4296cbe4,0x3f800000,2
-np.float32,0xc296cbe4,0x3f800000,2
-np.float32,0x4316cbe4,0x3f800000,2
-np.float32,0xc316cbe4,0x3f800000,2
-np.float32,0x4219f024,0x3f3504d8,2
-np.float32,0xc219f024,0x3f3504d8,2
-np.float32,0x4299f024,0xb69bde6c,2
-np.float32,0xc299f024,0xb69bde6c,2
-np.float32,0x4319f024,0xbf800000,2
-np.float32,0xc319f024,0xbf800000,2
-np.float32,0x421d1463,0xb5455799,2
-np.float32,0xc21d1463,0xb5455799,2
-np.float32,0x429d1463,0xbf800000,2
-np.float32,0xc29d1463,0xbf800000,2
-np.float32,0x431d1463,0x3f800000,2
-np.float32,0xc31d1463,0x3f800000,2
-np.float32,0x422038a3,0xbf350516,2
-np.float32,0xc22038a3,0xbf350516,2
-np.float32,0x42a038a3,0x36c6cd61,2
-np.float32,0xc2a038a3,0x36c6cd61,2
-np.float32,0x432038a3,0xbf800000,2
-np.float32,0xc32038a3,0xbf800000,2
-np.float32,0x42235ce2,0xbf800000,2
-np.float32,0xc2235ce2,0xbf800000,2
-np.float32,0x42a35ce2,0x3f800000,2
-np.float32,0xc2a35ce2,0x3f800000,2
-np.float32,0x43235ce2,0x3f800000,2
-np.float32,0xc3235ce2,0x3f800000,2
-np.float32,0x42268121,0xbf3504f6,2
-np.float32,0xc2268121,0xbf3504f6,2
-np.float32,0x42a68121,0x34e43aac,2
-np.float32,0xc2a68121,0x34e43aac,2
-np.float32,0x43268121,0xbf800000,2
-np.float32,0xc3268121,0xbf800000,2
-np.float32,0x4229a561,0x360733d0,2
-np.float32,0xc229a561,0x360733d0,2
-np.float32,0x42a9a561,0xbf800000,2
-np.float32,0xc2a9a561,0xbf800000,2
-np.float32,0x4329a561,0x3f800000,2
-np.float32,0xc329a561,0x3f800000,2
-np.float32,0x422cc9a0,0x3f3504f8,2
-np.float32,0xc22cc9a0,0x3f3504f8,2
-np.float32,0x42acc9a0,0x35655a50,2
-np.float32,0xc2acc9a0,0x35655a50,2
-np.float32,0x432cc9a0,0xbf800000,2
-np.float32,0xc32cc9a0,0xbf800000,2
-np.float32,0x422fede0,0x3f800000,2
-np.float32,0xc22fede0,0x3f800000,2
-np.float32,0x42afede0,0x3f800000,2
-np.float32,0xc2afede0,0x3f800000,2
-np.float32,0x432fede0,0x3f800000,2
-np.float32,0xc32fede0,0x3f800000,2
-np.float32,0x4233121f,0x3f3504e7,2
-np.float32,0xc233121f,0x3f3504e7,2
-np.float32,0x42b3121f,0xb60f347d,2
-np.float32,0xc2b3121f,0xb60f347d,2
-np.float32,0x4333121f,0xbf800000,2
-np.float32,0xc333121f,0xbf800000,2
-np.float32,0x4236365e,0x350bb91c,2
-np.float32,0xc236365e,0x350bb91c,2
-np.float32,0x42b6365e,0xbf800000,2
-np.float32,0xc2b6365e,0xbf800000,2
-np.float32,0x4336365e,0x3f800000,2
-np.float32,0xc336365e,0x3f800000,2
-np.float32,0x42395a9e,0xbf350507,2
-np.float32,0xc2395a9e,0xbf350507,2
-np.float32,0x42b95a9e,0x36651267,2
-np.float32,0xc2b95a9e,0x36651267,2
-np.float32,0x43395a9e,0xbf800000,2
-np.float32,0xc3395a9e,0xbf800000,2
-np.float32,0x423c7edd,0xbf800000,2
-np.float32,0xc23c7edd,0xbf800000,2
-np.float32,0x42bc7edd,0x3f800000,2
-np.float32,0xc2bc7edd,0x3f800000,2
-np.float32,0x433c7edd,0x3f800000,2
-np.float32,0xc33c7edd,0x3f800000,2
-np.float32,0x423fa31d,0xbf3504d7,2
-np.float32,0xc23fa31d,0xbf3504d7,2
-np.float32,0x42bfa31d,0xb69d7828,2
-np.float32,0xc2bfa31d,0xb69d7828,2
-np.float32,0x433fa31d,0xbf800000,2
-np.float32,0xc33fa31d,0xbf800000,2
-np.float32,0x4242c75c,0x354bbe8a,2
-np.float32,0xc242c75c,0x354bbe8a,2
-np.float32,0x42c2c75c,0xbf800000,2
-np.float32,0xc2c2c75c,0xbf800000,2
-np.float32,0x4342c75c,0x3f800000,2
-np.float32,0xc342c75c,0x3f800000,2
-np.float32,0x4245eb9c,0x3f350517,2
-np.float32,0xc245eb9c,0x3f350517,2
-np.float32,0x42c5eb9c,0x36c8671d,2
-np.float32,0xc2c5eb9c,0x36c8671d,2
-np.float32,0x4345eb9c,0xbf800000,2
-np.float32,0xc345eb9c,0xbf800000,2
-np.float32,0x42490fdb,0x3f800000,2
-np.float32,0xc2490fdb,0x3f800000,2
-np.float32,0x42c90fdb,0x3f800000,2
-np.float32,0xc2c90fdb,0x3f800000,2
-np.float32,0x43490fdb,0x3f800000,2
-np.float32,0xc3490fdb,0x3f800000,2
-np.float32,0x424c341a,0x3f3504f5,2
-np.float32,0xc24c341a,0x3f3504f5,2
-np.float32,0x42cc341a,0x34ca9ee6,2
-np.float32,0xc2cc341a,0x34ca9ee6,2
-np.float32,0x434c341a,0xbf800000,2
-np.float32,0xc34c341a,0xbf800000,2
-np.float32,0x424f585a,0xb608cd8c,2
-np.float32,0xc24f585a,0xb608cd8c,2
-np.float32,0x42cf585a,0xbf800000,2
-np.float32,0xc2cf585a,0xbf800000,2
-np.float32,0x434f585a,0x3f800000,2
-np.float32,0xc34f585a,0x3f800000,2
-np.float32,0x42527c99,0xbf3504f9,2
-np.float32,0xc2527c99,0xbf3504f9,2
-np.float32,0x42d27c99,0x35722833,2
-np.float32,0xc2d27c99,0x35722833,2
-np.float32,0x43527c99,0xbf800000,2
-np.float32,0xc3527c99,0xbf800000,2
-np.float32,0x4255a0d9,0xbf800000,2
-np.float32,0xc255a0d9,0xbf800000,2
-np.float32,0x42d5a0d9,0x3f800000,2
-np.float32,0xc2d5a0d9,0x3f800000,2
-np.float32,0x4355a0d9,0x3f800000,2
-np.float32,0xc355a0d9,0x3f800000,2
-np.float32,0x4258c518,0xbf3504e6,2
-np.float32,0xc258c518,0xbf3504e6,2
-np.float32,0x42d8c518,0xb61267f6,2
-np.float32,0xc2d8c518,0xb61267f6,2
-np.float32,0x4358c518,0xbf800000,2
-np.float32,0xc358c518,0xbf800000,2
-np.float32,0x425be958,0x365eab75,2
-np.float32,0xc25be958,0x365eab75,2
-np.float32,0x42dbe958,0xbf800000,2
-np.float32,0xc2dbe958,0xbf800000,2
-np.float32,0x435be958,0x3f800000,2
-np.float32,0xc35be958,0x3f800000,2
-np.float32,0x425f0d97,0x3f350508,2
-np.float32,0xc25f0d97,0x3f350508,2
-np.float32,0x42df0d97,0x366845e0,2
-np.float32,0xc2df0d97,0x366845e0,2
-np.float32,0x435f0d97,0xbf800000,2
-np.float32,0xc35f0d97,0xbf800000,2
-np.float32,0x426231d6,0x3f800000,2
-np.float32,0xc26231d6,0x3f800000,2
-np.float32,0x42e231d6,0x3f800000,2
-np.float32,0xc2e231d6,0x3f800000,2
-np.float32,0x436231d6,0x3f800000,2
-np.float32,0xc36231d6,0x3f800000,2
-np.float32,0x42655616,0x3f3504d7,2
-np.float32,0xc2655616,0x3f3504d7,2
-np.float32,0x42e55616,0xb69f11e5,2
-np.float32,0xc2e55616,0xb69f11e5,2
-np.float32,0x43655616,0xbf800000,2
-np.float32,0xc3655616,0xbf800000,2
-np.float32,0x42687a55,0xb552257b,2
-np.float32,0xc2687a55,0xb552257b,2
-np.float32,0x42e87a55,0xbf800000,2
-np.float32,0xc2e87a55,0xbf800000,2
-np.float32,0x43687a55,0x3f800000,2
-np.float32,0xc3687a55,0x3f800000,2
-np.float32,0x426b9e95,0xbf350517,2
-np.float32,0xc26b9e95,0xbf350517,2
-np.float32,0x42eb9e95,0x36ca00d9,2
-np.float32,0xc2eb9e95,0x36ca00d9,2
-np.float32,0x436b9e95,0xbf800000,2
-np.float32,0xc36b9e95,0xbf800000,2
-np.float32,0x426ec2d4,0xbf800000,2
-np.float32,0xc26ec2d4,0xbf800000,2
-np.float32,0x42eec2d4,0x3f800000,2
-np.float32,0xc2eec2d4,0x3f800000,2
-np.float32,0x436ec2d4,0x3f800000,2
-np.float32,0xc36ec2d4,0x3f800000,2
-np.float32,0x4271e713,0xbf3504f5,2
-np.float32,0xc271e713,0xbf3504f5,2
-np.float32,0x42f1e713,0x34b10321,2
-np.float32,0xc2f1e713,0x34b10321,2
-np.float32,0x4371e713,0xbf800000,2
-np.float32,0xc371e713,0xbf800000,2
-np.float32,0x42750b53,0x360a6748,2
-np.float32,0xc2750b53,0x360a6748,2
-np.float32,0x42f50b53,0xbf800000,2
-np.float32,0xc2f50b53,0xbf800000,2
-np.float32,0x43750b53,0x3f800000,2
-np.float32,0xc3750b53,0x3f800000,2
-np.float32,0x42782f92,0x3f3504f9,2
-np.float32,0xc2782f92,0x3f3504f9,2
-np.float32,0x42f82f92,0x357ef616,2
-np.float32,0xc2f82f92,0x357ef616,2
-np.float32,0x43782f92,0xbf800000,2
-np.float32,0xc3782f92,0xbf800000,2
-np.float32,0x427b53d2,0x3f800000,2
-np.float32,0xc27b53d2,0x3f800000,2
-np.float32,0x42fb53d2,0x3f800000,2
-np.float32,0xc2fb53d2,0x3f800000,2
-np.float32,0x437b53d2,0x3f800000,2
-np.float32,0xc37b53d2,0x3f800000,2
-np.float32,0x427e7811,0x3f3504e6,2
-np.float32,0xc27e7811,0x3f3504e6,2
-np.float32,0x42fe7811,0xb6159b6f,2
-np.float32,0xc2fe7811,0xb6159b6f,2
-np.float32,0x437e7811,0xbf800000,2
-np.float32,0xc37e7811,0xbf800000,2
-np.float32,0x4280ce28,0x34fdd672,2
-np.float32,0xc280ce28,0x34fdd672,2
-np.float32,0x4300ce28,0xbf800000,2
-np.float32,0xc300ce28,0xbf800000,2
-np.float32,0x4380ce28,0x3f800000,2
-np.float32,0xc380ce28,0x3f800000,2
-np.float32,0x42826048,0xbf350508,2
-np.float32,0xc2826048,0xbf350508,2
-np.float32,0x43026048,0x366b7958,2
-np.float32,0xc3026048,0x366b7958,2
-np.float32,0x43826048,0xbf800000,2
-np.float32,0xc3826048,0xbf800000,2
-np.float32,0x4283f268,0xbf800000,2
-np.float32,0xc283f268,0xbf800000,2
-np.float32,0x4303f268,0x3f800000,2
-np.float32,0xc303f268,0x3f800000,2
-np.float32,0x4383f268,0x3f800000,2
-np.float32,0xc383f268,0x3f800000,2
-np.float32,0x42858487,0xbf350504,2
-np.float32,0xc2858487,0xbf350504,2
-np.float32,0x43058487,0x363ea8be,2
-np.float32,0xc3058487,0x363ea8be,2
-np.float32,0x43858487,0xbf800000,2
-np.float32,0xc3858487,0xbf800000,2
-np.float32,0x428716a7,0x35588c6d,2
-np.float32,0xc28716a7,0x35588c6d,2
-np.float32,0x430716a7,0xbf800000,2
-np.float32,0xc30716a7,0xbf800000,2
-np.float32,0x438716a7,0x3f800000,2
-np.float32,0xc38716a7,0x3f800000,2
-np.float32,0x4288a8c7,0x3f350517,2
-np.float32,0xc288a8c7,0x3f350517,2
-np.float32,0x4308a8c7,0x36cb9a96,2
-np.float32,0xc308a8c7,0x36cb9a96,2
-np.float32,0x4388a8c7,0xbf800000,2
-np.float32,0xc388a8c7,0xbf800000,2
-np.float32,0x428a3ae7,0x3f800000,2
-np.float32,0xc28a3ae7,0x3f800000,2
-np.float32,0x430a3ae7,0x3f800000,2
-np.float32,0xc30a3ae7,0x3f800000,2
-np.float32,0x438a3ae7,0x3f800000,2
-np.float32,0xc38a3ae7,0x3f800000,2
-np.float32,0x428bcd06,0x3f3504f5,2
-np.float32,0xc28bcd06,0x3f3504f5,2
-np.float32,0x430bcd06,0x3497675b,2
-np.float32,0xc30bcd06,0x3497675b,2
-np.float32,0x438bcd06,0xbf800000,2
-np.float32,0xc38bcd06,0xbf800000,2
-np.float32,0x428d5f26,0xb60c0105,2
-np.float32,0xc28d5f26,0xb60c0105,2
-np.float32,0x430d5f26,0xbf800000,2
-np.float32,0xc30d5f26,0xbf800000,2
-np.float32,0x438d5f26,0x3f800000,2
-np.float32,0xc38d5f26,0x3f800000,2
-np.float32,0x428ef146,0xbf350526,2
-np.float32,0xc28ef146,0xbf350526,2
-np.float32,0x430ef146,0x3710bc40,2
-np.float32,0xc30ef146,0x3710bc40,2
-np.float32,0x438ef146,0xbf800000,2
-np.float32,0xc38ef146,0xbf800000,2
-np.float32,0x42908365,0xbf800000,2
-np.float32,0xc2908365,0xbf800000,2
-np.float32,0x43108365,0x3f800000,2
-np.float32,0xc3108365,0x3f800000,2
-np.float32,0x43908365,0x3f800000,2
-np.float32,0xc3908365,0x3f800000,2
-np.float32,0x42921585,0xbf3504e6,2
-np.float32,0xc2921585,0xbf3504e6,2
-np.float32,0x43121585,0xb618cee8,2
-np.float32,0xc3121585,0xb618cee8,2
-np.float32,0x43921585,0xbf800000,2
-np.float32,0xc3921585,0xbf800000,2
-np.float32,0x4293a7a5,0x3661deee,2
-np.float32,0xc293a7a5,0x3661deee,2
-np.float32,0x4313a7a5,0xbf800000,2
-np.float32,0xc313a7a5,0xbf800000,2
-np.float32,0x4393a7a5,0x3f800000,2
-np.float32,0xc393a7a5,0x3f800000,2
-np.float32,0x429539c5,0x3f350536,2
-np.float32,0xc29539c5,0x3f350536,2
-np.float32,0x431539c5,0x373bab34,2
-np.float32,0xc31539c5,0x373bab34,2
-np.float32,0x439539c5,0xbf800000,2
-np.float32,0xc39539c5,0xbf800000,2
-np.float32,0x4296cbe4,0x3f800000,2
-np.float32,0xc296cbe4,0x3f800000,2
-np.float32,0x4316cbe4,0x3f800000,2
-np.float32,0xc316cbe4,0x3f800000,2
-np.float32,0x4396cbe4,0x3f800000,2
-np.float32,0xc396cbe4,0x3f800000,2
-np.float32,0x42985e04,0x3f3504d7,2
-np.float32,0xc2985e04,0x3f3504d7,2
-np.float32,0x43185e04,0xb6a2455d,2
-np.float32,0xc3185e04,0xb6a2455d,2
-np.float32,0x43985e04,0xbf800000,2
-np.float32,0xc3985e04,0xbf800000,2
-np.float32,0x4299f024,0xb69bde6c,2
-np.float32,0xc299f024,0xb69bde6c,2
-np.float32,0x4319f024,0xbf800000,2
-np.float32,0xc319f024,0xbf800000,2
-np.float32,0x4399f024,0x3f800000,2
-np.float32,0xc399f024,0x3f800000,2
-np.float32,0x429b8243,0xbf3504ea,2
-np.float32,0xc29b8243,0xbf3504ea,2
-np.float32,0x431b8243,0xb5cb2eb8,2
-np.float32,0xc31b8243,0xb5cb2eb8,2
-np.float32,0x439b8243,0xbf800000,2
-np.float32,0xc39b8243,0xbf800000,2
-np.float32,0x435b2047,0x3f3504c1,2
-np.float32,0x42a038a2,0xb5e4ca7e,2
-np.float32,0x432038a2,0xbf800000,2
-np.float32,0x4345eb9b,0xbf800000,2
-np.float32,0x42c5eb9b,0xb5de638c,2
-np.float32,0x42eb9e94,0xb5d7fc9b,2
-np.float32,0x4350ea79,0x3631dadb,2
-np.float32,0x42dbe957,0xbf800000,2
-np.float32,0x425be957,0xb505522a,2
-np.float32,0x435be957,0x3f800000,2
-np.float32,0x46027eb2,0x3e7d94c9,2
-np.float32,0x4477baed,0xbe7f1824,2
-np.float32,0x454b8024,0x3e7f5268,2
-np.float32,0x455d2c09,0x3e7f40cb,2
-np.float32,0x4768d3de,0xba14b4af,2
-np.float32,0x46c1e7cd,0x3e7fb102,2
-np.float32,0x44a52949,0xbe7dc9d5,2
-np.float32,0x4454633a,0x3e7dbc7d,2
-np.float32,0x4689810b,0x3e7eb02b,2
-np.float32,0x473473cd,0xbe7eef6f,2
-np.float32,0x44a5193f,0x3e7e1b1f,2
-np.float32,0x46004b36,0x3e7dac59,2
-np.float32,0x467f604b,0x3d7ffd3a,2
-np.float32,0x45ea1805,0x3dffd2e0,2
-np.float32,0x457b6af3,0x3dff7831,2
-np.float32,0x44996159,0xbe7d85f4,2
-np.float32,0x47883553,0xbb80584e,2
-np.float32,0x44e19f0c,0xbdffcfe6,2
-np.float32,0x472b3bf6,0xbe7f7a82,2
-np.float32,0x4600bb4e,0x3a135e33,2
-np.float32,0x449f4556,0x3e7e42e5,2
-np.float32,0x474e9420,0x3dff77b2,2
-np.float32,0x45cbdb23,0x3dff7240,2
-np.float32,0x44222747,0x3dffb039,2
-np.float32,0x4772e419,0xbdff74b8,2
diff --git a/numpy/core/tests/data/umath-validation-set-cos.csv b/numpy/core/tests/data/umath-validation-set-cos.csv
new file mode 100644
index 000000000..e315c28b8
--- /dev/null
+++ b/numpy/core/tests/data/umath-validation-set-cos.csv
@@ -0,0 +1,1375 @@
+dtype,input,output,ulperrortol
+## +ve denormals ##
+np.float32,0x004b4716,0x3f800000,2
+np.float32,0x007b2490,0x3f800000,2
+np.float32,0x007c99fa,0x3f800000,2
+np.float32,0x00734a0c,0x3f800000,2
+np.float32,0x0070de24,0x3f800000,2
+np.float32,0x007fffff,0x3f800000,2
+np.float32,0x00000001,0x3f800000,2
+## -ve denormals ##
+np.float32,0x80495d65,0x3f800000,2
+np.float32,0x806894f6,0x3f800000,2
+np.float32,0x80555a76,0x3f800000,2
+np.float32,0x804e1fb8,0x3f800000,2
+np.float32,0x80687de9,0x3f800000,2
+np.float32,0x807fffff,0x3f800000,2
+np.float32,0x80000001,0x3f800000,2
+## +/-0.0f, +/-FLT_MIN +/-FLT_MAX ##
+np.float32,0x00000000,0x3f800000,2
+np.float32,0x80000000,0x3f800000,2
+np.float32,0x00800000,0x3f800000,2
+np.float32,0x80800000,0x3f800000,2
+## 1.00f + 0x00000001 ##
+np.float32,0x3f800000,0x3f0a5140,2
+np.float32,0x3f800001,0x3f0a513f,2
+np.float32,0x3f800002,0x3f0a513d,2
+np.float32,0xc090a8b0,0xbe4332ce,2
+np.float32,0x41ce3184,0x3f4d1de1,2
+np.float32,0xc1d85848,0xbeaa8980,2
+np.float32,0x402b8820,0xbf653aa3,2
+np.float32,0x42b4e454,0xbf4a338b,2
+np.float32,0x42a67a60,0x3c58202e,2
+np.float32,0x41d92388,0xbed987c7,2
+np.float32,0x422dd66c,0x3f5dcab3,2
+np.float32,0xc28f5be6,0xbf5688d8,2
+np.float32,0x41ab2674,0xbf53aa3b,2
+np.float32,0x3f490fdb,0x3f3504f3,2
+np.float32,0xbf490fdb,0x3f3504f3,2
+np.float32,0x3fc90fdb,0xb33bbd2e,2
+np.float32,0xbfc90fdb,0xb33bbd2e,2
+np.float32,0x40490fdb,0xbf800000,2
+np.float32,0xc0490fdb,0xbf800000,2
+np.float32,0x3fc90fdb,0xb33bbd2e,2
+np.float32,0xbfc90fdb,0xb33bbd2e,2
+np.float32,0x40490fdb,0xbf800000,2
+np.float32,0xc0490fdb,0xbf800000,2
+np.float32,0x40c90fdb,0x3f800000,2
+np.float32,0xc0c90fdb,0x3f800000,2
+np.float32,0x4016cbe4,0xbf3504f3,2
+np.float32,0xc016cbe4,0xbf3504f3,2
+np.float32,0x4096cbe4,0x324cde2e,2
+np.float32,0xc096cbe4,0x324cde2e,2
+np.float32,0x4116cbe4,0xbf800000,2
+np.float32,0xc116cbe4,0xbf800000,2
+np.float32,0x40490fdb,0xbf800000,2
+np.float32,0xc0490fdb,0xbf800000,2
+np.float32,0x40c90fdb,0x3f800000,2
+np.float32,0xc0c90fdb,0x3f800000,2
+np.float32,0x41490fdb,0x3f800000,2
+np.float32,0xc1490fdb,0x3f800000,2
+np.float32,0x407b53d2,0xbf3504f1,2
+np.float32,0xc07b53d2,0xbf3504f1,2
+np.float32,0x40fb53d2,0xb4b5563d,2
+np.float32,0xc0fb53d2,0xb4b5563d,2
+np.float32,0x417b53d2,0xbf800000,2
+np.float32,0xc17b53d2,0xbf800000,2
+np.float32,0x4096cbe4,0x324cde2e,2
+np.float32,0xc096cbe4,0x324cde2e,2
+np.float32,0x4116cbe4,0xbf800000,2
+np.float32,0xc116cbe4,0xbf800000,2
+np.float32,0x4196cbe4,0x3f800000,2
+np.float32,0xc196cbe4,0x3f800000,2
+np.float32,0x40afede0,0x3f3504f7,2
+np.float32,0xc0afede0,0x3f3504f7,2
+np.float32,0x412fede0,0x353222c4,2
+np.float32,0xc12fede0,0x353222c4,2
+np.float32,0x41afede0,0xbf800000,2
+np.float32,0xc1afede0,0xbf800000,2
+np.float32,0x40c90fdb,0x3f800000,2
+np.float32,0xc0c90fdb,0x3f800000,2
+np.float32,0x41490fdb,0x3f800000,2
+np.float32,0xc1490fdb,0x3f800000,2
+np.float32,0x41c90fdb,0x3f800000,2
+np.float32,0xc1c90fdb,0x3f800000,2
+np.float32,0x40e231d6,0x3f3504f3,2
+np.float32,0xc0e231d6,0x3f3504f3,2
+np.float32,0x416231d6,0xb319a6a2,2
+np.float32,0xc16231d6,0xb319a6a2,2
+np.float32,0x41e231d6,0xbf800000,2
+np.float32,0xc1e231d6,0xbf800000,2
+np.float32,0x40fb53d2,0xb4b5563d,2
+np.float32,0xc0fb53d2,0xb4b5563d,2
+np.float32,0x417b53d2,0xbf800000,2
+np.float32,0xc17b53d2,0xbf800000,2
+np.float32,0x41fb53d2,0x3f800000,2
+np.float32,0xc1fb53d2,0x3f800000,2
+np.float32,0x410a3ae7,0xbf3504fb,2
+np.float32,0xc10a3ae7,0xbf3504fb,2
+np.float32,0x418a3ae7,0x35b08908,2
+np.float32,0xc18a3ae7,0x35b08908,2
+np.float32,0x420a3ae7,0xbf800000,2
+np.float32,0xc20a3ae7,0xbf800000,2
+np.float32,0x4116cbe4,0xbf800000,2
+np.float32,0xc116cbe4,0xbf800000,2
+np.float32,0x4196cbe4,0x3f800000,2
+np.float32,0xc196cbe4,0x3f800000,2
+np.float32,0x4216cbe4,0x3f800000,2
+np.float32,0xc216cbe4,0x3f800000,2
+np.float32,0x41235ce2,0xbf3504ef,2
+np.float32,0xc1235ce2,0xbf3504ef,2
+np.float32,0x41a35ce2,0xb53889b6,2
+np.float32,0xc1a35ce2,0xb53889b6,2
+np.float32,0x42235ce2,0xbf800000,2
+np.float32,0xc2235ce2,0xbf800000,2
+np.float32,0x412fede0,0x353222c4,2
+np.float32,0xc12fede0,0x353222c4,2
+np.float32,0x41afede0,0xbf800000,2
+np.float32,0xc1afede0,0xbf800000,2
+np.float32,0x422fede0,0x3f800000,2
+np.float32,0xc22fede0,0x3f800000,2
+np.float32,0x413c7edd,0x3f3504f4,2
+np.float32,0xc13c7edd,0x3f3504f4,2
+np.float32,0x41bc7edd,0x33800add,2
+np.float32,0xc1bc7edd,0x33800add,2
+np.float32,0x423c7edd,0xbf800000,2
+np.float32,0xc23c7edd,0xbf800000,2
+np.float32,0x41490fdb,0x3f800000,2
+np.float32,0xc1490fdb,0x3f800000,2
+np.float32,0x41c90fdb,0x3f800000,2
+np.float32,0xc1c90fdb,0x3f800000,2
+np.float32,0x42490fdb,0x3f800000,2
+np.float32,0xc2490fdb,0x3f800000,2
+np.float32,0x4155a0d9,0x3f3504eb,2
+np.float32,0xc155a0d9,0x3f3504eb,2
+np.float32,0x41d5a0d9,0xb5b3bc81,2
+np.float32,0xc1d5a0d9,0xb5b3bc81,2
+np.float32,0x4255a0d9,0xbf800000,2
+np.float32,0xc255a0d9,0xbf800000,2
+np.float32,0x416231d6,0xb319a6a2,2
+np.float32,0xc16231d6,0xb319a6a2,2
+np.float32,0x41e231d6,0xbf800000,2
+np.float32,0xc1e231d6,0xbf800000,2
+np.float32,0x426231d6,0x3f800000,2
+np.float32,0xc26231d6,0x3f800000,2
+np.float32,0x416ec2d4,0xbf3504f7,2
+np.float32,0xc16ec2d4,0xbf3504f7,2
+np.float32,0x41eec2d4,0x353ef0a7,2
+np.float32,0xc1eec2d4,0x353ef0a7,2
+np.float32,0x426ec2d4,0xbf800000,2
+np.float32,0xc26ec2d4,0xbf800000,2
+np.float32,0x417b53d2,0xbf800000,2
+np.float32,0xc17b53d2,0xbf800000,2
+np.float32,0x41fb53d2,0x3f800000,2
+np.float32,0xc1fb53d2,0x3f800000,2
+np.float32,0x427b53d2,0x3f800000,2
+np.float32,0xc27b53d2,0x3f800000,2
+np.float32,0x4183f268,0xbf3504e7,2
+np.float32,0xc183f268,0xbf3504e7,2
+np.float32,0x4203f268,0xb6059a13,2
+np.float32,0xc203f268,0xb6059a13,2
+np.float32,0x4283f268,0xbf800000,2
+np.float32,0xc283f268,0xbf800000,2
+np.float32,0x418a3ae7,0x35b08908,2
+np.float32,0xc18a3ae7,0x35b08908,2
+np.float32,0x420a3ae7,0xbf800000,2
+np.float32,0xc20a3ae7,0xbf800000,2
+np.float32,0x428a3ae7,0x3f800000,2
+np.float32,0xc28a3ae7,0x3f800000,2
+np.float32,0x41908365,0x3f3504f0,2
+np.float32,0xc1908365,0x3f3504f0,2
+np.float32,0x42108365,0xb512200d,2
+np.float32,0xc2108365,0xb512200d,2
+np.float32,0x42908365,0xbf800000,2
+np.float32,0xc2908365,0xbf800000,2
+np.float32,0x4196cbe4,0x3f800000,2
+np.float32,0xc196cbe4,0x3f800000,2
+np.float32,0x4216cbe4,0x3f800000,2
+np.float32,0xc216cbe4,0x3f800000,2
+np.float32,0x4296cbe4,0x3f800000,2
+np.float32,0xc296cbe4,0x3f800000,2
+np.float32,0x419d1463,0x3f3504ef,2
+np.float32,0xc19d1463,0x3f3504ef,2
+np.float32,0x421d1463,0xb5455799,2
+np.float32,0xc21d1463,0xb5455799,2
+np.float32,0x429d1463,0xbf800000,2
+np.float32,0xc29d1463,0xbf800000,2
+np.float32,0x41a35ce2,0xb53889b6,2
+np.float32,0xc1a35ce2,0xb53889b6,2
+np.float32,0x42235ce2,0xbf800000,2
+np.float32,0xc2235ce2,0xbf800000,2
+np.float32,0x42a35ce2,0x3f800000,2
+np.float32,0xc2a35ce2,0x3f800000,2
+np.float32,0x41a9a561,0xbf3504ff,2
+np.float32,0xc1a9a561,0xbf3504ff,2
+np.float32,0x4229a561,0x360733d0,2
+np.float32,0xc229a561,0x360733d0,2
+np.float32,0x42a9a561,0xbf800000,2
+np.float32,0xc2a9a561,0xbf800000,2
+np.float32,0x41afede0,0xbf800000,2
+np.float32,0xc1afede0,0xbf800000,2
+np.float32,0x422fede0,0x3f800000,2
+np.float32,0xc22fede0,0x3f800000,2
+np.float32,0x42afede0,0x3f800000,2
+np.float32,0xc2afede0,0x3f800000,2
+np.float32,0x41b6365e,0xbf3504f6,2
+np.float32,0xc1b6365e,0xbf3504f6,2
+np.float32,0x4236365e,0x350bb91c,2
+np.float32,0xc236365e,0x350bb91c,2
+np.float32,0x42b6365e,0xbf800000,2
+np.float32,0xc2b6365e,0xbf800000,2
+np.float32,0x41bc7edd,0x33800add,2
+np.float32,0xc1bc7edd,0x33800add,2
+np.float32,0x423c7edd,0xbf800000,2
+np.float32,0xc23c7edd,0xbf800000,2
+np.float32,0x42bc7edd,0x3f800000,2
+np.float32,0xc2bc7edd,0x3f800000,2
+np.float32,0x41c2c75c,0x3f3504f8,2
+np.float32,0xc1c2c75c,0x3f3504f8,2
+np.float32,0x4242c75c,0x354bbe8a,2
+np.float32,0xc242c75c,0x354bbe8a,2
+np.float32,0x42c2c75c,0xbf800000,2
+np.float32,0xc2c2c75c,0xbf800000,2
+np.float32,0x41c90fdb,0x3f800000,2
+np.float32,0xc1c90fdb,0x3f800000,2
+np.float32,0x42490fdb,0x3f800000,2
+np.float32,0xc2490fdb,0x3f800000,2
+np.float32,0x42c90fdb,0x3f800000,2
+np.float32,0xc2c90fdb,0x3f800000,2
+np.float32,0x41cf585a,0x3f3504e7,2
+np.float32,0xc1cf585a,0x3f3504e7,2
+np.float32,0x424f585a,0xb608cd8c,2
+np.float32,0xc24f585a,0xb608cd8c,2
+np.float32,0x42cf585a,0xbf800000,2
+np.float32,0xc2cf585a,0xbf800000,2
+np.float32,0x41d5a0d9,0xb5b3bc81,2
+np.float32,0xc1d5a0d9,0xb5b3bc81,2
+np.float32,0x4255a0d9,0xbf800000,2
+np.float32,0xc255a0d9,0xbf800000,2
+np.float32,0x42d5a0d9,0x3f800000,2
+np.float32,0xc2d5a0d9,0x3f800000,2
+np.float32,0x41dbe958,0xbf350507,2
+np.float32,0xc1dbe958,0xbf350507,2
+np.float32,0x425be958,0x365eab75,2
+np.float32,0xc25be958,0x365eab75,2
+np.float32,0x42dbe958,0xbf800000,2
+np.float32,0xc2dbe958,0xbf800000,2
+np.float32,0x41e231d6,0xbf800000,2
+np.float32,0xc1e231d6,0xbf800000,2
+np.float32,0x426231d6,0x3f800000,2
+np.float32,0xc26231d6,0x3f800000,2
+np.float32,0x42e231d6,0x3f800000,2
+np.float32,0xc2e231d6,0x3f800000,2
+np.float32,0x41e87a55,0xbf3504ef,2
+np.float32,0xc1e87a55,0xbf3504ef,2
+np.float32,0x42687a55,0xb552257b,2
+np.float32,0xc2687a55,0xb552257b,2
+np.float32,0x42e87a55,0xbf800000,2
+np.float32,0xc2e87a55,0xbf800000,2
+np.float32,0x41eec2d4,0x353ef0a7,2
+np.float32,0xc1eec2d4,0x353ef0a7,2
+np.float32,0x426ec2d4,0xbf800000,2
+np.float32,0xc26ec2d4,0xbf800000,2
+np.float32,0x42eec2d4,0x3f800000,2
+np.float32,0xc2eec2d4,0x3f800000,2
+np.float32,0x41f50b53,0x3f3504ff,2
+np.float32,0xc1f50b53,0x3f3504ff,2
+np.float32,0x42750b53,0x360a6748,2
+np.float32,0xc2750b53,0x360a6748,2
+np.float32,0x42f50b53,0xbf800000,2
+np.float32,0xc2f50b53,0xbf800000,2
+np.float32,0x41fb53d2,0x3f800000,2
+np.float32,0xc1fb53d2,0x3f800000,2
+np.float32,0x427b53d2,0x3f800000,2
+np.float32,0xc27b53d2,0x3f800000,2
+np.float32,0x42fb53d2,0x3f800000,2
+np.float32,0xc2fb53d2,0x3f800000,2
+np.float32,0x4200ce28,0x3f3504f6,2
+np.float32,0xc200ce28,0x3f3504f6,2
+np.float32,0x4280ce28,0x34fdd672,2
+np.float32,0xc280ce28,0x34fdd672,2
+np.float32,0x4300ce28,0xbf800000,2
+np.float32,0xc300ce28,0xbf800000,2
+np.float32,0x4203f268,0xb6059a13,2
+np.float32,0xc203f268,0xb6059a13,2
+np.float32,0x4283f268,0xbf800000,2
+np.float32,0xc283f268,0xbf800000,2
+np.float32,0x4303f268,0x3f800000,2
+np.float32,0xc303f268,0x3f800000,2
+np.float32,0x420716a7,0xbf3504f8,2
+np.float32,0xc20716a7,0xbf3504f8,2
+np.float32,0x428716a7,0x35588c6d,2
+np.float32,0xc28716a7,0x35588c6d,2
+np.float32,0x430716a7,0xbf800000,2
+np.float32,0xc30716a7,0xbf800000,2
+np.float32,0x420a3ae7,0xbf800000,2
+np.float32,0xc20a3ae7,0xbf800000,2
+np.float32,0x428a3ae7,0x3f800000,2
+np.float32,0xc28a3ae7,0x3f800000,2
+np.float32,0x430a3ae7,0x3f800000,2
+np.float32,0xc30a3ae7,0x3f800000,2
+np.float32,0x420d5f26,0xbf3504e7,2
+np.float32,0xc20d5f26,0xbf3504e7,2
+np.float32,0x428d5f26,0xb60c0105,2
+np.float32,0xc28d5f26,0xb60c0105,2
+np.float32,0x430d5f26,0xbf800000,2
+np.float32,0xc30d5f26,0xbf800000,2
+np.float32,0x42108365,0xb512200d,2
+np.float32,0xc2108365,0xb512200d,2
+np.float32,0x42908365,0xbf800000,2
+np.float32,0xc2908365,0xbf800000,2
+np.float32,0x43108365,0x3f800000,2
+np.float32,0xc3108365,0x3f800000,2
+np.float32,0x4213a7a5,0x3f350507,2
+np.float32,0xc213a7a5,0x3f350507,2
+np.float32,0x4293a7a5,0x3661deee,2
+np.float32,0xc293a7a5,0x3661deee,2
+np.float32,0x4313a7a5,0xbf800000,2
+np.float32,0xc313a7a5,0xbf800000,2
+np.float32,0x4216cbe4,0x3f800000,2
+np.float32,0xc216cbe4,0x3f800000,2
+np.float32,0x4296cbe4,0x3f800000,2
+np.float32,0xc296cbe4,0x3f800000,2
+np.float32,0x4316cbe4,0x3f800000,2
+np.float32,0xc316cbe4,0x3f800000,2
+np.float32,0x4219f024,0x3f3504d8,2
+np.float32,0xc219f024,0x3f3504d8,2
+np.float32,0x4299f024,0xb69bde6c,2
+np.float32,0xc299f024,0xb69bde6c,2
+np.float32,0x4319f024,0xbf800000,2
+np.float32,0xc319f024,0xbf800000,2
+np.float32,0x421d1463,0xb5455799,2
+np.float32,0xc21d1463,0xb5455799,2
+np.float32,0x429d1463,0xbf800000,2
+np.float32,0xc29d1463,0xbf800000,2
+np.float32,0x431d1463,0x3f800000,2
+np.float32,0xc31d1463,0x3f800000,2
+np.float32,0x422038a3,0xbf350516,2
+np.float32,0xc22038a3,0xbf350516,2
+np.float32,0x42a038a3,0x36c6cd61,2
+np.float32,0xc2a038a3,0x36c6cd61,2
+np.float32,0x432038a3,0xbf800000,2
+np.float32,0xc32038a3,0xbf800000,2
+np.float32,0x42235ce2,0xbf800000,2
+np.float32,0xc2235ce2,0xbf800000,2
+np.float32,0x42a35ce2,0x3f800000,2
+np.float32,0xc2a35ce2,0x3f800000,2
+np.float32,0x43235ce2,0x3f800000,2
+np.float32,0xc3235ce2,0x3f800000,2
+np.float32,0x42268121,0xbf3504f6,2
+np.float32,0xc2268121,0xbf3504f6,2
+np.float32,0x42a68121,0x34e43aac,2
+np.float32,0xc2a68121,0x34e43aac,2
+np.float32,0x43268121,0xbf800000,2
+np.float32,0xc3268121,0xbf800000,2
+np.float32,0x4229a561,0x360733d0,2
+np.float32,0xc229a561,0x360733d0,2
+np.float32,0x42a9a561,0xbf800000,2
+np.float32,0xc2a9a561,0xbf800000,2
+np.float32,0x4329a561,0x3f800000,2
+np.float32,0xc329a561,0x3f800000,2
+np.float32,0x422cc9a0,0x3f3504f8,2
+np.float32,0xc22cc9a0,0x3f3504f8,2
+np.float32,0x42acc9a0,0x35655a50,2
+np.float32,0xc2acc9a0,0x35655a50,2
+np.float32,0x432cc9a0,0xbf800000,2
+np.float32,0xc32cc9a0,0xbf800000,2
+np.float32,0x422fede0,0x3f800000,2
+np.float32,0xc22fede0,0x3f800000,2
+np.float32,0x42afede0,0x3f800000,2
+np.float32,0xc2afede0,0x3f800000,2
+np.float32,0x432fede0,0x3f800000,2
+np.float32,0xc32fede0,0x3f800000,2
+np.float32,0x4233121f,0x3f3504e7,2
+np.float32,0xc233121f,0x3f3504e7,2
+np.float32,0x42b3121f,0xb60f347d,2
+np.float32,0xc2b3121f,0xb60f347d,2
+np.float32,0x4333121f,0xbf800000,2
+np.float32,0xc333121f,0xbf800000,2
+np.float32,0x4236365e,0x350bb91c,2
+np.float32,0xc236365e,0x350bb91c,2
+np.float32,0x42b6365e,0xbf800000,2
+np.float32,0xc2b6365e,0xbf800000,2
+np.float32,0x4336365e,0x3f800000,2
+np.float32,0xc336365e,0x3f800000,2
+np.float32,0x42395a9e,0xbf350507,2
+np.float32,0xc2395a9e,0xbf350507,2
+np.float32,0x42b95a9e,0x36651267,2
+np.float32,0xc2b95a9e,0x36651267,2
+np.float32,0x43395a9e,0xbf800000,2
+np.float32,0xc3395a9e,0xbf800000,2
+np.float32,0x423c7edd,0xbf800000,2
+np.float32,0xc23c7edd,0xbf800000,2
+np.float32,0x42bc7edd,0x3f800000,2
+np.float32,0xc2bc7edd,0x3f800000,2
+np.float32,0x433c7edd,0x3f800000,2
+np.float32,0xc33c7edd,0x3f800000,2
+np.float32,0x423fa31d,0xbf3504d7,2
+np.float32,0xc23fa31d,0xbf3504d7,2
+np.float32,0x42bfa31d,0xb69d7828,2
+np.float32,0xc2bfa31d,0xb69d7828,2
+np.float32,0x433fa31d,0xbf800000,2
+np.float32,0xc33fa31d,0xbf800000,2
+np.float32,0x4242c75c,0x354bbe8a,2
+np.float32,0xc242c75c,0x354bbe8a,2
+np.float32,0x42c2c75c,0xbf800000,2
+np.float32,0xc2c2c75c,0xbf800000,2
+np.float32,0x4342c75c,0x3f800000,2
+np.float32,0xc342c75c,0x3f800000,2
+np.float32,0x4245eb9c,0x3f350517,2
+np.float32,0xc245eb9c,0x3f350517,2
+np.float32,0x42c5eb9c,0x36c8671d,2
+np.float32,0xc2c5eb9c,0x36c8671d,2
+np.float32,0x4345eb9c,0xbf800000,2
+np.float32,0xc345eb9c,0xbf800000,2
+np.float32,0x42490fdb,0x3f800000,2
+np.float32,0xc2490fdb,0x3f800000,2
+np.float32,0x42c90fdb,0x3f800000,2
+np.float32,0xc2c90fdb,0x3f800000,2
+np.float32,0x43490fdb,0x3f800000,2
+np.float32,0xc3490fdb,0x3f800000,2
+np.float32,0x424c341a,0x3f3504f5,2
+np.float32,0xc24c341a,0x3f3504f5,2
+np.float32,0x42cc341a,0x34ca9ee6,2
+np.float32,0xc2cc341a,0x34ca9ee6,2
+np.float32,0x434c341a,0xbf800000,2
+np.float32,0xc34c341a,0xbf800000,2
+np.float32,0x424f585a,0xb608cd8c,2
+np.float32,0xc24f585a,0xb608cd8c,2
+np.float32,0x42cf585a,0xbf800000,2
+np.float32,0xc2cf585a,0xbf800000,2
+np.float32,0x434f585a,0x3f800000,2
+np.float32,0xc34f585a,0x3f800000,2
+np.float32,0x42527c99,0xbf3504f9,2
+np.float32,0xc2527c99,0xbf3504f9,2
+np.float32,0x42d27c99,0x35722833,2
+np.float32,0xc2d27c99,0x35722833,2
+np.float32,0x43527c99,0xbf800000,2
+np.float32,0xc3527c99,0xbf800000,2
+np.float32,0x4255a0d9,0xbf800000,2
+np.float32,0xc255a0d9,0xbf800000,2
+np.float32,0x42d5a0d9,0x3f800000,2
+np.float32,0xc2d5a0d9,0x3f800000,2
+np.float32,0x4355a0d9,0x3f800000,2
+np.float32,0xc355a0d9,0x3f800000,2
+np.float32,0x4258c518,0xbf3504e6,2
+np.float32,0xc258c518,0xbf3504e6,2
+np.float32,0x42d8c518,0xb61267f6,2
+np.float32,0xc2d8c518,0xb61267f6,2
+np.float32,0x4358c518,0xbf800000,2
+np.float32,0xc358c518,0xbf800000,2
+np.float32,0x425be958,0x365eab75,2
+np.float32,0xc25be958,0x365eab75,2
+np.float32,0x42dbe958,0xbf800000,2
+np.float32,0xc2dbe958,0xbf800000,2
+np.float32,0x435be958,0x3f800000,2
+np.float32,0xc35be958,0x3f800000,2
+np.float32,0x425f0d97,0x3f350508,2
+np.float32,0xc25f0d97,0x3f350508,2
+np.float32,0x42df0d97,0x366845e0,2
+np.float32,0xc2df0d97,0x366845e0,2
+np.float32,0x435f0d97,0xbf800000,2
+np.float32,0xc35f0d97,0xbf800000,2
+np.float32,0x426231d6,0x3f800000,2
+np.float32,0xc26231d6,0x3f800000,2
+np.float32,0x42e231d6,0x3f800000,2
+np.float32,0xc2e231d6,0x3f800000,2
+np.float32,0x436231d6,0x3f800000,2
+np.float32,0xc36231d6,0x3f800000,2
+np.float32,0x42655616,0x3f3504d7,2
+np.float32,0xc2655616,0x3f3504d7,2
+np.float32,0x42e55616,0xb69f11e5,2
+np.float32,0xc2e55616,0xb69f11e5,2
+np.float32,0x43655616,0xbf800000,2
+np.float32,0xc3655616,0xbf800000,2
+np.float32,0x42687a55,0xb552257b,2
+np.float32,0xc2687a55,0xb552257b,2
+np.float32,0x42e87a55,0xbf800000,2
+np.float32,0xc2e87a55,0xbf800000,2
+np.float32,0x43687a55,0x3f800000,2
+np.float32,0xc3687a55,0x3f800000,2
+np.float32,0x426b9e95,0xbf350517,2
+np.float32,0xc26b9e95,0xbf350517,2
+np.float32,0x42eb9e95,0x36ca00d9,2
+np.float32,0xc2eb9e95,0x36ca00d9,2
+np.float32,0x436b9e95,0xbf800000,2
+np.float32,0xc36b9e95,0xbf800000,2
+np.float32,0x426ec2d4,0xbf800000,2
+np.float32,0xc26ec2d4,0xbf800000,2
+np.float32,0x42eec2d4,0x3f800000,2
+np.float32,0xc2eec2d4,0x3f800000,2
+np.float32,0x436ec2d4,0x3f800000,2
+np.float32,0xc36ec2d4,0x3f800000,2
+np.float32,0x4271e713,0xbf3504f5,2
+np.float32,0xc271e713,0xbf3504f5,2
+np.float32,0x42f1e713,0x34b10321,2
+np.float32,0xc2f1e713,0x34b10321,2
+np.float32,0x4371e713,0xbf800000,2
+np.float32,0xc371e713,0xbf800000,2
+np.float32,0x42750b53,0x360a6748,2
+np.float32,0xc2750b53,0x360a6748,2
+np.float32,0x42f50b53,0xbf800000,2
+np.float32,0xc2f50b53,0xbf800000,2
+np.float32,0x43750b53,0x3f800000,2
+np.float32,0xc3750b53,0x3f800000,2
+np.float32,0x42782f92,0x3f3504f9,2
+np.float32,0xc2782f92,0x3f3504f9,2
+np.float32,0x42f82f92,0x357ef616,2
+np.float32,0xc2f82f92,0x357ef616,2
+np.float32,0x43782f92,0xbf800000,2
+np.float32,0xc3782f92,0xbf800000,2
+np.float32,0x427b53d2,0x3f800000,2
+np.float32,0xc27b53d2,0x3f800000,2
+np.float32,0x42fb53d2,0x3f800000,2
+np.float32,0xc2fb53d2,0x3f800000,2
+np.float32,0x437b53d2,0x3f800000,2
+np.float32,0xc37b53d2,0x3f800000,2
+np.float32,0x427e7811,0x3f3504e6,2
+np.float32,0xc27e7811,0x3f3504e6,2
+np.float32,0x42fe7811,0xb6159b6f,2
+np.float32,0xc2fe7811,0xb6159b6f,2
+np.float32,0x437e7811,0xbf800000,2
+np.float32,0xc37e7811,0xbf800000,2
+np.float32,0x4280ce28,0x34fdd672,2
+np.float32,0xc280ce28,0x34fdd672,2
+np.float32,0x4300ce28,0xbf800000,2
+np.float32,0xc300ce28,0xbf800000,2
+np.float32,0x4380ce28,0x3f800000,2
+np.float32,0xc380ce28,0x3f800000,2
+np.float32,0x42826048,0xbf350508,2
+np.float32,0xc2826048,0xbf350508,2
+np.float32,0x43026048,0x366b7958,2
+np.float32,0xc3026048,0x366b7958,2
+np.float32,0x43826048,0xbf800000,2
+np.float32,0xc3826048,0xbf800000,2
+np.float32,0x4283f268,0xbf800000,2
+np.float32,0xc283f268,0xbf800000,2
+np.float32,0x4303f268,0x3f800000,2
+np.float32,0xc303f268,0x3f800000,2
+np.float32,0x4383f268,0x3f800000,2
+np.float32,0xc383f268,0x3f800000,2
+np.float32,0x42858487,0xbf350504,2
+np.float32,0xc2858487,0xbf350504,2
+np.float32,0x43058487,0x363ea8be,2
+np.float32,0xc3058487,0x363ea8be,2
+np.float32,0x43858487,0xbf800000,2
+np.float32,0xc3858487,0xbf800000,2
+np.float32,0x428716a7,0x35588c6d,2
+np.float32,0xc28716a7,0x35588c6d,2
+np.float32,0x430716a7,0xbf800000,2
+np.float32,0xc30716a7,0xbf800000,2
+np.float32,0x438716a7,0x3f800000,2
+np.float32,0xc38716a7,0x3f800000,2
+np.float32,0x4288a8c7,0x3f350517,2
+np.float32,0xc288a8c7,0x3f350517,2
+np.float32,0x4308a8c7,0x36cb9a96,2
+np.float32,0xc308a8c7,0x36cb9a96,2
+np.float32,0x4388a8c7,0xbf800000,2
+np.float32,0xc388a8c7,0xbf800000,2
+np.float32,0x428a3ae7,0x3f800000,2
+np.float32,0xc28a3ae7,0x3f800000,2
+np.float32,0x430a3ae7,0x3f800000,2
+np.float32,0xc30a3ae7,0x3f800000,2
+np.float32,0x438a3ae7,0x3f800000,2
+np.float32,0xc38a3ae7,0x3f800000,2
+np.float32,0x428bcd06,0x3f3504f5,2
+np.float32,0xc28bcd06,0x3f3504f5,2
+np.float32,0x430bcd06,0x3497675b,2
+np.float32,0xc30bcd06,0x3497675b,2
+np.float32,0x438bcd06,0xbf800000,2
+np.float32,0xc38bcd06,0xbf800000,2
+np.float32,0x428d5f26,0xb60c0105,2
+np.float32,0xc28d5f26,0xb60c0105,2
+np.float32,0x430d5f26,0xbf800000,2
+np.float32,0xc30d5f26,0xbf800000,2
+np.float32,0x438d5f26,0x3f800000,2
+np.float32,0xc38d5f26,0x3f800000,2
+np.float32,0x428ef146,0xbf350526,2
+np.float32,0xc28ef146,0xbf350526,2
+np.float32,0x430ef146,0x3710bc40,2
+np.float32,0xc30ef146,0x3710bc40,2
+np.float32,0x438ef146,0xbf800000,2
+np.float32,0xc38ef146,0xbf800000,2
+np.float32,0x42908365,0xbf800000,2
+np.float32,0xc2908365,0xbf800000,2
+np.float32,0x43108365,0x3f800000,2
+np.float32,0xc3108365,0x3f800000,2
+np.float32,0x43908365,0x3f800000,2
+np.float32,0xc3908365,0x3f800000,2
+np.float32,0x42921585,0xbf3504e6,2
+np.float32,0xc2921585,0xbf3504e6,2
+np.float32,0x43121585,0xb618cee8,2
+np.float32,0xc3121585,0xb618cee8,2
+np.float32,0x43921585,0xbf800000,2
+np.float32,0xc3921585,0xbf800000,2
+np.float32,0x4293a7a5,0x3661deee,2
+np.float32,0xc293a7a5,0x3661deee,2
+np.float32,0x4313a7a5,0xbf800000,2
+np.float32,0xc313a7a5,0xbf800000,2
+np.float32,0x4393a7a5,0x3f800000,2
+np.float32,0xc393a7a5,0x3f800000,2
+np.float32,0x429539c5,0x3f350536,2
+np.float32,0xc29539c5,0x3f350536,2
+np.float32,0x431539c5,0x373bab34,2
+np.float32,0xc31539c5,0x373bab34,2
+np.float32,0x439539c5,0xbf800000,2
+np.float32,0xc39539c5,0xbf800000,2
+np.float32,0x4296cbe4,0x3f800000,2
+np.float32,0xc296cbe4,0x3f800000,2
+np.float32,0x4316cbe4,0x3f800000,2
+np.float32,0xc316cbe4,0x3f800000,2
+np.float32,0x4396cbe4,0x3f800000,2
+np.float32,0xc396cbe4,0x3f800000,2
+np.float32,0x42985e04,0x3f3504d7,2
+np.float32,0xc2985e04,0x3f3504d7,2
+np.float32,0x43185e04,0xb6a2455d,2
+np.float32,0xc3185e04,0xb6a2455d,2
+np.float32,0x43985e04,0xbf800000,2
+np.float32,0xc3985e04,0xbf800000,2
+np.float32,0x4299f024,0xb69bde6c,2
+np.float32,0xc299f024,0xb69bde6c,2
+np.float32,0x4319f024,0xbf800000,2
+np.float32,0xc319f024,0xbf800000,2
+np.float32,0x4399f024,0x3f800000,2
+np.float32,0xc399f024,0x3f800000,2
+np.float32,0x429b8243,0xbf3504ea,2
+np.float32,0xc29b8243,0xbf3504ea,2
+np.float32,0x431b8243,0xb5cb2eb8,2
+np.float32,0xc31b8243,0xb5cb2eb8,2
+np.float32,0x439b8243,0xbf800000,2
+np.float32,0xc39b8243,0xbf800000,2
+np.float32,0x435b2047,0x3f3504c1,2
+np.float32,0x42a038a2,0xb5e4ca7e,2
+np.float32,0x432038a2,0xbf800000,2
+np.float32,0x4345eb9b,0xbf800000,2
+np.float32,0x42c5eb9b,0xb5de638c,2
+np.float32,0x42eb9e94,0xb5d7fc9b,2
+np.float32,0x4350ea79,0x3631dadb,2
+np.float32,0x42dbe957,0xbf800000,2
+np.float32,0x425be957,0xb505522a,2
+np.float32,0x435be957,0x3f800000,2
+np.float32,0x46027eb2,0x3e7d94c9,2
+np.float32,0x4477baed,0xbe7f1824,2
+np.float32,0x454b8024,0x3e7f5268,2
+np.float32,0x455d2c09,0x3e7f40cb,2
+np.float32,0x4768d3de,0xba14b4af,2
+np.float32,0x46c1e7cd,0x3e7fb102,2
+np.float32,0x44a52949,0xbe7dc9d5,2
+np.float32,0x4454633a,0x3e7dbc7d,2
+np.float32,0x4689810b,0x3e7eb02b,2
+np.float32,0x473473cd,0xbe7eef6f,2
+np.float32,0x44a5193f,0x3e7e1b1f,2
+np.float32,0x46004b36,0x3e7dac59,2
+np.float32,0x467f604b,0x3d7ffd3a,2
+np.float32,0x45ea1805,0x3dffd2e0,2
+np.float32,0x457b6af3,0x3dff7831,2
+np.float32,0x44996159,0xbe7d85f4,2
+np.float32,0x47883553,0xbb80584e,2
+np.float32,0x44e19f0c,0xbdffcfe6,2
+np.float32,0x472b3bf6,0xbe7f7a82,2
+np.float32,0x4600bb4e,0x3a135e33,2
+np.float32,0x449f4556,0x3e7e42e5,2
+np.float32,0x474e9420,0x3dff77b2,2
+np.float32,0x45cbdb23,0x3dff7240,2
+np.float32,0x44222747,0x3dffb039,2
+np.float32,0x4772e419,0xbdff74b8,2
+np.float64,0x1,0x3ff0000000000000,4
+np.float64,0x8000000000000001,0x3ff0000000000000,4
+np.float64,0x10000000000000,0x3ff0000000000000,4
+np.float64,0x8010000000000000,0x3ff0000000000000,4
+np.float64,0x7fefffffffffffff,0xbfefffe62ecfab75,4
+np.float64,0xffefffffffffffff,0xbfefffe62ecfab75,4
+np.float64,0x7ff0000000000000,0xfff8000000000000,4
+np.float64,0xfff0000000000000,0xfff8000000000000,4
+np.float64,0x7ff8000000000000,0x7ff8000000000000,4
+np.float64,0x7ff4000000000000,0x7ffc000000000000,4
+np.float64,0xbfc28bd9dd2517b4,0x3fefaa28ba13a702,4
+np.float64,0x3fb673c62e2ce790,0x3fefe083847a717f,4
+np.float64,0xbfe3e1dac7e7c3b6,0x3fea0500ba099f3a,4
+np.float64,0xbfbe462caa3c8c58,0x3fefc6c8b9c1c87c,4
+np.float64,0xbfb9353576326a68,0x3fefd8513e50e6b1,4
+np.float64,0xbfc05e798520bcf4,0x3fefbd1ad81cf089,4
+np.float64,0xbfe3ca3be2e79478,0x3fea12b995ea6574,4
+np.float64,0xbfde875d46bd0eba,0x3fec6d888662a824,4
+np.float64,0x3fafc4e02c3f89c0,0x3feff03c34bffd69,4
+np.float64,0xbf98855848310ac0,0x3feffda6c1588bdb,4
+np.float64,0x3fe66c51186cd8a2,0x3fe875c61c630ecb,4
+np.float64,0xbfedff1c3b7bfe38,0x3fe2f0c8c9e8fa39,4
+np.float64,0x3fd6082267ac1044,0x3fee1f6023695050,4
+np.float64,0xbfe78449b06f0894,0x3fe7bda2b223850e,4
+np.float64,0x3feedb8e63fdb71c,0x3fe23d5dfd2dd33f,4
+np.float64,0xbfc0a9de3d2153bc,0x3fefbaadf5e5285e,4
+np.float64,0x3fc04c67432098d0,0x3fefbdae07b7de8d,4
+np.float64,0xbfeeef84c4fddf0a,0x3fe22cf37f309d88,4
+np.float64,0x3fc04bb025209760,0x3fefbdb3d7d34ecf,4
+np.float64,0x3fd6b84d48ad709c,0x3fee013403da6e2a,4
+np.float64,0x3fec1ae25d7835c4,0x3fe46e62195cf274,4
+np.float64,0xbfdc6fdf9bb8dfc0,0x3fece48dc78bbb2e,4
+np.float64,0x3fb4db2c9229b660,0x3fefe4d42f79bf49,4
+np.float64,0xbfc0ed698521dad4,0x3fefb8785ea658c9,4
+np.float64,0xbfee82772b7d04ee,0x3fe2864a80efe8e9,4
+np.float64,0x3fd575b664aaeb6c,0x3fee37c669a12879,4
+np.float64,0x3fe4afb1c5e95f64,0x3fe98b177194439c,4
+np.float64,0x3fd93962f9b272c4,0x3fed8bef61876294,4
+np.float64,0x3fd97ae025b2f5c0,0x3fed7f4cfbf4d300,4
+np.float64,0xbfd9afdb1bb35fb6,0x3fed74fdc44dabb1,4
+np.float64,0x3f8ae65e3035cc80,0x3fefff4b1a0ea62b,4
+np.float64,0xbfe7e58664efcb0d,0x3fe77c02a1cbb670,4
+np.float64,0x3fe5f68b37ebed16,0x3fe8c10f849a5d4d,4
+np.float64,0x3fd9137d61b226fc,0x3fed9330eb4815a1,4
+np.float64,0x3fc146d019228da0,0x3fefb57e2d4d52f8,4
+np.float64,0xbfda6036edb4c06e,0x3fed521b2b578679,4
+np.float64,0xbfe78ddfb0ef1bc0,0x3fe7b734319a77e4,4
+np.float64,0x3fe0877823610ef0,0x3febd33a993dd786,4
+np.float64,0x3fbc61af2e38c360,0x3fefcdb4f889756d,4
+np.float64,0x3fd4dcdca4a9b9b8,0x3fee50962ffea5ae,4
+np.float64,0xbfe03cb29f607965,0x3febf7dbf640a75a,4
+np.float64,0xbfc81de407303bc8,0x3fef6f066cef64bc,4
+np.float64,0x3fd8dea42db1bd48,0x3fed9d3e00dbe0b3,4
+np.float64,0x3feac75e94f58ebe,0x3fe56f1f47f97896,4
+np.float64,0x3fb3a1ea6e2743d0,0x3fefe7ec1247cdaa,4
+np.float64,0x3fd695c0f4ad2b80,0x3fee0730bd40883d,4
+np.float64,0xbfd2c631f5a58c64,0x3feea20cbd1105d7,4
+np.float64,0xbfe978a8e1f2f152,0x3fe663014d40ad7a,4
+np.float64,0x3fd8b6b76ab16d70,0x3feda4c879aacc19,4
+np.float64,0x3feaafd30e755fa6,0x3fe5809514c28453,4
+np.float64,0x3fe1e37dc263c6fc,0x3feb20f9ad1f3f5c,4
+np.float64,0x3fd0ec7c24a1d8f8,0x3feee34048f43b75,4
+np.float64,0xbfe3881cbf67103a,0x3fea38d7886e6f53,4
+np.float64,0xbfd7023957ae0472,0x3fedf4471c765a1c,4
+np.float64,0xbfebc51c4ef78a38,0x3fe4b01c424e297b,4
+np.float64,0xbfe20a93eae41528,0x3feb0c2aa321d2e0,4
+np.float64,0x3fef39be867e737e,0x3fe1efaba9164d27,4
+np.float64,0x3fe8ea9576f1d52a,0x3fe6c7a8826ce1be,4
+np.float64,0x3fea921d91f5243c,0x3fe5968c6cf78963,4
+np.float64,0x3fd7ee5d31afdcbc,0x3fedc9f19d43fe61,4
+np.float64,0xbfe3ed581767dab0,0x3fe9fe4ee2f2b1cd,4
+np.float64,0xbfc40923d5281248,0x3fef9bd8ee9f6e68,4
+np.float64,0x3fe411a834682350,0x3fe9e9103854f057,4
+np.float64,0xbfedf6ccdf7bed9a,0x3fe2f77ad6543246,4
+np.float64,0xbfe8788a44f0f114,0x3fe7172f3aa0c742,4
+np.float64,0xbfce728f173ce520,0x3fef1954083bea04,4
+np.float64,0xbfd64dd0acac9ba2,0x3fee138c3293c246,4
+np.float64,0xbfe00669f5600cd4,0x3fec121443945350,4
+np.float64,0xbfe7152ba2ee2a58,0x3fe8079465d09846,4
+np.float64,0x3fe8654d8f70ca9c,0x3fe7247c94f09596,4
+np.float64,0x3fea68045cf4d008,0x3fe5b58cfe81a243,4
+np.float64,0xbfcd4779073a8ef4,0x3fef2a9d78153fa5,4
+np.float64,0xbfdb4456e5b688ae,0x3fed23b11614203f,4
+np.float64,0x3fcb5d59cd36bab0,0x3fef45818216a515,4
+np.float64,0xbfd914ff5ab229fe,0x3fed92e73746fea8,4
+np.float64,0x3fe4d211db69a424,0x3fe97653f433d15f,4
+np.float64,0xbfdbbb9224b77724,0x3fed0adb593dde80,4
+np.float64,0x3fd424ceafa8499c,0x3fee6d9124795d33,4
+np.float64,0x3feb5968f976b2d2,0x3fe501d116efbf54,4
+np.float64,0x3fee7d92a2fcfb26,0x3fe28a479b6a9dcf,4
+np.float64,0x3fc308e9972611d0,0x3fefa595f4df0c89,4
+np.float64,0x3fda79cd77b4f39c,0x3fed4cf8e69ba1f8,4
+np.float64,0x3fcbcf42d5379e88,0x3fef3f6a6a77c187,4
+np.float64,0x3fe13a1da662743c,0x3feb79504faea888,4
+np.float64,0xbfee4435f07c886c,0x3fe2b8ea98d2fc29,4
+np.float64,0x3fd65d68ccacbad0,0x3fee10e1ac7ada89,4
+np.float64,0x3fef2f89bb7e5f14,0x3fe1f81e882cc3f4,4
+np.float64,0xbfef0a7769fe14ef,0x3fe216bf384fc646,4
+np.float64,0x3fc065277320ca50,0x3fefbce44835c193,4
+np.float64,0x3fe9c1a74d73834e,0x3fe62e9ee0c2f2bf,4
+np.float64,0x3fd9d96e5db3b2dc,0x3fed6cd88eb51f6a,4
+np.float64,0x3fe02bf1c56057e4,0x3febfffc24b5a7ba,4
+np.float64,0xbfd6814350ad0286,0x3fee0ab9ad318b84,4
+np.float64,0x3f9fcbec583f97c0,0x3feffc0d0f1d8e75,4
+np.float64,0x3fe23524e5e46a4a,0x3feaf55372949a06,4
+np.float64,0xbfbdc95f6a3b92c0,0x3fefc89c21d44995,4
+np.float64,0x3fe961bb9cf2c378,0x3fe6735d6e1cca58,4
+np.float64,0xbfe8f1c370f1e387,0x3fe6c29d1be8bee9,4
+np.float64,0x3fd880d43ab101a8,0x3fedaee3c7ccfc96,4
+np.float64,0xbfedb37005fb66e0,0x3fe32d91ef2e3bd3,4
+np.float64,0xfdce287bfb9c5,0x3ff0000000000000,4
+np.float64,0x9aa1b9e735437,0x3ff0000000000000,4
+np.float64,0x6beac6e0d7d59,0x3ff0000000000000,4
+np.float64,0x47457aae8e8b0,0x3ff0000000000000,4
+np.float64,0x35ff13b46bfe3,0x3ff0000000000000,4
+np.float64,0xb9c0c82b73819,0x3ff0000000000000,4
+np.float64,0x1a8dc21a351b9,0x3ff0000000000000,4
+np.float64,0x7e87ef6afd0ff,0x3ff0000000000000,4
+np.float64,0x620a6588c414d,0x3ff0000000000000,4
+np.float64,0x7f366000fe6e,0x3ff0000000000000,4
+np.float64,0x787e39f4f0fc8,0x3ff0000000000000,4
+np.float64,0xf5134f1fea26a,0x3ff0000000000000,4
+np.float64,0xbce700ef79ce0,0x3ff0000000000000,4
+np.float64,0x144d7cc8289b1,0x3ff0000000000000,4
+np.float64,0xb9fbc5b973f79,0x3ff0000000000000,4
+np.float64,0xc3d6292d87ac5,0x3ff0000000000000,4
+np.float64,0xc1084e618210a,0x3ff0000000000000,4
+np.float64,0xb6b9eca56d73e,0x3ff0000000000000,4
+np.float64,0xc7ac4b858f58a,0x3ff0000000000000,4
+np.float64,0x516d75d2a2daf,0x3ff0000000000000,4
+np.float64,0x9dc089d93b811,0x3ff0000000000000,4
+np.float64,0x7b5f2840f6be6,0x3ff0000000000000,4
+np.float64,0x121d3ce8243a9,0x3ff0000000000000,4
+np.float64,0xf0be0337e17c1,0x3ff0000000000000,4
+np.float64,0xff58a5cbfeb15,0x3ff0000000000000,4
+np.float64,0xdaf1d07fb5e3a,0x3ff0000000000000,4
+np.float64,0x61d95382c3b2b,0x3ff0000000000000,4
+np.float64,0xe4df943fc9bf3,0x3ff0000000000000,4
+np.float64,0xf72ac2bdee559,0x3ff0000000000000,4
+np.float64,0x12dafbf625b60,0x3ff0000000000000,4
+np.float64,0xee11d427dc23b,0x3ff0000000000000,4
+np.float64,0xf4f8eb37e9f1e,0x3ff0000000000000,4
+np.float64,0xad7cb5df5af97,0x3ff0000000000000,4
+np.float64,0x59fc9b06b3f94,0x3ff0000000000000,4
+np.float64,0x3c3e65e4787ce,0x3ff0000000000000,4
+np.float64,0xe37bc993c6f79,0x3ff0000000000000,4
+np.float64,0x13bd6330277ad,0x3ff0000000000000,4
+np.float64,0x56cc2800ad986,0x3ff0000000000000,4
+np.float64,0x6203b8fcc4078,0x3ff0000000000000,4
+np.float64,0x75c7c8b8eb8fa,0x3ff0000000000000,4
+np.float64,0x5ebf8e00bd7f2,0x3ff0000000000000,4
+np.float64,0xda81f2f1b503f,0x3ff0000000000000,4
+np.float64,0x6adb17d6d5b64,0x3ff0000000000000,4
+np.float64,0x1ba68eee374d3,0x3ff0000000000000,4
+np.float64,0xeecf6fbbdd9ee,0x3ff0000000000000,4
+np.float64,0x24d6dd8e49add,0x3ff0000000000000,4
+np.float64,0xdf7cb81bbef97,0x3ff0000000000000,4
+np.float64,0xafd7be1b5faf8,0x3ff0000000000000,4
+np.float64,0xdb90ca35b721a,0x3ff0000000000000,4
+np.float64,0xa72903a14e521,0x3ff0000000000000,4
+np.float64,0x14533ee028a7,0x3ff0000000000000,4
+np.float64,0x7951540cf2a2b,0x3ff0000000000000,4
+np.float64,0x22882be045106,0x3ff0000000000000,4
+np.float64,0x136270d626c4f,0x3ff0000000000000,4
+np.float64,0x6a0f5744d41ec,0x3ff0000000000000,4
+np.float64,0x21e0d1aa43c1b,0x3ff0000000000000,4
+np.float64,0xee544155dca88,0x3ff0000000000000,4
+np.float64,0xcbe8aac797d16,0x3ff0000000000000,4
+np.float64,0x6c065e80d80e,0x3ff0000000000000,4
+np.float64,0xe57f0411cafe1,0x3ff0000000000000,4
+np.float64,0xdec3a6bdbd875,0x3ff0000000000000,4
+np.float64,0xf4d23a0fe9a48,0x3ff0000000000000,4
+np.float64,0xda77ef47b4efe,0x3ff0000000000000,4
+np.float64,0x8c405c9b1880c,0x3ff0000000000000,4
+np.float64,0x4eced5149d9db,0x3ff0000000000000,4
+np.float64,0x16b6552c2d6cc,0x3ff0000000000000,4
+np.float64,0x6fbc262cdf785,0x3ff0000000000000,4
+np.float64,0x628c3844c5188,0x3ff0000000000000,4
+np.float64,0x6d827d2cdb050,0x3ff0000000000000,4
+np.float64,0xd1bfdf29a37fc,0x3ff0000000000000,4
+np.float64,0xd85400fdb0a80,0x3ff0000000000000,4
+np.float64,0xcc420b2d98842,0x3ff0000000000000,4
+np.float64,0xac41d21b5883b,0x3ff0000000000000,4
+np.float64,0x432f18d4865e4,0x3ff0000000000000,4
+np.float64,0xe7e89a1bcfd14,0x3ff0000000000000,4
+np.float64,0x9b1141d536228,0x3ff0000000000000,4
+np.float64,0x6805f662d00bf,0x3ff0000000000000,4
+np.float64,0xc76552358ecab,0x3ff0000000000000,4
+np.float64,0x4ae8ffee95d21,0x3ff0000000000000,4
+np.float64,0x4396c096872d9,0x3ff0000000000000,4
+np.float64,0x6e8e55d4dd1cb,0x3ff0000000000000,4
+np.float64,0x4c2e33dc985c7,0x3ff0000000000000,4
+np.float64,0xbce814a579d03,0x3ff0000000000000,4
+np.float64,0x911681b5222d0,0x3ff0000000000000,4
+np.float64,0x5f90a4b2bf215,0x3ff0000000000000,4
+np.float64,0x26f76be84deee,0x3ff0000000000000,4
+np.float64,0xb2f7536165eeb,0x3ff0000000000000,4
+np.float64,0x4de4e6089bc9d,0x3ff0000000000000,4
+np.float64,0xf2e016afe5c03,0x3ff0000000000000,4
+np.float64,0xb9b7b949736f7,0x3ff0000000000000,4
+np.float64,0x3363ea1866c7e,0x3ff0000000000000,4
+np.float64,0xd1a3bd6ba3478,0x3ff0000000000000,4
+np.float64,0xae89f3595d13f,0x3ff0000000000000,4
+np.float64,0xddbd9601bb7c,0x3ff0000000000000,4
+np.float64,0x5de41a06bbc84,0x3ff0000000000000,4
+np.float64,0xfd58c86dfab19,0x3ff0000000000000,4
+np.float64,0x24922e8c49247,0x3ff0000000000000,4
+np.float64,0xcda040339b408,0x3ff0000000000000,4
+np.float64,0x5fe500b2bfca1,0x3ff0000000000000,4
+np.float64,0x9214abb924296,0x3ff0000000000000,4
+np.float64,0x800609fe0a2c13fd,0x3ff0000000000000,4
+np.float64,0x800c7c6fe518f8e0,0x3ff0000000000000,4
+np.float64,0x800a1a9491b4352a,0x3ff0000000000000,4
+np.float64,0x800b45e0e8968bc2,0x3ff0000000000000,4
+np.float64,0x8008497e57d092fd,0x3ff0000000000000,4
+np.float64,0x800b9c0af0173816,0x3ff0000000000000,4
+np.float64,0x800194cccb43299a,0x3ff0000000000000,4
+np.float64,0x8001c91ef183923f,0x3ff0000000000000,4
+np.float64,0x800f25b5ccde4b6c,0x3ff0000000000000,4
+np.float64,0x800ce63ccc79cc7a,0x3ff0000000000000,4
+np.float64,0x800d8fb2e83b1f66,0x3ff0000000000000,4
+np.float64,0x80083cd06f7079a1,0x3ff0000000000000,4
+np.float64,0x800823598e9046b3,0x3ff0000000000000,4
+np.float64,0x8001c1319de38264,0x3ff0000000000000,4
+np.float64,0x800f2b68543e56d1,0x3ff0000000000000,4
+np.float64,0x80022a4f4364549f,0x3ff0000000000000,4
+np.float64,0x800f51badf7ea376,0x3ff0000000000000,4
+np.float64,0x8003fbf31e27f7e7,0x3ff0000000000000,4
+np.float64,0x800d4c00e2fa9802,0x3ff0000000000000,4
+np.float64,0x800023b974804774,0x3ff0000000000000,4
+np.float64,0x800860778990c0ef,0x3ff0000000000000,4
+np.float64,0x800a15c241542b85,0x3ff0000000000000,4
+np.float64,0x8003097d9dc612fc,0x3ff0000000000000,4
+np.float64,0x800d77d8541aefb1,0x3ff0000000000000,4
+np.float64,0x80093804ab52700a,0x3ff0000000000000,4
+np.float64,0x800d2b3bfd7a5678,0x3ff0000000000000,4
+np.float64,0x800da24bcd5b4498,0x3ff0000000000000,4
+np.float64,0x8006eee1c28dddc4,0x3ff0000000000000,4
+np.float64,0x80005137fa40a271,0x3ff0000000000000,4
+np.float64,0x8007a3fbc22f47f8,0x3ff0000000000000,4
+np.float64,0x800dcd97071b9b2e,0x3ff0000000000000,4
+np.float64,0x80065b36048cb66d,0x3ff0000000000000,4
+np.float64,0x8004206ba72840d8,0x3ff0000000000000,4
+np.float64,0x8007e82b98cfd058,0x3ff0000000000000,4
+np.float64,0x8001a116ed23422f,0x3ff0000000000000,4
+np.float64,0x800c69e9ff18d3d4,0x3ff0000000000000,4
+np.float64,0x8003843688e7086e,0x3ff0000000000000,4
+np.float64,0x800335e3b8866bc8,0x3ff0000000000000,4
+np.float64,0x800e3308f0bc6612,0x3ff0000000000000,4
+np.float64,0x8002a9ec55c553d9,0x3ff0000000000000,4
+np.float64,0x80001c2084e03842,0x3ff0000000000000,4
+np.float64,0x800bc2bbd8d78578,0x3ff0000000000000,4
+np.float64,0x800ae6bcc555cd7a,0x3ff0000000000000,4
+np.float64,0x80083f7a13907ef5,0x3ff0000000000000,4
+np.float64,0x800d83ed76db07db,0x3ff0000000000000,4
+np.float64,0x800a12251974244b,0x3ff0000000000000,4
+np.float64,0x800a69c95714d393,0x3ff0000000000000,4
+np.float64,0x800cd5a85639ab51,0x3ff0000000000000,4
+np.float64,0x800e0e1837bc1c31,0x3ff0000000000000,4
+np.float64,0x8007b5ca39ef6b95,0x3ff0000000000000,4
+np.float64,0x800cf961cad9f2c4,0x3ff0000000000000,4
+np.float64,0x80066e8fc14cdd20,0x3ff0000000000000,4
+np.float64,0x8001cb8c7b43971a,0x3ff0000000000000,4
+np.float64,0x800002df68a005c0,0x3ff0000000000000,4
+np.float64,0x8003e6681567ccd1,0x3ff0000000000000,4
+np.float64,0x800b039126b60723,0x3ff0000000000000,4
+np.float64,0x800d2e1b663a5c37,0x3ff0000000000000,4
+np.float64,0x800188b3e2a31169,0x3ff0000000000000,4
+np.float64,0x8001f272e943e4e7,0x3ff0000000000000,4
+np.float64,0x800d7f53607afea7,0x3ff0000000000000,4
+np.float64,0x80092cafa4f25960,0x3ff0000000000000,4
+np.float64,0x800fc009f07f8014,0x3ff0000000000000,4
+np.float64,0x8003da896507b514,0x3ff0000000000000,4
+np.float64,0x800d4d1b4c3a9a37,0x3ff0000000000000,4
+np.float64,0x8007a835894f506c,0x3ff0000000000000,4
+np.float64,0x80057ba0522af741,0x3ff0000000000000,4
+np.float64,0x8009b7054b336e0b,0x3ff0000000000000,4
+np.float64,0x800b2c6c125658d9,0x3ff0000000000000,4
+np.float64,0x8008b1840ad16308,0x3ff0000000000000,4
+np.float64,0x8007ea0e3befd41d,0x3ff0000000000000,4
+np.float64,0x800dd658683bacb1,0x3ff0000000000000,4
+np.float64,0x8008cda48fd19b49,0x3ff0000000000000,4
+np.float64,0x8003acca14c75995,0x3ff0000000000000,4
+np.float64,0x8008bd152d717a2b,0x3ff0000000000000,4
+np.float64,0x80010d1ea3621a3e,0x3ff0000000000000,4
+np.float64,0x800130b78b826170,0x3ff0000000000000,4
+np.float64,0x8002cf3a46e59e75,0x3ff0000000000000,4
+np.float64,0x800b76e7fa76edd0,0x3ff0000000000000,4
+np.float64,0x800e065fe1dc0cc0,0x3ff0000000000000,4
+np.float64,0x8000dd527ea1baa6,0x3ff0000000000000,4
+np.float64,0x80032cb234665965,0x3ff0000000000000,4
+np.float64,0x800affc1acb5ff84,0x3ff0000000000000,4
+np.float64,0x80074be23fee97c5,0x3ff0000000000000,4
+np.float64,0x8004f83eafc9f07e,0x3ff0000000000000,4
+np.float64,0x800b02a115560543,0x3ff0000000000000,4
+np.float64,0x800b324a55766495,0x3ff0000000000000,4
+np.float64,0x800ffbcfd69ff7a0,0x3ff0000000000000,4
+np.float64,0x800830bc7b906179,0x3ff0000000000000,4
+np.float64,0x800cbafe383975fd,0x3ff0000000000000,4
+np.float64,0x8001ee42bfe3dc86,0x3ff0000000000000,4
+np.float64,0x8005b00fdc0b6020,0x3ff0000000000000,4
+np.float64,0x8005e7addd0bcf5c,0x3ff0000000000000,4
+np.float64,0x8001ae4cb0635c9a,0x3ff0000000000000,4
+np.float64,0x80098a9941131533,0x3ff0000000000000,4
+np.float64,0x800334c929466993,0x3ff0000000000000,4
+np.float64,0x8009568239d2ad05,0x3ff0000000000000,4
+np.float64,0x800f0639935e0c73,0x3ff0000000000000,4
+np.float64,0x800cebce7499d79d,0x3ff0000000000000,4
+np.float64,0x800482ee4c2905dd,0x3ff0000000000000,4
+np.float64,0x8007b7bd9e2f6f7c,0x3ff0000000000000,4
+np.float64,0x3fe654469f2ca88d,0x3fe8853f6c01ffb3,4
+np.float64,0x3feb4d7297369ae5,0x3fe50ad5bb621408,4
+np.float64,0x3feef53ba43dea77,0x3fe2283f356f8658,4
+np.float64,0x3fddf564eabbeaca,0x3fec8ec0e0dead9c,4
+np.float64,0x3fd3a69078274d21,0x3fee80e05c320000,4
+np.float64,0x3fecdafe5d39b5fd,0x3fe3d91a5d440fd9,4
+np.float64,0x3fd93286bc32650d,0x3fed8d40696cd10e,4
+np.float64,0x3fc0d34eb821a69d,0x3fefb954023d4284,4
+np.float64,0x3fc7b4b9a02f6973,0x3fef73e8739787ce,4
+np.float64,0x3fe08c839a611907,0x3febd0bc6f5641cd,4
+np.float64,0x3fb3d1758627a2eb,0x3fefe776f6183f96,4
+np.float64,0x3fef93c9ff3f2794,0x3fe1a4d2f622627d,4
+np.float64,0x3fea8d0041351a01,0x3fe59a52a1c78c9e,4
+np.float64,0x3fe3e26a30e7c4d4,0x3fea04ad3e0bbf8d,4
+np.float64,0x3fe5a34c9f6b4699,0x3fe8f57c5ccd1eab,4
+np.float64,0x3fc21ef859243df1,0x3fefae0b68a3a2e7,4
+np.float64,0x3fed7dd585fafbab,0x3fe35860041e5b0d,4
+np.float64,0x3fe5abacf22b575a,0x3fe8f03d8b6ef0f2,4
+np.float64,0x3fe426451f284c8a,0x3fe9dcf21f13205b,4
+np.float64,0x3fc01f6456203ec9,0x3fefbf19e2a8e522,4
+np.float64,0x3fe1cf2772239e4f,0x3feb2bbd645c7697,4
+np.float64,0x3fd18c4ace231896,0x3feecdfdd086c110,4
+np.float64,0x3fe8387d5b7070fb,0x3fe74358f2ec4910,4
+np.float64,0x3fdce51c2239ca38,0x3feccb2ae5459632,4
+np.float64,0x3fe5b0f2e4eb61e6,0x3fe8ecef4dbe4277,4
+np.float64,0x3fe1ceeb08a39dd6,0x3feb2bdd4dcfb3df,4
+np.float64,0x3febc5899d778b13,0x3fe4afc8dd8ad228,4
+np.float64,0x3fe7a47fbe2f48ff,0x3fe7a7fd9b352ea5,4
+np.float64,0x3fe7f74e1fafee9c,0x3fe76feb2755b247,4
+np.float64,0x3fe2bfad04e57f5a,0x3feaa9b46adddaeb,4
+np.float64,0x3fd06a090320d412,0x3feef40c334f8fba,4
+np.float64,0x3fdc97297d392e53,0x3fecdc16a3e22fcb,4
+np.float64,0x3fdc1a3f3838347e,0x3fecf6db2769d404,4
+np.float64,0x3fcca90096395201,0x3fef338156fcd218,4
+np.float64,0x3fed464733fa8c8e,0x3fe38483f0465d91,4
+np.float64,0x3fe7e067d82fc0d0,0x3fe77f7c8c9de896,4
+np.float64,0x3fc014fa0b2029f4,0x3fefbf6d84c933f8,4
+np.float64,0x3fd3bf1524277e2a,0x3fee7d2997b74dec,4
+np.float64,0x3fec153b86782a77,0x3fe472bb5497bb2a,4
+np.float64,0x3fd3e4d9d5a7c9b4,0x3fee776842691902,4
+np.float64,0x3fea6c0e2c74d81c,0x3fe5b2954cb458d9,4
+np.float64,0x3fee8f6a373d1ed4,0x3fe27bb9e348125b,4
+np.float64,0x3fd30c6dd42618dc,0x3fee97d2cab2b0bc,4
+np.float64,0x3fe4f90e6d69f21d,0x3fe95ea3dd4007f2,4
+np.float64,0x3fe271d467e4e3a9,0x3fead470d6d4008b,4
+np.float64,0x3fef2983897e5307,0x3fe1fd1a4debe33b,4
+np.float64,0x3fe980cc83b30199,0x3fe65d2fb8a0eb46,4
+np.float64,0x3fdfdf53db3fbea8,0x3fec1cf95b2a1cc7,4
+np.float64,0x3fe4d5307ba9aa61,0x3fe974701b4156cb,4
+np.float64,0x3fdb4e2345b69c47,0x3fed21aa6c146512,4
+np.float64,0x3fe3f7830327ef06,0x3fe9f85f6c88c2a8,4
+np.float64,0x3fca915fb63522bf,0x3fef502b73a52ecf,4
+np.float64,0x3fe66d3709ecda6e,0x3fe87531d7372d7a,4
+np.float64,0x3fd86000bcb0c001,0x3fedb5018dd684ca,4
+np.float64,0x3fe516e5feea2dcc,0x3fe94c68b111404e,4
+np.float64,0x3fd83c53dd3078a8,0x3fedbb9e5dd9e165,4
+np.float64,0x3fedfeeb673bfdd7,0x3fe2f0f0253c5d5d,4
+np.float64,0x3fe0dc6f9c21b8df,0x3feba8e2452410c2,4
+np.float64,0x3fbe154d643c2a9b,0x3fefc780a9357457,4
+np.float64,0x3fe5f63986abec73,0x3fe8c1434951a40a,4
+np.float64,0x3fbce0e50839c1ca,0x3fefcbeeaa27de75,4
+np.float64,0x3fd7ef5c5c2fdeb9,0x3fedc9c3022495b3,4
+np.float64,0x3fc1073914220e72,0x3fefb79de80fc0fd,4
+np.float64,0x3fe1a93c3d235278,0x3feb3fb21f86ac67,4
+np.float64,0x3fe321ee53e643dd,0x3fea72e2999f1e22,4
+np.float64,0x3fa881578c3102af,0x3feff69e6e51e0d6,4
+np.float64,0x3fd313482a262690,0x3fee96d161199495,4
+np.float64,0x3fe7272cd6ae4e5a,0x3fe7fbacbd0d8f43,4
+np.float64,0x3fd6cf4015ad9e80,0x3fedfd3513d544b8,4
+np.float64,0x3fc67b7e6d2cf6fd,0x3fef81f5c16923a4,4
+np.float64,0x3fa1999c14233338,0x3feffb2913a14184,4
+np.float64,0x3fc74eb8dd2e9d72,0x3fef78909a138e3c,4
+np.float64,0x3fc0b9274921724f,0x3fefba2ebd5f3e1c,4
+np.float64,0x3fd53fa156aa7f43,0x3fee40a18e952e88,4
+np.float64,0x3feaccbca4b59979,0x3fe56b22b33eb713,4
+np.float64,0x3fe6a01e3a2d403c,0x3fe8543fbd820ecc,4
+np.float64,0x3fd392a869a72551,0x3fee83e0ffe0e8de,4
+np.float64,0x3fe44d8928689b12,0x3fe9c5bf3c8fffdb,4
+np.float64,0x3fca3f209f347e41,0x3fef5461b6fa0924,4
+np.float64,0x3fee9e84b07d3d09,0x3fe26f638f733549,4
+np.float64,0x3faf49acb03e9359,0x3feff0b583cd8c48,4
+np.float64,0x3fea874b2af50e96,0x3fe59e882fa6febf,4
+np.float64,0x3fc50b72772a16e5,0x3fef918777dc41be,4
+np.float64,0x3fe861d1d4f0c3a4,0x3fe726e44d9d42c2,4
+np.float64,0x3fcadd2e2535ba5c,0x3fef4c3e2b56da38,4
+np.float64,0x3fea59c29cb4b385,0x3fe5c0043e586439,4
+np.float64,0x3fc1ffef0d23ffde,0x3fefaf22be452d13,4
+np.float64,0x3fc2d8dbc125b1b8,0x3fefa75b646d8e4e,4
+np.float64,0x3fd66c6471acd8c9,0x3fee0e5038b895c0,4
+np.float64,0x3fd0854adfa10a96,0x3feef0945bcc5c99,4
+np.float64,0x3feaac7076f558e1,0x3fe58316c23a82ad,4
+np.float64,0x3fdda49db3bb493b,0x3feca0e347c0ad6f,4
+np.float64,0x3fe43a539de874a7,0x3fe9d11d722d4822,4
+np.float64,0x3feeee3ebbfddc7d,0x3fe22dffd251e9af,4
+np.float64,0x3f8ee2c5b03dc58b,0x3fefff11855a7b6c,4
+np.float64,0x3fcd7107c63ae210,0x3fef2840bb55ca52,4
+np.float64,0x3f8d950d203b2a1a,0x3fefff253a08e40e,4
+np.float64,0x3fd40a5e57a814bd,0x3fee71a633c761fc,4
+np.float64,0x3fee836ec83d06de,0x3fe28580975be2fd,4
+np.float64,0x3fd7bbe87f2f77d1,0x3fedd31f661890cc,4
+np.float64,0xbfe05bf138a0b7e2,0x3febe8a000d96e47,4
+np.float64,0xbf88bddd90317bc0,0x3fefff66f6e2ff26,4
+np.float64,0xbfdc9cbb12393976,0x3fecdae2982335db,4
+np.float64,0xbfd85b4eccb0b69e,0x3fedb5e0dd87f702,4
+np.float64,0xbfe5c326cb2b864e,0x3fe8e180f525fa12,4
+np.float64,0xbfe381a0e4a70342,0x3fea3c8e5e3ab78e,4
+np.float64,0xbfe58d892c2b1b12,0x3fe9031551617aed,4
+np.float64,0xbfd7f3a52cafe74a,0x3fedc8fa97edd080,4
+np.float64,0xbfef3417bc7e682f,0x3fe1f45989f6a009,4
+np.float64,0xbfddfb8208bbf704,0x3fec8d5fa9970773,4
+np.float64,0xbfdab69bcc356d38,0x3fed40b2f6c347c6,4
+np.float64,0xbfed3f7cf17a7efa,0x3fe389e4ff4d9235,4
+np.float64,0xbfe47675d9a8ecec,0x3fe9ad6829a69e94,4
+np.float64,0xbfd030e2902061c6,0x3feefb3f811e024f,4
+np.float64,0xbfc376ac7226ed58,0x3fefa1798712b37e,4
+np.float64,0xbfdb7e54a0b6fcaa,0x3fed17a974c4bc28,4
+np.float64,0xbfdb7d5d5736faba,0x3fed17dcf31a8d84,4
+np.float64,0xbf876bd6502ed7c0,0x3fefff76dce6232c,4
+np.float64,0xbfd211e6c02423ce,0x3feebba41f0a1764,4
+np.float64,0xbfb443e3962887c8,0x3fefe658953629d4,4
+np.float64,0xbfe81b09e9b03614,0x3fe757882e4fdbae,4
+np.float64,0xbfdcb905d2b9720c,0x3fecd4c22cfe84e5,4
+np.float64,0xbfe3b62d99276c5b,0x3fea1e5520b3098d,4
+np.float64,0xbfbf05b25c3e0b68,0x3fefc3ecc04bca8e,4
+np.float64,0xbfdedc885b3db910,0x3fec59e22feb49f3,4
+np.float64,0xbfe33aa282667545,0x3fea64f2d55ec471,4
+np.float64,0xbfec84745a3908e9,0x3fe41cb3214e7044,4
+np.float64,0xbfddefdff1bbdfc0,0x3fec8fff88d4d0ec,4
+np.float64,0xbfd26ae6aca4d5ce,0x3feeaf208c7fedf6,4
+np.float64,0xbfee010591fc020b,0x3fe2ef3e57211a5e,4
+np.float64,0xbfb8cfddca319fb8,0x3fefd98d8f7918ed,4
+np.float64,0xbfe991648f3322c9,0x3fe6514e54670bae,4
+np.float64,0xbfee63fd087cc7fa,0x3fe29f1bfa3297cc,4
+np.float64,0xbfe1685942a2d0b2,0x3feb617f5f839eee,4
+np.float64,0xbfc6fc2fd62df860,0x3fef7c4698fd58cf,4
+np.float64,0xbfe42723d3a84e48,0x3fe9dc6ef7243e90,4
+np.float64,0xbfc3a7e89d274fd0,0x3fef9f99e3314e77,4
+np.float64,0xbfeb4c9521f6992a,0x3fe50b7c919bc6d8,4
+np.float64,0xbf707b34e020f680,0x3fefffef05e30264,4
+np.float64,0xbfc078478e20f090,0x3fefbc479305d5aa,4
+np.float64,0xbfd494ac4ca92958,0x3fee5c11f1cd8269,4
+np.float64,0xbfdaf888a035f112,0x3fed3346ae600469,4
+np.float64,0xbfa5d8ed502bb1e0,0x3feff88b0f262609,4
+np.float64,0xbfeec0cbfffd8198,0x3fe253543b2371cb,4
+np.float64,0xbfe594b5986b296b,0x3fe8fe9b39fb3940,4
+np.float64,0xbfc8ece7c631d9d0,0x3fef652bd0611ac7,4
+np.float64,0xbfd8ffeca0b1ffda,0x3fed96ebdf9b65cb,4
+np.float64,0xbfba9b221e353648,0x3fefd3cc21e2f15c,4
+np.float64,0xbfca63a52c34c74c,0x3fef52848eb9ed3b,4
+np.float64,0xbfe588e9b06b11d4,0x3fe905f7403e8881,4
+np.float64,0xbfc76f82db2edf04,0x3fef77138fe9bbc2,4
+np.float64,0xbfeeb3f334bd67e6,0x3fe25ddadb1096d6,4
+np.float64,0xbfbf2b64ce3e56c8,0x3fefc35a9555f6df,4
+np.float64,0xbfe9920e4ff3241c,0x3fe650d4ab8f5c42,4
+np.float64,0xbfb4a54c02294a98,0x3fefe55fc85ae5e9,4
+np.float64,0xbfe353b0c766a762,0x3fea56c02d17e4b7,4
+np.float64,0xbfd99961a4b332c4,0x3fed795fcd00dbf9,4
+np.float64,0xbfef191ddabe323c,0x3fe20aa79524f636,4
+np.float64,0xbfb25d060224ba10,0x3fefeaeee5cc8c0b,4
+np.float64,0xbfe6022428ec0448,0x3fe8b9b46e776194,4
+np.float64,0xbfed1a236cba3447,0x3fe3a76bee0d9861,4
+np.float64,0xbfc59671e72b2ce4,0x3fef8bc4daef6f14,4
+np.float64,0xbfdf2711703e4e22,0x3fec4886a8c9ceb5,4
+np.float64,0xbfeb7e207536fc41,0x3fe4e610c783f168,4
+np.float64,0xbfe6cdf5bcad9bec,0x3fe8365f8a59bc81,4
+np.float64,0xbfe55294adaaa52a,0x3fe927b0af5ccd09,4
+np.float64,0xbfdf4a88913e9512,0x3fec4036df58ba74,4
+np.float64,0xbfebb7efe4376fe0,0x3fe4ba276006992d,4
+np.float64,0xbfe09f29cfa13e54,0x3febc77f4f9c95e7,4
+np.float64,0xbfdf8c75653f18ea,0x3fec30ac924e4f46,4
+np.float64,0xbfefd601c7ffac04,0x3fe16d6f21bcb9c1,4
+np.float64,0xbfeae97ff5f5d300,0x3fe555bb5b87efe9,4
+np.float64,0xbfed427f02fa84fe,0x3fe387830db093bc,4
+np.float64,0xbfa33909cc267210,0x3feffa3a1bcb50dd,4
+np.float64,0xbfe9aa4bf5f35498,0x3fe63f6e98f6aa0f,4
+np.float64,0xbfe2d7349b25ae69,0x3fea9caa7c331e7e,4
+np.float64,0xbfcdbb2a3a3b7654,0x3fef2401c9659e4b,4
+np.float64,0xbfc8a90919315214,0x3fef686fe7fc0513,4
+np.float64,0xbfe62a98df2c5532,0x3fe89ff22a02cc6b,4
+np.float64,0xbfdc0f67b3b81ed0,0x3fecf928b637798f,4
+np.float64,0xbfebb32bf6f76658,0x3fe4bdc893c09698,4
+np.float64,0xbfec067996380cf3,0x3fe47e132741db97,4
+np.float64,0xbfd9774e1d32ee9c,0x3fed7ffe1e87c434,4
+np.float64,0xbfef989890bf3131,0x3fe1a0d025c80cf4,4
+np.float64,0xbfe59887e62b3110,0x3fe8fc382a3d4197,4
+np.float64,0xbfdea0a11e3d4142,0x3fec67b987e236ec,4
+np.float64,0xbfe2ec495825d892,0x3fea90efb231602d,4
+np.float64,0xbfb329c5c2265388,0x3fefe90f1b8209c3,4
+np.float64,0xbfdcd2dcd339a5ba,0x3feccf24c60b1478,4
+np.float64,0xbfe537ea18aa6fd4,0x3fe938237e217fe0,4
+np.float64,0xbfe8675ce170ceba,0x3fe723105925ce3a,4
+np.float64,0xbfd70723acae0e48,0x3fedf369ac070e65,4
+np.float64,0xbfea9d8692b53b0d,0x3fe58e1ee42e3fdb,4
+np.float64,0xbfcfeb96653fd72c,0x3fef029770033bdc,4
+np.float64,0xbfcc06c92d380d94,0x3fef3c69797d9b0a,4
+np.float64,0xbfe16b7c4f62d6f8,0x3feb5fdf9f0a9a07,4
+np.float64,0xbfed4d7a473a9af4,0x3fe37ecee27b1eb7,4
+np.float64,0xbfe6a6f6942d4ded,0x3fe84fccdf762b19,4
+np.float64,0xbfda46d867348db0,0x3fed572d928fa657,4
+np.float64,0xbfdbd9482db7b290,0x3fed049b5f907b52,4
+np.float64,0x7fe992ceb933259c,0xbfeb15af92aad70e,4
+np.float64,0x7fe3069204a60d23,0xbfe5eeff454240e9,4
+np.float64,0x7fe729dbf32e53b7,0xbfefe0528a330e4c,4
+np.float64,0x7fec504fb638a09e,0x3fd288e95dbedf65,4
+np.float64,0x7fe1d30167a3a602,0xbfeffc41f946fd02,4
+np.float64,0x7fed7f8ffd3aff1f,0x3fefe68ec604a19d,4
+np.float64,0x7fd2f23635a5e46b,0x3fea63032efbb447,4
+np.float64,0x7fd4c86db1a990da,0x3fdf6b9f7888db5d,4
+np.float64,0x7fe7554db6eeaa9a,0x3fe1b41476861bb0,4
+np.float64,0x7fe34e823ba69d03,0x3fefc435532e6294,4
+np.float64,0x7fec5c82fef8b905,0x3fef8f0c6473034f,4
+np.float64,0x7feba221bff74442,0xbfea95b81eb19b47,4
+np.float64,0x7fe74808a5ae9010,0xbfd3aa322917c3e5,4
+np.float64,0x7fdf41b7e0be836f,0x3fd14283c7147282,4
+np.float64,0x7fec09892f381311,0x3fe5240376ae484b,4
+np.float64,0x7faaf80bf435f017,0x3fe20227fa811423,4
+np.float64,0x7f8422d8402845b0,0x3fe911714593b8a0,4
+np.float64,0x7fd23a7fada474fe,0x3feff9f40aa37e9c,4
+np.float64,0x7fef4a4806fe948f,0x3fec6eca89cb4a62,4
+np.float64,0x7fe1e71cf763ce39,0xbfea6ac63f9ba457,4
+np.float64,0x7fe3e555be27caaa,0xbfe75b305d0dbbfd,4
+np.float64,0x7fcb8bac96371758,0xbfe8b126077f9d4c,4
+np.float64,0x7fc98e2c84331c58,0x3fef9092eb0bc85a,4
+np.float64,0x7fe947cf2b728f9d,0xbfebfff2c5b7d198,4
+np.float64,0x7feee8058c3dd00a,0xbfef21ebaae2eb17,4
+np.float64,0x7fef61d8d5bec3b1,0xbfdf1a032fb1c864,4
+np.float64,0x7fcf714b6f3ee296,0x3fe6fc89a8084098,4
+np.float64,0x7fa9a8b44c335168,0xbfeb16c149cea943,4
+np.float64,0x7fd175c482a2eb88,0xbfef64d341e73f88,4
+np.float64,0x7feab8e6a87571cc,0x3feb10069c397464,4
+np.float64,0x7fe3ade72de75bcd,0x3fd1753e333d5790,4
+np.float64,0x7fb26d87d224db0f,0xbfe753d36b18f4ca,4
+np.float64,0x7fdb7ef159b6fde2,0x3fe5c0a6044d3607,4
+np.float64,0x7fd5af86422b5f0c,0x3fe77193c95f6484,4
+np.float64,0x7fee9e00b07d3c00,0x3fe864d494596845,4
+np.float64,0x7fef927a147f24f3,0xbfe673b14715693d,4
+np.float64,0x7fd0aea63c215d4b,0xbfeff435f119fce9,4
+np.float64,0x7fd02e3796a05c6e,0x3fe4f7e3706e9a3d,4
+np.float64,0x7fd3ed61da27dac3,0xbfefef2f057f168c,4
+np.float64,0x7fefaca0d4ff5941,0x3fd3e8ad205cd4ab,4
+np.float64,0x7feb659e06f6cb3b,0x3fd64d803203e027,4
+np.float64,0x7fc94ccfaf32999e,0x3fee04922209369a,4
+np.float64,0x7feb4ec294f69d84,0xbfd102763a056c89,4
+np.float64,0x7fe2ada6ac655b4c,0x3fef4f6792aa6093,4
+np.float64,0x7fe5f40fdc2be81f,0xbfb4a6327186eee8,4
+np.float64,0x7fe7584bc3eeb097,0xbfd685b8ff94651d,4
+np.float64,0x7fe45d276be8ba4e,0x3fee53b13f7e442f,4
+np.float64,0x7fe6449b3d6c8935,0xbfe7e08bafa75251,4
+np.float64,0x7f8d62e6b03ac5cc,0x3fe73d30762f38fd,4
+np.float64,0x7fe3a76f72a74ede,0xbfeb48a28bc60968,4
+np.float64,0x7fd057706920aee0,0x3fdece8fa06f626c,4
+np.float64,0x7fe45ae158e8b5c2,0x3fe7a70f47b4d349,4
+np.float64,0x7fea8a5a983514b4,0x3fefb053d5f9ddd7,4
+np.float64,0x7fdd1e86ab3a3d0c,0x3fe3cded1b93816b,4
+np.float64,0x7fdb456108b68ac1,0xbfe37574c0b9bf8f,4
+np.float64,0x7fe972602432e4bf,0x3fef9a26e65ec01c,4
+np.float64,0x7fdbe2385637c470,0x3fed541df57969e1,4
+np.float64,0x7fe57f03602afe06,0x3fbd90f595cbbd94,4
+np.float64,0x7feb0ceb68f619d6,0xbfeae9cb8ee5261f,4
+np.float64,0x7fe6abfe6c6d57fc,0xbfef40a6edaca26f,4
+np.float64,0x7fe037ea08606fd3,0xbfda817d75858597,4
+np.float64,0x7fdd75a52dbaeb49,0x3feef2a0d91d6aa1,4
+np.float64,0x7fe8f9af66b1f35e,0xbfedfceef2a3bfc9,4
+np.float64,0x7fedf762b53beec4,0x3fd8b4f21ef69ee3,4
+np.float64,0x7fe99295b7f3252a,0x3feffc24d970383e,4
+np.float64,0x7fe797b0172f2f5f,0x3fee089aa56f7ce8,4
+np.float64,0x7fed89dcc97b13b9,0xbfcfa2bb0c3ea41f,4
+np.float64,0x7fae9e8d5c3d3d1a,0xbfe512ffe16c6b08,4
+np.float64,0x7fefaecbe27f5d97,0x3fbfc718a5e972f1,4
+np.float64,0x7fce0236d93c046d,0xbfa9b7cd790db256,4
+np.float64,0x7fa9689aac32d134,0x3feced501946628a,4
+np.float64,0x7feb1469e93628d3,0x3fef2a988e7673ed,4
+np.float64,0x7fdba78344b74f06,0xbfe092e78965b30c,4
+np.float64,0x7fece54c3fb9ca97,0x3fd3cfd184bed2e6,4
+np.float64,0x7fdb84212b370841,0xbfe25ebf2db6ee55,4
+np.float64,0x7fbe3e8bf23c7d17,0x3fe2ee72df573345,4
+np.float64,0x7fe43d9803687b2f,0xbfed2eff6a9e66a0,4
+np.float64,0x7fb0f9c00a21f37f,0x3feff70f3276fdb7,4
+np.float64,0x7fea0c6cbbb418d8,0xbfefa612494798b2,4
+np.float64,0x7fe4b3239e296646,0xbfe74dd959af8cdc,4
+np.float64,0x7fe5c6a773eb8d4e,0xbfd06944048f8d2b,4
+np.float64,0x7fb1c1278223824e,0xbfeb533a34655bde,4
+np.float64,0x7fd21c09ee243813,0xbfe921ccbc9255c3,4
+np.float64,0x7fe051020c20a203,0x3fbd519d700c1f2f,4
+np.float64,0x7fe0c76845e18ed0,0x3fefb9595191a31b,4
+np.float64,0x7fe6b0b57b6d616a,0xbf8c59a8ba5fcd9a,4
+np.float64,0x7fd386c460270d88,0x3fe8ffea5d1a5c46,4
+np.float64,0x7feeb884713d7108,0x3fee9b2247ef6c0d,4
+np.float64,0x7fd85f71b6b0bee2,0xbfefc30ec3e28f07,4
+np.float64,0x7fc341366426826c,0x3fd4234d35386d3b,4
+np.float64,0x7fe56482dd6ac905,0x3fe7189de6a50668,4
+np.float64,0x7fec67a2e3f8cf45,0xbfef86d0b940f37f,4
+np.float64,0x7fe38b202fe7163f,0x3feb90b75caa2030,4
+np.float64,0x7fdcbc64883978c8,0x3fed4f758fbf64d4,4
+np.float64,0x7fea5f0598f4be0a,0x3fdd503a417b3d4d,4
+np.float64,0x7fda3b6bcf3476d7,0x3fea6e9af3f7f9f5,4
+np.float64,0x7fc7d7896c2faf12,0x3fda2bebc36a2363,4
+np.float64,0x7fe7e8e2626fd1c4,0xbfe7d5e390c4cc3f,4
+np.float64,0x7fde0f3d7abc1e7a,0xbfede7a0ecfa3606,4
+np.float64,0x7fc692b8f52d2571,0x3feff0cd7ab6f61b,4
+np.float64,0xff92d1fce825a400,0xbfc921c36fc014fa,4
+np.float64,0xffdec3af2fbd875e,0xbfed6a77e6a0364e,4
+np.float64,0xffef46e7d9be8dcf,0xbfed7d39476f7e27,4
+np.float64,0xffe2c2ce4525859c,0x3fe1757261316bc9,4
+np.float64,0xffe27c8b5864f916,0xbfefe017c0d43457,4
+np.float64,0xffe184d7442309ae,0x3fa1fb8c49dba596,4
+np.float64,0xffddf5f98d3bebf4,0x3fee4f8eaa5f847e,4
+np.float64,0xffee3ef354fc7de6,0xbfebfd60fa51b2ba,4
+np.float64,0xffdecb3e85bd967e,0x3fbfad2667a8b468,4
+np.float64,0xffe4ee900b29dd20,0xbfdc02dc626f91cd,4
+np.float64,0xffd3179f6da62f3e,0xbfe2cfe442511776,4
+np.float64,0xffe99ef7cef33def,0x3f50994542a7f303,4
+np.float64,0xffe2b66b1ae56cd6,0xbfefe3e066eb6329,4
+np.float64,0xff8f72aff03ee540,0x3fe9c46224cf5003,4
+np.float64,0xffd29beb85a537d8,0x3fefcb0b6166be71,4
+np.float64,0xffaef02d4c3de060,0xbfef5fb71028fc72,4
+np.float64,0xffd39a2a89273456,0x3fe6d4b183205dca,4
+np.float64,0xffef8a9392ff1526,0x3fedb99fbf402468,4
+np.float64,0xffb9b3f31e3367e8,0x3fee1005270fcf80,4
+np.float64,0xffed9d5c693b3ab8,0x3fd110f4b02365d5,4
+np.float64,0xffeaba45f9f5748b,0x3fe499e0a6f4afb2,4
+np.float64,0xffdba3f70d3747ee,0xbfca0c30493ae519,4
+np.float64,0xffa35b985426b730,0xbfdb625df56bcf45,4
+np.float64,0xffccbc9728397930,0x3fc53cbc59020704,4
+np.float64,0xffef73c942bee792,0xbfdc647a7a5e08be,4
+np.float64,0xffcb5acfb236b5a0,0x3feeb4ec038c39fc,4
+np.float64,0xffea116fe2b422df,0x3fefe03b6ae0b435,4
+np.float64,0xffe97de6e7b2fbcd,0xbfd2025698fab9eb,4
+np.float64,0xffdddba314bbb746,0x3fd31f0fdb8f93be,4
+np.float64,0xffd613a24a2c2744,0xbfebbb1efae884b3,4
+np.float64,0xffe3d938aa67b271,0xbfc2099cead3d3be,4
+np.float64,0xffdf08c2e33e1186,0xbfefd236839b900d,4
+np.float64,0xffea6ba8bd34d751,0x3fe8dfc032114719,4
+np.float64,0xffe3202083e64040,0x3fed513b81432a22,4
+np.float64,0xffb2397db62472f8,0xbfee7d7fe1c3f76c,4
+np.float64,0xffd9d0682ab3a0d0,0x3fe0bcf9e531ad79,4
+np.float64,0xffc293df202527c0,0xbfe58d0bdece5e64,4
+np.float64,0xffe1422c7da28458,0xbf81bd72595f2341,4
+np.float64,0xffd64e4ed4ac9c9e,0x3fa4334cc011c703,4
+np.float64,0xffe40a970ae8152e,0x3fead3d258b55b7d,4
+np.float64,0xffc8c2f2223185e4,0xbfef685f07c8b9fd,4
+np.float64,0xffe4b2f7216965ee,0x3fe3861d3d896a83,4
+np.float64,0xffdb531db3b6a63c,0x3fe18cb8332dd59d,4
+np.float64,0xffe8e727a3b1ce4e,0xbfe57b15abb677b9,4
+np.float64,0xffe530c1e12a6184,0xbfb973ea5535e48f,4
+np.float64,0xffe6f7849cedef08,0x3fd39a37ec5af4b6,4
+np.float64,0xffead62a78b5ac54,0x3fe69b3f6c7aa24b,4
+np.float64,0xffeefdd725fdfbad,0xbfc08a456111fdd5,4
+np.float64,0xffe682182fed0430,0x3fecc7c1292761d2,4
+np.float64,0xffee0ca8dcbc1951,0x3fef6cc361ef2c19,4
+np.float64,0xffec9b338f393666,0x3fefa9ab8e0471b5,4
+np.float64,0xffe13c5e29a278bc,0xbfef8da74ad83398,4
+np.float64,0xffd7bd48c62f7a92,0x3fe3468cd4ac9d34,4
+np.float64,0xffedd0ed14bba1d9,0xbfd563a83477077b,4
+np.float64,0xffe86b83f3f0d707,0x3fe9eb3c658e4b2d,4
+np.float64,0xffd6a4db4bad49b6,0xbfc7e11276166e17,4
+np.float64,0xffc29e8404253d08,0x3fd35971961c789f,4
+np.float64,0xffe27cf3d664f9e7,0xbfeca0f73c72f810,4
+np.float64,0xffc34152352682a4,0x3fef384e564c002c,4
+np.float64,0xffe395728ba72ae4,0x3f8fe18c2de86eba,4
+np.float64,0xffed86c4fbbb0d89,0x3fef709db881c672,4
+np.float64,0xffe8a98d37f1531a,0x3fd4879c8f73c3dc,4
+np.float64,0xffb8ce9fea319d40,0xbfb853c8fe46b08d,4
+np.float64,0xffe7f26db8efe4db,0xbfec1cfd3e5c2ac1,4
+np.float64,0xffd7935b77af26b6,0x3fb7368c89b2a460,4
+np.float64,0xffc5840ed02b081c,0x3fd92220b56631f3,4
+np.float64,0xffc36a873926d510,0x3fa84d61baf61811,4
+np.float64,0xffe06ea583e0dd4a,0x3feb647e348b9e39,4
+np.float64,0xffe6a33031ed4660,0xbfe096b851dc1a0a,4
+np.float64,0xffe001c938e00392,0x3fe4eece77623e7a,4
+np.float64,0xffc1e4f23b23c9e4,0xbfdb9bb1f83f6ac4,4
+np.float64,0xffecd3ecbab9a7d9,0x3fbafb1f800f177d,4
+np.float64,0xffc2d3016825a604,0xbfef650e8b0d6afb,4
+np.float64,0xffe222cb68e44596,0x3fde3690e44de5bd,4
+np.float64,0xffe5bb145e2b7628,0x3fedbb98e23c9dc1,4
+np.float64,0xffe9e5823b73cb04,0xbfee41661016c03c,4
+np.float64,0xffd234a00ba46940,0x3fda0312cda580c2,4
+np.float64,0xffe0913ed6e1227d,0xbfed508bb529bd23,4
+np.float64,0xffe8e3596171c6b2,0xbfdc33e1c1d0310e,4
+np.float64,0xffef9c6835ff38cf,0x3fea8ce6d27dfba3,4
+np.float64,0xffdd3bcf66ba779e,0x3fe50523d2b6470e,4
+np.float64,0xffe57e8cf06afd1a,0xbfee600933347247,4
+np.float64,0xffe0d8c65fa1b18c,0x3fe75091f93d5e4c,4
+np.float64,0xffea7c8c16b4f918,0x3fee681724795198,4
+np.float64,0xffe34f7a05269ef4,0xbfe3c3e179676f13,4
+np.float64,0xffd28894a6a5112a,0xbfe5d1027aee615d,4
+np.float64,0xffc73be6f22e77cc,0x3fe469bbc08b472a,4
+np.float64,0xffe7f71b066fee36,0x3fe7ed136c8fdfaa,4
+np.float64,0xffebc13e29f7827c,0x3fefcdc6e677d314,4
+np.float64,0xffd53e9c942a7d3a,0x3fea5a02c7341749,4
+np.float64,0xffd7191b23ae3236,0x3fea419b66023443,4
+np.float64,0xffe9480325b29006,0xbfefeaff5fa38cd5,4
+np.float64,0xffba46dc0e348db8,0xbfefa54f4de28eba,4
+np.float64,0xffdd4cc31eba9986,0x3fe60bb41fe1c4da,4
+np.float64,0xffe13a70dea274e1,0xbfaa9192f7bd6c9b,4
+np.float64,0xffde25127bbc4a24,0x3f7c75f45e29be7d,4
+np.float64,0xffe4076543a80eca,0x3fea5aad50d2f687,4
+np.float64,0xffe61512acec2a25,0xbfefffeb67401649,4
+np.float64,0xffef812ec1ff025d,0xbfe919c7c073c766,4
+np.float64,0xffd5552aeaaaaa56,0x3fc89d38ab047396,4
diff --git a/numpy/core/tests/data/umath-validation-set-cosh.csv b/numpy/core/tests/data/umath-validation-set-cosh.csv
new file mode 100644
index 000000000..c9e446c3b
--- /dev/null
+++ b/numpy/core/tests/data/umath-validation-set-cosh.csv
@@ -0,0 +1,1429 @@
+dtype,input,output,ulperrortol
+np.float32,0xfe0ac238,0x7f800000,3
+np.float32,0xbf553b86,0x3faf079b,3
+np.float32,0xff4457da,0x7f800000,3
+np.float32,0xff7253f3,0x7f800000,3
+np.float32,0x5a5802,0x3f800000,3
+np.float32,0x3db03413,0x3f80795b,3
+np.float32,0x7f6795c9,0x7f800000,3
+np.float32,0x805b9142,0x3f800000,3
+np.float32,0xfeea581a,0x7f800000,3
+np.float32,0x3f7e2dba,0x3fc472f6,3
+np.float32,0x3d9c4d74,0x3f805f7a,3
+np.float32,0x7f18c665,0x7f800000,3
+np.float32,0x7f003e23,0x7f800000,3
+np.float32,0x3d936fa0,0x3f8054f3,3
+np.float32,0x3f32034f,0x3fa0368e,3
+np.float32,0xff087604,0x7f800000,3
+np.float32,0x380a5,0x3f800000,3
+np.float32,0x3f59694e,0x3fb10077,3
+np.float32,0x3e63e648,0x3f832ee4,3
+np.float32,0x80712f42,0x3f800000,3
+np.float32,0x3e169908,0x3f816302,3
+np.float32,0x3f2d766e,0x3f9e8692,3
+np.float32,0x3d6412e0,0x3f8032d0,3
+np.float32,0xbde689e8,0x3f80cfd4,3
+np.float32,0x483e2e,0x3f800000,3
+np.float32,0xff1ba2d0,0x7f800000,3
+np.float32,0x80136bff,0x3f800000,3
+np.float32,0x3f72534c,0x3fbdc1d4,3
+np.float32,0x3e9eb381,0x3f8632c6,3
+np.float32,0x3e142892,0x3f815795,3
+np.float32,0x0,0x3f800000,3
+np.float32,0x2f2528,0x3f800000,3
+np.float32,0x7f38be13,0x7f800000,3
+np.float32,0xfeee6896,0x7f800000,3
+np.float32,0x7f09095d,0x7f800000,3
+np.float32,0xbe94d,0x3f800000,3
+np.float32,0xbedcf8d4,0x3f8c1b74,3
+np.float32,0xbf694c02,0x3fb8ef07,3
+np.float32,0x3e2261f8,0x3f819cde,3
+np.float32,0xbf01d3ce,0x3f90d0e0,3
+np.float32,0xbeb7b3a2,0x3f8853de,3
+np.float32,0x8046de7b,0x3f800000,3
+np.float32,0xbcb45ea0,0x3f8007f1,3
+np.float32,0x3eef14af,0x3f8e35dd,3
+np.float32,0xbf047316,0x3f91846e,3
+np.float32,0x801cef45,0x3f800000,3
+np.float32,0x3e9ad891,0x3f85e609,3
+np.float32,0xff20e9cf,0x7f800000,3
+np.float32,0x80068434,0x3f800000,3
+np.float32,0xbe253020,0x3f81ab49,3
+np.float32,0x3f13f4b8,0x3f95fac9,3
+np.float32,0x804accd1,0x3f800000,3
+np.float32,0x3dee3e10,0x3f80ddf7,3
+np.float32,0xbe6c4690,0x3f836c29,3
+np.float32,0xff30d431,0x7f800000,3
+np.float32,0xbec82416,0x3f89e791,3
+np.float32,0x3f30bbcb,0x3f9fbbcc,3
+np.float32,0x3f5620a2,0x3faf72b8,3
+np.float32,0x807a8130,0x3f800000,3
+np.float32,0x3e3cb02d,0x3f822de0,3
+np.float32,0xff4839ac,0x7f800000,3
+np.float32,0x800a3e9c,0x3f800000,3
+np.float32,0x3dffd65b,0x3f810002,3
+np.float32,0xbf2b1492,0x3f9da987,3
+np.float32,0xbf21602c,0x3f9a48fe,3
+np.float32,0x512531,0x3f800000,3
+np.float32,0x24b99a,0x3f800000,3
+np.float32,0xbf53e345,0x3fae67b1,3
+np.float32,0xff2126ec,0x7f800000,3
+np.float32,0x7e79b49d,0x7f800000,3
+np.float32,0x3ea3cf04,0x3f869b6f,3
+np.float32,0x7f270059,0x7f800000,3
+np.float32,0x3f625b2f,0x3fb561e1,3
+np.float32,0xbf59947e,0x3fb11519,3
+np.float32,0xfe0d1c64,0x7f800000,3
+np.float32,0xbf3f3eae,0x3fa568e2,3
+np.float32,0x7c04d1,0x3f800000,3
+np.float32,0x7e66bd,0x3f800000,3
+np.float32,0x8011880d,0x3f800000,3
+np.float32,0x3f302f07,0x3f9f8759,3
+np.float32,0x4e3375,0x3f800000,3
+np.float32,0xfe67a134,0x7f800000,3
+np.float32,0xff670249,0x7f800000,3
+np.float32,0x7e19f27d,0x7f800000,3
+np.float32,0xbf36ce12,0x3fa20b81,3
+np.float32,0xbe6bcfc4,0x3f8368b5,3
+np.float32,0x76fcba,0x3f800000,3
+np.float32,0x7f30abaf,0x7f800000,3
+np.float32,0x3f4c1f6d,0x3faae43c,3
+np.float32,0x7f61f44a,0x7f800000,3
+np.float32,0xbf4bb3c9,0x3faab4af,3
+np.float32,0xbda15ee0,0x3f8065c6,3
+np.float32,0xfbb4e800,0x7f800000,3
+np.float32,0x7fa00000,0x7fe00000,3
+np.float32,0x80568501,0x3f800000,3
+np.float32,0xfeb285e4,0x7f800000,3
+np.float32,0x804423a7,0x3f800000,3
+np.float32,0x7e6c0f21,0x7f800000,3
+np.float32,0x7f136b3c,0x7f800000,3
+np.float32,0x3f2d08e6,0x3f9e5e9c,3
+np.float32,0xbf6b454e,0x3fb9f7e6,3
+np.float32,0x3e6bceb0,0x3f8368ad,3
+np.float32,0xff1ad16a,0x7f800000,3
+np.float32,0x7cce1a04,0x7f800000,3
+np.float32,0xff7bcf95,0x7f800000,3
+np.float32,0x8049788d,0x3f800000,3
+np.float32,0x7ec45918,0x7f800000,3
+np.float32,0xff7fffff,0x7f800000,3
+np.float32,0x8039a1a0,0x3f800000,3
+np.float32,0x7e90cd72,0x7f800000,3
+np.float32,0xbf7dfd53,0x3fc456cc,3
+np.float32,0x3eeeb664,0x3f8e2a76,3
+np.float32,0x8055ef9b,0x3f800000,3
+np.float32,0x7ee06ddd,0x7f800000,3
+np.float32,0xba2cc000,0x3f800002,3
+np.float32,0x806da632,0x3f800000,3
+np.float32,0x7ecfaaf5,0x7f800000,3
+np.float32,0x3ddd12e6,0x3f80bf19,3
+np.float32,0xbf754394,0x3fbf60b1,3
+np.float32,0x6f3f19,0x3f800000,3
+np.float32,0x800a9af0,0x3f800000,3
+np.float32,0xfeef13ea,0x7f800000,3
+np.float32,0x7f74841f,0x7f800000,3
+np.float32,0xbeb9a2f0,0x3f888181,3
+np.float32,0x77cbb,0x3f800000,3
+np.float32,0xbf587f84,0x3fb0911b,3
+np.float32,0x210ba5,0x3f800000,3
+np.float32,0x3ee60a28,0x3f8d2367,3
+np.float32,0xbe3731ac,0x3f820dc7,3
+np.float32,0xbee8cfee,0x3f8d765e,3
+np.float32,0x7b2ef179,0x7f800000,3
+np.float32,0xfe81377c,0x7f800000,3
+np.float32,0x6ac98c,0x3f800000,3
+np.float32,0x3f51f144,0x3fad8288,3
+np.float32,0x80785750,0x3f800000,3
+np.float32,0x3f46615a,0x3fa864ff,3
+np.float32,0xbf35ac9e,0x3fa19b8e,3
+np.float32,0x7f0982ac,0x7f800000,3
+np.float32,0x1b2610,0x3f800000,3
+np.float32,0x3ed8bb25,0x3f8ba3df,3
+np.float32,0xbeb41bac,0x3f88006d,3
+np.float32,0xff48e89d,0x7f800000,3
+np.float32,0x3ed0ab8c,0x3f8ac755,3
+np.float32,0xbe64671c,0x3f833282,3
+np.float32,0x64bce4,0x3f800000,3
+np.float32,0x284f79,0x3f800000,3
+np.float32,0x7e09faa7,0x7f800000,3
+np.float32,0x4376c1,0x3f800000,3
+np.float32,0x805ca8c0,0x3f800000,3
+np.float32,0xff0859d5,0x7f800000,3
+np.float32,0xbed2f3b2,0x3f8b04dd,3
+np.float32,0x8045bd0c,0x3f800000,3
+np.float32,0x3f0e6216,0x3f94503f,3
+np.float32,0x3f41e3ae,0x3fa68035,3
+np.float32,0x80088ccc,0x3f800000,3
+np.float32,0x3f37fc19,0x3fa2812f,3
+np.float32,0x71c87d,0x3f800000,3
+np.float32,0x8024f4b2,0x3f800000,3
+np.float32,0xff78dd88,0x7f800000,3
+np.float32,0xbda66c90,0x3f806c40,3
+np.float32,0x7f33ef0d,0x7f800000,3
+np.float32,0x46a343,0x3f800000,3
+np.float32,0xff1dce38,0x7f800000,3
+np.float32,0x1b935d,0x3f800000,3
+np.float32,0x3ebec598,0x3f88fd0e,3
+np.float32,0xff115530,0x7f800000,3
+np.float32,0x803916aa,0x3f800000,3
+np.float32,0xff60a3e2,0x7f800000,3
+np.float32,0x3b8ddd48,0x3f80004f,3
+np.float32,0x3f761b6e,0x3fbfd8ea,3
+np.float32,0xbdf55b88,0x3f80eb70,3
+np.float32,0x37374,0x3f800000,3
+np.float32,0x3de150e0,0x3f80c682,3
+np.float32,0x3f343278,0x3fa10a83,3
+np.float32,0xbe9baefa,0x3f85f68b,3
+np.float32,0x3d8d43,0x3f800000,3
+np.float32,0x3e80994b,0x3f840f0c,3
+np.float32,0xbe573c6c,0x3f82d685,3
+np.float32,0x805b83b4,0x3f800000,3
+np.float32,0x683d88,0x3f800000,3
+np.float32,0x692465,0x3f800000,3
+np.float32,0xbdc345f8,0x3f809511,3
+np.float32,0x3f7c1c5a,0x3fc3406f,3
+np.float32,0xbf40bef3,0x3fa606df,3
+np.float32,0xff1e25b9,0x7f800000,3
+np.float32,0x3e4481e0,0x3f825d37,3
+np.float32,0x75d188,0x3f800000,3
+np.float32,0x3ea53cec,0x3f86b956,3
+np.float32,0xff105a54,0x7f800000,3
+np.float32,0x7f800000,0x7f800000,3
+np.float32,0x7f11f0b0,0x7f800000,3
+np.float32,0xbf58a57d,0x3fb0a328,3
+np.float32,0xbdd11e38,0x3f80aaf8,3
+np.float32,0xbea94adc,0x3f870fa0,3
+np.float32,0x3e9dd780,0x3f862180,3
+np.float32,0xff1786b9,0x7f800000,3
+np.float32,0xfec46aa2,0x7f800000,3
+np.float32,0x7f4300c1,0x7f800000,3
+np.float32,0x29ba2b,0x3f800000,3
+np.float32,0x3f4112e2,0x3fa62993,3
+np.float32,0xbe6c9224,0x3f836e5d,3
+np.float32,0x7f0e42a3,0x7f800000,3
+np.float32,0xff6390ad,0x7f800000,3
+np.float32,0x3f54e374,0x3faede94,3
+np.float32,0x7f2642a2,0x7f800000,3
+np.float32,0x7f46b2be,0x7f800000,3
+np.float32,0xfe59095c,0x7f800000,3
+np.float32,0x7146a0,0x3f800000,3
+np.float32,0x3f07763d,0x3f925786,3
+np.float32,0x3d172780,0x3f801651,3
+np.float32,0xff66f1c5,0x7f800000,3
+np.float32,0xff025349,0x7f800000,3
+np.float32,0x6ce99d,0x3f800000,3
+np.float32,0xbf7e4f50,0x3fc48685,3
+np.float32,0xbeff8ca2,0x3f904708,3
+np.float32,0x3e6c8,0x3f800000,3
+np.float32,0x7f7153dc,0x7f800000,3
+np.float32,0xbedcf612,0x3f8c1b26,3
+np.float32,0xbbc2f180,0x3f800094,3
+np.float32,0xbf397399,0x3fa314b8,3
+np.float32,0x6c6e35,0x3f800000,3
+np.float32,0x7f50a88b,0x7f800000,3
+np.float32,0xfe84093e,0x7f800000,3
+np.float32,0x3f737b9d,0x3fbe6478,3
+np.float32,0x7f6a5340,0x7f800000,3
+np.float32,0xbde83c20,0x3f80d2e7,3
+np.float32,0xff769ce9,0x7f800000,3
+np.float32,0xfdd33c30,0x7f800000,3
+np.float32,0xbc95cb60,0x3f80057a,3
+np.float32,0x8007a40d,0x3f800000,3
+np.float32,0x3f55d90c,0x3faf5132,3
+np.float32,0x80282082,0x3f800000,3
+np.float32,0xbf43b1f2,0x3fa7418c,3
+np.float32,0x3f1dc7cb,0x3f991731,3
+np.float32,0xbd4346a0,0x3f80253f,3
+np.float32,0xbf5aa82a,0x3fb19946,3
+np.float32,0x3f4b8c22,0x3faaa333,3
+np.float32,0x3d13468c,0x3f80152f,3
+np.float32,0x7db77097,0x7f800000,3
+np.float32,0x4a00df,0x3f800000,3
+np.float32,0xbedea5e0,0x3f8c4b64,3
+np.float32,0x80482543,0x3f800000,3
+np.float32,0xbef344fe,0x3f8eb8dd,3
+np.float32,0x7ebd4044,0x7f800000,3
+np.float32,0xbf512c0e,0x3fad287e,3
+np.float32,0x3db28cce,0x3f807c9c,3
+np.float32,0xbd0f5ae0,0x3f801412,3
+np.float32,0xfe7ed9ac,0x7f800000,3
+np.float32,0x3eb1aa82,0x3f87c8b4,3
+np.float32,0xfef1679e,0x7f800000,3
+np.float32,0xff3629f2,0x7f800000,3
+np.float32,0xff3562b4,0x7f800000,3
+np.float32,0x3dcafe1d,0x3f80a118,3
+np.float32,0xfedf242a,0x7f800000,3
+np.float32,0xbf43102a,0x3fa6fda4,3
+np.float32,0x8028834e,0x3f800000,3
+np.float32,0x805c8513,0x3f800000,3
+np.float32,0x3f59306a,0x3fb0e550,3
+np.float32,0x3eda2c9c,0x3f8bcc4a,3
+np.float32,0x80023524,0x3f800000,3
+np.float32,0x7ef72879,0x7f800000,3
+np.float32,0x661c8a,0x3f800000,3
+np.float32,0xfec3ba6c,0x7f800000,3
+np.float32,0x805aaca6,0x3f800000,3
+np.float32,0xff5c1f13,0x7f800000,3
+np.float32,0x3f6ab3f4,0x3fb9ab6b,3
+np.float32,0x3f014896,0x3f90ac20,3
+np.float32,0x3f030584,0x3f91222a,3
+np.float32,0xbf74853d,0x3fbef71d,3
+np.float32,0xbf534ee0,0x3fae2323,3
+np.float32,0x2c90c3,0x3f800000,3
+np.float32,0x7f62ad25,0x7f800000,3
+np.float32,0x1c8847,0x3f800000,3
+np.float32,0x7e2a8d43,0x7f800000,3
+np.float32,0x807a09cd,0x3f800000,3
+np.float32,0x413871,0x3f800000,3
+np.float32,0x80063692,0x3f800000,3
+np.float32,0x3edaf29b,0x3f8be211,3
+np.float32,0xbf64a7ab,0x3fb68b2d,3
+np.float32,0xfe56a720,0x7f800000,3
+np.float32,0xbf54a8d4,0x3faec350,3
+np.float32,0x3ecbaef7,0x3f8a4350,3
+np.float32,0x3f413714,0x3fa63890,3
+np.float32,0x7d3aa8,0x3f800000,3
+np.float32,0xbea9a13c,0x3f8716e7,3
+np.float32,0x7ef7553e,0x7f800000,3
+np.float32,0x8056f29f,0x3f800000,3
+np.float32,0xff1f7ffe,0x7f800000,3
+np.float32,0x3f41953b,0x3fa65f9c,3
+np.float32,0x3daa2f,0x3f800000,3
+np.float32,0xff0893e4,0x7f800000,3
+np.float32,0xbefc7ec6,0x3f8fe207,3
+np.float32,0xbb026800,0x3f800011,3
+np.float32,0x341e4f,0x3f800000,3
+np.float32,0x3e7b708a,0x3f83e0d1,3
+np.float32,0xa18cb,0x3f800000,3
+np.float32,0x7e290239,0x7f800000,3
+np.float32,0xbf4254f2,0x3fa6af62,3
+np.float32,0x80000000,0x3f800000,3
+np.float32,0x3f0a6c,0x3f800000,3
+np.float32,0xbec44d28,0x3f898609,3
+np.float32,0xf841f,0x3f800000,3
+np.float32,0x7f01a693,0x7f800000,3
+np.float32,0x8053340b,0x3f800000,3
+np.float32,0xfd4e7990,0x7f800000,3
+np.float32,0xbf782f1f,0x3fc10356,3
+np.float32,0xbe962118,0x3f858acc,3
+np.float32,0xfe8cd702,0x7f800000,3
+np.float32,0x7ecd986f,0x7f800000,3
+np.float32,0x3ebe775f,0x3f88f59b,3
+np.float32,0x8065524f,0x3f800000,3
+np.float32,0x3ede7fc4,0x3f8c471e,3
+np.float32,0x7f5e15ea,0x7f800000,3
+np.float32,0xbe871ada,0x3f847b78,3
+np.float32,0x3f21958b,0x3f9a5af7,3
+np.float32,0x3f64d480,0x3fb6a1fa,3
+np.float32,0xff18b0e9,0x7f800000,3
+np.float32,0xbf0840dd,0x3f928fd9,3
+np.float32,0x80104f5d,0x3f800000,3
+np.float32,0x643b94,0x3f800000,3
+np.float32,0xbc560a80,0x3f8002cc,3
+np.float32,0x3f5c75d6,0x3fb2786e,3
+np.float32,0x7f365fc9,0x7f800000,3
+np.float32,0x54e965,0x3f800000,3
+np.float32,0x6dcd4d,0x3f800000,3
+np.float32,0x3f2057a0,0x3f99f04d,3
+np.float32,0x272fa3,0x3f800000,3
+np.float32,0xff423dc9,0x7f800000,3
+np.float32,0x80273463,0x3f800000,3
+np.float32,0xfe21cc78,0x7f800000,3
+np.float32,0x7fc00000,0x7fc00000,3
+np.float32,0x802feb65,0x3f800000,3
+np.float32,0x3dc733d0,0x3f809b21,3
+np.float32,0x65d56b,0x3f800000,3
+np.float32,0x80351d8e,0x3f800000,3
+np.float32,0xbf244247,0x3f9b43dd,3
+np.float32,0x7f328e7e,0x7f800000,3
+np.float32,0x7f4d9712,0x7f800000,3
+np.float32,0x2c505d,0x3f800000,3
+np.float32,0xbf232ebe,0x3f9ae5a0,3
+np.float32,0x804a363a,0x3f800000,3
+np.float32,0x80417102,0x3f800000,3
+np.float32,0xbf48b170,0x3fa963d4,3
+np.float32,0x7ea3e3b6,0x7f800000,3
+np.float32,0xbf41415b,0x3fa63cd2,3
+np.float32,0xfe3af7c8,0x7f800000,3
+np.float32,0x7f478010,0x7f800000,3
+np.float32,0x80143113,0x3f800000,3
+np.float32,0x3f7626a7,0x3fbfdf2e,3
+np.float32,0xfea20b0a,0x7f800000,3
+np.float32,0x80144d64,0x3f800000,3
+np.float32,0x7db9ba47,0x7f800000,3
+np.float32,0x7f7fffff,0x7f800000,3
+np.float32,0xbe410834,0x3f8247ef,3
+np.float32,0x14a7af,0x3f800000,3
+np.float32,0x7eaebf9e,0x7f800000,3
+np.float32,0xff800000,0x7f800000,3
+np.float32,0x3f0a7d8e,0x3f9330fd,3
+np.float32,0x3ef780,0x3f800000,3
+np.float32,0x3f62253e,0x3fb546d1,3
+np.float32,0x3f4cbeac,0x3fab2acc,3
+np.float32,0x25db1,0x3f800000,3
+np.float32,0x65c54a,0x3f800000,3
+np.float32,0x800f0645,0x3f800000,3
+np.float32,0x3ed28c78,0x3f8af9f0,3
+np.float32,0x8040c6ce,0x3f800000,3
+np.float32,0x5e4e9a,0x3f800000,3
+np.float32,0xbd3fd2b0,0x3f8023f1,3
+np.float32,0xbf5d2d3f,0x3fb2d1b6,3
+np.float32,0x7ead999f,0x7f800000,3
+np.float32,0xbf30dc86,0x3f9fc805,3
+np.float32,0xff2b0a62,0x7f800000,3
+np.float32,0x3d5180e9,0x3f802adf,3
+np.float32,0x3f62716f,0x3fb56d0d,3
+np.float32,0x7e82ae9c,0x7f800000,3
+np.float32,0xfe2d4bdc,0x7f800000,3
+np.float32,0x805cc7d4,0x3f800000,3
+np.float32,0xfb50f700,0x7f800000,3
+np.float32,0xff57b684,0x7f800000,3
+np.float32,0x80344f01,0x3f800000,3
+np.float32,0x7f2af372,0x7f800000,3
+np.float32,0xfeab6204,0x7f800000,3
+np.float32,0x30b251,0x3f800000,3
+np.float32,0x3eed8cc4,0x3f8e0698,3
+np.float32,0x7eeb1c6a,0x7f800000,3
+np.float32,0x3f17ece6,0x3f9735b0,3
+np.float32,0x21e985,0x3f800000,3
+np.float32,0x3f3a7df3,0x3fa37e34,3
+np.float32,0x802a14a2,0x3f800000,3
+np.float32,0x807d4d5b,0x3f800000,3
+np.float32,0x7f6093ce,0x7f800000,3
+np.float32,0x3f800000,0x3fc583ab,3
+np.float32,0x3da2c26e,0x3f806789,3
+np.float32,0xfe05f278,0x7f800000,3
+np.float32,0x800000,0x3f800000,3
+np.float32,0xbee63342,0x3f8d282e,3
+np.float32,0xbf225586,0x3f9a9bd4,3
+np.float32,0xbed60e86,0x3f8b59ba,3
+np.float32,0xbec99484,0x3f8a0ca3,3
+np.float32,0x3e967c71,0x3f859199,3
+np.float32,0x7f26ab62,0x7f800000,3
+np.float32,0xca7f4,0x3f800000,3
+np.float32,0xbf543790,0x3fae8ebc,3
+np.float32,0x3e4c1ed9,0x3f828d2d,3
+np.float32,0xbdf37f88,0x3f80e7e1,3
+np.float32,0xff0cc44e,0x7f800000,3
+np.float32,0x5dea48,0x3f800000,3
+np.float32,0x31023c,0x3f800000,3
+np.float32,0x3ea10733,0x3f866208,3
+np.float32,0x3e11e6f2,0x3f814d2e,3
+np.float32,0x80641960,0x3f800000,3
+np.float32,0x3ef779a8,0x3f8f3edb,3
+np.float32,0x3f2a5062,0x3f9d632a,3
+np.float32,0x2b7d34,0x3f800000,3
+np.float32,0x3eeb95c5,0x3f8dca67,3
+np.float32,0x805c1357,0x3f800000,3
+np.float32,0x3db3a79d,0x3f807e29,3
+np.float32,0xfded1900,0x7f800000,3
+np.float32,0x45f362,0x3f800000,3
+np.float32,0x451f38,0x3f800000,3
+np.float32,0x801d3ae5,0x3f800000,3
+np.float32,0x458d45,0x3f800000,3
+np.float32,0xfda9d298,0x7f800000,3
+np.float32,0x467439,0x3f800000,3
+np.float32,0x7f66554a,0x7f800000,3
+np.float32,0xfef2375a,0x7f800000,3
+np.float32,0xbf33fc47,0x3fa0f5d7,3
+np.float32,0x3f75ba69,0x3fbfa2d0,3
+np.float32,0xfeb625b2,0x7f800000,3
+np.float32,0x8066b371,0x3f800000,3
+np.float32,0x3f5cb4e9,0x3fb29718,3
+np.float32,0x7f3b6a58,0x7f800000,3
+np.float32,0x7f6b35ea,0x7f800000,3
+np.float32,0xbf6ee555,0x3fbbe5be,3
+np.float32,0x3d836e21,0x3f804380,3
+np.float32,0xff43cd0c,0x7f800000,3
+np.float32,0xff55c1fa,0x7f800000,3
+np.float32,0xbf0dfccc,0x3f9432a6,3
+np.float32,0x3ed92121,0x3f8baf00,3
+np.float32,0x80068cc1,0x3f800000,3
+np.float32,0xff0103f9,0x7f800000,3
+np.float32,0x7e51b175,0x7f800000,3
+np.float32,0x8012f214,0x3f800000,3
+np.float32,0x62d298,0x3f800000,3
+np.float32,0xbf3e1525,0x3fa4ef8d,3
+np.float32,0x806b4882,0x3f800000,3
+np.float32,0xbf38c146,0x3fa2ce7c,3
+np.float32,0xbed59c30,0x3f8b4d70,3
+np.float32,0x3d1910c0,0x3f8016e2,3
+np.float32,0x7f33d55b,0x7f800000,3
+np.float32,0x7f5800e3,0x7f800000,3
+np.float32,0x5b2c5d,0x3f800000,3
+np.float32,0x807be750,0x3f800000,3
+np.float32,0x7eb297c1,0x7f800000,3
+np.float32,0x7dafee62,0x7f800000,3
+np.float32,0x7d9e23f0,0x7f800000,3
+np.float32,0x3e580537,0x3f82dbd8,3
+np.float32,0xbf800000,0x3fc583ab,3
+np.float32,0x7f40f880,0x7f800000,3
+np.float32,0x775ad3,0x3f800000,3
+np.float32,0xbedacd36,0x3f8bddf3,3
+np.float32,0x2138f6,0x3f800000,3
+np.float32,0x52c3b7,0x3f800000,3
+np.float32,0x8041cfdd,0x3f800000,3
+np.float32,0x7bf16791,0x7f800000,3
+np.float32,0xbe95869c,0x3f857f55,3
+np.float32,0xbf199796,0x3f97bcaf,3
+np.float32,0x3ef8da38,0x3f8f6b45,3
+np.float32,0x803f3648,0x3f800000,3
+np.float32,0x80026fd2,0x3f800000,3
+np.float32,0x7eb3ac26,0x7f800000,3
+np.float32,0x3e49921b,0x3f827ce8,3
+np.float32,0xbf689aed,0x3fb892de,3
+np.float32,0x3f253509,0x3f9b9779,3
+np.float32,0xff17894a,0x7f800000,3
+np.float32,0x3cd12639,0x3f800aae,3
+np.float32,0x1db14b,0x3f800000,3
+np.float32,0x39a0bf,0x3f800000,3
+np.float32,0xfdfe1d08,0x7f800000,3
+np.float32,0xff416cd2,0x7f800000,3
+np.float32,0x8070d818,0x3f800000,3
+np.float32,0x3e516e12,0x3f82afb8,3
+np.float32,0x80536651,0x3f800000,3
+np.float32,0xbf2903d2,0x3f9cecb7,3
+np.float32,0x3e896ae4,0x3f84a353,3
+np.float32,0xbd6ba2c0,0x3f80363d,3
+np.float32,0x80126d3e,0x3f800000,3
+np.float32,0xfd9d43d0,0x7f800000,3
+np.float32,0x7b56b6,0x3f800000,3
+np.float32,0xff04718e,0x7f800000,3
+np.float32,0x31440f,0x3f800000,3
+np.float32,0xbf7a1313,0x3fc215c9,3
+np.float32,0x7f43d6a0,0x7f800000,3
+np.float32,0x3f566503,0x3faf92cc,3
+np.float32,0xbf39eb0e,0x3fa343f1,3
+np.float32,0xbe35fd70,0x3f8206df,3
+np.float32,0x800c36ac,0x3f800000,3
+np.float32,0x60d061,0x3f800000,3
+np.float32,0x80453e12,0x3f800000,3
+np.float32,0xfe17c36c,0x7f800000,3
+np.float32,0x3d8c72,0x3f800000,3
+np.float32,0xfe8e9134,0x7f800000,3
+np.float32,0xff5d89de,0x7f800000,3
+np.float32,0x7f45020e,0x7f800000,3
+np.float32,0x3f28225e,0x3f9c9d01,3
+np.float32,0xbf3b6900,0x3fa3dbdd,3
+np.float32,0x80349023,0x3f800000,3
+np.float32,0xbf14d780,0x3f964042,3
+np.float32,0x3f56b5d2,0x3fafb8c3,3
+np.float32,0x800c639c,0x3f800000,3
+np.float32,0x7f7a19c8,0x7f800000,3
+np.float32,0xbf7a0815,0x3fc20f86,3
+np.float32,0xbec55926,0x3f89a06e,3
+np.float32,0x4b2cd2,0x3f800000,3
+np.float32,0xbf271eb2,0x3f9c41c8,3
+np.float32,0xff26e168,0x7f800000,3
+np.float32,0x800166b2,0x3f800000,3
+np.float32,0xbde97e38,0x3f80d532,3
+np.float32,0xbf1f93ec,0x3f99af1a,3
+np.float32,0x7f2896ed,0x7f800000,3
+np.float32,0x3da7d96d,0x3f806e1d,3
+np.float32,0x802b7237,0x3f800000,3
+np.float32,0xfdca6bc0,0x7f800000,3
+np.float32,0xbed2e300,0x3f8b0318,3
+np.float32,0x8079d9e8,0x3f800000,3
+np.float32,0x3f388c81,0x3fa2b9c2,3
+np.float32,0x3ed2607c,0x3f8af54a,3
+np.float32,0xff287de6,0x7f800000,3
+np.float32,0x3f55ed89,0x3faf5ac9,3
+np.float32,0x7f5b6af7,0x7f800000,3
+np.float32,0xbeb24730,0x3f87d698,3
+np.float32,0x1,0x3f800000,3
+np.float32,0x3f3a2350,0x3fa35a3b,3
+np.float32,0x8013b422,0x3f800000,3
+np.float32,0x3e9a6560,0x3f85dd35,3
+np.float32,0x80510631,0x3f800000,3
+np.float32,0xfeae39d6,0x7f800000,3
+np.float32,0x7eb437ad,0x7f800000,3
+np.float32,0x8047545b,0x3f800000,3
+np.float32,0x806a1c71,0x3f800000,3
+np.float32,0xbe5543f0,0x3f82c93b,3
+np.float32,0x40e8d,0x3f800000,3
+np.float32,0x63d18b,0x3f800000,3
+np.float32,0x1fa1ea,0x3f800000,3
+np.float32,0x801944e0,0x3f800000,3
+np.float32,0xbf4c7ac6,0x3fab0cae,3
+np.float32,0x7f2679d4,0x7f800000,3
+np.float32,0x3f0102fc,0x3f9099d0,3
+np.float32,0x7e44bdc1,0x7f800000,3
+np.float32,0xbf2072f6,0x3f99f970,3
+np.float32,0x5c7d38,0x3f800000,3
+np.float32,0x30a2e6,0x3f800000,3
+np.float32,0x805b9ca3,0x3f800000,3
+np.float32,0x7cc24ad5,0x7f800000,3
+np.float32,0x3f4f7920,0x3fac6357,3
+np.float32,0x111d62,0x3f800000,3
+np.float32,0xbf4de40a,0x3fabad77,3
+np.float32,0x805d0354,0x3f800000,3
+np.float32,0xbb3d2b00,0x3f800023,3
+np.float32,0x3ef229e7,0x3f8e960b,3
+np.float32,0x3f15754e,0x3f9670e0,3
+np.float32,0xbf689c6b,0x3fb893a5,3
+np.float32,0xbf3796c6,0x3fa2599b,3
+np.float32,0xbe95303c,0x3f8578f2,3
+np.float32,0xfee330de,0x7f800000,3
+np.float32,0xff0d9705,0x7f800000,3
+np.float32,0xbeb0ebd0,0x3f87b7dd,3
+np.float32,0xbf4d5a13,0x3fab6fe7,3
+np.float32,0x80142f5a,0x3f800000,3
+np.float32,0x7e01a87b,0x7f800000,3
+np.float32,0xbe45e5ec,0x3f8265d7,3
+np.float32,0x7f4ac255,0x7f800000,3
+np.float32,0x3ebf6a60,0x3f890ccb,3
+np.float32,0x7f771e16,0x7f800000,3
+np.float32,0x3f41834e,0x3fa6582b,3
+np.float32,0x3f7f6f98,0x3fc52ef0,3
+np.float32,0x7e4ad775,0x7f800000,3
+np.float32,0x3eb39991,0x3f87f4c4,3
+np.float32,0x1e3f4,0x3f800000,3
+np.float32,0x7e84ba19,0x7f800000,3
+np.float32,0x80640be4,0x3f800000,3
+np.float32,0x3f459fc8,0x3fa81272,3
+np.float32,0x3f554ed0,0x3faf109b,3
+np.float32,0x3c6617,0x3f800000,3
+np.float32,0x7f441158,0x7f800000,3
+np.float32,0x7f66e6d8,0x7f800000,3
+np.float32,0x7f565152,0x7f800000,3
+np.float32,0x7f16d550,0x7f800000,3
+np.float32,0xbd4f1950,0x3f8029e5,3
+np.float32,0xcf722,0x3f800000,3
+np.float32,0x3f37d6fd,0x3fa272ad,3
+np.float32,0xff7324ea,0x7f800000,3
+np.float32,0x804bc246,0x3f800000,3
+np.float32,0x7f099ef8,0x7f800000,3
+np.float32,0x5f838b,0x3f800000,3
+np.float32,0x80523534,0x3f800000,3
+np.float32,0x3f595e84,0x3fb0fb50,3
+np.float32,0xfdef8ac8,0x7f800000,3
+np.float32,0x3d9a07,0x3f800000,3
+np.float32,0x410f61,0x3f800000,3
+np.float32,0xbf715dbb,0x3fbd3bcb,3
+np.float32,0xbedd4734,0x3f8c242f,3
+np.float32,0x7e86739a,0x7f800000,3
+np.float32,0x3e81f144,0x3f8424fe,3
+np.float32,0x7f6342d1,0x7f800000,3
+np.float32,0xff6919a3,0x7f800000,3
+np.float32,0xff051878,0x7f800000,3
+np.float32,0x800ba28f,0x3f800000,3
+np.float32,0xfefab3d8,0x7f800000,3
+np.float32,0xff612a84,0x7f800000,3
+np.float32,0x800cd5ab,0x3f800000,3
+np.float32,0x802a07ae,0x3f800000,3
+np.float32,0xfef6ee3a,0x7f800000,3
+np.float32,0x8037e896,0x3f800000,3
+np.float32,0x3ef2d86f,0x3f8eab7d,3
+np.float32,0x3eafe53d,0x3f87a0cb,3
+np.float32,0xba591c00,0x3f800003,3
+np.float32,0x3e9ed028,0x3f863508,3
+np.float32,0x4a12a8,0x3f800000,3
+np.float32,0xbee55c84,0x3f8d0f45,3
+np.float32,0x8038a8d3,0x3f800000,3
+np.float32,0xff055243,0x7f800000,3
+np.float32,0xbf659067,0x3fb701ca,3
+np.float32,0xbee36a86,0x3f8cd5e0,3
+np.float32,0x7f1d74c1,0x7f800000,3
+np.float32,0xbf7657df,0x3fbffaad,3
+np.float32,0x7e37ee34,0x7f800000,3
+np.float32,0xff04bc74,0x7f800000,3
+np.float32,0x806d194e,0x3f800000,3
+np.float32,0x7f5596c3,0x7f800000,3
+np.float32,0xbe09d268,0x3f81293e,3
+np.float32,0x79ff75,0x3f800000,3
+np.float32,0xbf55479c,0x3faf0d3e,3
+np.float32,0xbe5428ec,0x3f82c1d4,3
+np.float32,0x3f624134,0x3fb554d7,3
+np.float32,0x2ccb8a,0x3f800000,3
+np.float32,0xfc082040,0x7f800000,3
+np.float32,0xff315467,0x7f800000,3
+np.float32,0x3e6ea2d2,0x3f837dd5,3
+np.float32,0x8020fdd1,0x3f800000,3
+np.float32,0x7f0416a1,0x7f800000,3
+np.float32,0x710a1b,0x3f800000,3
+np.float32,0x3dfcd050,0x3f80f9fc,3
+np.float32,0xfe995e96,0x7f800000,3
+np.float32,0x3f020d00,0x3f90e006,3
+np.float32,0x8064263e,0x3f800000,3
+np.float32,0xfcee4160,0x7f800000,3
+np.float32,0x801b3a18,0x3f800000,3
+np.float32,0x3f62c984,0x3fb59955,3
+np.float32,0x806e8355,0x3f800000,3
+np.float32,0x7e94f65d,0x7f800000,3
+np.float32,0x1173de,0x3f800000,3
+np.float32,0x3e3ff3b7,0x3f824166,3
+np.float32,0x803b4aea,0x3f800000,3
+np.float32,0x804c5bcc,0x3f800000,3
+np.float32,0x509fe5,0x3f800000,3
+np.float32,0xbf33b5ee,0x3fa0db0b,3
+np.float32,0x3f2ac15c,0x3f9d8ba4,3
+np.float32,0x7f2c54f8,0x7f800000,3
+np.float32,0x7f33d933,0x7f800000,3
+np.float32,0xbf09b2b4,0x3f92f795,3
+np.float32,0x805db8d6,0x3f800000,3
+np.float32,0x6d6e66,0x3f800000,3
+np.float32,0x3ddfea92,0x3f80c40c,3
+np.float32,0xfda719b8,0x7f800000,3
+np.float32,0x5d657f,0x3f800000,3
+np.float32,0xbf005ba3,0x3f906df6,3
+np.float32,0xbf45e606,0x3fa8305c,3
+np.float32,0x5e9fd1,0x3f800000,3
+np.float32,0x8079dc45,0x3f800000,3
+np.float32,0x7e9c40e3,0x7f800000,3
+np.float32,0x6bd5f6,0x3f800000,3
+np.float32,0xbea14a0e,0x3f866761,3
+np.float32,0x7e7323f3,0x7f800000,3
+np.float32,0x7f0c0a79,0x7f800000,3
+np.float32,0xbf7d7aeb,0x3fc40b0f,3
+np.float32,0x437588,0x3f800000,3
+np.float32,0xbf356376,0x3fa17f63,3
+np.float32,0x7f129921,0x7f800000,3
+np.float32,0x7f47a52e,0x7f800000,3
+np.float32,0xba8cb400,0x3f800005,3
+np.float32,0x802284e0,0x3f800000,3
+np.float32,0xbe820f56,0x3f8426ec,3
+np.float32,0x7f2ef6cf,0x7f800000,3
+np.float32,0xbf70a090,0x3fbcd501,3
+np.float32,0xbf173fea,0x3f96ff6d,3
+np.float32,0x3e19c489,0x3f817224,3
+np.float32,0x7f429b30,0x7f800000,3
+np.float32,0xbdae4118,0x3f8076af,3
+np.float32,0x3e70ad30,0x3f838d41,3
+np.float32,0x335fed,0x3f800000,3
+np.float32,0xff5359cf,0x7f800000,3
+np.float32,0xbf17e42b,0x3f9732f1,3
+np.float32,0xff3a950b,0x7f800000,3
+np.float32,0xbcca70c0,0x3f800a02,3
+np.float32,0x3f2cda62,0x3f9e4dad,3
+np.float32,0x3f50c185,0x3facf805,3
+np.float32,0x80000001,0x3f800000,3
+np.float32,0x807b86d2,0x3f800000,3
+np.float32,0x8010c2cf,0x3f800000,3
+np.float32,0x3f130fb8,0x3f95b519,3
+np.float32,0x807dc546,0x3f800000,3
+np.float32,0xbee20740,0x3f8cad3f,3
+np.float32,0x80800000,0x3f800000,3
+np.float32,0x3cbd90c0,0x3f8008c6,3
+np.float32,0x3e693488,0x3f835571,3
+np.float32,0xbe70cd44,0x3f838e35,3
+np.float32,0xbe348dc8,0x3f81feb1,3
+np.float32,0x3f31ea90,0x3fa02d3f,3
+np.float32,0xfcd7e180,0x7f800000,3
+np.float32,0xbe30a75c,0x3f81e8d0,3
+np.float32,0x3e552c5a,0x3f82c89d,3
+np.float32,0xff513f74,0x7f800000,3
+np.float32,0xbdb16248,0x3f807afd,3
+np.float64,0x7fbbf954e437f2a9,0x7ff0000000000000,2
+np.float64,0x581bbf0cb0379,0x3ff0000000000000,2
+np.float64,0x7ff8000000000000,0x7ff8000000000000,2
+np.float64,0xffb959a2a632b348,0x7ff0000000000000,2
+np.float64,0xbfdbd6baebb7ad76,0x3ff189a5ca25a6e1,2
+np.float64,0xbfd094ec9aa129da,0x3ff08a3f6b918065,2
+np.float64,0x3fe236753f646cea,0x3ff2a982660b8b43,2
+np.float64,0xbfe537fadfaa6ff6,0x3ff3a5f1c49c31bf,2
+np.float64,0xbfe31fa7dc663f50,0x3ff2f175374aef0e,2
+np.float64,0x3fc4b6569f296cb0,0x3ff035bde801bb53,2
+np.float64,0x800ce3c00f99c780,0x3ff0000000000000,2
+np.float64,0xbfebcde33e779bc6,0x3ff66de82cd30fc5,2
+np.float64,0x800dc09d3b7b813b,0x3ff0000000000000,2
+np.float64,0x80067d4c450cfa99,0x3ff0000000000000,2
+np.float64,0x1f6ade203ed7,0x3ff0000000000000,2
+np.float64,0xbfd4e311eca9c624,0x3ff0dc1383d6c3db,2
+np.float64,0x800649b3a54c9368,0x3ff0000000000000,2
+np.float64,0xcc14d1ab9829a,0x3ff0000000000000,2
+np.float64,0x3fc290c5bb25218b,0x3ff02b290f46dd6d,2
+np.float64,0x3fe78eb8376f1d70,0x3ff488f3bc259537,2
+np.float64,0xffc60f58e82c1eb0,0x7ff0000000000000,2
+np.float64,0x3fd35666ad26accd,0x3ff0bc6573da6bcd,2
+np.float64,0x7fc20257a62404ae,0x7ff0000000000000,2
+np.float64,0x80076d842e0edb09,0x3ff0000000000000,2
+np.float64,0x3fd8e44b08b1c898,0x3ff139b9a1f8428e,2
+np.float64,0x7fd6f6fc7a2dedf8,0x7ff0000000000000,2
+np.float64,0x3fa01b9f0820373e,0x3ff00206f8ad0f1b,2
+np.float64,0x69ed190ed3da4,0x3ff0000000000000,2
+np.float64,0xbfd997eb34b32fd6,0x3ff14be65a5db4a0,2
+np.float64,0x7feada2d0935b459,0x7ff0000000000000,2
+np.float64,0xbf80987120213100,0x3ff000226d29a9fc,2
+np.float64,0xbfef203e37fe407c,0x3ff82f51f04e8821,2
+np.float64,0xffe3dcf91fa7b9f2,0x7ff0000000000000,2
+np.float64,0x9a367283346cf,0x3ff0000000000000,2
+np.float64,0x800feb09f7bfd614,0x3ff0000000000000,2
+np.float64,0xbfe0319f9520633f,0x3ff217c5205c403f,2
+np.float64,0xbfa91eabd4323d50,0x3ff004ee4347f627,2
+np.float64,0x3fd19cbf7d23397f,0x3ff09c13e8e43571,2
+np.float64,0xffeb8945f0b7128b,0x7ff0000000000000,2
+np.float64,0x800a0eb4f2141d6a,0x3ff0000000000000,2
+np.float64,0xffe83e7312f07ce6,0x7ff0000000000000,2
+np.float64,0xffca53fee834a7fc,0x7ff0000000000000,2
+np.float64,0x800881cbf1710398,0x3ff0000000000000,2
+np.float64,0x80003e6abbe07cd6,0x3ff0000000000000,2
+np.float64,0xbfef6a998afed533,0x3ff859b7852d1b4d,2
+np.float64,0x3fd4eb7577a9d6eb,0x3ff0dcc601261aab,2
+np.float64,0xbfc9c12811338250,0x3ff05331268b05c8,2
+np.float64,0x7fddf84e5e3bf09c,0x7ff0000000000000,2
+np.float64,0xbfd4d6fbbc29adf8,0x3ff0db12db19d187,2
+np.float64,0x80077892bfaef126,0x3ff0000000000000,2
+np.float64,0xffae9d49543d3a90,0x7ff0000000000000,2
+np.float64,0xbfd8bef219317de4,0x3ff136034e5d2f1b,2
+np.float64,0xffe89c74ddb138e9,0x7ff0000000000000,2
+np.float64,0x8003b6bbb7e76d78,0x3ff0000000000000,2
+np.float64,0x315a4e8462b4b,0x3ff0000000000000,2
+np.float64,0x800ee616edddcc2e,0x3ff0000000000000,2
+np.float64,0xdfb27f97bf650,0x3ff0000000000000,2
+np.float64,0x8004723dc328e47c,0x3ff0000000000000,2
+np.float64,0xbfe529500daa52a0,0x3ff3a0b9b33fc84c,2
+np.float64,0xbfe4e46a7ce9c8d5,0x3ff3886ce0f92612,2
+np.float64,0xbf52003680240000,0x3ff00000a203d61a,2
+np.float64,0xffd3400458268008,0x7ff0000000000000,2
+np.float64,0x80076deb444edbd7,0x3ff0000000000000,2
+np.float64,0xa612f6c14c27,0x3ff0000000000000,2
+np.float64,0xbfd41c74c9a838ea,0x3ff0cbe61e16aecf,2
+np.float64,0x43f464a887e8d,0x3ff0000000000000,2
+np.float64,0x800976e748b2edcf,0x3ff0000000000000,2
+np.float64,0xffc79d6ba12f3ad8,0x7ff0000000000000,2
+np.float64,0xffd6dbcb022db796,0x7ff0000000000000,2
+np.float64,0xffd6a9672a2d52ce,0x7ff0000000000000,2
+np.float64,0x3fe95dcfa632bb9f,0x3ff54bbad2ee919e,2
+np.float64,0x3febadd2e1375ba6,0x3ff65e336c47c018,2
+np.float64,0x7fd47c37d828f86f,0x7ff0000000000000,2
+np.float64,0xbfd4ea59e0a9d4b4,0x3ff0dcae6af3e443,2
+np.float64,0x2c112afc58226,0x3ff0000000000000,2
+np.float64,0x8008122bced02458,0x3ff0000000000000,2
+np.float64,0x7fe7105ab3ee20b4,0x7ff0000000000000,2
+np.float64,0x80089634df312c6a,0x3ff0000000000000,2
+np.float64,0x68e9fbc8d1d40,0x3ff0000000000000,2
+np.float64,0xbfec1e1032f83c20,0x3ff69590b9f18ea8,2
+np.float64,0xbfedf181623be303,0x3ff787ef48935dc6,2
+np.float64,0xffe8600457f0c008,0x7ff0000000000000,2
+np.float64,0x7a841ec6f5084,0x3ff0000000000000,2
+np.float64,0x459a572e8b34c,0x3ff0000000000000,2
+np.float64,0x3fe8a232bef14465,0x3ff4fac1780f731e,2
+np.float64,0x3fcb37597d366eb3,0x3ff05cf08ab14ebd,2
+np.float64,0xbfb0261d00204c38,0x3ff00826fb86ca8a,2
+np.float64,0x3fc6e7a6dd2dcf4e,0x3ff041c1222ffa79,2
+np.float64,0xee65dd03dccbc,0x3ff0000000000000,2
+np.float64,0xffe26fdc23e4dfb8,0x7ff0000000000000,2
+np.float64,0x7fe8d6c8cab1ad91,0x7ff0000000000000,2
+np.float64,0xbfeb64bf2676c97e,0x3ff63abb8607828c,2
+np.float64,0x3fd28417b425082f,0x3ff0ac9eb22a732b,2
+np.float64,0xbfd26835b3a4d06c,0x3ff0aa94c48fb6d2,2
+np.float64,0xffec617a01b8c2f3,0x7ff0000000000000,2
+np.float64,0xe1bfff01c3800,0x3ff0000000000000,2
+np.float64,0x3fd4def913a9bdf4,0x3ff0dbbc7271046f,2
+np.float64,0x94f4c17129e98,0x3ff0000000000000,2
+np.float64,0x8009b2eaa33365d6,0x3ff0000000000000,2
+np.float64,0x3fd9633b41b2c678,0x3ff1468388bdfb65,2
+np.float64,0xffe0ae5c80e15cb8,0x7ff0000000000000,2
+np.float64,0x7fdfc35996bf86b2,0x7ff0000000000000,2
+np.float64,0x3fcfc5bdc23f8b7c,0x3ff07ed5caa4545c,2
+np.float64,0xd48b4907a9169,0x3ff0000000000000,2
+np.float64,0xbfe0a2cc52614598,0x3ff2361665895d95,2
+np.float64,0xbfe9068f90720d1f,0x3ff525b82491a1a5,2
+np.float64,0x4238b9208472,0x3ff0000000000000,2
+np.float64,0x800e6b2bf69cd658,0x3ff0000000000000,2
+np.float64,0x7fb638b6ae2c716c,0x7ff0000000000000,2
+np.float64,0x7fe267641764cec7,0x7ff0000000000000,2
+np.float64,0xffc0933d3521267c,0x7ff0000000000000,2
+np.float64,0x7fddfdfb533bfbf6,0x7ff0000000000000,2
+np.float64,0xced2a8e99da55,0x3ff0000000000000,2
+np.float64,0x2a80d5165501b,0x3ff0000000000000,2
+np.float64,0xbfeead2ab63d5a55,0x3ff7eeb5cbcfdcab,2
+np.float64,0x80097f6f92f2fee0,0x3ff0000000000000,2
+np.float64,0x3fee1f29b77c3e54,0x3ff7a0a58c13df62,2
+np.float64,0x3f9d06b8383a0d70,0x3ff001a54a2d8cf8,2
+np.float64,0xbfc8b41d3f31683c,0x3ff04c85379dd6b0,2
+np.float64,0xffd2a04c1e254098,0x7ff0000000000000,2
+np.float64,0xbfb71c01e02e3800,0x3ff010b34220e838,2
+np.float64,0xbfe69249ef6d2494,0x3ff425e48d1e938b,2
+np.float64,0xffefffffffffffff,0x7ff0000000000000,2
+np.float64,0x3feb1d52fbf63aa6,0x3ff618813ae922d7,2
+np.float64,0x7fb8d1a77e31a34e,0x7ff0000000000000,2
+np.float64,0xffc3cfc4ed279f88,0x7ff0000000000000,2
+np.float64,0x2164b9fc42c98,0x3ff0000000000000,2
+np.float64,0x3fbb868cee370d1a,0x3ff017b31b0d4d27,2
+np.float64,0x3fcd6dea583adbd5,0x3ff06cbd16bf44a0,2
+np.float64,0xbfecd041d479a084,0x3ff6efb25f61012d,2
+np.float64,0xbfb0552e6e20aa60,0x3ff00856ca83834a,2
+np.float64,0xe6293cbfcc528,0x3ff0000000000000,2
+np.float64,0x7fba58394034b072,0x7ff0000000000000,2
+np.float64,0x33bc96d467794,0x3ff0000000000000,2
+np.float64,0xffe90ea86bf21d50,0x7ff0000000000000,2
+np.float64,0xbfc626ea6d2c4dd4,0x3ff03d7e01ec3849,2
+np.float64,0x65b56fe4cb6af,0x3ff0000000000000,2
+np.float64,0x3fea409fb7f4813f,0x3ff5b171deab0ebd,2
+np.float64,0x3fe849c1df709384,0x3ff4d59063ff98c4,2
+np.float64,0x169073082d20f,0x3ff0000000000000,2
+np.float64,0xcc8b6add9916e,0x3ff0000000000000,2
+np.float64,0xbfef3d78d5fe7af2,0x3ff83fecc26abeea,2
+np.float64,0x3fe8c65a4a718cb4,0x3ff50a23bfeac7df,2
+np.float64,0x3fde9fa5c8bd3f4c,0x3ff1ddeb12b9d623,2
+np.float64,0xffe2af536da55ea6,0x7ff0000000000000,2
+np.float64,0x800186d0b0c30da2,0x3ff0000000000000,2
+np.float64,0x3fe9ba3c1d737478,0x3ff574ab2bf3a560,2
+np.float64,0xbfe1489c46a29138,0x3ff2641d36b30e21,2
+np.float64,0xbfe4b6b7c0e96d70,0x3ff37880ac8b0540,2
+np.float64,0x800e66ad82fccd5b,0x3ff0000000000000,2
+np.float64,0x7ff0000000000000,0x7ff0000000000000,2
+np.float64,0x7febb0fd477761fa,0x7ff0000000000000,2
+np.float64,0xbfdc433f2eb8867e,0x3ff195ec2a6cce27,2
+np.float64,0x3fe12c5a172258b4,0x3ff25c225b8a34bb,2
+np.float64,0xbfef6f116c3ede23,0x3ff85c47eaed49a0,2
+np.float64,0x800af6f60f35edec,0x3ff0000000000000,2
+np.float64,0xffe567999a2acf32,0x7ff0000000000000,2
+np.float64,0xbfc5ac5ae72b58b4,0x3ff03adb50ec04f3,2
+np.float64,0x3fea1b57e23436b0,0x3ff5a06f98541767,2
+np.float64,0x7fcc3e36fb387c6d,0x7ff0000000000000,2
+np.float64,0x8000c8dc698191ba,0x3ff0000000000000,2
+np.float64,0x3fee5085ed7ca10c,0x3ff7bb92f61245b8,2
+np.float64,0x7fbb9f803a373eff,0x7ff0000000000000,2
+np.float64,0xbfe1e5e806e3cbd0,0x3ff2918f2d773007,2
+np.float64,0x8008f8c3f3b1f188,0x3ff0000000000000,2
+np.float64,0x7fe53df515ea7be9,0x7ff0000000000000,2
+np.float64,0x7fdbb87fb3b770fe,0x7ff0000000000000,2
+np.float64,0x3fefcc0f50ff981f,0x3ff89210a6a04e6b,2
+np.float64,0x3fe33f87d0267f10,0x3ff2fb989ea4f2bc,2
+np.float64,0x1173992022e8,0x3ff0000000000000,2
+np.float64,0x3fef534632bea68c,0x3ff84c5ca9713ff9,2
+np.float64,0x3fc5991d552b3238,0x3ff03a72bfdb6e5f,2
+np.float64,0x3fdad90dc1b5b21c,0x3ff16db868180034,2
+np.float64,0xffe20b8078e41700,0x7ff0000000000000,2
+np.float64,0x7fdf409a82be8134,0x7ff0000000000000,2
+np.float64,0x3fccb7e691396fcd,0x3ff06786b6ccdbcb,2
+np.float64,0xffe416e0b7282dc1,0x7ff0000000000000,2
+np.float64,0xffe3a8a981275152,0x7ff0000000000000,2
+np.float64,0x3fd9c8bd31b3917c,0x3ff150ee6f5f692f,2
+np.float64,0xffeab6fef6356dfd,0x7ff0000000000000,2
+np.float64,0x3fe9c5e3faf38bc8,0x3ff579e18c9bd548,2
+np.float64,0x800b173e44762e7d,0x3ff0000000000000,2
+np.float64,0xffe2719db764e33b,0x7ff0000000000000,2
+np.float64,0x3fd1fcf31223f9e6,0x3ff0a2da7ad99856,2
+np.float64,0x80082c4afcd05896,0x3ff0000000000000,2
+np.float64,0xa56e5e4b4adcc,0x3ff0000000000000,2
+np.float64,0xffbbbddab2377bb8,0x7ff0000000000000,2
+np.float64,0x3b3927c076726,0x3ff0000000000000,2
+np.float64,0x3fec03fd58f807fb,0x3ff6889b8a774728,2
+np.float64,0xbfaa891fb4351240,0x3ff00580987bd914,2
+np.float64,0x7fb4800c4a290018,0x7ff0000000000000,2
+np.float64,0xffbb5d2b6036ba58,0x7ff0000000000000,2
+np.float64,0x7fd6608076acc100,0x7ff0000000000000,2
+np.float64,0x31267e4c624d1,0x3ff0000000000000,2
+np.float64,0x33272266664e5,0x3ff0000000000000,2
+np.float64,0x47bb37f28f768,0x3ff0000000000000,2
+np.float64,0x3fe134bb4ee26977,0x3ff25e7ea647a928,2
+np.float64,0xbfe2b5f42ba56be8,0x3ff2d05cbdc7344b,2
+np.float64,0xbfe0e013fd61c028,0x3ff246dfce572914,2
+np.float64,0x7fecedcda4f9db9a,0x7ff0000000000000,2
+np.float64,0x8001816c2da302d9,0x3ff0000000000000,2
+np.float64,0xffced8b65b3db16c,0x7ff0000000000000,2
+np.float64,0xffdc1d4a0b383a94,0x7ff0000000000000,2
+np.float64,0x7fe94e7339f29ce5,0x7ff0000000000000,2
+np.float64,0x33fb846667f71,0x3ff0000000000000,2
+np.float64,0x800a1380e9542702,0x3ff0000000000000,2
+np.float64,0x800b74eaa776e9d6,0x3ff0000000000000,2
+np.float64,0x5681784aad030,0x3ff0000000000000,2
+np.float64,0xbfee0eb7917c1d6f,0x3ff797b949f7f6b4,2
+np.float64,0xffe4ec5fd2a9d8bf,0x7ff0000000000000,2
+np.float64,0xbfcd7401dd3ae804,0x3ff06cea52c792c0,2
+np.float64,0x800587563beb0ead,0x3ff0000000000000,2
+np.float64,0x3fc15c6f3322b8de,0x3ff025bbd030166d,2
+np.float64,0x7feb6b4caf76d698,0x7ff0000000000000,2
+np.float64,0x7fe136ef82a26dde,0x7ff0000000000000,2
+np.float64,0xf592dac3eb25c,0x3ff0000000000000,2
+np.float64,0x7fd300baf6a60175,0x7ff0000000000000,2
+np.float64,0x7fc880de9e3101bc,0x7ff0000000000000,2
+np.float64,0x7fe7a1aa5caf4354,0x7ff0000000000000,2
+np.float64,0x2f9b8e0e5f373,0x3ff0000000000000,2
+np.float64,0xffcc9071993920e4,0x7ff0000000000000,2
+np.float64,0x8009e151b313c2a4,0x3ff0000000000000,2
+np.float64,0xbfd46e2d18a8dc5a,0x3ff0d27a7b37c1ae,2
+np.float64,0x3fe65c7961acb8f3,0x3ff4116946062a4c,2
+np.float64,0x7fd31b371626366d,0x7ff0000000000000,2
+np.float64,0x98dc924d31b93,0x3ff0000000000000,2
+np.float64,0x268bef364d17f,0x3ff0000000000000,2
+np.float64,0x7fd883ba56310774,0x7ff0000000000000,2
+np.float64,0x3fc53f01a32a7e03,0x3ff0388dea9cd63e,2
+np.float64,0xffe1ea8c0563d518,0x7ff0000000000000,2
+np.float64,0x3fd0bf0e63a17e1d,0x3ff08d0577f5ffa6,2
+np.float64,0x7fef42418f7e8482,0x7ff0000000000000,2
+np.float64,0x8000bccd38c1799b,0x3ff0000000000000,2
+np.float64,0xbfe6c48766ed890f,0x3ff43936fa4048c8,2
+np.float64,0xbfb2a38f3a254720,0x3ff00adc7f7b2822,2
+np.float64,0x3fd5262b2eaa4c56,0x3ff0e1af492c08f5,2
+np.float64,0x80065b4691ecb68e,0x3ff0000000000000,2
+np.float64,0xfb6b9e9ff6d74,0x3ff0000000000000,2
+np.float64,0x8006c71e6ecd8e3e,0x3ff0000000000000,2
+np.float64,0x3fd0a3e43ca147c8,0x3ff08b3ad7b42485,2
+np.float64,0xbfc82d8607305b0c,0x3ff04949d6733ef6,2
+np.float64,0xde048c61bc092,0x3ff0000000000000,2
+np.float64,0xffcf73e0fa3ee7c0,0x7ff0000000000000,2
+np.float64,0xbfe8639d7830c73b,0x3ff4e05f97948376,2
+np.float64,0x8010000000000000,0x3ff0000000000000,2
+np.float64,0x67f01a2acfe04,0x3ff0000000000000,2
+np.float64,0x3fe222e803e445d0,0x3ff2a3a75e5f29d8,2
+np.float64,0xffef84c6387f098b,0x7ff0000000000000,2
+np.float64,0x3fe5969c1e6b2d38,0x3ff3c80130462bb2,2
+np.float64,0x8009f56953d3ead3,0x3ff0000000000000,2
+np.float64,0x3fe05c9b6360b937,0x3ff2232e1cba5617,2
+np.float64,0x3fd8888d63b1111b,0x3ff130a5b788d52f,2
+np.float64,0xffe3a9e6f26753ce,0x7ff0000000000000,2
+np.float64,0x800e2aaa287c5554,0x3ff0000000000000,2
+np.float64,0x3fea8d6c82351ad9,0x3ff5d4d8cde9a11d,2
+np.float64,0x7feef700723dee00,0x7ff0000000000000,2
+np.float64,0x3fa5cb77242b96e0,0x3ff003b62b3e50f1,2
+np.float64,0x7fb68f0a862d1e14,0x7ff0000000000000,2
+np.float64,0x7fb97ee83432fdcf,0x7ff0000000000000,2
+np.float64,0x7fd74a78632e94f0,0x7ff0000000000000,2
+np.float64,0x7fcfe577713fcaee,0x7ff0000000000000,2
+np.float64,0xffe192ee5ea325dc,0x7ff0000000000000,2
+np.float64,0x477d6ae48efae,0x3ff0000000000000,2
+np.float64,0xffe34d5237669aa4,0x7ff0000000000000,2
+np.float64,0x7fe3ce8395a79d06,0x7ff0000000000000,2
+np.float64,0x80019c01ffa33805,0x3ff0000000000000,2
+np.float64,0x74b5b56ce96b7,0x3ff0000000000000,2
+np.float64,0x7fe05ecdeda0bd9b,0x7ff0000000000000,2
+np.float64,0xffe9693eb232d27d,0x7ff0000000000000,2
+np.float64,0xffd2be2c7da57c58,0x7ff0000000000000,2
+np.float64,0x800dbd5cbc1b7aba,0x3ff0000000000000,2
+np.float64,0xbfa36105d426c210,0x3ff002ef2e3a87f7,2
+np.float64,0x800b2d69fb765ad4,0x3ff0000000000000,2
+np.float64,0xbfdb81c9a9370394,0x3ff1802d409cbf7a,2
+np.float64,0x7fd481d014a9039f,0x7ff0000000000000,2
+np.float64,0xffe66c3c1fecd878,0x7ff0000000000000,2
+np.float64,0x3fc55865192ab0c8,0x3ff03915b51e8839,2
+np.float64,0xd6a78987ad4f1,0x3ff0000000000000,2
+np.float64,0x800c6cc80d58d990,0x3ff0000000000000,2
+np.float64,0x979435a12f29,0x3ff0000000000000,2
+np.float64,0xbfbd971e7a3b2e40,0x3ff01b647e45f5a6,2
+np.float64,0x80067565bfeceacc,0x3ff0000000000000,2
+np.float64,0x8001ad689ce35ad2,0x3ff0000000000000,2
+np.float64,0x7fa43253dc2864a7,0x7ff0000000000000,2
+np.float64,0xbfe3dda307e7bb46,0x3ff32ef99a2efe1d,2
+np.float64,0x3fe5d7b395ebaf68,0x3ff3dfd33cdc8ef4,2
+np.float64,0xd94cc9c3b2999,0x3ff0000000000000,2
+np.float64,0x3fee5a513fbcb4a2,0x3ff7c0f17b876ce5,2
+np.float64,0xffe27761fa64eec4,0x7ff0000000000000,2
+np.float64,0x3feb788119b6f102,0x3ff64446f67f4efa,2
+np.float64,0xbfed6e10dffadc22,0x3ff741d5ef610ca0,2
+np.float64,0x7fe73cf98b2e79f2,0x7ff0000000000000,2
+np.float64,0x7847d09af08fb,0x3ff0000000000000,2
+np.float64,0x29ded2da53bdb,0x3ff0000000000000,2
+np.float64,0xbfe51c1ec1aa383e,0x3ff39c0b7cf832e2,2
+np.float64,0xbfeafd5e65f5fabd,0x3ff609548a787f57,2
+np.float64,0x3fd872a26fb0e545,0x3ff12e7fbd95505c,2
+np.float64,0x7fed6b7c1b7ad6f7,0x7ff0000000000000,2
+np.float64,0xffe7ba9ec16f753d,0x7ff0000000000000,2
+np.float64,0x7f89b322f0336645,0x7ff0000000000000,2
+np.float64,0xbfad1677383a2cf0,0x3ff0069ca67e7baa,2
+np.float64,0x3fe0906d04a120da,0x3ff2311b04b7bfef,2
+np.float64,0xffe4b3c9d4296793,0x7ff0000000000000,2
+np.float64,0xbfe476bb0ce8ed76,0x3ff36277d2921a74,2
+np.float64,0x7fc35655cf26acab,0x7ff0000000000000,2
+np.float64,0x7fe9980f0373301d,0x7ff0000000000000,2
+np.float64,0x9e6e04cb3cdc1,0x3ff0000000000000,2
+np.float64,0x800b89e0afb713c2,0x3ff0000000000000,2
+np.float64,0x800bd951a3f7b2a4,0x3ff0000000000000,2
+np.float64,0x29644a9e52c8a,0x3ff0000000000000,2
+np.float64,0x3fe1be2843637c51,0x3ff285e90d8387e4,2
+np.float64,0x7fa233cce4246799,0x7ff0000000000000,2
+np.float64,0xbfcfb7bc2d3f6f78,0x3ff07e657de3e2ed,2
+np.float64,0xffd7c953e7af92a8,0x7ff0000000000000,2
+np.float64,0xbfc5bbaf772b7760,0x3ff03b2ee4febb1e,2
+np.float64,0x8007b7315a6f6e63,0x3ff0000000000000,2
+np.float64,0xbfe906d902320db2,0x3ff525d7e16acfe0,2
+np.float64,0x3fde33d8553c67b1,0x3ff1d09faa19aa53,2
+np.float64,0x61fe76a0c3fcf,0x3ff0000000000000,2
+np.float64,0xa75e355b4ebc7,0x3ff0000000000000,2
+np.float64,0x3fc9e6d86033cdb1,0x3ff05426299c7064,2
+np.float64,0x7fd83f489eb07e90,0x7ff0000000000000,2
+np.float64,0x8000000000000001,0x3ff0000000000000,2
+np.float64,0x80014434ae62886a,0x3ff0000000000000,2
+np.float64,0xbfe21af9686435f3,0x3ff2a149338bdefe,2
+np.float64,0x9354e6cd26a9d,0x3ff0000000000000,2
+np.float64,0xb42b95f768573,0x3ff0000000000000,2
+np.float64,0xbfecb4481bb96890,0x3ff6e15d269dd651,2
+np.float64,0x3f97842ae82f0840,0x3ff0011485156f28,2
+np.float64,0xffdef63d90bdec7c,0x7ff0000000000000,2
+np.float64,0x7fe511a8d36a2351,0x7ff0000000000000,2
+np.float64,0xbf8cb638a0396c80,0x3ff000670c318fb6,2
+np.float64,0x3fe467e1f668cfc4,0x3ff35d65f93ccac6,2
+np.float64,0xbfce7d88f03cfb10,0x3ff074c22475fe5b,2
+np.float64,0x6d0a4994da14a,0x3ff0000000000000,2
+np.float64,0xbfb3072580260e48,0x3ff00b51d3913e9f,2
+np.float64,0x8008fcde36b1f9bd,0x3ff0000000000000,2
+np.float64,0x3fd984df66b309c0,0x3ff149f29125eca4,2
+np.float64,0xffee2a10fe7c5421,0x7ff0000000000000,2
+np.float64,0x80039168ace722d2,0x3ff0000000000000,2
+np.float64,0xffda604379b4c086,0x7ff0000000000000,2
+np.float64,0xffdc6a405bb8d480,0x7ff0000000000000,2
+np.float64,0x3fe62888b26c5111,0x3ff3fdda754c4372,2
+np.float64,0x8008b452cb5168a6,0x3ff0000000000000,2
+np.float64,0x6165d540c2cbb,0x3ff0000000000000,2
+np.float64,0xbfee0c04d17c180a,0x3ff796431c64bcbe,2
+np.float64,0x800609b8448c1371,0x3ff0000000000000,2
+np.float64,0x800fc3fca59f87f9,0x3ff0000000000000,2
+np.float64,0x77f64848efeca,0x3ff0000000000000,2
+np.float64,0x8007cf522d8f9ea5,0x3ff0000000000000,2
+np.float64,0xbfe9fb0b93f3f617,0x3ff591cb0052e22c,2
+np.float64,0x7fd569d5f0aad3ab,0x7ff0000000000000,2
+np.float64,0x7fe5cf489d6b9e90,0x7ff0000000000000,2
+np.float64,0x7fd6e193e92dc327,0x7ff0000000000000,2
+np.float64,0xf78988a5ef131,0x3ff0000000000000,2
+np.float64,0x3fe8f97562b1f2eb,0x3ff5201080fbc12d,2
+np.float64,0x7febfd69d7b7fad3,0x7ff0000000000000,2
+np.float64,0xffc07b5c1720f6b8,0x7ff0000000000000,2
+np.float64,0xbfd966926832cd24,0x3ff146da9adf492e,2
+np.float64,0x7fef5bd9edfeb7b3,0x7ff0000000000000,2
+np.float64,0xbfd2afbc96255f7a,0x3ff0afd601febf44,2
+np.float64,0x7fdd4ea6293a9d4b,0x7ff0000000000000,2
+np.float64,0xbfe8a1e916b143d2,0x3ff4faa23c2793e5,2
+np.float64,0x800188fcd8c311fa,0x3ff0000000000000,2
+np.float64,0xbfe30803f1661008,0x3ff2e9fc729baaee,2
+np.float64,0x7fefffffffffffff,0x7ff0000000000000,2
+np.float64,0x3fd287bec3250f7e,0x3ff0ace34d3102f6,2
+np.float64,0x1f0ee9443e1de,0x3ff0000000000000,2
+np.float64,0xbfd92f73da325ee8,0x3ff14143e4fa2c5a,2
+np.float64,0x3fed7c9bdffaf938,0x3ff74984168734d3,2
+np.float64,0x8002c4d1696589a4,0x3ff0000000000000,2
+np.float64,0xfe03011bfc060,0x3ff0000000000000,2
+np.float64,0x7f7a391e6034723c,0x7ff0000000000000,2
+np.float64,0xffd6fd46f82dfa8e,0x7ff0000000000000,2
+np.float64,0xbfd7520a742ea414,0x3ff112f1ba5d4f91,2
+np.float64,0x8009389d8812713b,0x3ff0000000000000,2
+np.float64,0x7fefb846aaff708c,0x7ff0000000000000,2
+np.float64,0x3fd98a0983331413,0x3ff14a79efb8adbf,2
+np.float64,0xbfd897158db12e2c,0x3ff132137902cf3e,2
+np.float64,0xffc4048d5928091c,0x7ff0000000000000,2
+np.float64,0x80036ae46046d5ca,0x3ff0000000000000,2
+np.float64,0x7faba7ed3c374fd9,0x7ff0000000000000,2
+np.float64,0xbfec4265e1f884cc,0x3ff6a7b8602422c9,2
+np.float64,0xaa195e0b5432c,0x3ff0000000000000,2
+np.float64,0x3feac15d317582ba,0x3ff5ed115758145f,2
+np.float64,0x6c13a5bcd8275,0x3ff0000000000000,2
+np.float64,0xbfed20b8883a4171,0x3ff7194dbd0dc988,2
+np.float64,0x800cde65c899bccc,0x3ff0000000000000,2
+np.float64,0x7c72912af8e53,0x3ff0000000000000,2
+np.float64,0x3fe49d2bb4e93a57,0x3ff36fab3aba15d4,2
+np.float64,0xbfd598fa02ab31f4,0x3ff0eb72fc472025,2
+np.float64,0x8007a191712f4324,0x3ff0000000000000,2
+np.float64,0xbfdeb14872bd6290,0x3ff1e01ca83f35fd,2
+np.float64,0xbfe1da46b3e3b48e,0x3ff28e23ad2f5615,2
+np.float64,0x800a2f348e745e69,0x3ff0000000000000,2
+np.float64,0xbfee66928afccd25,0x3ff7c7ac7dbb3273,2
+np.float64,0xffd78a0a2b2f1414,0x7ff0000000000000,2
+np.float64,0x7fc5fa80b82bf500,0x7ff0000000000000,2
+np.float64,0x800e6d7260dcdae5,0x3ff0000000000000,2
+np.float64,0xbfd6cff2aaad9fe6,0x3ff106f78ee61642,2
+np.float64,0x7fe1041d1d220839,0x7ff0000000000000,2
+np.float64,0xbfdf75586cbeeab0,0x3ff1f8dbaa7e57f0,2
+np.float64,0xffdcaae410b955c8,0x7ff0000000000000,2
+np.float64,0x800fe5e0d1ffcbc2,0x3ff0000000000000,2
+np.float64,0x800d7999527af333,0x3ff0000000000000,2
+np.float64,0xbfe62c233bac5846,0x3ff3ff34220a204c,2
+np.float64,0x7fe99bbff8f3377f,0x7ff0000000000000,2
+np.float64,0x7feeaf471d3d5e8d,0x7ff0000000000000,2
+np.float64,0xd5904ff5ab20a,0x3ff0000000000000,2
+np.float64,0x3fd07aae3320f55c,0x3ff08888c227c968,2
+np.float64,0x7fea82b8dff50571,0x7ff0000000000000,2
+np.float64,0xffef2db9057e5b71,0x7ff0000000000000,2
+np.float64,0xbfe2077fef640f00,0x3ff29b7dd0d39d36,2
+np.float64,0xbfe09a4d7c61349b,0x3ff233c7e88881f4,2
+np.float64,0x3fda50c4cbb4a188,0x3ff15f28a71deee7,2
+np.float64,0x7fe7d9ee6b2fb3dc,0x7ff0000000000000,2
+np.float64,0x3febbf6faeb77edf,0x3ff666d13682ea93,2
+np.float64,0xc401a32988035,0x3ff0000000000000,2
+np.float64,0xbfeab30aa8f56615,0x3ff5e65dcc6603f8,2
+np.float64,0x92c8cea32591a,0x3ff0000000000000,2
+np.float64,0xbff0000000000000,0x3ff8b07551d9f550,2
+np.float64,0xbfbddfb4dc3bbf68,0x3ff01bebaec38faa,2
+np.float64,0xbfd8de3e2a31bc7c,0x3ff1391f4830d20b,2
+np.float64,0xffc83a8f8a307520,0x7ff0000000000000,2
+np.float64,0x3fee026ef53c04de,0x3ff7911337085827,2
+np.float64,0x7fbaf380b235e700,0x7ff0000000000000,2
+np.float64,0xffe5b89fa62b713f,0x7ff0000000000000,2
+np.float64,0xbfdc1ff54ab83fea,0x3ff191e8c0b60bb2,2
+np.float64,0x6ae3534cd5c6b,0x3ff0000000000000,2
+np.float64,0xbfea87e558750fcb,0x3ff5d24846013794,2
+np.float64,0xffe0f467bee1e8cf,0x7ff0000000000000,2
+np.float64,0x7fee3b0dc7bc761b,0x7ff0000000000000,2
+np.float64,0x3fed87521afb0ea4,0x3ff74f2f5cd36a5c,2
+np.float64,0x7b3c9882f6794,0x3ff0000000000000,2
+np.float64,0x7fdd1a62243a34c3,0x7ff0000000000000,2
+np.float64,0x800f1dc88d3e3b91,0x3ff0000000000000,2
+np.float64,0x7fc3213cfa264279,0x7ff0000000000000,2
+np.float64,0x3fe40e0f3d681c1e,0x3ff33f135e9d5ded,2
+np.float64,0x7febf14e51f7e29c,0x7ff0000000000000,2
+np.float64,0xffe96c630c72d8c5,0x7ff0000000000000,2
+np.float64,0x7fdd82fbe7bb05f7,0x7ff0000000000000,2
+np.float64,0xbf9a6a0b1034d420,0x3ff0015ce009f7d8,2
+np.float64,0xbfceb4f8153d69f0,0x3ff0766e3ecc77df,2
+np.float64,0x3fd9de31e633bc64,0x3ff15327b794a16e,2
+np.float64,0x3faa902a30352054,0x3ff00583848d1969,2
+np.float64,0x0,0x3ff0000000000000,2
+np.float64,0x3fbe3459c43c68b4,0x3ff01c8af6710ef6,2
+np.float64,0xbfa8df010031be00,0x3ff004d5632dc9f5,2
+np.float64,0x7fbcf6cf2a39ed9d,0x7ff0000000000000,2
+np.float64,0xffe4236202a846c4,0x7ff0000000000000,2
+np.float64,0x3fd35ed52e26bdaa,0x3ff0bd0b231f11f7,2
+np.float64,0x7fe7a2df532f45be,0x7ff0000000000000,2
+np.float64,0xffe32f8315665f06,0x7ff0000000000000,2
+np.float64,0x7fe1a69f03e34d3d,0x7ff0000000000000,2
+np.float64,0x7fa5542b742aa856,0x7ff0000000000000,2
+np.float64,0x3fe84e9f8ef09d3f,0x3ff4d79816359765,2
+np.float64,0x29076fe6520ef,0x3ff0000000000000,2
+np.float64,0xffd70894f7ae112a,0x7ff0000000000000,2
+np.float64,0x800188edcbe311dc,0x3ff0000000000000,2
+np.float64,0x3fe2c7acda258f5a,0x3ff2d5dad4617703,2
+np.float64,0x3f775d41a02ebb00,0x3ff000110f212445,2
+np.float64,0x7fe8a084d1714109,0x7ff0000000000000,2
+np.float64,0x3fe31562d8a62ac6,0x3ff2ee35055741cd,2
+np.float64,0xbfd195d4d1a32baa,0x3ff09b98a50c151b,2
+np.float64,0xffaae9ff0c35d400,0x7ff0000000000000,2
+np.float64,0xff819866502330c0,0x7ff0000000000000,2
+np.float64,0x7fddc64815bb8c8f,0x7ff0000000000000,2
+np.float64,0xbfd442b428288568,0x3ff0cef70aa73ae6,2
+np.float64,0x8002e7625aa5cec5,0x3ff0000000000000,2
+np.float64,0x7fe8d4f70e71a9ed,0x7ff0000000000000,2
+np.float64,0xbfc3bd015f277a04,0x3ff030cbf16f29d9,2
+np.float64,0x3fd315d5baa62bab,0x3ff0b77a551a5335,2
+np.float64,0x7fa638b4642c7168,0x7ff0000000000000,2
+np.float64,0x3fdea8b795bd516f,0x3ff1df0bb70cdb79,2
+np.float64,0xbfd78754762f0ea8,0x3ff117ee0f29abed,2
+np.float64,0x8009f6a37633ed47,0x3ff0000000000000,2
+np.float64,0x3fea1daf75343b5f,0x3ff5a1804789bf13,2
+np.float64,0x3fd044b6c0a0896e,0x3ff0850b7297d02f,2
+np.float64,0x8003547a9c86a8f6,0x3ff0000000000000,2
+np.float64,0x3fa6c2cd782d859b,0x3ff0040c4ac8f44a,2
+np.float64,0x3fe225baaae44b76,0x3ff2a47f5e1f5e85,2
+np.float64,0x8000000000000000,0x3ff0000000000000,2
+np.float64,0x3fcb53da8736a7b8,0x3ff05db45af470ac,2
+np.float64,0x80079f8f140f3f1f,0x3ff0000000000000,2
+np.float64,0xbfcd1d7e2b3a3afc,0x3ff06a6b6845d05f,2
+np.float64,0x96df93672dbf3,0x3ff0000000000000,2
+np.float64,0xdef86e43bdf0e,0x3ff0000000000000,2
+np.float64,0xbfec05a09db80b41,0x3ff6896b768eea08,2
+np.float64,0x7fe3ff91d267ff23,0x7ff0000000000000,2
+np.float64,0xffea3eaa07347d53,0x7ff0000000000000,2
+np.float64,0xbfebde1cc1f7bc3a,0x3ff675e34ac2afc2,2
+np.float64,0x629bcde8c537a,0x3ff0000000000000,2
+np.float64,0xbfdde4fcff3bc9fa,0x3ff1c7061d21f0fe,2
+np.float64,0x3fee60fd003cc1fa,0x3ff7c49af3878a51,2
+np.float64,0x3fe5c92ac32b9256,0x3ff3da7a7929588b,2
+np.float64,0xbfe249c78f64938f,0x3ff2af52a06f1a50,2
+np.float64,0xbfc6de9dbe2dbd3c,0x3ff0418d284ee29f,2
+np.float64,0xffc8ef094631de14,0x7ff0000000000000,2
+np.float64,0x3fdef05f423de0bf,0x3ff1e800caba8ab5,2
+np.float64,0xffc1090731221210,0x7ff0000000000000,2
+np.float64,0xbfedec9b5fbbd937,0x3ff7854b6792a24a,2
+np.float64,0xbfb873507630e6a0,0x3ff012b23b3b7a67,2
+np.float64,0xbfe3cd6692679acd,0x3ff3299d6936ec4b,2
+np.float64,0xbfb107c890220f90,0x3ff0091122162472,2
+np.float64,0xbfe4e6ee48e9cddc,0x3ff3894e5a5e70a6,2
+np.float64,0xffe6fa3413edf468,0x7ff0000000000000,2
+np.float64,0x3fe2faf79b65f5ef,0x3ff2e5e11fae8b54,2
+np.float64,0xbfdfeb8df9bfd71c,0x3ff208189691b15f,2
+np.float64,0x75d2d03ceba5b,0x3ff0000000000000,2
+np.float64,0x3feb48c182b69183,0x3ff62d4462eba6cb,2
+np.float64,0xffcda9f7ff3b53f0,0x7ff0000000000000,2
+np.float64,0x7fcafbdcbd35f7b8,0x7ff0000000000000,2
+np.float64,0xbfd1895523a312aa,0x3ff09aba642a78d9,2
+np.float64,0x3fe3129c3f662538,0x3ff2ed546bbfafcf,2
+np.float64,0x3fb444dee02889be,0x3ff00cd86273b964,2
+np.float64,0xbf73b32d7ee77,0x3ff0000000000000,2
+np.float64,0x3fae19904c3c3321,0x3ff00714865c498a,2
+np.float64,0x7fefbfaef5bf7f5d,0x7ff0000000000000,2
+np.float64,0x8000dc3816e1b871,0x3ff0000000000000,2
+np.float64,0x8003f957ba47f2b0,0x3ff0000000000000,2
+np.float64,0xbfe3563c7ea6ac79,0x3ff302dcebc92856,2
+np.float64,0xbfdc80fbae3901f8,0x3ff19cfe73e58092,2
+np.float64,0x8009223b04524476,0x3ff0000000000000,2
+np.float64,0x3fd95f431c32be86,0x3ff1461c21cb03f0,2
+np.float64,0x7ff4000000000000,0x7ffc000000000000,2
+np.float64,0xbfe7c12ed3ef825e,0x3ff49d59c265efcd,2
+np.float64,0x10000000000000,0x3ff0000000000000,2
+np.float64,0x7fc5e2632f2bc4c5,0x7ff0000000000000,2
+np.float64,0xffd8f6b4c7b1ed6a,0x7ff0000000000000,2
+np.float64,0x80034b93d4069728,0x3ff0000000000000,2
+np.float64,0xffdf5d4c1dbeba98,0x7ff0000000000000,2
+np.float64,0x800bc63d70178c7b,0x3ff0000000000000,2
+np.float64,0xbfeba31ea0f7463d,0x3ff658fa27073d2b,2
+np.float64,0xbfeebeede97d7ddc,0x3ff7f89a8e80dec4,2
+np.float64,0x7feb0f1f91361e3e,0x7ff0000000000000,2
+np.float64,0xffec3158d0b862b1,0x7ff0000000000000,2
+np.float64,0x3fde51cbfbbca398,0x3ff1d44c2ff15b3d,2
+np.float64,0xd58fb2b3ab1f7,0x3ff0000000000000,2
+np.float64,0x80028b9e32e5173d,0x3ff0000000000000,2
+np.float64,0x7fea77a56c74ef4a,0x7ff0000000000000,2
+np.float64,0x3fdaabbd4a35577b,0x3ff168d82edf2fe0,2
+np.float64,0xbfe69c39cc2d3874,0x3ff429b2f4cdb362,2
+np.float64,0x3b78f5d876f20,0x3ff0000000000000,2
+np.float64,0x7fa47d116428fa22,0x7ff0000000000000,2
+np.float64,0xbfe4118b0ce82316,0x3ff3403d989f780f,2
+np.float64,0x800482e793c905d0,0x3ff0000000000000,2
+np.float64,0xbfe48e5728e91cae,0x3ff36a9020bf9d20,2
+np.float64,0x7fe078ba8860f174,0x7ff0000000000000,2
+np.float64,0x3fd80843e5b01088,0x3ff1242f401e67da,2
+np.float64,0x3feb1f6965f63ed3,0x3ff6197fc590e143,2
+np.float64,0xffa41946d8283290,0x7ff0000000000000,2
+np.float64,0xffe30de129661bc2,0x7ff0000000000000,2
+np.float64,0x3fec9c8e1ab9391c,0x3ff6d542ea2f49b4,2
+np.float64,0x3fdc3e4490387c89,0x3ff1955ae18cac37,2
+np.float64,0xffef49d9c77e93b3,0x7ff0000000000000,2
+np.float64,0xfff0000000000000,0x7ff0000000000000,2
+np.float64,0x3fe0442455608849,0x3ff21cab90067d5c,2
+np.float64,0xbfed86aebd3b0d5e,0x3ff74ed8d4b75f50,2
+np.float64,0xffe4600d2b28c01a,0x7ff0000000000000,2
+np.float64,0x7fc1e8ccff23d199,0x7ff0000000000000,2
+np.float64,0x8008d49b0091a936,0x3ff0000000000000,2
+np.float64,0xbfe4139df028273c,0x3ff340ef3c86227c,2
+np.float64,0xbfe9ab4542b3568a,0x3ff56dfe32061247,2
+np.float64,0xbfd76dd365aedba6,0x3ff11589bab5fe71,2
+np.float64,0x3fd42cf829a859f0,0x3ff0cd3844bb0e11,2
+np.float64,0x7fd077cf2e20ef9d,0x7ff0000000000000,2
+np.float64,0x3fd7505760aea0b0,0x3ff112c937b3f088,2
+np.float64,0x1f93341a3f267,0x3ff0000000000000,2
+np.float64,0x7fe3c3c1b0678782,0x7ff0000000000000,2
+np.float64,0x800f85cec97f0b9e,0x3ff0000000000000,2
+np.float64,0xd93ab121b2756,0x3ff0000000000000,2
+np.float64,0xbfef8066fd7f00ce,0x3ff8663ed7d15189,2
+np.float64,0xffe31dd4af663ba9,0x7ff0000000000000,2
+np.float64,0xbfd7ff05a6affe0c,0x3ff1234c09bb686d,2
+np.float64,0xbfe718c31fee3186,0x3ff45a0c2d0ef7b0,2
+np.float64,0x800484bf33e9097f,0x3ff0000000000000,2
+np.float64,0xffd409dad02813b6,0x7ff0000000000000,2
+np.float64,0x3fe59679896b2cf4,0x3ff3c7f49e4fbbd3,2
+np.float64,0xbfd830c54d30618a,0x3ff1281729861390,2
+np.float64,0x1d4fc81c3a9fa,0x3ff0000000000000,2
+np.float64,0x3fd334e4272669c8,0x3ff0b9d5d82894f0,2
+np.float64,0xffc827e65c304fcc,0x7ff0000000000000,2
+np.float64,0xffe2d1814aa5a302,0x7ff0000000000000,2
+np.float64,0xffd7b5b8d32f6b72,0x7ff0000000000000,2
+np.float64,0xbfdbc9f077b793e0,0x3ff18836b9106ad0,2
+np.float64,0x7fc724c2082e4983,0x7ff0000000000000,2
+np.float64,0x3fa39ed72c273da0,0x3ff00302051ce17e,2
+np.float64,0xbfe3c4c209678984,0x3ff326c4fd16b5cd,2
+np.float64,0x7fe91f6d00f23ed9,0x7ff0000000000000,2
+np.float64,0x8004ee93fea9dd29,0x3ff0000000000000,2
+np.float64,0xbfe7c32d0eaf865a,0x3ff49e290ed2ca0e,2
+np.float64,0x800ea996b29d532d,0x3ff0000000000000,2
+np.float64,0x2df9ec1c5bf3e,0x3ff0000000000000,2
+np.float64,0xabb175df5762f,0x3ff0000000000000,2
+np.float64,0xffe3fc9c8e27f938,0x7ff0000000000000,2
+np.float64,0x7fb358a62826b14b,0x7ff0000000000000,2
+np.float64,0x800aedcccaf5db9a,0x3ff0000000000000,2
+np.float64,0xffca530c5234a618,0x7ff0000000000000,2
+np.float64,0x40f91e9681f24,0x3ff0000000000000,2
+np.float64,0x80098f4572f31e8b,0x3ff0000000000000,2
+np.float64,0xbfdc58c21fb8b184,0x3ff1986115f8fe92,2
+np.float64,0xbfebeafd40b7d5fa,0x3ff67c3cf34036e3,2
+np.float64,0x7fd108861a22110b,0x7ff0000000000000,2
+np.float64,0xff8e499ae03c9340,0x7ff0000000000000,2
+np.float64,0xbfd2f58caa25eb1a,0x3ff0b50b1bffafdf,2
+np.float64,0x3fa040c9bc208193,0x3ff002105e95aefa,2
+np.float64,0xbfd2ebc0a5a5d782,0x3ff0b44ed5a11584,2
+np.float64,0xffe237bc93a46f78,0x7ff0000000000000,2
+np.float64,0x3fd557c5eeaaaf8c,0x3ff0e5e0a575e1ba,2
+np.float64,0x7abb419ef5769,0x3ff0000000000000,2
+np.float64,0xffefa1fe353f43fb,0x7ff0000000000000,2
+np.float64,0x3fa6f80ba02df017,0x3ff0041f51fa0d76,2
+np.float64,0xbfdce79488b9cf2a,0x3ff1a8e32877beb4,2
+np.float64,0x2285f3e4450bf,0x3ff0000000000000,2
+np.float64,0x3bf7eb7277efe,0x3ff0000000000000,2
+np.float64,0xbfd5925fd3ab24c0,0x3ff0eae1c2ac2e78,2
+np.float64,0xbfed6325227ac64a,0x3ff73c14a2ad5bfe,2
+np.float64,0x8000429c02408539,0x3ff0000000000000,2
+np.float64,0xb67c21e76cf84,0x3ff0000000000000,2
+np.float64,0x3fec3d3462f87a69,0x3ff6a51e4c027eb7,2
+np.float64,0x3feae69cbcf5cd3a,0x3ff5fe9387314afd,2
+np.float64,0x7fd0c9a0ec219341,0x7ff0000000000000,2
+np.float64,0x8004adb7f6295b71,0x3ff0000000000000,2
+np.float64,0xffd61fe8bb2c3fd2,0x7ff0000000000000,2
+np.float64,0xffe7fb3834aff670,0x7ff0000000000000,2
+np.float64,0x7fd1eef163a3dde2,0x7ff0000000000000,2
+np.float64,0x2e84547a5d08b,0x3ff0000000000000,2
+np.float64,0x8002d8875ee5b10f,0x3ff0000000000000,2
+np.float64,0x3fe1d1c5f763a38c,0x3ff28ba524fb6de8,2
+np.float64,0x8001dea0bc43bd42,0x3ff0000000000000,2
+np.float64,0xfecfad91fd9f6,0x3ff0000000000000,2
+np.float64,0xffed7965fa3af2cb,0x7ff0000000000000,2
+np.float64,0xbfe6102ccc2c205a,0x3ff3f4c082506686,2
+np.float64,0x3feff75b777feeb6,0x3ff8ab6222578e0c,2
+np.float64,0x3fb8a97bd43152f8,0x3ff013057f0a9d89,2
+np.float64,0xffe234b5e964696c,0x7ff0000000000000,2
+np.float64,0x984d9137309b2,0x3ff0000000000000,2
+np.float64,0xbfe42e9230e85d24,0x3ff349fb7d1a7560,2
+np.float64,0xbfecc8b249f99165,0x3ff6ebd0fea0ea72,2
+np.float64,0x8000840910410813,0x3ff0000000000000,2
+np.float64,0xbfd81db9e7303b74,0x3ff126402d3539ec,2
+np.float64,0x800548eb7fea91d8,0x3ff0000000000000,2
+np.float64,0xbfe4679ad0e8cf36,0x3ff35d4db89296a3,2
+np.float64,0x3fd4c55b5a298ab7,0x3ff0d99da31081f9,2
+np.float64,0xbfa8f5b38c31eb60,0x3ff004de3a23b32d,2
+np.float64,0x80005d348e80ba6a,0x3ff0000000000000,2
+np.float64,0x800c348d6118691b,0x3ff0000000000000,2
+np.float64,0xffd6b88f84ad7120,0x7ff0000000000000,2
+np.float64,0x3fc1aaaa82235555,0x3ff027136afd08e0,2
+np.float64,0x7fca7d081b34fa0f,0x7ff0000000000000,2
+np.float64,0x1,0x3ff0000000000000,2
+np.float64,0xbfdc810d1139021a,0x3ff19d007408cfe3,2
+np.float64,0xbfe5dce05f2bb9c0,0x3ff3e1bb9234617b,2
+np.float64,0xffecfe2c32b9fc58,0x7ff0000000000000,2
+np.float64,0x95b2891b2b651,0x3ff0000000000000,2
+np.float64,0x8000b60c6c616c1a,0x3ff0000000000000,2
+np.float64,0x4944f0889289f,0x3ff0000000000000,2
+np.float64,0x3fe6e508696dca10,0x3ff445d1b94863e9,2
+np.float64,0xbfe63355d0ec66ac,0x3ff401e74f16d16f,2
+np.float64,0xbfe9b9595af372b3,0x3ff57445e1b4d670,2
+np.float64,0x800e16f7313c2dee,0x3ff0000000000000,2
+np.float64,0xffe898f5f0b131eb,0x7ff0000000000000,2
+np.float64,0x3fe91ac651f2358d,0x3ff52e787c21c004,2
+np.float64,0x7fbfaac6783f558c,0x7ff0000000000000,2
+np.float64,0xd8ef3dfbb1de8,0x3ff0000000000000,2
+np.float64,0xbfc58c13a52b1828,0x3ff03a2c19d65019,2
+np.float64,0xbfbde55e8a3bcac0,0x3ff01bf648a3e0a7,2
+np.float64,0xffc3034930260694,0x7ff0000000000000,2
+np.float64,0xea77a64dd4ef5,0x3ff0000000000000,2
+np.float64,0x800cfe7e7739fcfd,0x3ff0000000000000,2
+np.float64,0x4960f31a92c1f,0x3ff0000000000000,2
+np.float64,0x3fd9552c94b2aa58,0x3ff14515a29add09,2
+np.float64,0xffe8b3244c316648,0x7ff0000000000000,2
+np.float64,0x3fe8201e6a70403d,0x3ff4c444fa679cce,2
+np.float64,0xffe9ab7c20f356f8,0x7ff0000000000000,2
+np.float64,0x3fed8bba5f7b1774,0x3ff751853c4c95c5,2
+np.float64,0x8007639cb76ec73a,0x3ff0000000000000,2
+np.float64,0xbfe396db89672db7,0x3ff317bfd1d6fa8c,2
+np.float64,0xbfeb42f888f685f1,0x3ff62a7e0eee56b1,2
+np.float64,0x3fe894827c712904,0x3ff4f4f561d9ea13,2
+np.float64,0xb66b3caf6cd68,0x3ff0000000000000,2
+np.float64,0x800f8907fdbf1210,0x3ff0000000000000,2
+np.float64,0x7fe9b0cddb73619b,0x7ff0000000000000,2
+np.float64,0xbfda70c0e634e182,0x3ff1628c6fdffc53,2
+np.float64,0x3fe0b5f534a16bea,0x3ff23b4ed4c2b48e,2
+np.float64,0xbfe8eee93671ddd2,0x3ff51b85b3c50ae4,2
+np.float64,0xbfe8c22627f1844c,0x3ff50858787a3bfe,2
+np.float64,0x37bb83c86f771,0x3ff0000000000000,2
+np.float64,0xffb7827ffe2f0500,0x7ff0000000000000,2
+np.float64,0x64317940c864,0x3ff0000000000000,2
+np.float64,0x800430ecee6861db,0x3ff0000000000000,2
+np.float64,0x3fa4291fbc285240,0x3ff0032d0204f6dd,2
+np.float64,0xffec69f76af8d3ee,0x7ff0000000000000,2
+np.float64,0x3ff0000000000000,0x3ff8b07551d9f550,2
+np.float64,0x3fc4cf3c42299e79,0x3ff0363fb1d3c254,2
+np.float64,0x7fe0223a77e04474,0x7ff0000000000000,2
+np.float64,0x800a3d4fa4347aa0,0x3ff0000000000000,2
+np.float64,0x3fdd273f94ba4e7f,0x3ff1b05b686e6879,2
+np.float64,0x3feca79052f94f20,0x3ff6dadedfa283aa,2
+np.float64,0x5e7f6f80bcfef,0x3ff0000000000000,2
+np.float64,0xbfef035892fe06b1,0x3ff81efb39cbeba2,2
+np.float64,0x3fee6c08e07cd812,0x3ff7caad952860a1,2
+np.float64,0xffeda715877b4e2a,0x7ff0000000000000,2
+np.float64,0x800580286b0b0052,0x3ff0000000000000,2
+np.float64,0x800703a73fee074f,0x3ff0000000000000,2
+np.float64,0xbfccf96a6639f2d4,0x3ff0696330a60832,2
+np.float64,0x7feb408442368108,0x7ff0000000000000,2
+np.float64,0x3fedc87a46fb90f5,0x3ff771e3635649a9,2
+np.float64,0x3fd8297b773052f7,0x3ff12762bc0cea76,2
+np.float64,0x3fee41bb03fc8376,0x3ff7b37b2da48ab4,2
+np.float64,0xbfe2b05a226560b4,0x3ff2cea17ae7c528,2
+np.float64,0xbfd2e92cf2a5d25a,0x3ff0b41d605ced61,2
+np.float64,0x4817f03a902ff,0x3ff0000000000000,2
+np.float64,0x8c9d4f0d193aa,0x3ff0000000000000,2
diff --git a/numpy/core/tests/data/umath-validation-set-exp b/numpy/core/tests/data/umath-validation-set-exp.csv
index 7c5ef3b33..7c5ef3b33 100644
--- a/numpy/core/tests/data/umath-validation-set-exp
+++ b/numpy/core/tests/data/umath-validation-set-exp.csv
diff --git a/numpy/core/tests/data/umath-validation-set-exp2.csv b/numpy/core/tests/data/umath-validation-set-exp2.csv
new file mode 100644
index 000000000..e19e9ebd6
--- /dev/null
+++ b/numpy/core/tests/data/umath-validation-set-exp2.csv
@@ -0,0 +1,1429 @@
+dtype,input,output,ulperrortol
+np.float32,0xbdfe94b0,0x3f6adda6,2
+np.float32,0x3f20f8f8,0x3fc5ec69,2
+np.float32,0x7040b5,0x3f800000,2
+np.float32,0x30ec5,0x3f800000,2
+np.float32,0x3eb63070,0x3fa3ce29,2
+np.float32,0xff4dda3d,0x0,2
+np.float32,0x805b832f,0x3f800000,2
+np.float32,0x3e883fb7,0x3f99ed8c,2
+np.float32,0x3f14d71f,0x3fbf8708,2
+np.float32,0xff7b1e55,0x0,2
+np.float32,0xbf691ac6,0x3f082fa2,2
+np.float32,0x7ee3e6ab,0x7f800000,2
+np.float32,0xbec6e2b4,0x3f439248,2
+np.float32,0xbf5f5ec2,0x3f0bd2c0,2
+np.float32,0x8025cc2c,0x3f800000,2
+np.float32,0x7e0d7672,0x7f800000,2
+np.float32,0xff4bbc5c,0x0,2
+np.float32,0xbd94fb30,0x3f73696b,2
+np.float32,0x6cc079,0x3f800000,2
+np.float32,0x803cf080,0x3f800000,2
+np.float32,0x71d418,0x3f800000,2
+np.float32,0xbf24a442,0x3f23ec1e,2
+np.float32,0xbe6c9510,0x3f5a1e1d,2
+np.float32,0xbe8fb284,0x3f52be38,2
+np.float32,0x7ea64754,0x7f800000,2
+np.float32,0x7fc00000,0x7fc00000,2
+np.float32,0x80620cfd,0x3f800000,2
+np.float32,0x3f3e20e8,0x3fd62e72,2
+np.float32,0x3f384600,0x3fd2d00e,2
+np.float32,0xff362150,0x0,2
+np.float32,0xbf349fa8,0x3f1cfaef,2
+np.float32,0xbf776cf2,0x3f0301a6,2
+np.float32,0x8021fc60,0x3f800000,2
+np.float32,0xbdb75280,0x3f70995c,2
+np.float32,0x7e9363a6,0x7f800000,2
+np.float32,0x7e728422,0x7f800000,2
+np.float32,0xfe91edc2,0x0,2
+np.float32,0x3f5f438c,0x3fea491d,2
+np.float32,0x3f2afae9,0x3fcb5c1f,2
+np.float32,0xbef8e766,0x3f36c448,2
+np.float32,0xba522c00,0x3f7fdb97,2
+np.float32,0xff18ee8c,0x0,2
+np.float32,0xbee8c5f4,0x3f3acd44,2
+np.float32,0x3e790448,0x3f97802c,2
+np.float32,0x3e8c9541,0x3f9ad571,2
+np.float32,0xbf03fa9f,0x3f331460,2
+np.float32,0x801ee053,0x3f800000,2
+np.float32,0xbf773230,0x3f03167f,2
+np.float32,0x356fd9,0x3f800000,2
+np.float32,0x8009cd88,0x3f800000,2
+np.float32,0x7f2bac51,0x7f800000,2
+np.float32,0x4d9eeb,0x3f800000,2
+np.float32,0x3133,0x3f800000,2
+np.float32,0x7f4290e0,0x7f800000,2
+np.float32,0xbf5e6523,0x3f0c3161,2
+np.float32,0x3f19182e,0x3fc1bf10,2
+np.float32,0x7e1248bb,0x7f800000,2
+np.float32,0xff5f7aae,0x0,2
+np.float32,0x7e8557b5,0x7f800000,2
+np.float32,0x26fc7f,0x3f800000,2
+np.float32,0x80397d61,0x3f800000,2
+np.float32,0x3cb1825d,0x3f81efe0,2
+np.float32,0x3ed808d0,0x3fab7c45,2
+np.float32,0xbf6f668a,0x3f05e259,2
+np.float32,0x3e3c7802,0x3f916abd,2
+np.float32,0xbd5ac5a0,0x3f76b21b,2
+np.float32,0x805aa6c9,0x3f800000,2
+np.float32,0xbe4d6f68,0x3f5ec3e1,2
+np.float32,0x3f3108b2,0x3fceb87f,2
+np.float32,0x3ec385cc,0x3fa6c9fb,2
+np.float32,0xbe9fc1ce,0x3f4e35e8,2
+np.float32,0x43b68,0x3f800000,2
+np.float32,0x3ef0cdcc,0x3fb15557,2
+np.float32,0x3e3f729b,0x3f91b5e1,2
+np.float32,0x7f52a4df,0x7f800000,2
+np.float32,0xbf56da96,0x3f0f15b9,2
+np.float32,0xbf161d2b,0x3f2a7faf,2
+np.float32,0x3e8df763,0x3f9b1fbe,2
+np.float32,0xff4f0780,0x0,2
+np.float32,0x8048f594,0x3f800000,2
+np.float32,0x3e62bb1d,0x3f953b7e,2
+np.float32,0xfe58e764,0x0,2
+np.float32,0x3dd2c922,0x3f897718,2
+np.float32,0x7fa00000,0x7fe00000,2
+np.float32,0xff07b4b2,0x0,2
+np.float32,0x7f6231a0,0x7f800000,2
+np.float32,0xb8d1d,0x3f800000,2
+np.float32,0x3ee01d24,0x3fad5f16,2
+np.float32,0xbf43f59f,0x3f169869,2
+np.float32,0x801f5257,0x3f800000,2
+np.float32,0x803c15d8,0x3f800000,2
+np.float32,0x3f171a08,0x3fc0b42a,2
+np.float32,0x127aef,0x3f800000,2
+np.float32,0xfd1c6,0x3f800000,2
+np.float32,0x3f1ed13e,0x3fc4c59a,2
+np.float32,0x57fd4f,0x3f800000,2
+np.float32,0x6e8c61,0x3f800000,2
+np.float32,0x804019ab,0x3f800000,2
+np.float32,0x3ef4e5c6,0x3fb251a1,2
+np.float32,0x5044c3,0x3f800000,2
+np.float32,0x3f04460f,0x3fb7204b,2
+np.float32,0x7e326b47,0x7f800000,2
+np.float32,0x800a7e4c,0x3f800000,2
+np.float32,0xbf47ec82,0x3f14fccc,2
+np.float32,0xbedb1b3e,0x3f3e4a4d,2
+np.float32,0x3f741d86,0x3ff7e4b0,2
+np.float32,0xbe249d20,0x3f6501a6,2
+np.float32,0xbf2ea152,0x3f1f8c68,2
+np.float32,0x3ec6dbcc,0x3fa78b3f,2
+np.float32,0x7ebd9bb4,0x7f800000,2
+np.float32,0x3f61b574,0x3febd77a,2
+np.float32,0x3f3dfb2b,0x3fd61891,2
+np.float32,0x3c7d95,0x3f800000,2
+np.float32,0x8071e840,0x3f800000,2
+np.float32,0x15c6fe,0x3f800000,2
+np.float32,0xbf096601,0x3f307893,2
+np.float32,0x7f5c2ef9,0x7f800000,2
+np.float32,0xbe79f750,0x3f582689,2
+np.float32,0x1eb692,0x3f800000,2
+np.float32,0xbd8024f0,0x3f75226d,2
+np.float32,0xbf5a8be8,0x3f0da950,2
+np.float32,0xbf4d28f3,0x3f12e3e1,2
+np.float32,0x7f800000,0x7f800000,2
+np.float32,0xfea8a758,0x0,2
+np.float32,0x8075d2cf,0x3f800000,2
+np.float32,0xfd99af58,0x0,2
+np.float32,0x9e6a,0x3f800000,2
+np.float32,0x2fa19f,0x3f800000,2
+np.float32,0x3e9f4206,0x3f9ecc56,2
+np.float32,0xbee0b666,0x3f3cd9fc,2
+np.float32,0xbec558c4,0x3f43fab1,2
+np.float32,0x7e9a77df,0x7f800000,2
+np.float32,0xff3a9694,0x0,2
+np.float32,0x3f3b3708,0x3fd47f9a,2
+np.float32,0x807cd6d4,0x3f800000,2
+np.float32,0x804aa422,0x3f800000,2
+np.float32,0xfead7a70,0x0,2
+np.float32,0x3f08c610,0x3fb95efe,2
+np.float32,0xff390126,0x0,2
+np.float32,0x5d2d47,0x3f800000,2
+np.float32,0x8006849c,0x3f800000,2
+np.float32,0x654f6e,0x3f800000,2
+np.float32,0xff478a16,0x0,2
+np.float32,0x3f480b0c,0x3fdc024c,2
+np.float32,0xbc3b96c0,0x3f7df9f4,2
+np.float32,0xbcc96460,0x3f7bacb5,2
+np.float32,0x7f349f30,0x7f800000,2
+np.float32,0xbe08fa98,0x3f6954a1,2
+np.float32,0x4f3a13,0x3f800000,2
+np.float32,0x7f6a5ab4,0x7f800000,2
+np.float32,0x7eb85247,0x7f800000,2
+np.float32,0xbf287246,0x3f223e08,2
+np.float32,0x801584d0,0x3f800000,2
+np.float32,0x7ec25371,0x7f800000,2
+np.float32,0x3f002165,0x3fb51552,2
+np.float32,0x3e1108a8,0x3f8d3429,2
+np.float32,0x4f0f88,0x3f800000,2
+np.float32,0x7f67c1ce,0x7f800000,2
+np.float32,0xbf4348f8,0x3f16dedf,2
+np.float32,0xbe292b64,0x3f644d24,2
+np.float32,0xbf2bfa36,0x3f20b2d6,2
+np.float32,0xbf2a6e58,0x3f215f71,2
+np.float32,0x3e97d5d3,0x3f9d35df,2
+np.float32,0x31f597,0x3f800000,2
+np.float32,0x100544,0x3f800000,2
+np.float32,0x10a197,0x3f800000,2
+np.float32,0x3f44df50,0x3fda20d2,2
+np.float32,0x59916d,0x3f800000,2
+np.float32,0x707472,0x3f800000,2
+np.float32,0x8054194e,0x3f800000,2
+np.float32,0x80627b01,0x3f800000,2
+np.float32,0x7f4d5a5b,0x7f800000,2
+np.float32,0xbcecad00,0x3f7aeca5,2
+np.float32,0xff69c541,0x0,2
+np.float32,0xbe164e20,0x3f673c3a,2
+np.float32,0x3dd321de,0x3f897b39,2
+np.float32,0x3c9c4900,0x3f81b431,2
+np.float32,0x7f0efae3,0x7f800000,2
+np.float32,0xbf1b3ee6,0x3f282567,2
+np.float32,0x3ee858ac,0x3faf5083,2
+np.float32,0x3f0e6a39,0x3fbc3965,2
+np.float32,0x7f0c06d8,0x7f800000,2
+np.float32,0x801dd236,0x3f800000,2
+np.float32,0x564245,0x3f800000,2
+np.float32,0x7e99d3ad,0x7f800000,2
+np.float32,0xff3b0164,0x0,2
+np.float32,0x3f386f18,0x3fd2e785,2
+np.float32,0x7f603c39,0x7f800000,2
+np.float32,0x3cbd9b00,0x3f8211f0,2
+np.float32,0x2178e2,0x3f800000,2
+np.float32,0x5db226,0x3f800000,2
+np.float32,0xfec78d62,0x0,2
+np.float32,0x7f40bc1e,0x7f800000,2
+np.float32,0x80325064,0x3f800000,2
+np.float32,0x3f6068dc,0x3feb0377,2
+np.float32,0xfe8b95c6,0x0,2
+np.float32,0xbe496894,0x3f5f5f87,2
+np.float32,0xbf18722a,0x3f296cf4,2
+np.float32,0x332d0e,0x3f800000,2
+np.float32,0x3f6329dc,0x3fecc5c0,2
+np.float32,0x807d1802,0x3f800000,2
+np.float32,0x3e8afcee,0x3f9a7ff1,2
+np.float32,0x26a0a7,0x3f800000,2
+np.float32,0x7f13085d,0x7f800000,2
+np.float32,0x68d547,0x3f800000,2
+np.float32,0x7e9b04ae,0x7f800000,2
+np.float32,0x3f3ecdfe,0x3fd692ea,2
+np.float32,0x805256f4,0x3f800000,2
+np.float32,0x3f312dc8,0x3fcecd42,2
+np.float32,0x23ca15,0x3f800000,2
+np.float32,0x3f53c455,0x3fe31ad6,2
+np.float32,0xbf21186c,0x3f2580fd,2
+np.float32,0x803b9bb1,0x3f800000,2
+np.float32,0xff6ae1fc,0x0,2
+np.float32,0x2103cf,0x3f800000,2
+np.float32,0xbedcec6c,0x3f3dd29d,2
+np.float32,0x7f520afa,0x7f800000,2
+np.float32,0x7e8b44f2,0x7f800000,2
+np.float32,0xfef7f6ce,0x0,2
+np.float32,0xbd5e7c30,0x3f768a6f,2
+np.float32,0xfeb36848,0x0,2
+np.float32,0xff49effb,0x0,2
+np.float32,0xbec207c0,0x3f44dc74,2
+np.float32,0x3e91147f,0x3f9bc77f,2
+np.float32,0xfe784cd4,0x0,2
+np.float32,0xfd1a7250,0x0,2
+np.float32,0xff3b3f48,0x0,2
+np.float32,0x3f685db5,0x3ff0219f,2
+np.float32,0x3f370976,0x3fd21bae,2
+np.float32,0xfed4cc20,0x0,2
+np.float32,0xbf41e337,0x3f17714a,2
+np.float32,0xbf4e8638,0x3f12593a,2
+np.float32,0x3edaf0f1,0x3fac295e,2
+np.float32,0x803cbb4f,0x3f800000,2
+np.float32,0x7f492043,0x7f800000,2
+np.float32,0x2cabcf,0x3f800000,2
+np.float32,0x17f8ac,0x3f800000,2
+np.float32,0x3e846478,0x3f99205a,2
+np.float32,0x76948f,0x3f800000,2
+np.float32,0x1,0x3f800000,2
+np.float32,0x7ea6419e,0x7f800000,2
+np.float32,0xa5315,0x3f800000,2
+np.float32,0xff3a8e32,0x0,2
+np.float32,0xbe5714e8,0x3f5d50b7,2
+np.float32,0xfeadf960,0x0,2
+np.float32,0x3ebbd1a8,0x3fa50efc,2
+np.float32,0x7f31dce7,0x7f800000,2
+np.float32,0x80314999,0x3f800000,2
+np.float32,0x8017f41b,0x3f800000,2
+np.float32,0x7ed6d051,0x7f800000,2
+np.float32,0x7f525688,0x7f800000,2
+np.float32,0x7f7fffff,0x7f800000,2
+np.float32,0x3e8b0461,0x3f9a8180,2
+np.float32,0x3d9fe46e,0x3f871e1f,2
+np.float32,0x5e6d8f,0x3f800000,2
+np.float32,0xbf09ae55,0x3f305608,2
+np.float32,0xfe7028c4,0x0,2
+np.float32,0x7f3ade56,0x7f800000,2
+np.float32,0xff4c9ef9,0x0,2
+np.float32,0x7e3199cf,0x7f800000,2
+np.float32,0x8048652f,0x3f800000,2
+np.float32,0x805e1237,0x3f800000,2
+np.float32,0x189ed8,0x3f800000,2
+np.float32,0xbea7c094,0x3f4bfd98,2
+np.float32,0xbf2f109c,0x3f1f5c5c,2
+np.float32,0xbf0e7f4c,0x3f2e0d2c,2
+np.float32,0x8005981f,0x3f800000,2
+np.float32,0xbf762005,0x3f0377f3,2
+np.float32,0xbf0f60ab,0x3f2da317,2
+np.float32,0xbf4aa3e7,0x3f13e54e,2
+np.float32,0xbf348fd2,0x3f1d01aa,2
+np.float32,0x3e530b50,0x3f93a7fb,2
+np.float32,0xbf0b05a4,0x3f2fb26a,2
+np.float32,0x3eea416c,0x3fafc4aa,2
+np.float32,0x805ad04d,0x3f800000,2
+np.float32,0xbf6328d8,0x3f0a655e,2
+np.float32,0x3f7347b9,0x3ff75558,2
+np.float32,0xfda3ca68,0x0,2
+np.float32,0x80497d21,0x3f800000,2
+np.float32,0x3e740452,0x3f96fd22,2
+np.float32,0x3e528e57,0x3f939b7e,2
+np.float32,0x3e9e19fa,0x3f9e8cbd,2
+np.float32,0x8078060b,0x3f800000,2
+np.float32,0x3f3fea7a,0x3fd73872,2
+np.float32,0xfcfa30a0,0x0,2
+np.float32,0x7f4eb4bf,0x7f800000,2
+np.float32,0x3f712618,0x3ff5e900,2
+np.float32,0xbf668f0e,0x3f0920c6,2
+np.float32,0x3f3001e9,0x3fce259d,2
+np.float32,0xbe9b6fac,0x3f4f6b9c,2
+np.float32,0xbf61fcf3,0x3f0ad5ec,2
+np.float32,0xff08a55c,0x0,2
+np.float32,0x3e805014,0x3f984872,2
+np.float32,0x6ce04c,0x3f800000,2
+np.float32,0x7f7cbc07,0x7f800000,2
+np.float32,0x3c87dc,0x3f800000,2
+np.float32,0x3f2ee498,0x3fcd869a,2
+np.float32,0x4b1116,0x3f800000,2
+np.float32,0x3d382d06,0x3f840d5f,2
+np.float32,0xff7de21e,0x0,2
+np.float32,0x3f2f1d6d,0x3fcda63c,2
+np.float32,0xbf1c1618,0x3f27c38a,2
+np.float32,0xff4264b1,0x0,2
+np.float32,0x8026e5e7,0x3f800000,2
+np.float32,0xbe6fa180,0x3f59ab02,2
+np.float32,0xbe923c02,0x3f52053b,2
+np.float32,0xff3aa453,0x0,2
+np.float32,0x3f77a7ac,0x3ffa47d0,2
+np.float32,0xbed15f36,0x3f40d08a,2
+np.float32,0xa62d,0x3f800000,2
+np.float32,0xbf342038,0x3f1d3123,2
+np.float32,0x7f2f7f80,0x7f800000,2
+np.float32,0x7f2b6fc1,0x7f800000,2
+np.float32,0xff323540,0x0,2
+np.float32,0x3f1a2b6e,0x3fc24faa,2
+np.float32,0x800cc1d2,0x3f800000,2
+np.float32,0xff38fa01,0x0,2
+np.float32,0x80800000,0x3f800000,2
+np.float32,0xbf3d22e0,0x3f196745,2
+np.float32,0x7f40fd62,0x7f800000,2
+np.float32,0x7e1785c7,0x7f800000,2
+np.float32,0x807408c4,0x3f800000,2
+np.float32,0xbf300192,0x3f1ef485,2
+np.float32,0x351e3d,0x3f800000,2
+np.float32,0x7f5ab736,0x7f800000,2
+np.float32,0x2f1696,0x3f800000,2
+np.float32,0x806ac5d7,0x3f800000,2
+np.float32,0x42ec59,0x3f800000,2
+np.float32,0x7f79f52d,0x7f800000,2
+np.float32,0x44ad28,0x3f800000,2
+np.float32,0xbf49dc9c,0x3f143532,2
+np.float32,0x3f6c1f1f,0x3ff295e7,2
+np.float32,0x1589b3,0x3f800000,2
+np.float32,0x3f49b44e,0x3fdd0031,2
+np.float32,0x7f5942c9,0x7f800000,2
+np.float32,0x3f2dab28,0x3fccd877,2
+np.float32,0xff7fffff,0x0,2
+np.float32,0x80578eb2,0x3f800000,2
+np.float32,0x3f39ba67,0x3fd3a50b,2
+np.float32,0x8020340d,0x3f800000,2
+np.float32,0xbf6025b2,0x3f0b8783,2
+np.float32,0x8015ccfe,0x3f800000,2
+np.float32,0x3f6b9762,0x3ff23cd0,2
+np.float32,0xfeeb0c86,0x0,2
+np.float32,0x802779bc,0x3f800000,2
+np.float32,0xbf32bf64,0x3f1dc796,2
+np.float32,0xbf577eb6,0x3f0ed631,2
+np.float32,0x0,0x3f800000,2
+np.float32,0xfe99de6c,0x0,2
+np.float32,0x7a4e53,0x3f800000,2
+np.float32,0x1a15d3,0x3f800000,2
+np.float32,0x8035fe16,0x3f800000,2
+np.float32,0x3e845784,0x3f991dab,2
+np.float32,0x43d688,0x3f800000,2
+np.float32,0xbd447cc0,0x3f77a0b7,2
+np.float32,0x3f83fa,0x3f800000,2
+np.float32,0x3f141df2,0x3fbf2719,2
+np.float32,0x805c586a,0x3f800000,2
+np.float32,0x14c47e,0x3f800000,2
+np.float32,0x3d3bed00,0x3f8422d4,2
+np.float32,0x7f6f4ecd,0x7f800000,2
+np.float32,0x3f0a5e5a,0x3fba2c5c,2
+np.float32,0x523ecf,0x3f800000,2
+np.float32,0xbef4a6e8,0x3f37d262,2
+np.float32,0xff54eb58,0x0,2
+np.float32,0xff3fc875,0x0,2
+np.float32,0x8067c392,0x3f800000,2
+np.float32,0xfedae910,0x0,2
+np.float32,0x80595979,0x3f800000,2
+np.float32,0x3ee87d1d,0x3faf5929,2
+np.float32,0x7f5bad33,0x7f800000,2
+np.float32,0xbf45b868,0x3f15e109,2
+np.float32,0x3ef2277d,0x3fb1a868,2
+np.float32,0x3ca5a950,0x3f81ce8c,2
+np.float32,0x3e70f4e6,0x3f96ad25,2
+np.float32,0xfe3515bc,0x0,2
+np.float32,0xfe4af088,0x0,2
+np.float32,0xff3c78b2,0x0,2
+np.float32,0x7f50f51a,0x7f800000,2
+np.float32,0x3e3a232a,0x3f913009,2
+np.float32,0x7dfec6ff,0x7f800000,2
+np.float32,0x3e1bbaec,0x3f8e3ad6,2
+np.float32,0xbd658fa0,0x3f763ee7,2
+np.float32,0xfe958684,0x0,2
+np.float32,0x503670,0x3f800000,2
+np.float32,0x3f800000,0x40000000,2
+np.float32,0x1bbec6,0x3f800000,2
+np.float32,0xbea7bb7c,0x3f4bff00,2
+np.float32,0xff3a24a2,0x0,2
+np.float32,0xbf416240,0x3f17a635,2
+np.float32,0xbf800000,0x3f000000,2
+np.float32,0xff0c965c,0x0,2
+np.float32,0x80000000,0x3f800000,2
+np.float32,0xbec2c69a,0x3f44a99e,2
+np.float32,0x5b68d4,0x3f800000,2
+np.float32,0xb9a93000,0x3f7ff158,2
+np.float32,0x3d5a0dd8,0x3f84cfbc,2
+np.float32,0xbeaf7a28,0x3f49de4e,2
+np.float32,0x3ee83555,0x3faf4820,2
+np.float32,0xfd320330,0x0,2
+np.float32,0xe1af2,0x3f800000,2
+np.float32,0x7cf28caf,0x7f800000,2
+np.float32,0x80781009,0x3f800000,2
+np.float32,0xbf1e0baf,0x3f26e04d,2
+np.float32,0x7edb05b1,0x7f800000,2
+np.float32,0x3de004,0x3f800000,2
+np.float32,0xff436af6,0x0,2
+np.float32,0x802a9408,0x3f800000,2
+np.float32,0x7ed82205,0x7f800000,2
+np.float32,0x3e3f8212,0x3f91b767,2
+np.float32,0x16a2b2,0x3f800000,2
+np.float32,0xff1e5af3,0x0,2
+np.float32,0xbf1c860c,0x3f2790b7,2
+np.float32,0x3f3bc5da,0x3fd4d1d6,2
+np.float32,0x7f5f7085,0x7f800000,2
+np.float32,0x7f68e409,0x7f800000,2
+np.float32,0x7f4b3388,0x7f800000,2
+np.float32,0x7ecaf440,0x7f800000,2
+np.float32,0x80078785,0x3f800000,2
+np.float32,0x3ebd800d,0x3fa56f45,2
+np.float32,0xbe39a140,0x3f61c58e,2
+np.float32,0x803b587e,0x3f800000,2
+np.float32,0xbeaaa418,0x3f4b31c4,2
+np.float32,0xff7e2b9f,0x0,2
+np.float32,0xff5180a3,0x0,2
+np.float32,0xbf291394,0x3f21f73c,2
+np.float32,0x7f7b9698,0x7f800000,2
+np.float32,0x4218da,0x3f800000,2
+np.float32,0x7f135262,0x7f800000,2
+np.float32,0x804c10e8,0x3f800000,2
+np.float32,0xbf1c2a54,0x3f27ba5a,2
+np.float32,0x7f41fd32,0x7f800000,2
+np.float32,0x3e5cc464,0x3f94a195,2
+np.float32,0xff7a2fa7,0x0,2
+np.float32,0x3e05dc30,0x3f8c23c9,2
+np.float32,0x7f206d99,0x7f800000,2
+np.float32,0xbe9ae520,0x3f4f9287,2
+np.float32,0xfe4f4d58,0x0,2
+np.float32,0xbf44db42,0x3f163ae3,2
+np.float32,0x3f65ac48,0x3fee6300,2
+np.float32,0x3ebfaf36,0x3fa5ecb0,2
+np.float32,0x3f466719,0x3fdb08b0,2
+np.float32,0x80000001,0x3f800000,2
+np.float32,0xff4b3c7b,0x0,2
+np.float32,0x3df44374,0x3f8b0819,2
+np.float32,0xfea4b540,0x0,2
+np.float32,0x7f358e3d,0x7f800000,2
+np.float32,0x801f5e63,0x3f800000,2
+np.float32,0x804ae77e,0x3f800000,2
+np.float32,0xdbb5,0x3f800000,2
+np.float32,0x7f0a7e3b,0x7f800000,2
+np.float32,0xbe4152e4,0x3f609953,2
+np.float32,0x4b9579,0x3f800000,2
+np.float32,0x3ece0bd4,0x3fa92ea5,2
+np.float32,0x7e499d9a,0x7f800000,2
+np.float32,0x80637d8a,0x3f800000,2
+np.float32,0x3e50a425,0x3f936a8b,2
+np.float32,0xbf0e8cb0,0x3f2e06dd,2
+np.float32,0x802763e2,0x3f800000,2
+np.float32,0xff73041b,0x0,2
+np.float32,0xfea466da,0x0,2
+np.float32,0x80064c73,0x3f800000,2
+np.float32,0xbef29222,0x3f385728,2
+np.float32,0x8029c215,0x3f800000,2
+np.float32,0xbd3994e0,0x3f7815d1,2
+np.float32,0xbe6ac9e4,0x3f5a61f3,2
+np.float32,0x804b58b0,0x3f800000,2
+np.float32,0xbdb83be0,0x3f70865c,2
+np.float32,0x7ee18da2,0x7f800000,2
+np.float32,0xfd4ca010,0x0,2
+np.float32,0x807c668b,0x3f800000,2
+np.float32,0xbd40ed90,0x3f77c6e9,2
+np.float32,0x7efc6881,0x7f800000,2
+np.float32,0xfe633bfc,0x0,2
+np.float32,0x803ce363,0x3f800000,2
+np.float32,0x7ecba81e,0x7f800000,2
+np.float32,0xfdcb2378,0x0,2
+np.float32,0xbebc5524,0x3f4662b2,2
+np.float32,0xfaa30000,0x0,2
+np.float32,0x805d451b,0x3f800000,2
+np.float32,0xbee85600,0x3f3ae996,2
+np.float32,0xfefb0a54,0x0,2
+np.float32,0xbdfc6690,0x3f6b0a08,2
+np.float32,0x58a57,0x3f800000,2
+np.float32,0x3b41b7,0x3f800000,2
+np.float32,0x7c99812d,0x7f800000,2
+np.float32,0xbd3ae740,0x3f78079d,2
+np.float32,0xbf4a48a7,0x3f1409dd,2
+np.float32,0xfdeaad58,0x0,2
+np.float32,0xbe9aa65a,0x3f4fa42c,2
+np.float32,0x3f79d78c,0x3ffbc458,2
+np.float32,0x805e7389,0x3f800000,2
+np.float32,0x7ebb3612,0x7f800000,2
+np.float32,0x2e27dc,0x3f800000,2
+np.float32,0x80726dec,0x3f800000,2
+np.float32,0xfe8fb738,0x0,2
+np.float32,0xff1ff3bd,0x0,2
+np.float32,0x7f5264a2,0x7f800000,2
+np.float32,0x3f5a6893,0x3fe739ca,2
+np.float32,0xbec4029c,0x3f44558d,2
+np.float32,0xbef65cfa,0x3f37657e,2
+np.float32,0x63aba1,0x3f800000,2
+np.float32,0xfbb6e200,0x0,2
+np.float32,0xbf3466fc,0x3f1d1307,2
+np.float32,0x3f258844,0x3fc861d7,2
+np.float32,0xbf5f29a7,0x3f0be6dc,2
+np.float32,0x802b51cd,0x3f800000,2
+np.float32,0xbe9094dc,0x3f527dae,2
+np.float32,0xfec2e68c,0x0,2
+np.float32,0x807b38bd,0x3f800000,2
+np.float32,0xbf594662,0x3f0e2663,2
+np.float32,0x7cbcf747,0x7f800000,2
+np.float32,0xbe4b88f0,0x3f5f0d47,2
+np.float32,0x3c53c4,0x3f800000,2
+np.float32,0xbe883562,0x3f54e3f7,2
+np.float32,0xbf1efaf0,0x3f267456,2
+np.float32,0x3e22cd3e,0x3f8ee98b,2
+np.float32,0x80434875,0x3f800000,2
+np.float32,0xbf000b44,0x3f34ff6e,2
+np.float32,0x7f311c3a,0x7f800000,2
+np.float32,0x802f7f3f,0x3f800000,2
+np.float32,0x805155fe,0x3f800000,2
+np.float32,0x7f5d7485,0x7f800000,2
+np.float32,0x80119197,0x3f800000,2
+np.float32,0x3f445b8b,0x3fd9d30d,2
+np.float32,0xbf638eb3,0x3f0a3f38,2
+np.float32,0x402410,0x3f800000,2
+np.float32,0xbc578a40,0x3f7dad1d,2
+np.float32,0xbeecbf8a,0x3f39cc9e,2
+np.float32,0x7f2935a4,0x7f800000,2
+np.float32,0x3f570fea,0x3fe523e2,2
+np.float32,0xbf06bffa,0x3f31bdb6,2
+np.float32,0xbf2afdfd,0x3f2120ba,2
+np.float32,0x7f76f7ab,0x7f800000,2
+np.float32,0xfee2d1e8,0x0,2
+np.float32,0x800b026d,0x3f800000,2
+np.float32,0xff0eda75,0x0,2
+np.float32,0x3d4c,0x3f800000,2
+np.float32,0xbed538a2,0x3f3fcffb,2
+np.float32,0x3f73f4f9,0x3ff7c979,2
+np.float32,0x2aa9fc,0x3f800000,2
+np.float32,0x806a45b3,0x3f800000,2
+np.float32,0xff770d35,0x0,2
+np.float32,0x7e999be3,0x7f800000,2
+np.float32,0x80741128,0x3f800000,2
+np.float32,0xff6aac34,0x0,2
+np.float32,0x470f74,0x3f800000,2
+np.float32,0xff423b7b,0x0,2
+np.float32,0x17dfdd,0x3f800000,2
+np.float32,0x7f029e12,0x7f800000,2
+np.float32,0x803fcb9d,0x3f800000,2
+np.float32,0x3f3dc3,0x3f800000,2
+np.float32,0x7f3a27bc,0x7f800000,2
+np.float32,0x3e473108,0x3f9279ec,2
+np.float32,0x7f4add5d,0x7f800000,2
+np.float32,0xfd9736e0,0x0,2
+np.float32,0x805f1df2,0x3f800000,2
+np.float32,0x6c49c1,0x3f800000,2
+np.float32,0x7ec733c7,0x7f800000,2
+np.float32,0x804c1abf,0x3f800000,2
+np.float32,0x3de2e887,0x3f8a37a5,2
+np.float32,0x3f51630a,0x3fe1a561,2
+np.float32,0x3de686a8,0x3f8a62ff,2
+np.float32,0xbedb3538,0x3f3e439c,2
+np.float32,0xbf3aa892,0x3f1a6f9e,2
+np.float32,0x7ee5fb32,0x7f800000,2
+np.float32,0x7e916c9b,0x7f800000,2
+np.float32,0x3f033f1c,0x3fb69e19,2
+np.float32,0x25324b,0x3f800000,2
+np.float32,0x3f348d1d,0x3fd0b2e2,2
+np.float32,0x3f5797e8,0x3fe57851,2
+np.float32,0xbf69c316,0x3f07f1a0,2
+np.float32,0xbe8b7fb0,0x3f53f1bf,2
+np.float32,0xbdbbc190,0x3f703d00,2
+np.float32,0xff6c4fc0,0x0,2
+np.float32,0x7f29fcbe,0x7f800000,2
+np.float32,0x3f678d19,0x3fef9a23,2
+np.float32,0x73d140,0x3f800000,2
+np.float32,0x3e25bdd2,0x3f8f326b,2
+np.float32,0xbeb775ec,0x3f47b2c6,2
+np.float32,0xff451c4d,0x0,2
+np.float32,0x8072c466,0x3f800000,2
+np.float32,0x3f65e836,0x3fee89b2,2
+np.float32,0x52ca7a,0x3f800000,2
+np.float32,0x62cfed,0x3f800000,2
+np.float32,0xbf583dd0,0x3f0e8c5c,2
+np.float32,0xbf683842,0x3f088342,2
+np.float32,0x3f1a7828,0x3fc2780c,2
+np.float32,0x800ea979,0x3f800000,2
+np.float32,0xbeb9133c,0x3f474328,2
+np.float32,0x3ef09fc7,0x3fb14a4b,2
+np.float32,0x7ebbcb75,0x7f800000,2
+np.float32,0xff316c0e,0x0,2
+np.float32,0x805b84e3,0x3f800000,2
+np.float32,0x3d6a55e0,0x3f852d8a,2
+np.float32,0x3e755788,0x3f971fd1,2
+np.float32,0x3ee7aacb,0x3faf2743,2
+np.float32,0x7f714039,0x7f800000,2
+np.float32,0xff70bad8,0x0,2
+np.float32,0xbe0b74c8,0x3f68f08c,2
+np.float32,0xbf6cb170,0x3f06de86,2
+np.float32,0x7ec1fbff,0x7f800000,2
+np.float32,0x8014b1f6,0x3f800000,2
+np.float32,0xfe8b45fe,0x0,2
+np.float32,0x6e2220,0x3f800000,2
+np.float32,0x3ed1777d,0x3fa9f7ab,2
+np.float32,0xff48e467,0x0,2
+np.float32,0xff76c5aa,0x0,2
+np.float32,0x3e9bd330,0x3f9e0fd7,2
+np.float32,0x3f17de4f,0x3fc11aae,2
+np.float32,0x7eeaa2fd,0x7f800000,2
+np.float32,0xbf572746,0x3f0ef806,2
+np.float32,0x7e235554,0x7f800000,2
+np.float32,0xfe24fc1c,0x0,2
+np.float32,0x7daf71ad,0x7f800000,2
+np.float32,0x800d4a6b,0x3f800000,2
+np.float32,0xbf6fc31d,0x3f05c0ce,2
+np.float32,0x1c4d93,0x3f800000,2
+np.float32,0x7ee9200c,0x7f800000,2
+np.float32,0x3f54b4da,0x3fe3aeec,2
+np.float32,0x2b37b1,0x3f800000,2
+np.float32,0x3f7468bd,0x3ff81731,2
+np.float32,0x3f2850ea,0x3fc9e5f4,2
+np.float32,0xbe0d47ac,0x3f68a6f9,2
+np.float32,0x314877,0x3f800000,2
+np.float32,0x802700c3,0x3f800000,2
+np.float32,0x7e2c915f,0x7f800000,2
+np.float32,0x800d0059,0x3f800000,2
+np.float32,0x3f7f3c25,0x3fff7862,2
+np.float32,0xff735d31,0x0,2
+np.float32,0xff7e339e,0x0,2
+np.float32,0xbef96cf0,0x3f36a340,2
+np.float32,0x3db6ea21,0x3f882cb2,2
+np.float32,0x67cb3d,0x3f800000,2
+np.float32,0x801f349d,0x3f800000,2
+np.float32,0x3f1390ec,0x3fbede29,2
+np.float32,0x7f13644a,0x7f800000,2
+np.float32,0x804a369b,0x3f800000,2
+np.float32,0x80262666,0x3f800000,2
+np.float32,0x7e850fbc,0x7f800000,2
+np.float32,0x18b002,0x3f800000,2
+np.float32,0x8051f1ed,0x3f800000,2
+np.float32,0x3eba48f6,0x3fa4b753,2
+np.float32,0xbf3f4130,0x3f1886a9,2
+np.float32,0xbedac006,0x3f3e61cf,2
+np.float32,0xbf097c70,0x3f306ddc,2
+np.float32,0x4aba6d,0x3f800000,2
+np.float32,0x580078,0x3f800000,2
+np.float32,0x3f64d82e,0x3fedda40,2
+np.float32,0x7f781fd6,0x7f800000,2
+np.float32,0x6aff3d,0x3f800000,2
+np.float32,0xff25e074,0x0,2
+np.float32,0x7ea9ec89,0x7f800000,2
+np.float32,0xbf63b816,0x3f0a2fbb,2
+np.float32,0x133f07,0x3f800000,2
+np.float32,0xff800000,0x0,2
+np.float32,0x8013dde7,0x3f800000,2
+np.float32,0xff770b95,0x0,2
+np.float32,0x806154e8,0x3f800000,2
+np.float32,0x3f1e7bce,0x3fc4981a,2
+np.float32,0xff262c78,0x0,2
+np.float32,0x3f59a652,0x3fe6c04c,2
+np.float32,0x7f220166,0x7f800000,2
+np.float32,0x7eb24939,0x7f800000,2
+np.float32,0xbed58bb0,0x3f3fba6a,2
+np.float32,0x3c2ad000,0x3f80eda7,2
+np.float32,0x2adb2e,0x3f800000,2
+np.float32,0xfe8b213e,0x0,2
+np.float32,0xbf2e0c1e,0x3f1fccea,2
+np.float32,0x7e1716be,0x7f800000,2
+np.float32,0x80184e73,0x3f800000,2
+np.float32,0xbf254743,0x3f23a3d5,2
+np.float32,0x8063a722,0x3f800000,2
+np.float32,0xbe50adf0,0x3f5e46c7,2
+np.float32,0x3f614158,0x3feb8d60,2
+np.float32,0x8014bbc8,0x3f800000,2
+np.float32,0x283bc7,0x3f800000,2
+np.float32,0x3ffb5c,0x3f800000,2
+np.float32,0xfe8de6bc,0x0,2
+np.float32,0xbea6e086,0x3f4c3b82,2
+np.float32,0xfee64b92,0x0,2
+np.float32,0x506c1a,0x3f800000,2
+np.float32,0xff342af8,0x0,2
+np.float32,0x6b6f4c,0x3f800000,2
+np.float32,0xfeb42b1e,0x0,2
+np.float32,0x3e49384a,0x3f92ad71,2
+np.float32,0x152d08,0x3f800000,2
+np.float32,0x804c8f09,0x3f800000,2
+np.float32,0xff5e927d,0x0,2
+np.float32,0x6374da,0x3f800000,2
+np.float32,0x3f48f011,0x3fdc8ae4,2
+np.float32,0xbf446a30,0x3f1668e8,2
+np.float32,0x3ee77073,0x3faf196e,2
+np.float32,0xff4caa40,0x0,2
+np.float32,0x7efc9363,0x7f800000,2
+np.float32,0xbf706dcc,0x3f05830d,2
+np.float32,0xfe29c7e8,0x0,2
+np.float32,0x803cfe58,0x3f800000,2
+np.float32,0x3ec34c7c,0x3fa6bd0a,2
+np.float32,0x3eb85b62,0x3fa44968,2
+np.float32,0xfda1b9d8,0x0,2
+np.float32,0x802932cd,0x3f800000,2
+np.float32,0xbf5cde78,0x3f0cc5fa,2
+np.float32,0x3f31bf44,0x3fcf1ec8,2
+np.float32,0x803a0882,0x3f800000,2
+np.float32,0x800000,0x3f800000,2
+np.float32,0x3f54110e,0x3fe34a08,2
+np.float32,0x80645ea9,0x3f800000,2
+np.float32,0xbd8c1070,0x3f7425c3,2
+np.float32,0x801a006a,0x3f800000,2
+np.float32,0x7f5d161e,0x7f800000,2
+np.float32,0x805b5df3,0x3f800000,2
+np.float32,0xbf71a7c0,0x3f0511be,2
+np.float32,0xbe9a55c0,0x3f4fbad6,2
+np.float64,0xde7e2fd9bcfc6,0x3ff0000000000000,2
+np.float64,0xbfd8cd88eb319b12,0x3fe876349efbfa2b,2
+np.float64,0x3fe4fa13ace9f428,0x3ff933fbb117d196,2
+np.float64,0x475b3d048eb68,0x3ff0000000000000,2
+np.float64,0x7fef39ed07be73d9,0x7ff0000000000000,2
+np.float64,0x80026b84d904d70a,0x3ff0000000000000,2
+np.float64,0xebd60627d7ac1,0x3ff0000000000000,2
+np.float64,0xbfd7cbefdbaf97e0,0x3fe8bad30f6cf8e1,2
+np.float64,0x7fc17c605a22f8c0,0x7ff0000000000000,2
+np.float64,0x8cdac05119b58,0x3ff0000000000000,2
+np.float64,0x3fc45cd60a28b9ac,0x3ff1dd8028ec3f41,2
+np.float64,0x7fef4fce137e9f9b,0x7ff0000000000000,2
+np.float64,0xe5a2b819cb457,0x3ff0000000000000,2
+np.float64,0xe3bcfd4dc77a0,0x3ff0000000000000,2
+np.float64,0x68f0b670d1e17,0x3ff0000000000000,2
+np.float64,0xae69a6455cd35,0x3ff0000000000000,2
+np.float64,0xffe7007a0c6e00f4,0x0,2
+np.float64,0x59fc57a8b3f8c,0x3ff0000000000000,2
+np.float64,0xbfeee429c0bdc854,0x3fe0638fa62bed9f,2
+np.float64,0x80030bb6e206176f,0x3ff0000000000000,2
+np.float64,0x8006967a36ad2cf5,0x3ff0000000000000,2
+np.float64,0x3fe128176a22502f,0x3ff73393301e5dc8,2
+np.float64,0x218de20c431bd,0x3ff0000000000000,2
+np.float64,0x3fe7dbc48aafb789,0x3ffad38989b5955c,2
+np.float64,0xffda1ef411343de8,0x0,2
+np.float64,0xc6b392838d673,0x3ff0000000000000,2
+np.float64,0x7fe6d080c1ada101,0x7ff0000000000000,2
+np.float64,0xbfed36dd67fa6dbb,0x3fe0fec342c4ee89,2
+np.float64,0x3fee2bb6a3fc576e,0x3ffec1c149f1f092,2
+np.float64,0xbfd1f785eb23ef0c,0x3fea576eb01233cb,2
+np.float64,0x7fdad29a1f35a533,0x7ff0000000000000,2
+np.float64,0xffe8928c4fb12518,0x0,2
+np.float64,0x7fb123160022462b,0x7ff0000000000000,2
+np.float64,0x8007ab56cfaf56ae,0x3ff0000000000000,2
+np.float64,0x7fda342d6634685a,0x7ff0000000000000,2
+np.float64,0xbfe3b7e42c676fc8,0x3fe4e05cf8685b8a,2
+np.float64,0xffa708be7c2e1180,0x0,2
+np.float64,0xbfe8ffbece31ff7e,0x3fe29eb84077a34a,2
+np.float64,0xbf91002008220040,0x3fefa245058f05cb,2
+np.float64,0x8000281f0ee0503f,0x3ff0000000000000,2
+np.float64,0x8005617adc2ac2f6,0x3ff0000000000000,2
+np.float64,0x7fa84fec60309fd8,0x7ff0000000000000,2
+np.float64,0x8d00c0231a018,0x3ff0000000000000,2
+np.float64,0xbfdfe52ca63fca5a,0x3fe6a7324cc00d57,2
+np.float64,0x7fcc81073d39020d,0x7ff0000000000000,2
+np.float64,0x800134ff5a6269ff,0x3ff0000000000000,2
+np.float64,0xffc7fff98d2ffff4,0x0,2
+np.float64,0x8000925ce50124bb,0x3ff0000000000000,2
+np.float64,0xffe2530c66a4a618,0x0,2
+np.float64,0x7fc99070673320e0,0x7ff0000000000000,2
+np.float64,0xbfddd5c1f13bab84,0x3fe72a0c80f8df39,2
+np.float64,0x3fe1c220fee38442,0x3ff7817ec66aa55b,2
+np.float64,0x3fb9a1e1043343c2,0x3ff1265e575e6404,2
+np.float64,0xffef72e0833ee5c0,0x0,2
+np.float64,0x3fe710c0416e2181,0x3ffa5e93588aaa69,2
+np.float64,0xbfd8d23cbab1a47a,0x3fe874f5b9d99885,2
+np.float64,0x7fe9628ebd72c51c,0x7ff0000000000000,2
+np.float64,0xdd5fa611babf5,0x3ff0000000000000,2
+np.float64,0x8002bafac86575f6,0x3ff0000000000000,2
+np.float64,0x68acea44d159e,0x3ff0000000000000,2
+np.float64,0xffd776695eaeecd2,0x0,2
+np.float64,0x80059b59bb4b36b4,0x3ff0000000000000,2
+np.float64,0xbdcdd2af7b9bb,0x3ff0000000000000,2
+np.float64,0x8002b432ee856867,0x3ff0000000000000,2
+np.float64,0xcbc72f09978e6,0x3ff0000000000000,2
+np.float64,0xbfee8f4bf6fd1e98,0x3fe081cc0318b170,2
+np.float64,0xffc6e2892d2dc514,0x0,2
+np.float64,0x7feb682e4db6d05c,0x7ff0000000000000,2
+np.float64,0x8004b70a04296e15,0x3ff0000000000000,2
+np.float64,0x42408a4284812,0x3ff0000000000000,2
+np.float64,0xbfe9b8b197f37163,0x3fe254b4c003ce0a,2
+np.float64,0x3fcaadf5f5355bec,0x3ff27ca7876a8d20,2
+np.float64,0xfff0000000000000,0x0,2
+np.float64,0x7fea8376d33506ed,0x7ff0000000000000,2
+np.float64,0xffef73c2d63ee785,0x0,2
+np.float64,0xffe68b2bae2d1657,0x0,2
+np.float64,0x3fd8339cb2306739,0x3ff4cb774d616f90,2
+np.float64,0xbfc6d1db4d2da3b8,0x3fec47bb873a309c,2
+np.float64,0x7fe858016230b002,0x7ff0000000000000,2
+np.float64,0x7fe74cb99d2e9972,0x7ff0000000000000,2
+np.float64,0xffec2e96dc385d2d,0x0,2
+np.float64,0xb762a9876ec55,0x3ff0000000000000,2
+np.float64,0x3feca230c5794462,0x3ffdbfe62a572f52,2
+np.float64,0xbfb5ebad3a2bd758,0x3fee27eed86dcc39,2
+np.float64,0x471c705a8e38f,0x3ff0000000000000,2
+np.float64,0x7fc79bb5cf2f376b,0x7ff0000000000000,2
+np.float64,0xbfe53d6164ea7ac3,0x3fe4331b3beb73bd,2
+np.float64,0xbfe375a3f766eb48,0x3fe4fe67edb516e6,2
+np.float64,0x3fe1c7686ca38ed1,0x3ff7842f04770ba9,2
+np.float64,0x242e74dc485cf,0x3ff0000000000000,2
+np.float64,0x8009c06ab71380d6,0x3ff0000000000000,2
+np.float64,0x3fd08505efa10a0c,0x3ff3227b735b956d,2
+np.float64,0xffe3dfcecda7bf9d,0x0,2
+np.float64,0x8001f079bbc3e0f4,0x3ff0000000000000,2
+np.float64,0x3fddc706b6bb8e0c,0x3ff616d927987363,2
+np.float64,0xbfd151373ea2a26e,0x3fea870ba53ec126,2
+np.float64,0x7fe89533bfb12a66,0x7ff0000000000000,2
+np.float64,0xffed302cbc3a6059,0x0,2
+np.float64,0x3fd871cc28b0e398,0x3ff4d97d58c16ae2,2
+np.float64,0x7fbe9239683d2472,0x7ff0000000000000,2
+np.float64,0x848a445909149,0x3ff0000000000000,2
+np.float64,0x8007b104ce2f620a,0x3ff0000000000000,2
+np.float64,0x7fc2cd6259259ac4,0x7ff0000000000000,2
+np.float64,0xbfeadb640df5b6c8,0x3fe1e2b068de10af,2
+np.float64,0x800033b2f1a06767,0x3ff0000000000000,2
+np.float64,0x7fe54e5b7caa9cb6,0x7ff0000000000000,2
+np.float64,0x4f928f209f26,0x3ff0000000000000,2
+np.float64,0x8003c3dc6f2787ba,0x3ff0000000000000,2
+np.float64,0xbfd55a59daaab4b4,0x3fe9649d57b32b5d,2
+np.float64,0xffe3e2968d67c52c,0x0,2
+np.float64,0x80087434d550e86a,0x3ff0000000000000,2
+np.float64,0xffdde800083bd000,0x0,2
+np.float64,0xffe291f0542523e0,0x0,2
+np.float64,0xbfe1419bc3e28338,0x3fe6051d4f95a34a,2
+np.float64,0x3fd9d00ee1b3a01e,0x3ff5292bb8d5f753,2
+np.float64,0x3fdb720b60b6e417,0x3ff589d133625374,2
+np.float64,0xbfe3e21f0967c43e,0x3fe4cd4d02e3ef9a,2
+np.float64,0x7fd7e27f3dafc4fd,0x7ff0000000000000,2
+np.float64,0x3fd1cc2620a3984c,0x3ff366befbc38e3e,2
+np.float64,0x3fe78d05436f1a0b,0x3ffaa5ee4ea54b79,2
+np.float64,0x7e2acc84fc55a,0x3ff0000000000000,2
+np.float64,0x800ffb861c5ff70c,0x3ff0000000000000,2
+np.float64,0xffb2b0db1a2561b8,0x0,2
+np.float64,0xbfe80c2363701847,0x3fe301fdfe789576,2
+np.float64,0x7fe383c1c3e70783,0x7ff0000000000000,2
+np.float64,0xbfeefc02e6fdf806,0x3fe05b1a8528bf6c,2
+np.float64,0xbfe42c9268285925,0x3fe4abdc14793cb8,2
+np.float64,0x1,0x3ff0000000000000,2
+np.float64,0xa71c7ce94e390,0x3ff0000000000000,2
+np.float64,0x800ed4e6777da9cd,0x3ff0000000000000,2
+np.float64,0x3fde11b35d3c2367,0x3ff628bdc6dd1b78,2
+np.float64,0x3fef3964dbfe72ca,0x3fff777cae357608,2
+np.float64,0x3fefe369b7ffc6d4,0x3fffec357be508a3,2
+np.float64,0xbfdef1855f3de30a,0x3fe6e348c58e3fed,2
+np.float64,0x3fee0e2bc13c1c58,0x3ffeae1909c1b973,2
+np.float64,0xbfd31554ffa62aaa,0x3fea06628b2f048a,2
+np.float64,0x800dc56bcc7b8ad8,0x3ff0000000000000,2
+np.float64,0x7fbba01b8e374036,0x7ff0000000000000,2
+np.float64,0x7fd9737a92b2e6f4,0x7ff0000000000000,2
+np.float64,0x3feeae0fac3d5c1f,0x3fff1913705f1f07,2
+np.float64,0x3fdcc64fcdb98ca0,0x3ff5d9c3e5862972,2
+np.float64,0x3fdad9f83db5b3f0,0x3ff56674e81c1bd1,2
+np.float64,0x32b8797065710,0x3ff0000000000000,2
+np.float64,0x3fd20deae6241bd6,0x3ff37495bc057394,2
+np.float64,0x7fc899f0763133e0,0x7ff0000000000000,2
+np.float64,0x80045805fc08b00d,0x3ff0000000000000,2
+np.float64,0xbfcd8304cb3b0608,0x3feb4611f1eaa30c,2
+np.float64,0x3fd632a2fcac6544,0x3ff4592e1ea14fb0,2
+np.float64,0xffeeb066007d60cb,0x0,2
+np.float64,0x800bb12a42b76255,0x3ff0000000000000,2
+np.float64,0xbfe060fe1760c1fc,0x3fe6714640ab2574,2
+np.float64,0x80067ed737acfdaf,0x3ff0000000000000,2
+np.float64,0x3fd5ec3211abd864,0x3ff449adea82e73e,2
+np.float64,0x7fc4b2fdc22965fb,0x7ff0000000000000,2
+np.float64,0xff656afd002ad600,0x0,2
+np.float64,0xffeadefcdcb5bdf9,0x0,2
+np.float64,0x80052f18610a5e32,0x3ff0000000000000,2
+np.float64,0xbfd5b75c78ab6eb8,0x3fe94b15e0f39194,2
+np.float64,0xa4d3de2b49a7c,0x3ff0000000000000,2
+np.float64,0xbfe321c93de64392,0x3fe524ac7bbee401,2
+np.float64,0x3feb32f5def665ec,0x3ffcd6e4e5f9c271,2
+np.float64,0x7fe6b07e4ced60fc,0x7ff0000000000000,2
+np.float64,0x3fe013bb2de02776,0x3ff6aa4c32ab5ba4,2
+np.float64,0xbfeadd81d375bb04,0x3fe1e1de89b4aebf,2
+np.float64,0xffece7678079cece,0x0,2
+np.float64,0x3fe3d87b8467b0f8,0x3ff897cf22505e4d,2
+np.float64,0xffc4e3a05129c740,0x0,2
+np.float64,0xbfddee6b03bbdcd6,0x3fe723dd83ab49bd,2
+np.float64,0x3fcc4e2672389c4d,0x3ff2a680db769116,2
+np.float64,0x3fd8ed221ab1da44,0x3ff4f569aec8b850,2
+np.float64,0x80000a3538a0146b,0x3ff0000000000000,2
+np.float64,0x8004832eb109065e,0x3ff0000000000000,2
+np.float64,0xffdca83c60395078,0x0,2
+np.float64,0xffef551cda3eaa39,0x0,2
+np.float64,0x800fd95dd65fb2bc,0x3ff0000000000000,2
+np.float64,0x3ff0000000000000,0x4000000000000000,2
+np.float64,0xbfc06f5c4f20deb8,0x3fed466c17305ad8,2
+np.float64,0xbfeb01b5f476036c,0x3fe1d3de0f4211f4,2
+np.float64,0xbfdb2b9284365726,0x3fe7d7b02f790b05,2
+np.float64,0xff76ba83202d7500,0x0,2
+np.float64,0x3fd3f1c59ea7e38c,0x3ff3db96b3a0aaad,2
+np.float64,0x8b99ff6d17340,0x3ff0000000000000,2
+np.float64,0xbfeb383aa0f67075,0x3fe1bedcf2531c08,2
+np.float64,0x3fe321e35fa643c7,0x3ff83749a5d686ee,2
+np.float64,0xbfd863eb2130c7d6,0x3fe8923fcc39bac7,2
+np.float64,0x9e71dd333ce3c,0x3ff0000000000000,2
+np.float64,0x9542962b2a853,0x3ff0000000000000,2
+np.float64,0xba2c963b74593,0x3ff0000000000000,2
+np.float64,0x80019f4d0ca33e9b,0x3ff0000000000000,2
+np.float64,0xffde3e39a73c7c74,0x0,2
+np.float64,0x800258ae02c4b15d,0x3ff0000000000000,2
+np.float64,0xbfd99a535a3334a6,0x3fe8402f3a0662a5,2
+np.float64,0xe6c62143cd8c4,0x3ff0000000000000,2
+np.float64,0x7fbcc828f0399051,0x7ff0000000000000,2
+np.float64,0xbfe42e3596285c6b,0x3fe4ab2066d66071,2
+np.float64,0xffe2ee42d365dc85,0x0,2
+np.float64,0x3fe1f98abea3f315,0x3ff79dc68002a80b,2
+np.float64,0x7fd7225891ae44b0,0x7ff0000000000000,2
+np.float64,0x477177408ee30,0x3ff0000000000000,2
+np.float64,0xbfe16a7e2162d4fc,0x3fe5f1a5c745385d,2
+np.float64,0xbf98aaee283155e0,0x3fef785952e9c089,2
+np.float64,0x7fd7c14a8daf8294,0x7ff0000000000000,2
+np.float64,0xf7e7713defcee,0x3ff0000000000000,2
+np.float64,0x800769aa11aed355,0x3ff0000000000000,2
+np.float64,0xbfed30385e3a6071,0x3fe10135a3bd9ae6,2
+np.float64,0x3fe6dd7205edbae4,0x3ffa4155899efd70,2
+np.float64,0x800d705d26bae0ba,0x3ff0000000000000,2
+np.float64,0xa443ac1f48876,0x3ff0000000000000,2
+np.float64,0xbfec8cfec43919fe,0x3fe13dbf966e6633,2
+np.float64,0x7fd246efaa248dde,0x7ff0000000000000,2
+np.float64,0x800f2ad14afe55a3,0x3ff0000000000000,2
+np.float64,0x800487a894c90f52,0x3ff0000000000000,2
+np.float64,0x80014c4f19e2989f,0x3ff0000000000000,2
+np.float64,0x3fc11f265f223e4d,0x3ff18def05c971e5,2
+np.float64,0xffeb6d565776daac,0x0,2
+np.float64,0x7fd5ca5df8ab94bb,0x7ff0000000000000,2
+np.float64,0xbfe33de4fde67bca,0x3fe517d0e212cd1c,2
+np.float64,0xbfd1c738e5a38e72,0x3fea6539e9491693,2
+np.float64,0xbfec1d8c33b83b18,0x3fe16790fbca0c65,2
+np.float64,0xbfeecb464b7d968d,0x3fe06c67e2aefa55,2
+np.float64,0xbfd621dbf1ac43b8,0x3fe92dfa32d93846,2
+np.float64,0x80069a02860d3406,0x3ff0000000000000,2
+np.float64,0xbfe84f650e309eca,0x3fe2e661300f1975,2
+np.float64,0x7fc1d2cec523a59d,0x7ff0000000000000,2
+np.float64,0x3fd7706d79aee0db,0x3ff49fb033353dfe,2
+np.float64,0xffd94ba458329748,0x0,2
+np.float64,0x7fea98ba1a753173,0x7ff0000000000000,2
+np.float64,0xbfe756ba092ead74,0x3fe34d428d1857bc,2
+np.float64,0xffecfbd836b9f7b0,0x0,2
+np.float64,0x3fd211fbe5a423f8,0x3ff375711a3641e0,2
+np.float64,0x7fee24f7793c49ee,0x7ff0000000000000,2
+np.float64,0x7fe6a098886d4130,0x7ff0000000000000,2
+np.float64,0xbfd4ade909a95bd2,0x3fe99436524db1f4,2
+np.float64,0xbfeb704e6476e09d,0x3fe1a95be4a21bc6,2
+np.float64,0xffefc0f6627f81ec,0x0,2
+np.float64,0x7feff3f896ffe7f0,0x7ff0000000000000,2
+np.float64,0xa3f74edb47eea,0x3ff0000000000000,2
+np.float64,0xbfe0a551cf214aa4,0x3fe65027a7ff42e3,2
+np.float64,0x3fe164b23622c964,0x3ff7521c6225f51d,2
+np.float64,0x7fc258752324b0e9,0x7ff0000000000000,2
+np.float64,0x4739b3348e737,0x3ff0000000000000,2
+np.float64,0xb0392b1d60726,0x3ff0000000000000,2
+np.float64,0x7fe26f42e5e4de85,0x7ff0000000000000,2
+np.float64,0x8004601f87e8c040,0x3ff0000000000000,2
+np.float64,0xffe92ce37b3259c6,0x0,2
+np.float64,0x3fe620da3a6c41b4,0x3ff9d6ee3d005466,2
+np.float64,0x3fd850cfa2b0a1a0,0x3ff4d20bd249d411,2
+np.float64,0xffdcdfdfb5b9bfc0,0x0,2
+np.float64,0x800390297d672054,0x3ff0000000000000,2
+np.float64,0x3fde5864f6bcb0ca,0x3ff639bb9321f5ef,2
+np.float64,0x3fee484cec7c909a,0x3ffed4d2c6274219,2
+np.float64,0x7fe9b9a064b37340,0x7ff0000000000000,2
+np.float64,0xffe50028b8aa0051,0x0,2
+np.float64,0x3fe37774ade6eee9,0x3ff864558498a9a8,2
+np.float64,0x7fef83c724bf078d,0x7ff0000000000000,2
+np.float64,0xbfeb58450fb6b08a,0x3fe1b290556be73d,2
+np.float64,0x7fd7161475ae2c28,0x7ff0000000000000,2
+np.float64,0x3fece09621f9c12c,0x3ffde836a583bbdd,2
+np.float64,0x3fd045790ea08af2,0x3ff31554778fd4e2,2
+np.float64,0xbfe7c7dd6cef8fbb,0x3fe31e2eeda857fc,2
+np.float64,0xffe9632f5372c65e,0x0,2
+np.float64,0x800d4f3a703a9e75,0x3ff0000000000000,2
+np.float64,0xffea880e4df5101c,0x0,2
+np.float64,0xbfeb7edc4ff6fdb8,0x3fe1a3cb5dc33594,2
+np.float64,0xbfcaae4bab355c98,0x3febb1ee65e16b58,2
+np.float64,0xbfde598a19bcb314,0x3fe709145eafaaf8,2
+np.float64,0x3feefb6d78fdf6db,0x3fff4d5c8c68e39a,2
+np.float64,0x13efc75427dfa,0x3ff0000000000000,2
+np.float64,0xffe26f65c064decb,0x0,2
+np.float64,0xbfed5c1addfab836,0x3fe0f1133bd2189a,2
+np.float64,0x7fe7a7cf756f4f9e,0x7ff0000000000000,2
+np.float64,0xffc681702e2d02e0,0x0,2
+np.float64,0x8003d6ab5067ad57,0x3ff0000000000000,2
+np.float64,0xffa695f1342d2be0,0x0,2
+np.float64,0xbfcf8857db3f10b0,0x3feafa14da8c29a4,2
+np.float64,0xbfe8ca06be71940e,0x3fe2b46f6d2c64b4,2
+np.float64,0x3451c74468a3a,0x3ff0000000000000,2
+np.float64,0x3fde47d5f6bc8fac,0x3ff635bf8e024716,2
+np.float64,0xffda159d5db42b3a,0x0,2
+np.float64,0x7fef9fecaa3f3fd8,0x7ff0000000000000,2
+np.float64,0x3fd4e745e3a9ce8c,0x3ff410a9cb6fd8bf,2
+np.float64,0xffef57019b3eae02,0x0,2
+np.float64,0xbfe6604f4f6cc09e,0x3fe3b55de43c626d,2
+np.float64,0xffe066a424a0cd48,0x0,2
+np.float64,0x3fd547de85aa8fbc,0x3ff425b2a7a16675,2
+np.float64,0xffb3c69280278d28,0x0,2
+np.float64,0xffebe0b759f7c16e,0x0,2
+np.float64,0x3fefc84106ff9082,0x3fffd973687337d8,2
+np.float64,0x501c42a4a0389,0x3ff0000000000000,2
+np.float64,0x7feb45d13eb68ba1,0x7ff0000000000000,2
+np.float64,0xbfb16a8c2e22d518,0x3fee86a9c0f9291a,2
+np.float64,0x3be327b877c66,0x3ff0000000000000,2
+np.float64,0x7fe4a58220694b03,0x7ff0000000000000,2
+np.float64,0x3fe0286220a050c4,0x3ff6b472157ab8f2,2
+np.float64,0x3fc9381825327030,0x3ff2575fbea2bf5d,2
+np.float64,0xbfd1af7ee8a35efe,0x3fea6c032cf7e669,2
+np.float64,0xbfea9b0f39b5361e,0x3fe1fbae14b40b4d,2
+np.float64,0x39efe4aa73dfd,0x3ff0000000000000,2
+np.float64,0xffeb06fdc8360dfb,0x0,2
+np.float64,0xbfda481e72b4903c,0x3fe812b4b08d4884,2
+np.float64,0xbfd414ba5ba82974,0x3fe9bec9474bdfe6,2
+np.float64,0x7fe707177b6e0e2e,0x7ff0000000000000,2
+np.float64,0x8000000000000001,0x3ff0000000000000,2
+np.float64,0xbfede6a75bbbcd4f,0x3fe0be874cccd399,2
+np.float64,0x8006cdb577cd9b6c,0x3ff0000000000000,2
+np.float64,0x800051374f20a26f,0x3ff0000000000000,2
+np.float64,0x3fe5cba8c96b9752,0x3ff9a76b3adcc122,2
+np.float64,0xbfee3933487c7267,0x3fe0a0b190f9609a,2
+np.float64,0x3fd574b8d8aae970,0x3ff42f7e83de1af9,2
+np.float64,0xba5db72b74bb7,0x3ff0000000000000,2
+np.float64,0x3fa9bf512c337ea0,0x3ff0914a7f743a94,2
+np.float64,0xffe8cb736c3196e6,0x0,2
+np.float64,0x3761b2f06ec37,0x3ff0000000000000,2
+np.float64,0x8b4d4433169a9,0x3ff0000000000000,2
+np.float64,0x800f0245503e048b,0x3ff0000000000000,2
+np.float64,0x7fb20d54ac241aa8,0x7ff0000000000000,2
+np.float64,0x3fdf26666b3e4ccd,0x3ff66b8995142017,2
+np.float64,0xbfcbf2a83737e550,0x3feb8173a7b9d6b5,2
+np.float64,0x3fd31572a0a62ae5,0x3ff3ac6c94313dcd,2
+np.float64,0x7fb6c2807a2d8500,0x7ff0000000000000,2
+np.float64,0x800799758f2f32ec,0x3ff0000000000000,2
+np.float64,0xe72f1f6bce5e4,0x3ff0000000000000,2
+np.float64,0x3fe0e0f223a1c1e4,0x3ff70fed5b761673,2
+np.float64,0x3fe6d4f133eda9e2,0x3ffa3c8000c169eb,2
+np.float64,0xbfe1ccc3d8639988,0x3fe5c32148bedbda,2
+np.float64,0x3fea71c53574e38a,0x3ffc5f31201fe9be,2
+np.float64,0x9e0323eb3c065,0x3ff0000000000000,2
+np.float64,0x8005cc79a5cb98f4,0x3ff0000000000000,2
+np.float64,0x1dace1f83b59d,0x3ff0000000000000,2
+np.float64,0x10000000000000,0x3ff0000000000000,2
+np.float64,0xbfdef50830bdea10,0x3fe6e269fc17ebef,2
+np.float64,0x8010000000000000,0x3ff0000000000000,2
+np.float64,0xbfdfa82192bf5044,0x3fe6b6313ee0a095,2
+np.float64,0x3fd9398fe2b27320,0x3ff506ca2093c060,2
+np.float64,0x8002721fe664e441,0x3ff0000000000000,2
+np.float64,0x800c04166ad8082d,0x3ff0000000000000,2
+np.float64,0xffec3918b3387230,0x0,2
+np.float64,0x3fec62d5dfb8c5ac,0x3ffd972ea4a54b32,2
+np.float64,0x3fe7e42a0b6fc854,0x3ffad86b0443181d,2
+np.float64,0x3fc0aff5f3215fec,0x3ff1836058d4d210,2
+np.float64,0xbf82ff68a025fec0,0x3fefcb7f06862dce,2
+np.float64,0xae2e35195c5c7,0x3ff0000000000000,2
+np.float64,0x3fece3bddf79c77c,0x3ffdea41fb1ba8fa,2
+np.float64,0xbfa97b947832f730,0x3feeea34ebedbbd2,2
+np.float64,0xbfdfb1b1ce3f6364,0x3fe6b3d72871335c,2
+np.float64,0xbfe61a4f24ac349e,0x3fe3d356bf991b06,2
+np.float64,0x7fe23117a5e4622e,0x7ff0000000000000,2
+np.float64,0x800552a8cccaa552,0x3ff0000000000000,2
+np.float64,0x625b4d0ac4b6a,0x3ff0000000000000,2
+np.float64,0x3f86cf15702d9e00,0x3ff01fbe0381676d,2
+np.float64,0x800d7d1b685afa37,0x3ff0000000000000,2
+np.float64,0x3fe2cb6e40a596dd,0x3ff80a1a562f7fc9,2
+np.float64,0x3fe756eb8e2eadd7,0x3ffa86c638aad07d,2
+np.float64,0x800dc9a5513b934b,0x3ff0000000000000,2
+np.float64,0xbfbbdd118a37ba20,0x3fedacb4624f3cee,2
+np.float64,0x800de01f8efbc03f,0x3ff0000000000000,2
+np.float64,0x800da1a3fe9b4348,0x3ff0000000000000,2
+np.float64,0xbf87d8c7602fb180,0x3fefbe2614998ab6,2
+np.float64,0xbfdfff6141bffec2,0x3fe6a0c54d9f1bc8,2
+np.float64,0xee8fbba5dd1f8,0x3ff0000000000000,2
+np.float64,0x3fe79dc93e6f3b92,0x3ffaaf9d7d955b2c,2
+np.float64,0xffedd4b3d07ba967,0x0,2
+np.float64,0x800905dfc1720bc0,0x3ff0000000000000,2
+np.float64,0x3fd9e483b8b3c907,0x3ff52ddc6c950e7f,2
+np.float64,0xe34ffefdc6a00,0x3ff0000000000000,2
+np.float64,0x2168e62242d1e,0x3ff0000000000000,2
+np.float64,0x800349950e26932b,0x3ff0000000000000,2
+np.float64,0x7fc50da8532a1b50,0x7ff0000000000000,2
+np.float64,0xae1a4d115c34a,0x3ff0000000000000,2
+np.float64,0xa020f0b74041e,0x3ff0000000000000,2
+np.float64,0x3fd2aa2f77a5545f,0x3ff3959f09519a25,2
+np.float64,0x3fbfefc3223fdf86,0x3ff171f3df2d408b,2
+np.float64,0xbfea9fc340b53f86,0x3fe1f9d92b712654,2
+np.float64,0xffe9b920a5337240,0x0,2
+np.float64,0xbfe2eb0265e5d605,0x3fe53dd195782de3,2
+np.float64,0x7fb932c70e32658d,0x7ff0000000000000,2
+np.float64,0x3fda816bfcb502d8,0x3ff551f8d5c84c82,2
+np.float64,0x3fed68cbe9fad198,0x3ffe40f6692d5693,2
+np.float64,0x32df077665be2,0x3ff0000000000000,2
+np.float64,0x7fdc9c2f3539385d,0x7ff0000000000000,2
+np.float64,0x7fe71091a2ee2122,0x7ff0000000000000,2
+np.float64,0xbfe68106c46d020e,0x3fe3a76b56024c2c,2
+np.float64,0xffcf0572823e0ae4,0x0,2
+np.float64,0xbfeeab341fbd5668,0x3fe077d496941cda,2
+np.float64,0x7fe7ada0d2af5b41,0x7ff0000000000000,2
+np.float64,0xffacdef2a439bde0,0x0,2
+np.float64,0x3fe4200f3128401e,0x3ff8be0ddf30fd1e,2
+np.float64,0xffd9022a69320454,0x0,2
+np.float64,0xbfe8e06914f1c0d2,0x3fe2ab5fe7fffb5a,2
+np.float64,0x3fc4b976602972ed,0x3ff1e6786fa7a890,2
+np.float64,0xbfd784c105af0982,0x3fe8cdeb1cdbd57e,2
+np.float64,0x7feb20a20eb64143,0x7ff0000000000000,2
+np.float64,0xbfc87dd83630fbb0,0x3fec067c1e7e6983,2
+np.float64,0x7fe5400cbe6a8018,0x7ff0000000000000,2
+np.float64,0xbfb4a1f5e22943e8,0x3fee42e6c81559a9,2
+np.float64,0x3fe967c575f2cf8a,0x3ffbbd8bc0d5c50d,2
+np.float64,0xbfeb059cf4760b3a,0x3fe1d25c592c4dab,2
+np.float64,0xbfeef536d5bdea6e,0x3fe05d832c15c64a,2
+np.float64,0x3fa90b3f6432167f,0x3ff08d410dd732cc,2
+np.float64,0xbfeaff265e75fe4d,0x3fe1d4db3fb3208d,2
+np.float64,0x6d93d688db27b,0x3ff0000000000000,2
+np.float64,0x800ab9b4ea55736a,0x3ff0000000000000,2
+np.float64,0x3fd444b39d288967,0x3ff3ed749d48d444,2
+np.float64,0xbfd5f2c0d0abe582,0x3fe93ad6124d88e7,2
+np.float64,0x3fea8fd915f51fb2,0x3ffc71b32cb92d60,2
+np.float64,0xbfd23d6491a47aca,0x3fea43875709b0f0,2
+np.float64,0xffe76f75ce6edeeb,0x0,2
+np.float64,0x1f5670da3eacf,0x3ff0000000000000,2
+np.float64,0x8000d89c9621b13a,0x3ff0000000000000,2
+np.float64,0x3fedb51c52bb6a39,0x3ffe732279c228ff,2
+np.float64,0x7f99215ac83242b5,0x7ff0000000000000,2
+np.float64,0x742a6864e854e,0x3ff0000000000000,2
+np.float64,0xbfe02fb340205f66,0x3fe689495f9164e3,2
+np.float64,0x7fef4c12b0fe9824,0x7ff0000000000000,2
+np.float64,0x3fd40e17c2a81c30,0x3ff3e1aee8ed972f,2
+np.float64,0x7fdcd264e939a4c9,0x7ff0000000000000,2
+np.float64,0x3fdb675838b6ceb0,0x3ff587526241c550,2
+np.float64,0x3fdf1a4081be3480,0x3ff66896a18c2385,2
+np.float64,0xbfea5082b874a106,0x3fe218cf8f11be13,2
+np.float64,0xffe1a0ebf7e341d8,0x0,2
+np.float64,0x3fed0a2222ba1444,0x3ffe032ce928ae7d,2
+np.float64,0xffeae036da75c06d,0x0,2
+np.float64,0x5b05fc8ab60c0,0x3ff0000000000000,2
+np.float64,0x7fd8aae5f03155cb,0x7ff0000000000000,2
+np.float64,0xbfd0b4d9fda169b4,0x3feab41e58b6ccb7,2
+np.float64,0xffdcaffa57395ff4,0x0,2
+np.float64,0xbfcbf1455437e28c,0x3feb81a884182c5d,2
+np.float64,0x3f9d6700b83ace01,0x3ff0525657db35d4,2
+np.float64,0x4fd5b0b29fab7,0x3ff0000000000000,2
+np.float64,0x3fe9af2df5b35e5c,0x3ffbe895684df916,2
+np.float64,0x800dfd41f9dbfa84,0x3ff0000000000000,2
+np.float64,0xbf2a30457e546,0x3ff0000000000000,2
+np.float64,0x7fc6be37182d7c6d,0x7ff0000000000000,2
+np.float64,0x800e0f9788dc1f2f,0x3ff0000000000000,2
+np.float64,0x8006890c704d121a,0x3ff0000000000000,2
+np.float64,0xffecb1a7cbb9634f,0x0,2
+np.float64,0xffb35c330426b868,0x0,2
+np.float64,0x7fe8f2ba8a71e574,0x7ff0000000000000,2
+np.float64,0xf3ccff8fe79a0,0x3ff0000000000000,2
+np.float64,0x3fdf19a84e3e3351,0x3ff66871b17474c1,2
+np.float64,0x80049a662d0934cd,0x3ff0000000000000,2
+np.float64,0xdf5bb4bbbeb77,0x3ff0000000000000,2
+np.float64,0x8005eca030cbd941,0x3ff0000000000000,2
+np.float64,0xffe5f239586be472,0x0,2
+np.float64,0xbfc4526a0728a4d4,0x3fecaa52fbf5345e,2
+np.float64,0xbfe8f1ecda31e3da,0x3fe2a44c080848b3,2
+np.float64,0x3feebd32f4bd7a66,0x3fff234788938c3e,2
+np.float64,0xffd6ca04e9ad940a,0x0,2
+np.float64,0x7ff0000000000000,0x7ff0000000000000,2
+np.float64,0xbfd4c560a9a98ac2,0x3fe98db6d97442fc,2
+np.float64,0x8005723471cae46a,0x3ff0000000000000,2
+np.float64,0xbfeb278299764f05,0x3fe1c54b48f8ba4b,2
+np.float64,0x8007907b376f20f7,0x3ff0000000000000,2
+np.float64,0x7fe9c2fd01b385f9,0x7ff0000000000000,2
+np.float64,0x7fdaa37368b546e6,0x7ff0000000000000,2
+np.float64,0xbfe6d0f3786da1e7,0x3fe38582271cada7,2
+np.float64,0xbfea9b77823536ef,0x3fe1fb8575cd1b7d,2
+np.float64,0xbfe90ac38bf21587,0x3fe29a471b47a2e8,2
+np.float64,0xbfe9c51844738a30,0x3fe24fc8de03ea84,2
+np.float64,0x3fe45a9013a8b520,0x3ff8dd7c80f1cf75,2
+np.float64,0xbfe5780551eaf00a,0x3fe419832a6a4c56,2
+np.float64,0xffefffffffffffff,0x0,2
+np.float64,0x7fe3778c84a6ef18,0x7ff0000000000000,2
+np.float64,0xbfdc8a60413914c0,0x3fe77dc55b85028f,2
+np.float64,0xef47ae2fde8f6,0x3ff0000000000000,2
+np.float64,0x8001269fa4c24d40,0x3ff0000000000000,2
+np.float64,0x3fe9d2d39e73a5a7,0x3ffbfe2a66c4148e,2
+np.float64,0xffee61f528fcc3e9,0x0,2
+np.float64,0x3fe8a259ab7144b3,0x3ffb47e797a34bd2,2
+np.float64,0x3f906d610820dac0,0x3ff02dccda8e1a75,2
+np.float64,0x3fe70739f32e0e74,0x3ffa59232f4fcd07,2
+np.float64,0x3fe6b7f5e6ad6fec,0x3ffa2c0cc54f2c16,2
+np.float64,0x95a91a792b524,0x3ff0000000000000,2
+np.float64,0xbfedf6fcf57bedfa,0x3fe0b89bb40081cc,2
+np.float64,0xbfa4d2de9c29a5c0,0x3fef1c485678d657,2
+np.float64,0x3fe130470d22608e,0x3ff737b0be409a38,2
+np.float64,0x3fcf8035423f006b,0x3ff2f9d7c3c6a302,2
+np.float64,0xffe5995a3eab32b4,0x0,2
+np.float64,0xffca68c63034d18c,0x0,2
+np.float64,0xff9d53af903aa760,0x0,2
+np.float64,0x800563f1de6ac7e4,0x3ff0000000000000,2
+np.float64,0x7fce284fa63c509e,0x7ff0000000000000,2
+np.float64,0x7fb2a3959a25472a,0x7ff0000000000000,2
+np.float64,0x7fdbe2652f37c4c9,0x7ff0000000000000,2
+np.float64,0x800d705bbc1ae0b8,0x3ff0000000000000,2
+np.float64,0x7fd9bd2347b37a46,0x7ff0000000000000,2
+np.float64,0x3fcac3c0fb358782,0x3ff27ed62d6c8221,2
+np.float64,0x800110691ec220d3,0x3ff0000000000000,2
+np.float64,0x3fef79a8157ef350,0x3fffa368513eb909,2
+np.float64,0x7fe8bd2f0e317a5d,0x7ff0000000000000,2
+np.float64,0x7fd3040e60a6081c,0x7ff0000000000000,2
+np.float64,0xffea50723234a0e4,0x0,2
+np.float64,0xbfe6220054ac4400,0x3fe3d00961238a93,2
+np.float64,0x3f9eddd8c83dbbc0,0x3ff0567b0c73005a,2
+np.float64,0xbfa4a062c42940c0,0x3fef1e68badde324,2
+np.float64,0xbfd077ad4720ef5a,0x3feac5d577581d07,2
+np.float64,0x7fdfd4b025bfa95f,0x7ff0000000000000,2
+np.float64,0xd00d3cf3a01a8,0x3ff0000000000000,2
+np.float64,0x7fe3010427260207,0x7ff0000000000000,2
+np.float64,0x22ea196645d44,0x3ff0000000000000,2
+np.float64,0x7fd747e8cd2e8fd1,0x7ff0000000000000,2
+np.float64,0xd50665e7aa0cd,0x3ff0000000000000,2
+np.float64,0x7fe1da580ae3b4af,0x7ff0000000000000,2
+np.float64,0xffeb218ecfb6431d,0x0,2
+np.float64,0xbf887d0dd030fa00,0x3fefbc6252c8b354,2
+np.float64,0x3fcaa31067354621,0x3ff27b904c07e07f,2
+np.float64,0x7fe698cc4ded3198,0x7ff0000000000000,2
+np.float64,0x1c40191a38804,0x3ff0000000000000,2
+np.float64,0x80086fd20e30dfa4,0x3ff0000000000000,2
+np.float64,0x7fed34d5eaba69ab,0x7ff0000000000000,2
+np.float64,0xffd00b52622016a4,0x0,2
+np.float64,0x3f80abcdb021579b,0x3ff0172d27945851,2
+np.float64,0x3fe614cfd66c29a0,0x3ff9d031e1839191,2
+np.float64,0x80021d71c8843ae4,0x3ff0000000000000,2
+np.float64,0x800bc2adc657855c,0x3ff0000000000000,2
+np.float64,0x6b9fec1cd73fe,0x3ff0000000000000,2
+np.float64,0xffd9093b5f321276,0x0,2
+np.float64,0x800d3c6c77fa78d9,0x3ff0000000000000,2
+np.float64,0xffe80fc1cbf01f83,0x0,2
+np.float64,0xffbffbaf2a3ff760,0x0,2
+np.float64,0x3fea1ed29eb43da5,0x3ffc2c64ec0e17a3,2
+np.float64,0x7ff4000000000000,0x7ffc000000000000,2
+np.float64,0x3fd944a052328941,0x3ff5094f4c43ecca,2
+np.float64,0x800b1f9416163f29,0x3ff0000000000000,2
+np.float64,0x800f06bf33de0d7e,0x3ff0000000000000,2
+np.float64,0xbfdbf0d226b7e1a4,0x3fe7a4f73793d95b,2
+np.float64,0xffe7306c30ae60d8,0x0,2
+np.float64,0x7fe991accfb32359,0x7ff0000000000000,2
+np.float64,0x3fcc0040d2380082,0x3ff29ea47e4f07d4,2
+np.float64,0x7fefffffffffffff,0x7ff0000000000000,2
+np.float64,0x0,0x3ff0000000000000,2
+np.float64,0x3fe1423f7be2847e,0x3ff740bc1d3b20f8,2
+np.float64,0xbfeae3a3cab5c748,0x3fe1df7e936f8504,2
+np.float64,0x800b2da7d6165b50,0x3ff0000000000000,2
+np.float64,0x800b2404fcd6480a,0x3ff0000000000000,2
+np.float64,0x6fcbcf88df97b,0x3ff0000000000000,2
+np.float64,0xa248c0e14492,0x3ff0000000000000,2
+np.float64,0xffd255776824aaee,0x0,2
+np.float64,0x80057b3effeaf67f,0x3ff0000000000000,2
+np.float64,0x3feb0b07d7761610,0x3ffcbdfe1be5a594,2
+np.float64,0x924e1019249c2,0x3ff0000000000000,2
+np.float64,0x80074307e80e8611,0x3ff0000000000000,2
+np.float64,0xffb207fa46240ff8,0x0,2
+np.float64,0x95ac388d2b587,0x3ff0000000000000,2
+np.float64,0xbff0000000000000,0x3fe0000000000000,2
+np.float64,0x3fd38b6a492716d5,0x3ff3c59f62b5add5,2
+np.float64,0x7fe49362c3e926c5,0x7ff0000000000000,2
+np.float64,0x7fe842889db08510,0x7ff0000000000000,2
+np.float64,0xbfba6003e834c008,0x3fedcb620a2d9856,2
+np.float64,0xffe7e782bd6fcf05,0x0,2
+np.float64,0x7fd9b93d9433727a,0x7ff0000000000000,2
+np.float64,0x7fc8fcb61d31f96b,0x7ff0000000000000,2
+np.float64,0xbfef9be8db3f37d2,0x3fe022d603b81dc2,2
+np.float64,0x6f4fc766de9fa,0x3ff0000000000000,2
+np.float64,0xbfe93016f132602e,0x3fe28b42d782d949,2
+np.float64,0x3fe10e52b8e21ca5,0x3ff726a38b0bb895,2
+np.float64,0x3fbbba0ae6377416,0x3ff13f56084a9da3,2
+np.float64,0x3fe09e42ece13c86,0x3ff6eeb57e775e24,2
+np.float64,0x800942e39fb285c8,0x3ff0000000000000,2
+np.float64,0xffe5964370eb2c86,0x0,2
+np.float64,0x3fde479f32bc8f3e,0x3ff635b2619ba53a,2
+np.float64,0x3fe826e187f04dc3,0x3ffaff52b79c3a08,2
+np.float64,0x3febcbf1eab797e4,0x3ffd37152e5e2598,2
+np.float64,0x3fa0816a202102d4,0x3ff05c8e6a8b00d5,2
+np.float64,0xbd005ccb7a00c,0x3ff0000000000000,2
+np.float64,0x44c12fdc89827,0x3ff0000000000000,2
+np.float64,0xffc8fdffa431fc00,0x0,2
+np.float64,0xffeb4f5a87b69eb4,0x0,2
+np.float64,0xbfb07e7f8420fd00,0x3fee9a32924fe6a0,2
+np.float64,0xbfbd9d1bb63b3a38,0x3fed88ca81e5771c,2
+np.float64,0x8008682a74f0d055,0x3ff0000000000000,2
+np.float64,0x3fdeedbc7b3ddb79,0x3ff65dcb7c55f4dc,2
+np.float64,0x8009e889c613d114,0x3ff0000000000000,2
+np.float64,0x3faea831f43d5064,0x3ff0ad935e890e49,2
+np.float64,0xf0af1703e15e3,0x3ff0000000000000,2
+np.float64,0xffec06c4a5f80d88,0x0,2
+np.float64,0x53a1cc0ca743a,0x3ff0000000000000,2
+np.float64,0x7fd10c9eea22193d,0x7ff0000000000000,2
+np.float64,0xbfd48a6bf0a914d8,0x3fe99e0d109f2bac,2
+np.float64,0x3fd6dfe931adbfd4,0x3ff47f81c2dfc5d3,2
+np.float64,0x3fed20e86b7a41d0,0x3ffe11fecc7bc686,2
+np.float64,0xbfea586818b4b0d0,0x3fe215b7747d5cb8,2
+np.float64,0xbfd4ad3e20295a7c,0x3fe99465ab8c3275,2
+np.float64,0x3fd6619ee4acc33e,0x3ff4638b7b80c08a,2
+np.float64,0x3fdf6fcb63bedf97,0x3ff67d62fd3d560c,2
+np.float64,0x800a9191e7152324,0x3ff0000000000000,2
+np.float64,0x3fd2ff3c0da5fe78,0x3ff3a7b17e892a28,2
+np.float64,0x8003dbf1f327b7e5,0x3ff0000000000000,2
+np.float64,0xffea6b89a934d712,0x0,2
+np.float64,0x7fcfb879043f70f1,0x7ff0000000000000,2
+np.float64,0xea6a84dbd4d51,0x3ff0000000000000,2
+np.float64,0x800ec97a815d92f5,0x3ff0000000000000,2
+np.float64,0xffe304c3a8660987,0x0,2
+np.float64,0xbfefe24dd3ffc49c,0x3fe00a4e065be96d,2
+np.float64,0xffd3cc8c00a79918,0x0,2
+np.float64,0x95be8b7b2b7d2,0x3ff0000000000000,2
+np.float64,0x7fe20570cba40ae1,0x7ff0000000000000,2
+np.float64,0x7f97a06da02f40da,0x7ff0000000000000,2
+np.float64,0xffe702b9522e0572,0x0,2
+np.float64,0x3fada2d8543b45b1,0x3ff0a7adc4201e08,2
+np.float64,0x235e6acc46bce,0x3ff0000000000000,2
+np.float64,0x3fea6bc28ef4d786,0x3ffc5b7fc68fddac,2
+np.float64,0xffdbc9f505b793ea,0x0,2
+np.float64,0xffe98b137ff31626,0x0,2
+np.float64,0x800e26c6721c4d8d,0x3ff0000000000000,2
+np.float64,0x80080de445301bc9,0x3ff0000000000000,2
+np.float64,0x37e504a86fca1,0x3ff0000000000000,2
+np.float64,0x8002f5f60325ebed,0x3ff0000000000000,2
+np.float64,0x5c8772feb90ef,0x3ff0000000000000,2
+np.float64,0xbfe021abb4604358,0x3fe69023a51d22b8,2
+np.float64,0x3fde744f8fbce8a0,0x3ff64074dc84edd7,2
+np.float64,0xbfdd92899f3b2514,0x3fe73aefd9701858,2
+np.float64,0x7fc1ad5c51235ab8,0x7ff0000000000000,2
+np.float64,0xaae2f98955c5f,0x3ff0000000000000,2
+np.float64,0x7f9123d5782247aa,0x7ff0000000000000,2
+np.float64,0xbfe3f8e94b67f1d2,0x3fe4c30ab28e9cb7,2
+np.float64,0x7fdaba8b4cb57516,0x7ff0000000000000,2
+np.float64,0x7fefc85cfeff90b9,0x7ff0000000000000,2
+np.float64,0xffb83b4f523076a0,0x0,2
+np.float64,0xbfe888a68c71114d,0x3fe2ceff17c203d1,2
+np.float64,0x800de1dac4bbc3b6,0x3ff0000000000000,2
+np.float64,0xbfe4f27f09e9e4fe,0x3fe453f9af407eac,2
+np.float64,0xffe3d2713467a4e2,0x0,2
+np.float64,0xbfebaab840375570,0x3fe1931131b98842,2
+np.float64,0x93892a1b27126,0x3ff0000000000000,2
+np.float64,0x1e8e7f983d1d1,0x3ff0000000000000,2
+np.float64,0x3fecc950627992a0,0x3ffdd926f036add0,2
+np.float64,0xbfd41dfb1aa83bf6,0x3fe9bc34ece35b94,2
+np.float64,0x800aebfc6555d7f9,0x3ff0000000000000,2
+np.float64,0x7fe33ba52ca67749,0x7ff0000000000000,2
+np.float64,0xffe57c9b3feaf936,0x0,2
+np.float64,0x3fdd12464fba248c,0x3ff5ebc5598e6bd0,2
+np.float64,0xffe06d7f0fe0dafe,0x0,2
+np.float64,0x800e55b7fe9cab70,0x3ff0000000000000,2
+np.float64,0x3fd33803c8267008,0x3ff3b3cb78b2d642,2
+np.float64,0xe9cab8a1d3957,0x3ff0000000000000,2
+np.float64,0x3fb38ac166271580,0x3ff0de906947c0f0,2
+np.float64,0xbfd67aa552acf54a,0x3fe915cf64a389fd,2
+np.float64,0x1db96daa3b72f,0x3ff0000000000000,2
+np.float64,0xbfee9f08f4fd3e12,0x3fe07c2c615add3c,2
+np.float64,0xf14f6d65e29ee,0x3ff0000000000000,2
+np.float64,0x800bce089e179c12,0x3ff0000000000000,2
+np.float64,0xffc42dcc37285b98,0x0,2
+np.float64,0x7fd5f37063abe6e0,0x7ff0000000000000,2
+np.float64,0xbfd943c2cbb28786,0x3fe856f6452ec753,2
+np.float64,0x8ddfbc091bbf8,0x3ff0000000000000,2
+np.float64,0xbfe153491e22a692,0x3fe5fcb075dbbd5d,2
+np.float64,0xffe7933999ef2672,0x0,2
+np.float64,0x7ff8000000000000,0x7ff8000000000000,2
+np.float64,0x8000000000000000,0x3ff0000000000000,2
+np.float64,0xbfe9154580b22a8b,0x3fe2960bac3a8220,2
+np.float64,0x800dc6dda21b8dbb,0x3ff0000000000000,2
+np.float64,0xbfb26225a824c448,0x3fee7239a457df81,2
+np.float64,0xbfd7b68c83af6d1a,0x3fe8c08e351ab468,2
+np.float64,0xffde01f7213c03ee,0x0,2
+np.float64,0x3fe54cbe0faa997c,0x3ff9614527191d72,2
+np.float64,0xbfd6bec3732d7d86,0x3fe90354909493de,2
+np.float64,0xbfef3c85bd7e790b,0x3fe0444f8c489ca6,2
+np.float64,0x899501b7132a0,0x3ff0000000000000,2
+np.float64,0xbfe17a456462f48b,0x3fe5ea2719a9a84b,2
+np.float64,0xffe34003b8668007,0x0,2
+np.float64,0x7feff6a3633fed46,0x7ff0000000000000,2
+np.float64,0x3fba597ecc34b2fe,0x3ff12ee72e4de474,2
+np.float64,0x4084c7b68109a,0x3ff0000000000000,2
+np.float64,0x3fad23bf4c3a4780,0x3ff0a4d06193ff6d,2
+np.float64,0xffd0fe2707a1fc4e,0x0,2
+np.float64,0xb96cb43f72d97,0x3ff0000000000000,2
+np.float64,0x7fc4d684d829ad09,0x7ff0000000000000,2
+np.float64,0x7fdc349226b86923,0x7ff0000000000000,2
+np.float64,0x7fd82851cd3050a3,0x7ff0000000000000,2
+np.float64,0x800cde0041b9bc01,0x3ff0000000000000,2
+np.float64,0x4e8caa1e9d196,0x3ff0000000000000,2
+np.float64,0xbfed06a6d2fa0d4e,0x3fe1108c3682b05a,2
+np.float64,0xffe8908122312102,0x0,2
+np.float64,0xffe56ed6d9aaddad,0x0,2
+np.float64,0x3fedd6db00fbadb6,0x3ffe896c68c4b26e,2
+np.float64,0x3fde31f9b4bc63f4,0x3ff6307e08f8b6ba,2
+np.float64,0x6bb963c2d772d,0x3ff0000000000000,2
+np.float64,0x787b7142f0f6f,0x3ff0000000000000,2
+np.float64,0x3fe6e4147c6dc829,0x3ffa451bbdece240,2
+np.float64,0x8003857401470ae9,0x3ff0000000000000,2
+np.float64,0xbfeae82c3c75d058,0x3fe1ddbd66e65aab,2
+np.float64,0x7fe174707c62e8e0,0x7ff0000000000000,2
+np.float64,0x80008d2545e11a4b,0x3ff0000000000000,2
+np.float64,0xbfecc2dce17985ba,0x3fe129ad4325985a,2
+np.float64,0xbfe1fa1daf63f43c,0x3fe5adcb0731a44b,2
+np.float64,0x7fcf2530203e4a5f,0x7ff0000000000000,2
+np.float64,0xbfea5cefe874b9e0,0x3fe213f134b61f4a,2
+np.float64,0x800103729f2206e6,0x3ff0000000000000,2
+np.float64,0xbfe8442ff7708860,0x3fe2eaf850faa169,2
+np.float64,0x8006c78e19ed8f1d,0x3ff0000000000000,2
+np.float64,0x3fc259589c24b2b1,0x3ff1abe6a4d28816,2
+np.float64,0xffed02b7b5ba056e,0x0,2
+np.float64,0xbfce0aa4fe3c1548,0x3feb32115d92103e,2
+np.float64,0x7fec06e78bf80dce,0x7ff0000000000000,2
+np.float64,0xbfe0960bbc612c18,0x3fe6578ab29b70d4,2
+np.float64,0x3fee45841cbc8b08,0x3ffed2f6ca808ad3,2
+np.float64,0xbfeb0f8ebef61f1e,0x3fe1ce86003044cd,2
+np.float64,0x8002c357358586af,0x3ff0000000000000,2
+np.float64,0x3fe9aa10cc735422,0x3ffbe57e294ce68b,2
+np.float64,0x800256c0a544ad82,0x3ff0000000000000,2
+np.float64,0x4de6e1449bcdd,0x3ff0000000000000,2
+np.float64,0x65e9bc9ccbd38,0x3ff0000000000000,2
+np.float64,0xbfe53b0fa9aa7620,0x3fe4341f0aa29bbc,2
+np.float64,0xbfcdd94cd13bb298,0x3feb3956acd2e2dd,2
+np.float64,0x8004a49b65a94938,0x3ff0000000000000,2
+np.float64,0x800d3d05deba7a0c,0x3ff0000000000000,2
+np.float64,0x3fe4e05bce69c0b8,0x3ff925f55602a7e0,2
+np.float64,0xffe391e3256723c6,0x0,2
+np.float64,0xbfe92f0f37b25e1e,0x3fe28bacc76ae753,2
+np.float64,0x3f990238d8320472,0x3ff045edd36e2d62,2
+np.float64,0xffed8d15307b1a2a,0x0,2
+np.float64,0x3fee82e01afd05c0,0x3ffefc09e8b9c2b7,2
+np.float64,0xffb2d94b2225b298,0x0,2
diff --git a/numpy/core/tests/data/umath-validation-set-expm1.csv b/numpy/core/tests/data/umath-validation-set-expm1.csv
new file mode 100644
index 000000000..732ae8654
--- /dev/null
+++ b/numpy/core/tests/data/umath-validation-set-expm1.csv
@@ -0,0 +1,1429 @@
+dtype,input,output,ulperrortol
+np.float32,0x80606724,0x80606724,3
+np.float32,0xbf16790f,0xbee38e14,3
+np.float32,0xbf1778a1,0xbee4a97f,3
+np.float32,0x7d4fc610,0x7f800000,3
+np.float32,0xbec30a20,0xbea230d5,3
+np.float32,0x3eae8a36,0x3ecffac5,3
+np.float32,0xbf1f08f1,0xbeece93c,3
+np.float32,0x80374376,0x80374376,3
+np.float32,0x3f2e04ca,0x3f793115,3
+np.float32,0x7e2c7e36,0x7f800000,3
+np.float32,0xbf686cae,0xbf18bcf0,3
+np.float32,0xbf5518cd,0xbf10a3da,3
+np.float32,0x807e233c,0x807e233c,3
+np.float32,0x7f4edd54,0x7f800000,3
+np.float32,0x7ed70088,0x7f800000,3
+np.float32,0x801675da,0x801675da,3
+np.float32,0x806735d5,0x806735d5,3
+np.float32,0xfe635fec,0xbf800000,3
+np.float32,0xfed88a0a,0xbf800000,3
+np.float32,0xff52c052,0xbf800000,3
+np.float32,0x7fc00000,0x7fc00000,3
+np.float32,0xff4f65f9,0xbf800000,3
+np.float32,0xfe0f6c20,0xbf800000,3
+np.float32,0x80322b30,0x80322b30,3
+np.float32,0xfb757000,0xbf800000,3
+np.float32,0x3c81e0,0x3c81e0,3
+np.float32,0x79d56a,0x79d56a,3
+np.float32,0x8029d7af,0x8029d7af,3
+np.float32,0x8058a593,0x8058a593,3
+np.float32,0x3f3a13c7,0x3f88c75c,3
+np.float32,0x2a6b05,0x2a6b05,3
+np.float32,0xbd64c960,0xbd5e83ae,3
+np.float32,0x80471052,0x80471052,3
+np.float32,0xbe5dd950,0xbe47766c,3
+np.float32,0xfd8f88f0,0xbf800000,3
+np.float32,0x75a4b7,0x75a4b7,3
+np.float32,0x3f726f2e,0x3fc9fb7d,3
+np.float32,0x3ed6795c,0x3f053115,3
+np.float32,0x17d7f5,0x17d7f5,3
+np.float32,0xbf4cf19b,0xbf0d094f,3
+np.float32,0x3e0ec532,0x3e1933c6,3
+np.float32,0xff084016,0xbf800000,3
+np.float32,0x800829aa,0x800829aa,3
+np.float32,0x806d7302,0x806d7302,3
+np.float32,0x7f59d9da,0x7f800000,3
+np.float32,0x15f8b9,0x15f8b9,3
+np.float32,0x803befb3,0x803befb3,3
+np.float32,0x525043,0x525043,3
+np.float32,0x51a647,0x51a647,3
+np.float32,0xbf1cfce4,0xbeeab3d9,3
+np.float32,0x3f1f27a4,0x3f5cb1d2,3
+np.float32,0xbebc3a04,0xbe9d8142,3
+np.float32,0xbeea548c,0xbebc07e5,3
+np.float32,0x3f47401c,0x3f96c2a3,3
+np.float32,0x806b1ea3,0x806b1ea3,3
+np.float32,0x3ea56bb8,0x3ec3450c,3
+np.float32,0x3f7b4963,0x3fd597b5,3
+np.float32,0x7f051fa0,0x7f800000,3
+np.float32,0x1d411c,0x1d411c,3
+np.float32,0xff0b6a35,0xbf800000,3
+np.float32,0xbead63c0,0xbe9314f7,3
+np.float32,0x3738be,0x3738be,3
+np.float32,0x3f138cc8,0x3f479155,3
+np.float32,0x800a539f,0x800a539f,3
+np.float32,0x801b0ebd,0x801b0ebd,3
+np.float32,0x318fcd,0x318fcd,3
+np.float32,0x3ed67556,0x3f052e06,3
+np.float32,0x702886,0x702886,3
+np.float32,0x80000001,0x80000001,3
+np.float32,0x70a174,0x70a174,3
+np.float32,0x4f9c66,0x4f9c66,3
+np.float32,0x3e3e1927,0x3e50e351,3
+np.float32,0x7eac9a4d,0x7f800000,3
+np.float32,0x4b7407,0x4b7407,3
+np.float32,0x7f5bd2fd,0x7f800000,3
+np.float32,0x3eaafc58,0x3ecaffbd,3
+np.float32,0xbc989360,0xbc9729e2,3
+np.float32,0x3f470e5c,0x3f968c7b,3
+np.float32,0x4c5672,0x4c5672,3
+np.float32,0xff2b2ee2,0xbf800000,3
+np.float32,0xbf28a104,0xbef7079b,3
+np.float32,0x2c6175,0x2c6175,3
+np.float32,0x3d7e4fb0,0x3d832f9f,3
+np.float32,0x763276,0x763276,3
+np.float32,0x3cf364,0x3cf364,3
+np.float32,0xbf7ace75,0xbf1fe48c,3
+np.float32,0xff19e858,0xbf800000,3
+np.float32,0x80504c70,0x80504c70,3
+np.float32,0xff390210,0xbf800000,3
+np.float32,0x8046a743,0x8046a743,3
+np.float32,0x80000000,0x80000000,3
+np.float32,0x806c51da,0x806c51da,3
+np.float32,0x806ab38f,0x806ab38f,3
+np.float32,0x3f3de863,0x3f8cc538,3
+np.float32,0x7f6d45bb,0x7f800000,3
+np.float32,0xfd16ec60,0xbf800000,3
+np.float32,0x80513cba,0x80513cba,3
+np.float32,0xbf68996b,0xbf18cefa,3
+np.float32,0xfe039f2c,0xbf800000,3
+np.float32,0x3f013207,0x3f280c55,3
+np.float32,0x7ef4bc07,0x7f800000,3
+np.float32,0xbe8b65ac,0xbe741069,3
+np.float32,0xbf7a8186,0xbf1fc7a6,3
+np.float32,0x802532e5,0x802532e5,3
+np.float32,0x32c7df,0x32c7df,3
+np.float32,0x3ce4dceb,0x3ce81701,3
+np.float32,0xfe801118,0xbf800000,3
+np.float32,0x3d905f20,0x3d9594fb,3
+np.float32,0xbe11ed28,0xbe080168,3
+np.float32,0x59e773,0x59e773,3
+np.float32,0x3e9a2547,0x3eb3dd57,3
+np.float32,0x7ecb7c67,0x7f800000,3
+np.float32,0x7f69a67e,0x7f800000,3
+np.float32,0xff121e11,0xbf800000,3
+np.float32,0x3f7917cb,0x3fd2ad8c,3
+np.float32,0xbf1a7da8,0xbee7fc0c,3
+np.float32,0x3f077e66,0x3f329c40,3
+np.float32,0x3ce8e040,0x3cec37b3,3
+np.float32,0xbf3f0b8e,0xbf069f4d,3
+np.float32,0x3f52f194,0x3fa3c9d6,3
+np.float32,0xbf0e7422,0xbeda80f2,3
+np.float32,0xfd67e230,0xbf800000,3
+np.float32,0xff14d9a9,0xbf800000,3
+np.float32,0x3f3546e3,0x3f83dc2b,3
+np.float32,0x3e152e3a,0x3e20983d,3
+np.float32,0x4a89a3,0x4a89a3,3
+np.float32,0x63217,0x63217,3
+np.float32,0xbeb9e2a8,0xbe9be153,3
+np.float32,0x7e9fa049,0x7f800000,3
+np.float32,0x7f58110c,0x7f800000,3
+np.float32,0x3e88290c,0x3e9bfba9,3
+np.float32,0xbf2cb206,0xbefb3494,3
+np.float32,0xff5880c4,0xbf800000,3
+np.float32,0x7ecff3ac,0x7f800000,3
+np.float32,0x3f4b3de6,0x3f9b23fd,3
+np.float32,0xbebd2048,0xbe9e208c,3
+np.float32,0xff08f7a2,0xbf800000,3
+np.float32,0xff473330,0xbf800000,3
+np.float32,0x1,0x1,3
+np.float32,0xbf5dc239,0xbf14584b,3
+np.float32,0x458e3f,0x458e3f,3
+np.float32,0xbdb8a650,0xbdb091f8,3
+np.float32,0xff336ffc,0xbf800000,3
+np.float32,0x3c60bd00,0x3c624966,3
+np.float32,0xbe16a4f8,0xbe0c1664,3
+np.float32,0x3f214246,0x3f60a0f0,3
+np.float32,0x7fa00000,0x7fe00000,3
+np.float32,0x7e08737e,0x7f800000,3
+np.float32,0x3f70574c,0x3fc74b8e,3
+np.float32,0xbed5745c,0xbeae8c77,3
+np.float32,0x361752,0x361752,3
+np.float32,0x3eb276d6,0x3ed584ea,3
+np.float32,0x3f03fc1e,0x3f2cb1a5,3
+np.float32,0x3fafd1,0x3fafd1,3
+np.float32,0x7e50d74c,0x7f800000,3
+np.float32,0x3eeca5,0x3eeca5,3
+np.float32,0x5dc963,0x5dc963,3
+np.float32,0x7f0e63ae,0x7f800000,3
+np.float32,0x8021745f,0x8021745f,3
+np.float32,0xbf5881a9,0xbf121d07,3
+np.float32,0x7dadc7fd,0x7f800000,3
+np.float32,0xbf2c0798,0xbefa86bb,3
+np.float32,0x3e635f50,0x3e7e97a9,3
+np.float32,0xbf2053fa,0xbeee4c0e,3
+np.float32,0x3e8eee2b,0x3ea4dfcc,3
+np.float32,0xfc8a03c0,0xbf800000,3
+np.float32,0xfd9e4948,0xbf800000,3
+np.float32,0x801e817e,0x801e817e,3
+np.float32,0xbf603a27,0xbf1560c3,3
+np.float32,0x7f729809,0x7f800000,3
+np.float32,0x3f5a1864,0x3fac0e04,3
+np.float32,0x3e7648b8,0x3e8b3677,3
+np.float32,0x3edade24,0x3f088bc1,3
+np.float32,0x65e16e,0x65e16e,3
+np.float32,0x3f24aa50,0x3f671117,3
+np.float32,0x803cb1d0,0x803cb1d0,3
+np.float32,0xbe7b1858,0xbe5eadcc,3
+np.float32,0xbf19bb27,0xbee726fb,3
+np.float32,0xfd1f6e60,0xbf800000,3
+np.float32,0xfeb0de60,0xbf800000,3
+np.float32,0xff511a52,0xbf800000,3
+np.float32,0xff7757f7,0xbf800000,3
+np.float32,0x463ff5,0x463ff5,3
+np.float32,0x3f770d12,0x3fcffcc2,3
+np.float32,0xbf208562,0xbeee80dc,3
+np.float32,0x6df204,0x6df204,3
+np.float32,0xbf62d24f,0xbf1673fb,3
+np.float32,0x3dfcf210,0x3e069d5f,3
+np.float32,0xbef26002,0xbec114d7,3
+np.float32,0x7f800000,0x7f800000,3
+np.float32,0x7f30fb85,0x7f800000,3
+np.float32,0x7ee5dfef,0x7f800000,3
+np.float32,0x3f317829,0x3f800611,3
+np.float32,0x3f4b0bbd,0x3f9aec88,3
+np.float32,0x7edf708c,0x7f800000,3
+np.float32,0xff071260,0xbf800000,3
+np.float32,0x3e7b8c30,0x3e8e9198,3
+np.float32,0x3f33778b,0x3f82077f,3
+np.float32,0x3e8cd11d,0x3ea215fd,3
+np.float32,0x8004483d,0x8004483d,3
+np.float32,0x801633e3,0x801633e3,3
+np.float32,0x7e76eb15,0x7f800000,3
+np.float32,0x3c1571,0x3c1571,3
+np.float32,0x7de3de52,0x7f800000,3
+np.float32,0x804ae906,0x804ae906,3
+np.float32,0x7f3a2616,0x7f800000,3
+np.float32,0xff7fffff,0xbf800000,3
+np.float32,0xff5d17e4,0xbf800000,3
+np.float32,0xbeaa6704,0xbe90f252,3
+np.float32,0x7e6a43af,0x7f800000,3
+np.float32,0x2a0f35,0x2a0f35,3
+np.float32,0xfd8fece0,0xbf800000,3
+np.float32,0xfeef2e2a,0xbf800000,3
+np.float32,0xff800000,0xbf800000,3
+np.float32,0xbeefcc52,0xbebf78e4,3
+np.float32,0x3db6c490,0x3dbf2bd5,3
+np.float32,0x8290f,0x8290f,3
+np.float32,0xbeace648,0xbe92bb7f,3
+np.float32,0x801fea79,0x801fea79,3
+np.float32,0x3ea6c230,0x3ec51ebf,3
+np.float32,0x3e5f2ca3,0x3e795c8a,3
+np.float32,0x3eb6f634,0x3edbeb9f,3
+np.float32,0xff790b45,0xbf800000,3
+np.float32,0x3d82e240,0x3d872816,3
+np.float32,0x3f0d6a57,0x3f3cc7db,3
+np.float32,0x7f08531a,0x7f800000,3
+np.float32,0x702b6d,0x702b6d,3
+np.float32,0x7d3a3c38,0x7f800000,3
+np.float32,0x3d0a7fb3,0x3d0cddf3,3
+np.float32,0xff28084c,0xbf800000,3
+np.float32,0xfeee8804,0xbf800000,3
+np.float32,0x804094eb,0x804094eb,3
+np.float32,0x7acb39,0x7acb39,3
+np.float32,0x3f01c07a,0x3f28f88c,3
+np.float32,0x3e05c500,0x3e0ee674,3
+np.float32,0xbe6f7c38,0xbe558ac1,3
+np.float32,0x803b1f4b,0x803b1f4b,3
+np.float32,0xbf76561f,0xbf1e332b,3
+np.float32,0xff30d368,0xbf800000,3
+np.float32,0x7e2e1f38,0x7f800000,3
+np.float32,0x3ee085b8,0x3f0ce7c0,3
+np.float32,0x8064c4a7,0x8064c4a7,3
+np.float32,0xa7c1d,0xa7c1d,3
+np.float32,0x3f27498a,0x3f6c14bc,3
+np.float32,0x137ca,0x137ca,3
+np.float32,0x3d0a5c60,0x3d0cb969,3
+np.float32,0x80765f1f,0x80765f1f,3
+np.float32,0x80230a71,0x80230a71,3
+np.float32,0x3f321ed2,0x3f80acf4,3
+np.float32,0x7d61e7f4,0x7f800000,3
+np.float32,0xbf39f7f2,0xbf0430f7,3
+np.float32,0xbe2503f8,0xbe1867e8,3
+np.float32,0x29333d,0x29333d,3
+np.float32,0x7edc5a0e,0x7f800000,3
+np.float32,0xbe81a8a2,0xbe651663,3
+np.float32,0x7f76ab6d,0x7f800000,3
+np.float32,0x7f46111f,0x7f800000,3
+np.float32,0xff0fc888,0xbf800000,3
+np.float32,0x805ece89,0x805ece89,3
+np.float32,0xc390b,0xc390b,3
+np.float32,0xff64bdee,0xbf800000,3
+np.float32,0x3dd07e4e,0x3ddb79bd,3
+np.float32,0xfecc1f10,0xbf800000,3
+np.float32,0x803f5177,0x803f5177,3
+np.float32,0x802a24d2,0x802a24d2,3
+np.float32,0x7f27d0cc,0x7f800000,3
+np.float32,0x3ef57c98,0x3f1d7e88,3
+np.float32,0x7b848d,0x7b848d,3
+np.float32,0x7f7fffff,0x7f800000,3
+np.float32,0xfe889c46,0xbf800000,3
+np.float32,0xff2d6dc5,0xbf800000,3
+np.float32,0x3f53a186,0x3fa492a6,3
+np.float32,0xbf239c94,0xbef1c90c,3
+np.float32,0xff7c0f4e,0xbf800000,3
+np.float32,0x3e7c69a9,0x3e8f1f3a,3
+np.float32,0xbf47c9e9,0xbf0ab2a9,3
+np.float32,0xbc1eaf00,0xbc1deae9,3
+np.float32,0x3f4a6d39,0x3f9a3d8e,3
+np.float32,0x3f677930,0x3fbc26eb,3
+np.float32,0x3f45eea1,0x3f955418,3
+np.float32,0x7f61a1f8,0x7f800000,3
+np.float32,0xff58c7c6,0xbf800000,3
+np.float32,0x80239801,0x80239801,3
+np.float32,0xff56e616,0xbf800000,3
+np.float32,0xff62052c,0xbf800000,3
+np.float32,0x8009b615,0x8009b615,3
+np.float32,0x293d6b,0x293d6b,3
+np.float32,0xfe9e585c,0xbf800000,3
+np.float32,0x7f58ff4b,0x7f800000,3
+np.float32,0x10937c,0x10937c,3
+np.float32,0x7f5cc13f,0x7f800000,3
+np.float32,0x110c5d,0x110c5d,3
+np.float32,0x805e51fc,0x805e51fc,3
+np.float32,0xbedcf70a,0xbeb3766c,3
+np.float32,0x3f4d5e42,0x3f9d8091,3
+np.float32,0xff5925a0,0xbf800000,3
+np.float32,0x7e87cafa,0x7f800000,3
+np.float32,0xbf6474b2,0xbf171fee,3
+np.float32,0x4b39b2,0x4b39b2,3
+np.float32,0x8020cc28,0x8020cc28,3
+np.float32,0xff004ed8,0xbf800000,3
+np.float32,0xbf204cf5,0xbeee448d,3
+np.float32,0x3e30cf10,0x3e40fdb1,3
+np.float32,0x80202bee,0x80202bee,3
+np.float32,0xbf55a985,0xbf10e2bc,3
+np.float32,0xbe297dd8,0xbe1c351c,3
+np.float32,0x5780d9,0x5780d9,3
+np.float32,0x7ef729fa,0x7f800000,3
+np.float32,0x8039a3b5,0x8039a3b5,3
+np.float32,0x7cdd3f,0x7cdd3f,3
+np.float32,0x7ef0145a,0x7f800000,3
+np.float32,0x807ad7ae,0x807ad7ae,3
+np.float32,0x7f6c2643,0x7f800000,3
+np.float32,0xbec56124,0xbea3c929,3
+np.float32,0x512c3b,0x512c3b,3
+np.float32,0xbed3effe,0xbead8c1e,3
+np.float32,0x7f5e0a4d,0x7f800000,3
+np.float32,0x3f315316,0x3f7fc200,3
+np.float32,0x7eca5727,0x7f800000,3
+np.float32,0x7f4834f3,0x7f800000,3
+np.float32,0x8004af6d,0x8004af6d,3
+np.float32,0x3f223ca4,0x3f6277e3,3
+np.float32,0x7eea4fdd,0x7f800000,3
+np.float32,0x3e7143e8,0x3e880763,3
+np.float32,0xbf737008,0xbf1d160e,3
+np.float32,0xfc408b00,0xbf800000,3
+np.float32,0x803912ca,0x803912ca,3
+np.float32,0x7db31f4e,0x7f800000,3
+np.float32,0xff578b54,0xbf800000,3
+np.float32,0x3f068ec4,0x3f31062b,3
+np.float32,0x35f64f,0x35f64f,3
+np.float32,0x80437df4,0x80437df4,3
+np.float32,0x568059,0x568059,3
+np.float32,0x8005f8ba,0x8005f8ba,3
+np.float32,0x6824ad,0x6824ad,3
+np.float32,0xff3fdf30,0xbf800000,3
+np.float32,0xbf6f7682,0xbf1b89d6,3
+np.float32,0x3dcea8a0,0x3dd971f5,3
+np.float32,0x3ee32a62,0x3f0ef5a9,3
+np.float32,0xbf735bcd,0xbf1d0e3d,3
+np.float32,0x7e8c7c28,0x7f800000,3
+np.float32,0x3ed552bc,0x3f045161,3
+np.float32,0xfed90a8a,0xbf800000,3
+np.float32,0xbe454368,0xbe336d2a,3
+np.float32,0xbf171d26,0xbee4442d,3
+np.float32,0x80652bf9,0x80652bf9,3
+np.float32,0xbdbaaa20,0xbdb26914,3
+np.float32,0x3f56063d,0x3fa7522e,3
+np.float32,0x3d3d4fd3,0x3d41c13f,3
+np.float32,0x80456040,0x80456040,3
+np.float32,0x3dc15586,0x3dcac0ef,3
+np.float32,0x7f753060,0x7f800000,3
+np.float32,0x7f7d8039,0x7f800000,3
+np.float32,0xfdebf280,0xbf800000,3
+np.float32,0xbf1892c3,0xbee5e116,3
+np.float32,0xbf0f1468,0xbedb3878,3
+np.float32,0x40d85c,0x40d85c,3
+np.float32,0x3f93dd,0x3f93dd,3
+np.float32,0xbf5730fd,0xbf118c24,3
+np.float32,0xfe17aa44,0xbf800000,3
+np.float32,0x3dc0baf4,0x3dca1716,3
+np.float32,0xbf3433d8,0xbf015efb,3
+np.float32,0x1c59f5,0x1c59f5,3
+np.float32,0x802b1540,0x802b1540,3
+np.float32,0xbe47df6c,0xbe35936e,3
+np.float32,0xbe8e7070,0xbe78af32,3
+np.float32,0xfe7057f4,0xbf800000,3
+np.float32,0x80668b69,0x80668b69,3
+np.float32,0xbe677810,0xbe4f2c2d,3
+np.float32,0xbe7a2f1c,0xbe5df733,3
+np.float32,0xfeb79e3c,0xbf800000,3
+np.float32,0xbeb6e320,0xbe99c9e8,3
+np.float32,0xfea188f2,0xbf800000,3
+np.float32,0x7dcaeb15,0x7f800000,3
+np.float32,0x1be567,0x1be567,3
+np.float32,0xbf4041cc,0xbf07320d,3
+np.float32,0x3f721aa7,0x3fc98e9a,3
+np.float32,0x7f5aa835,0x7f800000,3
+np.float32,0x15180e,0x15180e,3
+np.float32,0x3f73d739,0x3fcbccdb,3
+np.float32,0xbeecd380,0xbebd9b36,3
+np.float32,0x3f2caec7,0x3f768fea,3
+np.float32,0xbeaf65f2,0xbe9482bb,3
+np.float32,0xfe6aa384,0xbf800000,3
+np.float32,0xbf4f2c0a,0xbf0e085e,3
+np.float32,0xbf2b5907,0xbef9d431,3
+np.float32,0x3e855e0d,0x3e985960,3
+np.float32,0x8056cc64,0x8056cc64,3
+np.float32,0xff746bb5,0xbf800000,3
+np.float32,0x3e0332f6,0x3e0bf986,3
+np.float32,0xff637720,0xbf800000,3
+np.float32,0xbf330676,0xbf00c990,3
+np.float32,0x3ec449a1,0x3eef3862,3
+np.float32,0x766541,0x766541,3
+np.float32,0xfe2edf6c,0xbf800000,3
+np.float32,0xbebb28ca,0xbe9cc3e2,3
+np.float32,0x3f16c930,0x3f4d5ce4,3
+np.float32,0x7f1a9a4a,0x7f800000,3
+np.float32,0x3e9ba1,0x3e9ba1,3
+np.float32,0xbf73d5f6,0xbf1d3d69,3
+np.float32,0xfdc8a8b0,0xbf800000,3
+np.float32,0x50f051,0x50f051,3
+np.float32,0xff0add02,0xbf800000,3
+np.float32,0x1e50bf,0x1e50bf,3
+np.float32,0x3f04d287,0x3f2e1948,3
+np.float32,0x7f1e50,0x7f1e50,3
+np.float32,0x2affb3,0x2affb3,3
+np.float32,0x80039f07,0x80039f07,3
+np.float32,0x804ba79e,0x804ba79e,3
+np.float32,0x7b5a8eed,0x7f800000,3
+np.float32,0x3e1a8b28,0x3e26d0a7,3
+np.float32,0x3ea95f29,0x3ec8bfa4,3
+np.float32,0x7e09fa55,0x7f800000,3
+np.float32,0x7eacb1b3,0x7f800000,3
+np.float32,0x3e8ad7c0,0x3e9f7dec,3
+np.float32,0x7e0e997c,0x7f800000,3
+np.float32,0x3f4422b4,0x3f936398,3
+np.float32,0x806bd222,0x806bd222,3
+np.float32,0x677ae6,0x677ae6,3
+np.float32,0x62cf68,0x62cf68,3
+np.float32,0x7e4e594e,0x7f800000,3
+np.float32,0x80445fd1,0x80445fd1,3
+np.float32,0xff3a0d04,0xbf800000,3
+np.float32,0x8052b256,0x8052b256,3
+np.float32,0x3cb34440,0x3cb53e11,3
+np.float32,0xbf0e3865,0xbeda3c6d,3
+np.float32,0x3f49f5df,0x3f99ba17,3
+np.float32,0xbed75a22,0xbeafcc09,3
+np.float32,0xbf7aec64,0xbf1fefc8,3
+np.float32,0x7f35a62d,0x7f800000,3
+np.float32,0xbf787b03,0xbf1f03fc,3
+np.float32,0x8006a62a,0x8006a62a,3
+np.float32,0x3f6419e7,0x3fb803c7,3
+np.float32,0x3ecea2e5,0x3efe8f01,3
+np.float32,0x80603577,0x80603577,3
+np.float32,0xff73198c,0xbf800000,3
+np.float32,0x7def110a,0x7f800000,3
+np.float32,0x544efd,0x544efd,3
+np.float32,0x3f052340,0x3f2ea0fc,3
+np.float32,0xff306666,0xbf800000,3
+np.float32,0xbf800000,0xbf21d2a7,3
+np.float32,0xbed3e150,0xbead826a,3
+np.float32,0x3f430c99,0x3f92390f,3
+np.float32,0xbf4bffa4,0xbf0c9c73,3
+np.float32,0xfd97a710,0xbf800000,3
+np.float32,0x3cadf0fe,0x3cafcd1a,3
+np.float32,0x807af7b4,0x807af7b4,3
+np.float32,0xbc508600,0xbc4f33bc,3
+np.float32,0x7f3e0ec7,0x7f800000,3
+np.float32,0xbe51334c,0xbe3d36f7,3
+np.float32,0xfe7b7fb4,0xbf800000,3
+np.float32,0xfed9c45e,0xbf800000,3
+np.float32,0x3da024eb,0x3da6926a,3
+np.float32,0x7eed9e76,0x7f800000,3
+np.float32,0xbf2b8f1f,0xbefa0b91,3
+np.float32,0x3f2b9286,0x3f746318,3
+np.float32,0xfe8af49c,0xbf800000,3
+np.float32,0x9c4f7,0x9c4f7,3
+np.float32,0x801d7543,0x801d7543,3
+np.float32,0xbf66474a,0xbf17de66,3
+np.float32,0xbf562155,0xbf1116b1,3
+np.float32,0x46a8de,0x46a8de,3
+np.float32,0x8053fe6b,0x8053fe6b,3
+np.float32,0xbf6ee842,0xbf1b51f3,3
+np.float32,0xbf6ad78e,0xbf19b565,3
+np.float32,0xbf012574,0xbecad7ff,3
+np.float32,0x748364,0x748364,3
+np.float32,0x8073f59b,0x8073f59b,3
+np.float32,0xff526825,0xbf800000,3
+np.float32,0xfeb02dc4,0xbf800000,3
+np.float32,0x8033eb1c,0x8033eb1c,3
+np.float32,0x3f3685ea,0x3f8520cc,3
+np.float32,0x7f657902,0x7f800000,3
+np.float32,0xbf75eac4,0xbf1e0a1f,3
+np.float32,0xfe67f384,0xbf800000,3
+np.float32,0x3f56d3cc,0x3fa83faf,3
+np.float32,0x44a4ce,0x44a4ce,3
+np.float32,0x1dc4b3,0x1dc4b3,3
+np.float32,0x4fb3b2,0x4fb3b2,3
+np.float32,0xbea904a4,0xbe8ff3ed,3
+np.float32,0x7e668f16,0x7f800000,3
+np.float32,0x7f538378,0x7f800000,3
+np.float32,0x80541709,0x80541709,3
+np.float32,0x80228040,0x80228040,3
+np.float32,0x7ef9694e,0x7f800000,3
+np.float32,0x3f5fca9b,0x3fb2ce54,3
+np.float32,0xbe9c43c2,0xbe86ab84,3
+np.float32,0xfecee000,0xbf800000,3
+np.float32,0x5a65c2,0x5a65c2,3
+np.float32,0x3f736572,0x3fcb3985,3
+np.float32,0xbf2a03f7,0xbef87600,3
+np.float32,0xfe96b488,0xbf800000,3
+np.float32,0xfedd8800,0xbf800000,3
+np.float32,0x80411804,0x80411804,3
+np.float32,0x7edcb0a6,0x7f800000,3
+np.float32,0x2bb882,0x2bb882,3
+np.float32,0x3f800000,0x3fdbf0a9,3
+np.float32,0x764b27,0x764b27,3
+np.float32,0x7e92035d,0x7f800000,3
+np.float32,0x3e80facb,0x3e92ae1d,3
+np.float32,0x8040b81a,0x8040b81a,3
+np.float32,0x7f487fe4,0x7f800000,3
+np.float32,0xbc641780,0xbc6282ed,3
+np.float32,0x804b0bb9,0x804b0bb9,3
+np.float32,0x7d0b7c39,0x7f800000,3
+np.float32,0xff072080,0xbf800000,3
+np.float32,0xbed7aff8,0xbeb00462,3
+np.float32,0x35e247,0x35e247,3
+np.float32,0xbf7edd19,0xbf216766,3
+np.float32,0x8004a539,0x8004a539,3
+np.float32,0xfdfc1790,0xbf800000,3
+np.float32,0x8037a841,0x8037a841,3
+np.float32,0xfed0a8a8,0xbf800000,3
+np.float32,0x7f1f1697,0x7f800000,3
+np.float32,0x3f2ccc6e,0x3f76ca23,3
+np.float32,0x35eada,0x35eada,3
+np.float32,0xff111f42,0xbf800000,3
+np.float32,0x3ee1ab7f,0x3f0dcbbe,3
+np.float32,0xbf6e89ee,0xbf1b2cd4,3
+np.float32,0x3f58611c,0x3faa0cdc,3
+np.float32,0x1ac6a6,0x1ac6a6,3
+np.float32,0xbf1286fa,0xbedf2312,3
+np.float32,0x7e451137,0x7f800000,3
+np.float32,0xbe92c326,0xbe7f3405,3
+np.float32,0x3f2fdd16,0x3f7cd87b,3
+np.float32,0xbe5c0ea0,0xbe4604c2,3
+np.float32,0xbdb29968,0xbdab0883,3
+np.float32,0x3964,0x3964,3
+np.float32,0x3f0dc236,0x3f3d60a0,3
+np.float32,0x7c3faf06,0x7f800000,3
+np.float32,0xbef41f7a,0xbec22b16,3
+np.float32,0x3f4c0289,0x3f9bfdcc,3
+np.float32,0x806084e9,0x806084e9,3
+np.float32,0x3ed1d8dd,0x3f01b0c1,3
+np.float32,0x806d8d8b,0x806d8d8b,3
+np.float32,0x3f052180,0x3f2e9e0a,3
+np.float32,0x803d85d5,0x803d85d5,3
+np.float32,0x3e0afd70,0x3e14dd48,3
+np.float32,0x2fbc63,0x2fbc63,3
+np.float32,0x2e436f,0x2e436f,3
+np.float32,0xbf7b19e6,0xbf2000da,3
+np.float32,0x3f34022e,0x3f829362,3
+np.float32,0x3d2b40e0,0x3d2ee246,3
+np.float32,0x3f5298b4,0x3fa3649b,3
+np.float32,0xbdb01328,0xbda8b7de,3
+np.float32,0x7f693c81,0x7f800000,3
+np.float32,0xbeb1abc0,0xbe961edc,3
+np.float32,0x801d9b5d,0x801d9b5d,3
+np.float32,0x80628668,0x80628668,3
+np.float32,0x800f57dd,0x800f57dd,3
+np.float32,0x8017c94f,0x8017c94f,3
+np.float32,0xbf16f5f4,0xbee418b8,3
+np.float32,0x3e686476,0x3e827022,3
+np.float32,0xbf256796,0xbef3abd9,3
+np.float32,0x7f1b4485,0x7f800000,3
+np.float32,0xbea0b3cc,0xbe89ed21,3
+np.float32,0xfee08b2e,0xbf800000,3
+np.float32,0x523cb4,0x523cb4,3
+np.float32,0x3daf2cb2,0x3db6e273,3
+np.float32,0xbd531c40,0xbd4dc323,3
+np.float32,0x80078fe5,0x80078fe5,3
+np.float32,0x80800000,0x80800000,3
+np.float32,0x3f232438,0x3f642d1a,3
+np.float32,0x3ec29446,0x3eecb7c0,3
+np.float32,0x3dbcd2a4,0x3dc5cd1d,3
+np.float32,0x7f045b0d,0x7f800000,3
+np.float32,0x7f22e6d1,0x7f800000,3
+np.float32,0xbf5d3430,0xbf141c80,3
+np.float32,0xbe03ec70,0xbdf78ee6,3
+np.float32,0x3e93ec9a,0x3eab822f,3
+np.float32,0x7f3b9262,0x7f800000,3
+np.float32,0x65ac6a,0x65ac6a,3
+np.float32,0x3db9a8,0x3db9a8,3
+np.float32,0xbf37ab59,0xbf031306,3
+np.float32,0x33c40e,0x33c40e,3
+np.float32,0x7f7a478f,0x7f800000,3
+np.float32,0xbe8532d0,0xbe6a906f,3
+np.float32,0x801c081d,0x801c081d,3
+np.float32,0xbe4212a0,0xbe30ca73,3
+np.float32,0xff0b603e,0xbf800000,3
+np.float32,0x4554dc,0x4554dc,3
+np.float32,0x3dd324be,0x3dde695e,3
+np.float32,0x3f224c44,0x3f629557,3
+np.float32,0x8003cd79,0x8003cd79,3
+np.float32,0xbf31351c,0xbeffc2fd,3
+np.float32,0x8034603a,0x8034603a,3
+np.float32,0xbf6fcb70,0xbf1bab24,3
+np.float32,0x804eb67e,0x804eb67e,3
+np.float32,0xff05c00e,0xbf800000,3
+np.float32,0x3eb5b36f,0x3eda1ec7,3
+np.float32,0x3f1ed7f9,0x3f5c1d90,3
+np.float32,0x3f052d8a,0x3f2eb24b,3
+np.float32,0x5ddf51,0x5ddf51,3
+np.float32,0x7e50c11c,0x7f800000,3
+np.float32,0xff74f55a,0xbf800000,3
+np.float32,0x4322d,0x4322d,3
+np.float32,0x3f16f8a9,0x3f4db27a,3
+np.float32,0x3f4f23d6,0x3f9f7c2c,3
+np.float32,0xbf706c1e,0xbf1bea0a,3
+np.float32,0x3f2cbd52,0x3f76ac77,3
+np.float32,0xf3043,0xf3043,3
+np.float32,0xfee79de0,0xbf800000,3
+np.float32,0x7e942f69,0x7f800000,3
+np.float32,0x180139,0x180139,3
+np.float32,0xff69c678,0xbf800000,3
+np.float32,0x3f46773f,0x3f95e840,3
+np.float32,0x804aae1c,0x804aae1c,3
+np.float32,0x3eb383b4,0x3ed7024c,3
+np.float32,0x8032624e,0x8032624e,3
+np.float32,0xbd0a0f80,0xbd07c27d,3
+np.float32,0xbf1c9b98,0xbeea4a61,3
+np.float32,0x7f370999,0x7f800000,3
+np.float32,0x801931f9,0x801931f9,3
+np.float32,0x3f6f45ce,0x3fc5eea0,3
+np.float32,0xff0ab4cc,0xbf800000,3
+np.float32,0x4c043d,0x4c043d,3
+np.float32,0x8002a599,0x8002a599,3
+np.float32,0xbc4a6080,0xbc4921d7,3
+np.float32,0x3f008d14,0x3f26fb72,3
+np.float32,0x7f48b3d9,0x7f800000,3
+np.float32,0x7cb2ec7e,0x7f800000,3
+np.float32,0xbf1338bd,0xbedfeb61,3
+np.float32,0x0,0x0,3
+np.float32,0xbf2f5b64,0xbefde71c,3
+np.float32,0xbe422974,0xbe30dd56,3
+np.float32,0x3f776be8,0x3fd07950,3
+np.float32,0xbf3e97a1,0xbf06684a,3
+np.float32,0x7d28cb26,0x7f800000,3
+np.float32,0x801618d2,0x801618d2,3
+np.float32,0x807e4f83,0x807e4f83,3
+np.float32,0x8006b07d,0x8006b07d,3
+np.float32,0xfea1c042,0xbf800000,3
+np.float32,0xff24ef74,0xbf800000,3
+np.float32,0xfef7ab16,0xbf800000,3
+np.float32,0x70b771,0x70b771,3
+np.float32,0x7daeb64e,0x7f800000,3
+np.float32,0xbe66e378,0xbe4eb59c,3
+np.float32,0xbead1534,0xbe92dcf7,3
+np.float32,0x7e6769b8,0x7f800000,3
+np.float32,0x7ecd0890,0x7f800000,3
+np.float32,0xbe7380d8,0xbe58b747,3
+np.float32,0x3efa6f2f,0x3f218265,3
+np.float32,0x3f59dada,0x3fabc5eb,3
+np.float32,0xff0f2d20,0xbf800000,3
+np.float32,0x8060210e,0x8060210e,3
+np.float32,0x3ef681e8,0x3f1e51c8,3
+np.float32,0x77a6dd,0x77a6dd,3
+np.float32,0xbebfdd0e,0xbea00399,3
+np.float32,0xfe889b72,0xbf800000,3
+np.float32,0x8049ed2c,0x8049ed2c,3
+np.float32,0x3b089dc4,0x3b08c23e,3
+np.float32,0xbf13c7c4,0xbee08c28,3
+np.float32,0x3efa13b9,0x3f2137d7,3
+np.float32,0x3e9385dc,0x3eaaf914,3
+np.float32,0x7e0e6a43,0x7f800000,3
+np.float32,0x7df6d63f,0x7f800000,3
+np.float32,0x3f3efead,0x3f8dea03,3
+np.float32,0xff52548c,0xbf800000,3
+np.float32,0x803ff9d8,0x803ff9d8,3
+np.float32,0x3c825823,0x3c836303,3
+np.float32,0xfc9e97a0,0xbf800000,3
+np.float32,0xfe644f48,0xbf800000,3
+np.float32,0x802f5017,0x802f5017,3
+np.float32,0x3d5753b9,0x3d5d1661,3
+np.float32,0x7f2a55d2,0x7f800000,3
+np.float32,0x7f4dabfe,0x7f800000,3
+np.float32,0x3f49492a,0x3f98fc47,3
+np.float32,0x3f4d1589,0x3f9d2f82,3
+np.float32,0xff016208,0xbf800000,3
+np.float32,0xbf571cb7,0xbf118365,3
+np.float32,0xbf1ef297,0xbeecd136,3
+np.float32,0x36266b,0x36266b,3
+np.float32,0xbed07b0e,0xbeab4129,3
+np.float32,0x7f553365,0x7f800000,3
+np.float32,0xfe9bb8c6,0xbf800000,3
+np.float32,0xbeb497d6,0xbe982e19,3
+np.float32,0xbf27af6c,0xbef60d16,3
+np.float32,0x55cf51,0x55cf51,3
+np.float32,0x3eab1db0,0x3ecb2e4f,3
+np.float32,0x3e777603,0x3e8bf62f,3
+np.float32,0x7f10e374,0x7f800000,3
+np.float32,0xbf1f6480,0xbeed4b8d,3
+np.float32,0x40479d,0x40479d,3
+np.float32,0x156259,0x156259,3
+np.float32,0x3d852e30,0x3d899b2d,3
+np.float32,0x80014ff3,0x80014ff3,3
+np.float32,0xbd812fa8,0xbd7a645c,3
+np.float32,0x800ab780,0x800ab780,3
+np.float32,0x3ea02ff4,0x3ebc13bd,3
+np.float32,0x7e858b8e,0x7f800000,3
+np.float32,0x75d63b,0x75d63b,3
+np.float32,0xbeb15c94,0xbe95e6e3,3
+np.float32,0x3da0cee0,0x3da74a39,3
+np.float32,0xff21c01c,0xbf800000,3
+np.float32,0x8049b5eb,0x8049b5eb,3
+np.float32,0x80177ab0,0x80177ab0,3
+np.float32,0xff137a50,0xbf800000,3
+np.float32,0x3f7febba,0x3fdbd51c,3
+np.float32,0x8041e4dd,0x8041e4dd,3
+np.float32,0x99b8c,0x99b8c,3
+np.float32,0x5621ba,0x5621ba,3
+np.float32,0x14b534,0x14b534,3
+np.float32,0xbe2eb3a8,0xbe209c95,3
+np.float32,0x7e510c28,0x7f800000,3
+np.float32,0x804ec2f2,0x804ec2f2,3
+np.float32,0x3f662406,0x3fba82b0,3
+np.float32,0x800000,0x800000,3
+np.float32,0x3f3120d6,0x3f7f5d96,3
+np.float32,0x7f179b8e,0x7f800000,3
+np.float32,0x7f65278e,0x7f800000,3
+np.float32,0xfeb50f52,0xbf800000,3
+np.float32,0x7f051bd1,0x7f800000,3
+np.float32,0x7ea0558d,0x7f800000,3
+np.float32,0xbd0a96c0,0xbd08453f,3
+np.float64,0xee82da5ddd05c,0xee82da5ddd05c,3
+np.float64,0x800c3a22d7f87446,0x800c3a22d7f87446,3
+np.float64,0xbfd34b20eaa69642,0xbfd0a825e7688d3e,3
+np.float64,0x3fd6a0f2492d41e5,0x3fdb253b906057b3,3
+np.float64,0xbfda13d8783427b0,0xbfd56b1d76684332,3
+np.float64,0xbfe50b5a99ea16b5,0xbfded7dd82c6f746,3
+np.float64,0x3f82468fc0248d20,0x3f825b7fa9378ee9,3
+np.float64,0x7ff0000000000000,0x7ff0000000000000,3
+np.float64,0x856e50290adca,0x856e50290adca,3
+np.float64,0x7fde55a5fa3cab4b,0x7ff0000000000000,3
+np.float64,0x7fcf2c8dd93e591b,0x7ff0000000000000,3
+np.float64,0x8001b3a0e3236743,0x8001b3a0e3236743,3
+np.float64,0x8000fdb14821fb63,0x8000fdb14821fb63,3
+np.float64,0xbfe3645e08e6c8bc,0xbfdd161362a5e9ef,3
+np.float64,0x7feb34d28b3669a4,0x7ff0000000000000,3
+np.float64,0x80099dd810933bb1,0x80099dd810933bb1,3
+np.float64,0xbfedbcc1097b7982,0xbfe35d86414d53dc,3
+np.float64,0x7fdc406fbdb880de,0x7ff0000000000000,3
+np.float64,0x800c4bf85ab897f1,0x800c4bf85ab897f1,3
+np.float64,0x3fd8f7b0e0b1ef60,0x3fde89b497ae20d8,3
+np.float64,0xffe4fced5c69f9da,0xbff0000000000000,3
+np.float64,0xbfe54d421fea9a84,0xbfdf1be0cbfbfcba,3
+np.float64,0x800af72f3535ee5f,0x800af72f3535ee5f,3
+np.float64,0x3fe24e6570e49ccb,0x3fe8b3a86d970411,3
+np.float64,0xbfdd7b22d0baf646,0xbfd79fac2e4f7558,3
+np.float64,0xbfe6a7654c6d4eca,0xbfe03c1f13f3b409,3
+np.float64,0x3fe2c3eb662587d7,0x3fe98566e625d4f5,3
+np.float64,0x3b1ef71e763e0,0x3b1ef71e763e0,3
+np.float64,0xffed03c6baba078d,0xbff0000000000000,3
+np.float64,0x3febac19d0b75834,0x3ff5fdacc9d51bcd,3
+np.float64,0x800635d6794c6bae,0x800635d6794c6bae,3
+np.float64,0xbfe8cafc827195f9,0xbfe1411438608ae1,3
+np.float64,0x7feeb616a83d6c2c,0x7ff0000000000000,3
+np.float64,0x3fd52d62a2aa5ac5,0x3fd91a07a7f18f44,3
+np.float64,0x80036996b8a6d32e,0x80036996b8a6d32e,3
+np.float64,0x2b1945965632a,0x2b1945965632a,3
+np.float64,0xbfecb5e8c9796bd2,0xbfe2f40fca276aa2,3
+np.float64,0x3fe8669ed4f0cd3e,0x3ff24c89fc9cdbff,3
+np.float64,0x71e9f65ee3d3f,0x71e9f65ee3d3f,3
+np.float64,0xbfd5ab262bab564c,0xbfd261ae108ef79e,3
+np.float64,0xbfe7091342ee1226,0xbfe06bf5622d75f6,3
+np.float64,0x49e888d093d12,0x49e888d093d12,3
+np.float64,0x2272f3dc44e5f,0x2272f3dc44e5f,3
+np.float64,0x7fe98736e0b30e6d,0x7ff0000000000000,3
+np.float64,0x30fa9cde61f54,0x30fa9cde61f54,3
+np.float64,0x7fdc163fc0382c7f,0x7ff0000000000000,3
+np.float64,0xffb40d04ee281a08,0xbff0000000000000,3
+np.float64,0xffe624617f2c48c2,0xbff0000000000000,3
+np.float64,0x3febb582bd376b05,0x3ff608da584d1716,3
+np.float64,0xfc30a5a5f8615,0xfc30a5a5f8615,3
+np.float64,0x3fef202efd7e405e,0x3ffa52009319b069,3
+np.float64,0x8004d0259829a04c,0x8004d0259829a04c,3
+np.float64,0x800622dc71ec45ba,0x800622dc71ec45ba,3
+np.float64,0xffefffffffffffff,0xbff0000000000000,3
+np.float64,0x800e89113c9d1223,0x800e89113c9d1223,3
+np.float64,0x7fba7fde3034ffbb,0x7ff0000000000000,3
+np.float64,0xbfeea31e807d463d,0xbfe3b7369b725915,3
+np.float64,0x3feb7c9589f6f92c,0x3ff5c56cf71b0dff,3
+np.float64,0x3fd52d3b59aa5a77,0x3fd919d0f683fd07,3
+np.float64,0x800de90a43fbd215,0x800de90a43fbd215,3
+np.float64,0x3fe7eb35a9efd66b,0x3ff1c940dbfc6ef9,3
+np.float64,0xbda0adcb7b416,0xbda0adcb7b416,3
+np.float64,0x7fc5753e3a2aea7b,0x7ff0000000000000,3
+np.float64,0xffdd101d103a203a,0xbff0000000000000,3
+np.float64,0x7fcb54f56836a9ea,0x7ff0000000000000,3
+np.float64,0xbfd61c8d6eac391a,0xbfd2b23bc0a2cef4,3
+np.float64,0x3feef55de37deabc,0x3ffa198639a0161d,3
+np.float64,0x7fe4ffbfaea9ff7e,0x7ff0000000000000,3
+np.float64,0x9d1071873a20e,0x9d1071873a20e,3
+np.float64,0x3fef1ecb863e3d97,0x3ffa502a81e09cfc,3
+np.float64,0xad2da12b5a5b4,0xad2da12b5a5b4,3
+np.float64,0xffe614b74c6c296e,0xbff0000000000000,3
+np.float64,0xffe60d3f286c1a7e,0xbff0000000000000,3
+np.float64,0x7fda7d91f4b4fb23,0x7ff0000000000000,3
+np.float64,0x800023f266a047e6,0x800023f266a047e6,3
+np.float64,0x7fdf5f9ad23ebf35,0x7ff0000000000000,3
+np.float64,0x3fa7459f002e8b3e,0x3fa7cf178dcf0af6,3
+np.float64,0x3fe9938d61f3271b,0x3ff39516a13caec3,3
+np.float64,0xbfd59314c3ab262a,0xbfd250830f73efd2,3
+np.float64,0xbfc7e193f72fc328,0xbfc5c924339dd7a8,3
+np.float64,0x7fec1965f17832cb,0x7ff0000000000000,3
+np.float64,0xbfd932908eb26522,0xbfd4d4312d272580,3
+np.float64,0xbfdf2d08e2be5a12,0xbfd8add1413b0b1b,3
+np.float64,0x7fdcf7cc74b9ef98,0x7ff0000000000000,3
+np.float64,0x7fc79300912f2600,0x7ff0000000000000,3
+np.float64,0xffd4bd8f23297b1e,0xbff0000000000000,3
+np.float64,0x41869ce0830e,0x41869ce0830e,3
+np.float64,0x3fe5dcec91ebb9da,0x3fef5e213598cbd4,3
+np.float64,0x800815d9c2902bb4,0x800815d9c2902bb4,3
+np.float64,0x800ba1a4b877434a,0x800ba1a4b877434a,3
+np.float64,0x80069d7bdc4d3af8,0x80069d7bdc4d3af8,3
+np.float64,0xcf00d4339e01b,0xcf00d4339e01b,3
+np.float64,0x80072b71bd4e56e4,0x80072b71bd4e56e4,3
+np.float64,0x80059ca6fbab394f,0x80059ca6fbab394f,3
+np.float64,0x3fe522fc092a45f8,0x3fedf212682bf894,3
+np.float64,0x7fe17f384ea2fe70,0x7ff0000000000000,3
+np.float64,0x0,0x0,3
+np.float64,0x3f72bb4c20257698,0x3f72c64766b52069,3
+np.float64,0x7fbc97c940392f92,0x7ff0000000000000,3
+np.float64,0xffc5904ebd2b209c,0xbff0000000000000,3
+np.float64,0xbfe34fb55b669f6a,0xbfdcff81dd30a49d,3
+np.float64,0x8007ccda006f99b5,0x8007ccda006f99b5,3
+np.float64,0x3fee50e4c8fca1ca,0x3ff9434c7750ad0f,3
+np.float64,0x7fee7b07c67cf60f,0x7ff0000000000000,3
+np.float64,0x3fdcce4a5a399c95,0x3fe230c83f28218a,3
+np.float64,0x7fee5187b37ca30e,0x7ff0000000000000,3
+np.float64,0x3fc48f6a97291ed8,0x3fc64db6200a9833,3
+np.float64,0xc7fec3498ffd9,0xc7fec3498ffd9,3
+np.float64,0x800769c59d2ed38c,0x800769c59d2ed38c,3
+np.float64,0xffe69ede782d3dbc,0xbff0000000000000,3
+np.float64,0x3fecd9770979b2ee,0x3ff76a1f2f0f08f2,3
+np.float64,0x5aa358a8b546c,0x5aa358a8b546c,3
+np.float64,0xbfe795a0506f2b40,0xbfe0afcc52c0166b,3
+np.float64,0xffd4ada1e8a95b44,0xbff0000000000000,3
+np.float64,0xffcac1dc213583b8,0xbff0000000000000,3
+np.float64,0xffe393c15fa72782,0xbff0000000000000,3
+np.float64,0xbfcd6a3c113ad478,0xbfca47a2157b9cdd,3
+np.float64,0xffedde20647bbc40,0xbff0000000000000,3
+np.float64,0x3fd0d011b1a1a024,0x3fd33a57945559f4,3
+np.float64,0x3fef27e29f7e4fc6,0x3ffa5c314e0e3d69,3
+np.float64,0xffe96ff71f72dfee,0xbff0000000000000,3
+np.float64,0xffe762414f2ec482,0xbff0000000000000,3
+np.float64,0x3fc2dcfd3d25b9fa,0x3fc452f41682a12e,3
+np.float64,0xbfbdb125b63b6248,0xbfbc08e6553296d4,3
+np.float64,0x7b915740f724,0x7b915740f724,3
+np.float64,0x60b502b2c16a1,0x60b502b2c16a1,3
+np.float64,0xbfeb38b0be367162,0xbfe254f6782cfc47,3
+np.float64,0x800dc39a3edb8735,0x800dc39a3edb8735,3
+np.float64,0x3fea4fb433349f68,0x3ff468b97cf699f5,3
+np.float64,0xbfd49967962932d0,0xbfd19ceb41ff4cd0,3
+np.float64,0xbfebf75cd377eeba,0xbfe2a576bdbccccc,3
+np.float64,0xbfb653d65c2ca7b0,0xbfb561ab8fcb3f26,3
+np.float64,0xffe3f34b8727e696,0xbff0000000000000,3
+np.float64,0x3fdd798064baf301,0x3fe2b7c130a6fc63,3
+np.float64,0x3febe027e6b7c050,0x3ff63bac1b22e12d,3
+np.float64,0x7fcaa371af3546e2,0x7ff0000000000000,3
+np.float64,0xbfe6ee980a2ddd30,0xbfe05f0bc5dc80d2,3
+np.float64,0xc559c33f8ab39,0xc559c33f8ab39,3
+np.float64,0x84542c2b08a86,0x84542c2b08a86,3
+np.float64,0xbfe5645e046ac8bc,0xbfdf3398dc3cc1bd,3
+np.float64,0x3fee8c48ae7d1892,0x3ff9902899480526,3
+np.float64,0x3fb706471c2e0c8e,0x3fb817787aace8db,3
+np.float64,0x7fefe78f91ffcf1e,0x7ff0000000000000,3
+np.float64,0xbfcf6d560b3edaac,0xbfcbddc72a2130df,3
+np.float64,0x7fd282bfd925057f,0x7ff0000000000000,3
+np.float64,0x3fb973dbee32e7b8,0x3fbac2c87cbd0215,3
+np.float64,0x3fd1ce38ff239c72,0x3fd4876de5164420,3
+np.float64,0x8008ac2e3c31585d,0x8008ac2e3c31585d,3
+np.float64,0x3fa05e06dc20bc00,0x3fa0a1b7de904dce,3
+np.float64,0x7fd925f215324be3,0x7ff0000000000000,3
+np.float64,0x3f949d95d0293b2c,0x3f94d31197d51874,3
+np.float64,0xffdded9e67bbdb3c,0xbff0000000000000,3
+np.float64,0x3fed390dcfba721c,0x3ff7e08c7a709240,3
+np.float64,0x7fe6e62300adcc45,0x7ff0000000000000,3
+np.float64,0xbfd779bc312ef378,0xbfd3a6cb64bb0181,3
+np.float64,0x3fe43e9877287d31,0x3fec3e100ef935fd,3
+np.float64,0x210b68e44216e,0x210b68e44216e,3
+np.float64,0x3fcdffc1e73bff84,0x3fd0e729d02ec539,3
+np.float64,0xcea10c0f9d422,0xcea10c0f9d422,3
+np.float64,0x7feb97a82d772f4f,0x7ff0000000000000,3
+np.float64,0x9b4b4d953696a,0x9b4b4d953696a,3
+np.float64,0x3fd1bd8e95237b1d,0x3fd4716dd34cf828,3
+np.float64,0x800fc273841f84e7,0x800fc273841f84e7,3
+np.float64,0xbfd2aef167255de2,0xbfd0340f30d82f18,3
+np.float64,0x800d021a551a0435,0x800d021a551a0435,3
+np.float64,0xffebf934a8b7f268,0xbff0000000000000,3
+np.float64,0x3fd819849fb03308,0x3fdd43bca0aac749,3
+np.float64,0x7ff8000000000000,0x7ff8000000000000,3
+np.float64,0x27c34b064f86a,0x27c34b064f86a,3
+np.float64,0x7fef4f5a373e9eb3,0x7ff0000000000000,3
+np.float64,0x7fd92fccce325f99,0x7ff0000000000000,3
+np.float64,0x800520869d6a410e,0x800520869d6a410e,3
+np.float64,0x3fccbcaddf397958,0x3fd01bf6b0c4d97f,3
+np.float64,0x80039ebfc4273d80,0x80039ebfc4273d80,3
+np.float64,0xbfed1f0b3c7a3e16,0xbfe31ea6e4c69141,3
+np.float64,0x7fee1bb7c4bc376f,0x7ff0000000000000,3
+np.float64,0xbfa8bee1d8317dc0,0xbfa8283b7dbf95a9,3
+np.float64,0x3fe797db606f2fb6,0x3ff171b1c2bc8fe5,3
+np.float64,0xbfee2ecfdbbc5da0,0xbfe38a3f0a43d14e,3
+np.float64,0x3fe815c7f1302b90,0x3ff1f65165c45d71,3
+np.float64,0xbfbb265c94364cb8,0xbfb9c27ec61a9a1d,3
+np.float64,0x3fcf1cab5d3e3957,0x3fd19c07444642f9,3
+np.float64,0xbfe6ae753f6d5cea,0xbfe03f99666dbe17,3
+np.float64,0xbfd18a2a73a31454,0xbfceaee204aca016,3
+np.float64,0x3fb8a1dffc3143c0,0x3fb9db38341ab1a3,3
+np.float64,0x7fd2a0376025406e,0x7ff0000000000000,3
+np.float64,0x7fe718c0e3ae3181,0x7ff0000000000000,3
+np.float64,0x3fb264d42424c9a8,0x3fb3121f071d4db4,3
+np.float64,0xd27190a7a4e32,0xd27190a7a4e32,3
+np.float64,0xbfe467668c68cecd,0xbfde2c4616738d5e,3
+np.float64,0x800ab9a2b9357346,0x800ab9a2b9357346,3
+np.float64,0x7fcbd108d537a211,0x7ff0000000000000,3
+np.float64,0x3fb79bba6e2f3770,0x3fb8bb2c140d3445,3
+np.float64,0xffefa7165e3f4e2c,0xbff0000000000000,3
+np.float64,0x7fb40185a428030a,0x7ff0000000000000,3
+np.float64,0xbfe9e3d58e73c7ab,0xbfe1c04d51c83d69,3
+np.float64,0x7fef5b97b17eb72e,0x7ff0000000000000,3
+np.float64,0x800a2957683452af,0x800a2957683452af,3
+np.float64,0x800f54f1925ea9e3,0x800f54f1925ea9e3,3
+np.float64,0xeffa4e77dff4a,0xeffa4e77dff4a,3
+np.float64,0xffbe501aa03ca038,0xbff0000000000000,3
+np.float64,0x8006c651bced8ca4,0x8006c651bced8ca4,3
+np.float64,0x3fe159faff22b3f6,0x3fe708f78efbdbed,3
+np.float64,0x800e7d59a31cfab3,0x800e7d59a31cfab3,3
+np.float64,0x3fe6ac2f272d585e,0x3ff07ee5305385c3,3
+np.float64,0x7fd014c054202980,0x7ff0000000000000,3
+np.float64,0xbfe4800b11e90016,0xbfde4648c6f29ce5,3
+np.float64,0xbfe6738470ece709,0xbfe0227b5b42b713,3
+np.float64,0x3fed052add3a0a56,0x3ff7a01819e65c6e,3
+np.float64,0xffe03106f120620e,0xbff0000000000000,3
+np.float64,0x7fe11df4d4e23be9,0x7ff0000000000000,3
+np.float64,0xbfcea25d7b3d44bc,0xbfcb3e808e7ce852,3
+np.float64,0xd0807b03a1010,0xd0807b03a1010,3
+np.float64,0x8004eda4fec9db4b,0x8004eda4fec9db4b,3
+np.float64,0x3fceb5c98d3d6b90,0x3fd15a894b15dd9f,3
+np.float64,0xbfee27228afc4e45,0xbfe38741702f3c0b,3
+np.float64,0xbfe606278c6c0c4f,0xbfdfd7cb6093652d,3
+np.float64,0xbfd66f59bc2cdeb4,0xbfd2ecb2297f6afc,3
+np.float64,0x4aee390095dc8,0x4aee390095dc8,3
+np.float64,0xbfe391355d67226a,0xbfdd46ddc0997014,3
+np.float64,0xffd27765e7a4eecc,0xbff0000000000000,3
+np.float64,0xbfe795e20a2f2bc4,0xbfe0afebc66c4dbd,3
+np.float64,0x7fc9a62e81334c5c,0x7ff0000000000000,3
+np.float64,0xffe4e57e52a9cafc,0xbff0000000000000,3
+np.float64,0x7fac326c8c3864d8,0x7ff0000000000000,3
+np.float64,0x3fe8675f6370cebf,0x3ff24d5863029c15,3
+np.float64,0x7fcf4745e73e8e8b,0x7ff0000000000000,3
+np.float64,0x7fcc9aec9f3935d8,0x7ff0000000000000,3
+np.float64,0x3fec2e8fcab85d20,0x3ff699ccd0b2fed6,3
+np.float64,0x3fd110a968222153,0x3fd38e81a88c2d13,3
+np.float64,0xffb3a68532274d08,0xbff0000000000000,3
+np.float64,0xf0e562bbe1cad,0xf0e562bbe1cad,3
+np.float64,0xbfe815b9e5f02b74,0xbfe0ec9f5023aebc,3
+np.float64,0xbf5151d88022a400,0xbf514f80c465feea,3
+np.float64,0x2547e3144a8fd,0x2547e3144a8fd,3
+np.float64,0x3fedcc0c28fb9818,0x3ff899612fbeb4c5,3
+np.float64,0x3fdc3d1c0f387a38,0x3fe1bf6e2d39bd75,3
+np.float64,0x7fe544dbe62a89b7,0x7ff0000000000000,3
+np.float64,0x8001500e48e2a01d,0x8001500e48e2a01d,3
+np.float64,0xbfed3b2b09fa7656,0xbfe329f3e7bada64,3
+np.float64,0xbfe76a943aeed528,0xbfe09b24e3aa3f79,3
+np.float64,0x3fe944330e328866,0x3ff33d472dee70c5,3
+np.float64,0x8004bbbd6cc9777c,0x8004bbbd6cc9777c,3
+np.float64,0xbfe28133fb650268,0xbfdc1ac230ac4ef5,3
+np.float64,0xc1370af7826e2,0xc1370af7826e2,3
+np.float64,0x7fcfa47f5f3f48fe,0x7ff0000000000000,3
+np.float64,0xbfa3002a04260050,0xbfa2a703a538b54e,3
+np.float64,0xffef44f3903e89e6,0xbff0000000000000,3
+np.float64,0xc32cce298659a,0xc32cce298659a,3
+np.float64,0x7b477cc2f68f0,0x7b477cc2f68f0,3
+np.float64,0x40a7f4ec814ff,0x40a7f4ec814ff,3
+np.float64,0xffee38edf67c71db,0xbff0000000000000,3
+np.float64,0x3fe23f6f1ce47ede,0x3fe8992b8bb03499,3
+np.float64,0x7fc8edfe7f31dbfc,0x7ff0000000000000,3
+np.float64,0x800bb8e6fb3771ce,0x800bb8e6fb3771ce,3
+np.float64,0xbfe11d364ee23a6c,0xbfda82a0c2ef9e46,3
+np.float64,0xbfeb993cb4b7327a,0xbfe27df565da85dc,3
+np.float64,0x10000000000000,0x10000000000000,3
+np.float64,0x3fc1f997d723f330,0x3fc34c5cff060af1,3
+np.float64,0x6e326fa0dc64f,0x6e326fa0dc64f,3
+np.float64,0x800fa30c2c5f4618,0x800fa30c2c5f4618,3
+np.float64,0x7fed16ad603a2d5a,0x7ff0000000000000,3
+np.float64,0x9411cf172823a,0x9411cf172823a,3
+np.float64,0xffece51d4cb9ca3a,0xbff0000000000000,3
+np.float64,0x3fdda3d1453b47a3,0x3fe2d954f7849890,3
+np.float64,0xffd58330172b0660,0xbff0000000000000,3
+np.float64,0xbfc6962ae52d2c54,0xbfc4b4bdf0069f17,3
+np.float64,0xbfb4010a8e280218,0xbfb33e1236f7efa0,3
+np.float64,0x7fd0444909208891,0x7ff0000000000000,3
+np.float64,0xbfe027a24de04f44,0xbfd95e9064101e7c,3
+np.float64,0xa6f3f3214de9,0xa6f3f3214de9,3
+np.float64,0xbfe112eb0fe225d6,0xbfda768f7cbdf346,3
+np.float64,0xbfe99e90d4b33d22,0xbfe1a153e45a382a,3
+np.float64,0xffecb34f8e79669e,0xbff0000000000000,3
+np.float64,0xbfdf32c9653e6592,0xbfd8b159caf5633d,3
+np.float64,0x3fe9519829b2a330,0x3ff34c0a8152e20f,3
+np.float64,0xffd08ec8a7a11d92,0xbff0000000000000,3
+np.float64,0xffd19b71b6a336e4,0xbff0000000000000,3
+np.float64,0x7feda6b9377b4d71,0x7ff0000000000000,3
+np.float64,0x800fda2956bfb453,0x800fda2956bfb453,3
+np.float64,0x3fe54f601bea9ec0,0x3fee483cb03cbde4,3
+np.float64,0xbfe2a8ad5ee5515a,0xbfdc46ee7a10bf0d,3
+np.float64,0xbfd336c8bd266d92,0xbfd09916d432274a,3
+np.float64,0xfff0000000000000,0xbff0000000000000,3
+np.float64,0x3fd9a811a9b35024,0x3fdf8fa68cc048e3,3
+np.float64,0x3fe078c68520f18d,0x3fe58aecc1f9649b,3
+np.float64,0xbfc6d5aa3a2dab54,0xbfc4e9ea84f3d73c,3
+np.float64,0xf9682007f2d04,0xf9682007f2d04,3
+np.float64,0x3fee54523dbca8a4,0x3ff947b826de81f4,3
+np.float64,0x80461e5d008c4,0x80461e5d008c4,3
+np.float64,0x3fdd6d12d5bada26,0x3fe2ade8dee2fa02,3
+np.float64,0x3fcd5f0dfd3abe18,0x3fd081d6cd25731d,3
+np.float64,0x7fa36475c826c8eb,0x7ff0000000000000,3
+np.float64,0xbfdf3ce052be79c0,0xbfd8b78baccfb908,3
+np.float64,0x7fcd890dd13b121b,0x7ff0000000000000,3
+np.float64,0x8000000000000001,0x8000000000000001,3
+np.float64,0x800ec0f4281d81e8,0x800ec0f4281d81e8,3
+np.float64,0xbfba960116352c00,0xbfb94085424496d9,3
+np.float64,0x3fdddedc9bbbbdb8,0x3fe30853fe4ef5ce,3
+np.float64,0x238092a847013,0x238092a847013,3
+np.float64,0xbfe38d4803271a90,0xbfdd429a955c46af,3
+np.float64,0xbfd4c9067329920c,0xbfd1bf6255ed91a4,3
+np.float64,0xbfbee213923dc428,0xbfbd17ce1bda6088,3
+np.float64,0xffd5a2d337ab45a6,0xbff0000000000000,3
+np.float64,0x7fe21bfcf82437f9,0x7ff0000000000000,3
+np.float64,0x3fe2a2714da544e3,0x3fe949594a74ea25,3
+np.float64,0x800e05cf8ebc0b9f,0x800e05cf8ebc0b9f,3
+np.float64,0x559a1526ab343,0x559a1526ab343,3
+np.float64,0xffe6a1b7906d436e,0xbff0000000000000,3
+np.float64,0xffef27d6253e4fab,0xbff0000000000000,3
+np.float64,0xbfe0f90ab0a1f216,0xbfda5828a1edde48,3
+np.float64,0x9675d2ab2cebb,0x9675d2ab2cebb,3
+np.float64,0xffee0f7eecfc1efd,0xbff0000000000000,3
+np.float64,0x2ec005625d801,0x2ec005625d801,3
+np.float64,0x7fde35ff14bc6bfd,0x7ff0000000000000,3
+np.float64,0xffe03f36d9e07e6d,0xbff0000000000000,3
+np.float64,0x7fe09ff7c4213fef,0x7ff0000000000000,3
+np.float64,0xffeac29dd1b5853b,0xbff0000000000000,3
+np.float64,0x3fb63120aa2c6241,0x3fb72ea3de98a853,3
+np.float64,0xffd079eb84a0f3d8,0xbff0000000000000,3
+np.float64,0xbfd3c2cc75a78598,0xbfd1005996880b3f,3
+np.float64,0x7fb80507ee300a0f,0x7ff0000000000000,3
+np.float64,0xffe8006105f000c1,0xbff0000000000000,3
+np.float64,0x8009138b0ab22716,0x8009138b0ab22716,3
+np.float64,0xbfd6dfb40b2dbf68,0xbfd33b8e4008e3b0,3
+np.float64,0xbfe7c2cf9bef859f,0xbfe0c55c807460df,3
+np.float64,0xbfe75fe4da6ebfca,0xbfe09600256d3b81,3
+np.float64,0xffd662fc73acc5f8,0xbff0000000000000,3
+np.float64,0x20b99dbc41735,0x20b99dbc41735,3
+np.float64,0x3fe10b38ade21671,0x3fe68229a9bbeefc,3
+np.float64,0x3743b99c6e878,0x3743b99c6e878,3
+np.float64,0xff9eb5ed903d6be0,0xbff0000000000000,3
+np.float64,0x3ff0000000000000,0x3ffb7e151628aed3,3
+np.float64,0xffb9e0569e33c0b0,0xbff0000000000000,3
+np.float64,0x7fd39c804fa73900,0x7ff0000000000000,3
+np.float64,0x3fe881ef67f103df,0x3ff269dd704b7129,3
+np.float64,0x1b6eb40236dd7,0x1b6eb40236dd7,3
+np.float64,0xbfe734ea432e69d4,0xbfe0813e6355d02f,3
+np.float64,0xffcf48f3743e91e8,0xbff0000000000000,3
+np.float64,0xffed10bcf6fa2179,0xbff0000000000000,3
+np.float64,0x3fef07723b7e0ee4,0x3ffa3156123f3c15,3
+np.float64,0xffe45c704aa8b8e0,0xbff0000000000000,3
+np.float64,0xb7b818d96f703,0xb7b818d96f703,3
+np.float64,0x42fcc04085f99,0x42fcc04085f99,3
+np.float64,0xbfda7ced01b4f9da,0xbfd5b0ce1e5524ae,3
+np.float64,0xbfe1e5963d63cb2c,0xbfdb6a87b6c09185,3
+np.float64,0x7fdfa18003bf42ff,0x7ff0000000000000,3
+np.float64,0xbfe3790a43e6f214,0xbfdd2c9a38b4f089,3
+np.float64,0xffe0ff5b9ae1feb6,0xbff0000000000000,3
+np.float64,0x80085a7d3110b4fb,0x80085a7d3110b4fb,3
+np.float64,0xffd6bfa6622d7f4c,0xbff0000000000000,3
+np.float64,0xbfef5ddc7cfebbb9,0xbfe3fe170521593e,3
+np.float64,0x3fc21773fa242ee8,0x3fc36ebda1f91a72,3
+np.float64,0x7fc04d98da209b31,0x7ff0000000000000,3
+np.float64,0xbfeba3b535b7476a,0xbfe282602e3c322e,3
+np.float64,0xffd41fb5c1a83f6c,0xbff0000000000000,3
+np.float64,0xf87d206df0fa4,0xf87d206df0fa4,3
+np.float64,0x800060946fc0c12a,0x800060946fc0c12a,3
+np.float64,0x3fe69d5f166d3abe,0x3ff06fdddcf4ca93,3
+np.float64,0x7fe9b5793b336af1,0x7ff0000000000000,3
+np.float64,0x7fe0dd4143e1ba82,0x7ff0000000000000,3
+np.float64,0xbfa8eaea3c31d5d0,0xbfa8522e397da3bd,3
+np.float64,0x119f0078233e1,0x119f0078233e1,3
+np.float64,0xbfd78a207aaf1440,0xbfd3b225bbf2ab4f,3
+np.float64,0xc66a6d4d8cd4e,0xc66a6d4d8cd4e,3
+np.float64,0xe7fc4b57cff8a,0xe7fc4b57cff8a,3
+np.float64,0x800883e8091107d0,0x800883e8091107d0,3
+np.float64,0x3fa6520c842ca419,0x3fa6d06e1041743a,3
+np.float64,0x3fa563182c2ac630,0x3fa5d70e27a84c97,3
+np.float64,0xe6a30b61cd462,0xe6a30b61cd462,3
+np.float64,0x3fee85dac37d0bb6,0x3ff987cfa41a9778,3
+np.float64,0x3fe8f621db71ec44,0x3ff2e7b768a2e9d0,3
+np.float64,0x800f231d861e463b,0x800f231d861e463b,3
+np.float64,0xbfe22eb07c645d61,0xbfdbbdbb853ab4c6,3
+np.float64,0x7fd2dda2dea5bb45,0x7ff0000000000000,3
+np.float64,0xbfd09b79a0a136f4,0xbfcd4147606ffd27,3
+np.float64,0xca039cc394074,0xca039cc394074,3
+np.float64,0x8000000000000000,0x8000000000000000,3
+np.float64,0xcb34575d9668b,0xcb34575d9668b,3
+np.float64,0x3fea62c1f3f4c584,0x3ff47e6dc67ec89f,3
+np.float64,0x7fe544c8606a8990,0x7ff0000000000000,3
+np.float64,0xffe0a980c4615301,0xbff0000000000000,3
+np.float64,0x3fdd67d5f8bacfac,0x3fe2a9c3421830f1,3
+np.float64,0xffe41d3dda283a7b,0xbff0000000000000,3
+np.float64,0xffeed59e5ffdab3c,0xbff0000000000000,3
+np.float64,0xffeeae8326fd5d05,0xbff0000000000000,3
+np.float64,0x800d70b4fa7ae16a,0x800d70b4fa7ae16a,3
+np.float64,0xffec932e6839265c,0xbff0000000000000,3
+np.float64,0xee30b185dc616,0xee30b185dc616,3
+np.float64,0x7fc3cf4397279e86,0x7ff0000000000000,3
+np.float64,0xbfeab34f1875669e,0xbfe21b868229de7d,3
+np.float64,0xf45f5f7de8bec,0xf45f5f7de8bec,3
+np.float64,0x3fad2c4b203a5896,0x3fae0528b568f3cf,3
+np.float64,0xbfe2479543e48f2a,0xbfdbd9e57cf64028,3
+np.float64,0x3fd41a1473283429,0x3fd79df2bc60debb,3
+np.float64,0x3febb5155ef76a2a,0x3ff608585afd698b,3
+np.float64,0xffe21f5303e43ea6,0xbff0000000000000,3
+np.float64,0x7fe9ef390833de71,0x7ff0000000000000,3
+np.float64,0xffe8ee873d71dd0e,0xbff0000000000000,3
+np.float64,0x7fd7cbc55e2f978a,0x7ff0000000000000,3
+np.float64,0x80081f9080d03f21,0x80081f9080d03f21,3
+np.float64,0x7fecbafc8b3975f8,0x7ff0000000000000,3
+np.float64,0x800b6c4b0b16d896,0x800b6c4b0b16d896,3
+np.float64,0xbfaa0fc2d4341f80,0xbfa968cdf32b98ad,3
+np.float64,0x3fec79fe4078f3fc,0x3ff6f5361a4a5d93,3
+np.float64,0xbfb14b79de2296f0,0xbfb0b93b75ecec11,3
+np.float64,0x800009d084c013a2,0x800009d084c013a2,3
+np.float64,0x4a4cdfe29499d,0x4a4cdfe29499d,3
+np.float64,0xbfe721c2d56e4386,0xbfe077f541987d76,3
+np.float64,0x3e5f539e7cbeb,0x3e5f539e7cbeb,3
+np.float64,0x3fd23f044c247e09,0x3fd51ceafcdd64aa,3
+np.float64,0x3fc70785b02e0f0b,0x3fc93b2a37eb342a,3
+np.float64,0xbfe7ab4ec7af569e,0xbfe0ba28eecbf6b0,3
+np.float64,0x800c1d4134583a83,0x800c1d4134583a83,3
+np.float64,0xffd9a73070334e60,0xbff0000000000000,3
+np.float64,0x68a4bf24d1499,0x68a4bf24d1499,3
+np.float64,0x7feba9d9507753b2,0x7ff0000000000000,3
+np.float64,0xbfe9d747db73ae90,0xbfe1bab53d932010,3
+np.float64,0x800a9a4aed953496,0x800a9a4aed953496,3
+np.float64,0xffcb89b0ad371360,0xbff0000000000000,3
+np.float64,0xbfc62388b82c4710,0xbfc4547be442a38c,3
+np.float64,0x800a006d187400db,0x800a006d187400db,3
+np.float64,0x3fcef2fbd33de5f8,0x3fd18177b2150148,3
+np.float64,0x8000b74e3da16e9d,0x8000b74e3da16e9d,3
+np.float64,0x25be536e4b7cb,0x25be536e4b7cb,3
+np.float64,0x3fa86e189430dc31,0x3fa905b4684c9f01,3
+np.float64,0xa7584b114eb0a,0xa7584b114eb0a,3
+np.float64,0x800331133c866227,0x800331133c866227,3
+np.float64,0x3fb52b48142a5690,0x3fb611a6f6e7c664,3
+np.float64,0x3fe825797cf04af2,0x3ff206fd60e98116,3
+np.float64,0x3fd0bec4e5217d8a,0x3fd323db3ffd59b2,3
+np.float64,0x907b43a120f7,0x907b43a120f7,3
+np.float64,0x3fed31eb1d3a63d6,0x3ff7d7a91c6930a4,3
+np.float64,0x7f97a13d782f427a,0x7ff0000000000000,3
+np.float64,0xffc7121a702e2434,0xbff0000000000000,3
+np.float64,0xbfe8bb4cbbf1769a,0xbfe139d7f46f1fb1,3
+np.float64,0xbfe3593cc5a6b27a,0xbfdd09ec91d6cd48,3
+np.float64,0x7fcff218ff9ff,0x7fcff218ff9ff,3
+np.float64,0x3fe73651d4ae6ca4,0x3ff10c5c1d21d127,3
+np.float64,0x80054e396eaa9c74,0x80054e396eaa9c74,3
+np.float64,0x3fe527d5f9aa4fac,0x3fedfb7743db9b53,3
+np.float64,0x7fec6f28c5f8de51,0x7ff0000000000000,3
+np.float64,0x3fcd2bbff53a5780,0x3fd061987416b49b,3
+np.float64,0xffd1f0046423e008,0xbff0000000000000,3
+np.float64,0x80034d97fac69b31,0x80034d97fac69b31,3
+np.float64,0x3faa803f14350080,0x3fab32e3f8073be4,3
+np.float64,0x3fcf8da0163f1b40,0x3fd1e42ba2354c8e,3
+np.float64,0x3fd573c2632ae785,0x3fd97c37609d18d7,3
+np.float64,0x7f922960482452c0,0x7ff0000000000000,3
+np.float64,0x800ebd0c5d3d7a19,0x800ebd0c5d3d7a19,3
+np.float64,0xbfee63b7807cc76f,0xbfe39ec7981035db,3
+np.float64,0xffdc023f8e380480,0xbff0000000000000,3
+np.float64,0x3fe3ffa02c67ff40,0x3febc7f8b900ceba,3
+np.float64,0x36c508b86d8a2,0x36c508b86d8a2,3
+np.float64,0x3fc9fbb0f133f760,0x3fcccee9f6ba801c,3
+np.float64,0x3fd75c1d5faeb83b,0x3fdc3150f9eff99e,3
+np.float64,0x3fe9a8d907b351b2,0x3ff3accc78a31df8,3
+np.float64,0x3fdd8fdcafbb1fb8,0x3fe2c97c97757994,3
+np.float64,0x3fb10c34ca22186a,0x3fb1a0cc42c76b86,3
+np.float64,0xbff0000000000000,0xbfe43a54e4e98864,3
+np.float64,0xffd046aefda08d5e,0xbff0000000000000,3
+np.float64,0x80067989758cf314,0x80067989758cf314,3
+np.float64,0x3fee9d77763d3aef,0x3ff9a67ff0841ba5,3
+np.float64,0xffe4d3cbf8e9a798,0xbff0000000000000,3
+np.float64,0x800f9cab273f3956,0x800f9cab273f3956,3
+np.float64,0x800a5c84f9f4b90a,0x800a5c84f9f4b90a,3
+np.float64,0x4fd377009fa8,0x4fd377009fa8,3
+np.float64,0xbfe7ba26af6f744e,0xbfe0c13ce45d6f95,3
+np.float64,0x609c8a86c1392,0x609c8a86c1392,3
+np.float64,0x7fe4d0296ea9a052,0x7ff0000000000000,3
+np.float64,0x59847bccb3090,0x59847bccb3090,3
+np.float64,0xbfdf944157bf2882,0xbfd8ed092bacad43,3
+np.float64,0xbfe7560a632eac15,0xbfe091405ec34973,3
+np.float64,0x3fea0699f4340d34,0x3ff415eb72089230,3
+np.float64,0x800a5533f374aa68,0x800a5533f374aa68,3
+np.float64,0xbf8e8cdb103d19c0,0xbf8e52cffcb83774,3
+np.float64,0x3fe87d9e52f0fb3d,0x3ff2653952344b81,3
+np.float64,0x7fca3950f73472a1,0x7ff0000000000000,3
+np.float64,0xffd5d1068aaba20e,0xbff0000000000000,3
+np.float64,0x3fd1a5f169a34be4,0x3fd4524b6ef17f91,3
+np.float64,0x3fdc4b95a8b8972c,0x3fe1caafd8652bf7,3
+np.float64,0x3fe333f65a6667ed,0x3fea502fb1f8a578,3
+np.float64,0xbfc117aaac222f54,0xbfc00018a4b84b6e,3
+np.float64,0x7fecf2efdf39e5df,0x7ff0000000000000,3
+np.float64,0x4e99d83e9d33c,0x4e99d83e9d33c,3
+np.float64,0x800d18937bda3127,0x800d18937bda3127,3
+np.float64,0x3fd6c67778ad8cef,0x3fdb5aba70a3ea9e,3
+np.float64,0x3fdbb71770b76e2f,0x3fe157ae8da20bc5,3
+np.float64,0xbfe9faf6ebf3f5ee,0xbfe1ca963d83f17f,3
+np.float64,0x80038850ac0710a2,0x80038850ac0710a2,3
+np.float64,0x8006beb72f8d7d6f,0x8006beb72f8d7d6f,3
+np.float64,0x3feead67bffd5acf,0x3ff9bb43e8b15e2f,3
+np.float64,0xbfd1174b89222e98,0xbfcdff9972799907,3
+np.float64,0x7fee2c077cfc580e,0x7ff0000000000000,3
+np.float64,0xbfbdbd904e3b7b20,0xbfbc13f4916ed466,3
+np.float64,0xffee47b8fe3c8f71,0xbff0000000000000,3
+np.float64,0xffd161884222c310,0xbff0000000000000,3
+np.float64,0xbfd42f27c4a85e50,0xbfd14fa8d67ba5ee,3
+np.float64,0x7fefffffffffffff,0x7ff0000000000000,3
+np.float64,0x8008151791b02a30,0x8008151791b02a30,3
+np.float64,0xbfba79029234f208,0xbfb926616cf41755,3
+np.float64,0x8004c486be29890e,0x8004c486be29890e,3
+np.float64,0x7fe5325a252a64b3,0x7ff0000000000000,3
+np.float64,0x5a880f04b5103,0x5a880f04b5103,3
+np.float64,0xbfe6f4b7702de96f,0xbfe06209002dd72c,3
+np.float64,0xbfdf8b3739bf166e,0xbfd8e783efe3c30f,3
+np.float64,0xbfe32571c8e64ae4,0xbfdcd128b9aa49a1,3
+np.float64,0xbfe97c98c172f932,0xbfe1920ac0fc040f,3
+np.float64,0x3fd0b513a2a16a28,0x3fd31744e3a1bf0a,3
+np.float64,0xffe3ab70832756e0,0xbff0000000000000,3
+np.float64,0x80030f055ce61e0b,0x80030f055ce61e0b,3
+np.float64,0xffd5f3b21b2be764,0xbff0000000000000,3
+np.float64,0x800c1f2d6c783e5b,0x800c1f2d6c783e5b,3
+np.float64,0x80075f4f148ebe9f,0x80075f4f148ebe9f,3
+np.float64,0xbfa5a046f42b4090,0xbfa52cfbf8992256,3
+np.float64,0xffd6702583ace04c,0xbff0000000000000,3
+np.float64,0x800dc0a5cf1b814c,0x800dc0a5cf1b814c,3
+np.float64,0x14f2203a29e45,0x14f2203a29e45,3
+np.float64,0x800421a40ee84349,0x800421a40ee84349,3
+np.float64,0xbfea7c279df4f84f,0xbfe2037fff3ed877,3
+np.float64,0xbfe9b41ddcf3683c,0xbfe1aafe18a44bf8,3
+np.float64,0xffe7b037022f606e,0xbff0000000000000,3
+np.float64,0x800bafb648775f6d,0x800bafb648775f6d,3
+np.float64,0x800b81681d5702d1,0x800b81681d5702d1,3
+np.float64,0x3fe29f8dc8653f1c,0x3fe9442da1c32c6b,3
+np.float64,0xffef9a05dc7f340b,0xbff0000000000000,3
+np.float64,0x800c8c65a65918cb,0x800c8c65a65918cb,3
+np.float64,0xffe99df0d5f33be1,0xbff0000000000000,3
+np.float64,0x9afeb22535fd7,0x9afeb22535fd7,3
+np.float64,0x7fc620dd822c41ba,0x7ff0000000000000,3
+np.float64,0x29c2cdf25385b,0x29c2cdf25385b,3
+np.float64,0x2d92284e5b246,0x2d92284e5b246,3
+np.float64,0xffc794aa942f2954,0xbff0000000000000,3
+np.float64,0xbfe7ed907eafdb21,0xbfe0d9a7b1442497,3
+np.float64,0xbfd4e0d4aea9c1aa,0xbfd1d09366dba2a7,3
+np.float64,0xa70412c34e083,0xa70412c34e083,3
+np.float64,0x41dc0ee083b9,0x41dc0ee083b9,3
+np.float64,0x8000ece20da1d9c5,0x8000ece20da1d9c5,3
+np.float64,0x3fdf3dae103e7b5c,0x3fe42314bf826bc5,3
+np.float64,0x3fe972533c72e4a6,0x3ff3703761e70f04,3
+np.float64,0xffba1d2b82343a58,0xbff0000000000000,3
+np.float64,0xe0086c83c010e,0xe0086c83c010e,3
+np.float64,0x3fe6fb0dde6df61c,0x3ff0cf5fae01aa08,3
+np.float64,0x3fcfaf057e3f5e0b,0x3fd1f98c1fd20139,3
+np.float64,0xbfdca19d9239433c,0xbfd7158745192ca9,3
+np.float64,0xffb17f394e22fe70,0xbff0000000000000,3
+np.float64,0x7fe40f05c7681e0b,0x7ff0000000000000,3
+np.float64,0x800b3c575d5678af,0x800b3c575d5678af,3
+np.float64,0x7fa4ab20ac295640,0x7ff0000000000000,3
+np.float64,0xbfd2fff4f6a5ffea,0xbfd07069bb50e1a6,3
+np.float64,0xbfef81b9147f0372,0xbfe40b845a749787,3
+np.float64,0x7fd7400e54ae801c,0x7ff0000000000000,3
+np.float64,0x3fd4401a17a88034,0x3fd7d20fb76a4f3d,3
+np.float64,0xbfd3e907fd27d210,0xbfd11c64b7577fc5,3
+np.float64,0x7fe34bed9ae697da,0x7ff0000000000000,3
+np.float64,0x80039119c0472234,0x80039119c0472234,3
+np.float64,0xbfe2e36ac565c6d6,0xbfdc88454ee997b3,3
+np.float64,0xbfec57204478ae40,0xbfe2cd3183de1d2d,3
+np.float64,0x7fed7e2a12fafc53,0x7ff0000000000000,3
+np.float64,0x7fd5c5fa7d2b8bf4,0x7ff0000000000000,3
+np.float64,0x3fdcf368d6b9e6d0,0x3fe24decce1ebd35,3
+np.float64,0xbfe0ebfcf2e1d7fa,0xbfda48c9247ae8cf,3
+np.float64,0xbfe10dbea2e21b7e,0xbfda707d68b59674,3
+np.float64,0xbfdf201b6ebe4036,0xbfd8a5df27742fdf,3
+np.float64,0xffe16555be62caab,0xbff0000000000000,3
+np.float64,0xffc23a5db22474bc,0xbff0000000000000,3
+np.float64,0xffe1cbb3f8a39768,0xbff0000000000000,3
+np.float64,0x8007b823be0f7048,0x8007b823be0f7048,3
+np.float64,0xbfa5d1f3042ba3e0,0xbfa55c97cd77bf6e,3
+np.float64,0xbfe316a074662d41,0xbfdcc0da4e7334d0,3
+np.float64,0xbfdfab2bf2bf5658,0xbfd8fb046b88b51f,3
+np.float64,0xfacc9dabf5994,0xfacc9dabf5994,3
+np.float64,0xffe7e420a4efc841,0xbff0000000000000,3
+np.float64,0x800bb986cd57730e,0x800bb986cd57730e,3
+np.float64,0xbfe314fa38e629f4,0xbfdcbf09302c3bf5,3
+np.float64,0x7fc56b17772ad62e,0x7ff0000000000000,3
+np.float64,0x8006a87d54ad50fb,0x8006a87d54ad50fb,3
+np.float64,0xbfe6633e4a6cc67c,0xbfe01a67c3b3ff32,3
+np.float64,0x3fe0ff56eb21feae,0x3fe66df01defb0fb,3
+np.float64,0xffc369cfc126d3a0,0xbff0000000000000,3
+np.float64,0x7fe8775d9a30eeba,0x7ff0000000000000,3
+np.float64,0x3fb53db13e2a7b60,0x3fb625a7279cdac3,3
+np.float64,0xffee76e7e6fcedcf,0xbff0000000000000,3
+np.float64,0xb45595b568ab3,0xb45595b568ab3,3
+np.float64,0xffa09a1d50213440,0xbff0000000000000,3
+np.float64,0x7d11dc16fa23c,0x7d11dc16fa23c,3
+np.float64,0x7fd4cc2928299851,0x7ff0000000000000,3
+np.float64,0x6a30e0ead461d,0x6a30e0ead461d,3
+np.float64,0x7fd3ee735a27dce6,0x7ff0000000000000,3
+np.float64,0x8008d7084b31ae11,0x8008d7084b31ae11,3
+np.float64,0x3fe469353fe8d26a,0x3fec8e7e2df38590,3
+np.float64,0x3fcecef2743d9de5,0x3fd16a888b715dfd,3
+np.float64,0x460130d68c027,0x460130d68c027,3
+np.float64,0xbfd76510c62eca22,0xbfd398766b741d6e,3
+np.float64,0x800ec88c2a5d9118,0x800ec88c2a5d9118,3
+np.float64,0x3fac969c6c392d40,0x3fad66ca6a1e583c,3
+np.float64,0x3fe5c616bf6b8c2e,0x3fef30f931e8dde5,3
+np.float64,0xb4cb6cd56996e,0xb4cb6cd56996e,3
+np.float64,0xffc3eacf8827d5a0,0xbff0000000000000,3
+np.float64,0x3fe1ceaf60e39d5f,0x3fe7d31e0a627cf9,3
+np.float64,0xffea69b42ff4d368,0xbff0000000000000,3
+np.float64,0x800ff8aef99ff15e,0x800ff8aef99ff15e,3
+np.float64,0x6c3953f0d872b,0x6c3953f0d872b,3
+np.float64,0x8007ca5a0d0f94b5,0x8007ca5a0d0f94b5,3
+np.float64,0x800993ce3ad3279d,0x800993ce3ad3279d,3
+np.float64,0x3fe5a4d1516b49a2,0x3feeef67b22ac65b,3
+np.float64,0x8003d7512a67aea3,0x8003d7512a67aea3,3
+np.float64,0x33864430670c9,0x33864430670c9,3
+np.float64,0xbfdbf477e3b7e8f0,0xbfd6a63f1b36f424,3
+np.float64,0x3fb5da92582bb525,0x3fb6d04ef1a1d31a,3
+np.float64,0xe38aae71c7156,0xe38aae71c7156,3
+np.float64,0x3fcaf5590a35eab2,0x3fce01ed6eb6188e,3
+np.float64,0x800deba9b05bd754,0x800deba9b05bd754,3
+np.float64,0x7fee0cde287c19bb,0x7ff0000000000000,3
+np.float64,0xbfe0c2ae70e1855d,0xbfda17fa64d84fcf,3
+np.float64,0x518618faa30c4,0x518618faa30c4,3
+np.float64,0xbfeb4c49b8769894,0xbfe25d52cd7e529f,3
+np.float64,0xbfeb3aa21b367544,0xbfe255cae1df4cfd,3
+np.float64,0xffd23f1c5d247e38,0xbff0000000000000,3
+np.float64,0xff9a75132034ea20,0xbff0000000000000,3
+np.float64,0xbfef9d96307f3b2c,0xbfe415e8b6ce0e50,3
+np.float64,0x8004046f2f0808df,0x8004046f2f0808df,3
+np.float64,0x3fe15871aea2b0e3,0x3fe706532ea5c770,3
+np.float64,0x7fd86b1576b0d62a,0x7ff0000000000000,3
+np.float64,0xbfc240a5c724814c,0xbfc102c7971ca455,3
+np.float64,0xffd8ea670bb1d4ce,0xbff0000000000000,3
+np.float64,0xbfeb1ddd1ff63bba,0xbfe2497c4e27bb8e,3
+np.float64,0x3fcd47e0a33a8fc1,0x3fd0734444150d83,3
+np.float64,0xe00b6a65c016e,0xe00b6a65c016e,3
+np.float64,0xbfc7d582142fab04,0xbfc5bf1fbe755a4c,3
+np.float64,0x8cc91ca11993,0x8cc91ca11993,3
+np.float64,0x7fdbc530e3b78a61,0x7ff0000000000000,3
+np.float64,0x7fee437522bc86e9,0x7ff0000000000000,3
+np.float64,0xffe9e09ae2b3c135,0xbff0000000000000,3
+np.float64,0x8002841cada5083a,0x8002841cada5083a,3
+np.float64,0x3fd6b485f8ad690c,0x3fdb412135932699,3
+np.float64,0x80070e8d0b0e1d1b,0x80070e8d0b0e1d1b,3
+np.float64,0x7fed5df165babbe2,0x7ff0000000000000,3
+np.float64,0x7ff4000000000000,0x7ffc000000000000,3
+np.float64,0x7fe99d08cd333a11,0x7ff0000000000000,3
+np.float64,0xdfff4201bfff,0xdfff4201bfff,3
+np.float64,0x800ccf7aaf999ef6,0x800ccf7aaf999ef6,3
+np.float64,0x3fddb05aad3b60b5,0x3fe2e34bdd1dd9d5,3
+np.float64,0xbfe5e1c60e6bc38c,0xbfdfb3275cc1675f,3
+np.float64,0x8004fe674269fccf,0x8004fe674269fccf,3
+np.float64,0x7fe9280363325006,0x7ff0000000000000,3
+np.float64,0xf605b9f1ec0b7,0xf605b9f1ec0b7,3
+np.float64,0x800c7c214018f843,0x800c7c214018f843,3
+np.float64,0x7fd97eb6b9b2fd6c,0x7ff0000000000000,3
+np.float64,0x7fd03f8fb6207f1e,0x7ff0000000000000,3
+np.float64,0x7fc526b64d2a4d6c,0x7ff0000000000000,3
+np.float64,0xbfef1a7c42fe34f9,0xbfe3e4b4399e0fcf,3
+np.float64,0xffdde10a2fbbc214,0xbff0000000000000,3
+np.float64,0xbfdd274f72ba4e9e,0xbfd76aa73788863c,3
+np.float64,0xbfecf7f77af9efef,0xbfe30ee2ae03fed1,3
+np.float64,0xffde709322bce126,0xbff0000000000000,3
+np.float64,0x268b5dac4d16d,0x268b5dac4d16d,3
+np.float64,0x8005c099606b8134,0x8005c099606b8134,3
+np.float64,0xffcf54c1593ea984,0xbff0000000000000,3
+np.float64,0xbfee9b8ebabd371d,0xbfe3b44f2663139d,3
+np.float64,0x3faf0330643e0661,0x3faff88fab74b447,3
+np.float64,0x7fe1c6011be38c01,0x7ff0000000000000,3
+np.float64,0xbfe9d58053b3ab01,0xbfe1b9ea12242485,3
+np.float64,0xbfe15a80fee2b502,0xbfdaca2aa7d1231a,3
+np.float64,0x7fe0d766d8a1aecd,0x7ff0000000000000,3
+np.float64,0x800f65e6a21ecbcd,0x800f65e6a21ecbcd,3
+np.float64,0x7fc85e45a530bc8a,0x7ff0000000000000,3
+np.float64,0x3fcc240e5438481d,0x3fcf7954fc080ac3,3
+np.float64,0xffddd49da2bba93c,0xbff0000000000000,3
+np.float64,0x1376f36c26edf,0x1376f36c26edf,3
+np.float64,0x3feffb7af17ff6f6,0x3ffb77f0ead2f881,3
+np.float64,0x3fd9354ea9b26a9d,0x3fdee4e4c8db8239,3
+np.float64,0xffdf7beed4bef7de,0xbff0000000000000,3
+np.float64,0xbfdef256ecbde4ae,0xbfd889b0e213a019,3
+np.float64,0x800d78bd1e7af17a,0x800d78bd1e7af17a,3
+np.float64,0xb66d66276cdad,0xb66d66276cdad,3
+np.float64,0x7fd8f51138b1ea21,0x7ff0000000000000,3
+np.float64,0xffe8c9c302b19385,0xbff0000000000000,3
+np.float64,0x8000be4cf5417c9b,0x8000be4cf5417c9b,3
+np.float64,0xbfe2293a25645274,0xbfdbb78a8c547c68,3
+np.float64,0xce8392c19d08,0xce8392c19d08,3
+np.float64,0xbfe075736b60eae7,0xbfd9bc0f6e34a283,3
+np.float64,0xbfe8d6fe6a71adfd,0xbfe1469ba80b4915,3
+np.float64,0xffe0c7993fa18f32,0xbff0000000000000,3
+np.float64,0x3fce5210fd3ca422,0x3fd11b40a1270a95,3
+np.float64,0x6c0534a8d80a7,0x6c0534a8d80a7,3
+np.float64,0x23c1823647831,0x23c1823647831,3
+np.float64,0x3fc901253732024a,0x3fcb9d264accb07c,3
+np.float64,0x3fe42b8997685714,0x3fec1a39e207b6e4,3
+np.float64,0x3fec4fd00fb89fa0,0x3ff6c1fdd0c262c8,3
+np.float64,0x8007b333caaf6668,0x8007b333caaf6668,3
+np.float64,0x800f9275141f24ea,0x800f9275141f24ea,3
+np.float64,0xffbba361a23746c0,0xbff0000000000000,3
+np.float64,0xbfee4effa9fc9dff,0xbfe396c11d0cd524,3
+np.float64,0x3e47e84c7c8fe,0x3e47e84c7c8fe,3
+np.float64,0x3fe80eb7b1301d6f,0x3ff1eed318a00153,3
+np.float64,0x7fd3f4c5b4a7e98a,0x7ff0000000000000,3
+np.float64,0x158abab02b158,0x158abab02b158,3
+np.float64,0x1,0x1,3
+np.float64,0x1f1797883e2f4,0x1f1797883e2f4,3
+np.float64,0x3feec055d03d80ac,0x3ff9d3fb0394de33,3
+np.float64,0x8010000000000000,0x8010000000000000,3
+np.float64,0xbfd070860ea0e10c,0xbfccfeec2828efef,3
+np.float64,0x80015c8b3e82b917,0x80015c8b3e82b917,3
+np.float64,0xffef9956d9ff32ad,0xbff0000000000000,3
+np.float64,0x7fe7f087dd2fe10f,0x7ff0000000000000,3
+np.float64,0x8002e7718665cee4,0x8002e7718665cee4,3
+np.float64,0x3fdfb9adb2bf735c,0x3fe4887a86214c1e,3
+np.float64,0xffc7747dfb2ee8fc,0xbff0000000000000,3
+np.float64,0x3fec309bb5386137,0x3ff69c44e1738547,3
+np.float64,0xffdbe2bf9ab7c580,0xbff0000000000000,3
+np.float64,0xbfe6a274daed44ea,0xbfe039aff2be9d48,3
+np.float64,0x7fd5a4e4efab49c9,0x7ff0000000000000,3
+np.float64,0xffbe6aaeb03cd560,0xbff0000000000000,3
diff --git a/numpy/core/tests/data/umath-validation-set-log b/numpy/core/tests/data/umath-validation-set-log.csv
index b8f6b0875..b8f6b0875 100644
--- a/numpy/core/tests/data/umath-validation-set-log
+++ b/numpy/core/tests/data/umath-validation-set-log.csv
diff --git a/numpy/core/tests/data/umath-validation-set-log10.csv b/numpy/core/tests/data/umath-validation-set-log10.csv
new file mode 100644
index 000000000..7f5241a2e
--- /dev/null
+++ b/numpy/core/tests/data/umath-validation-set-log10.csv
@@ -0,0 +1,1629 @@
+dtype,input,output,ulperrortol
+np.float32,0x3f6fd5c8,0xbce80e8e,4
+np.float32,0x3ea4ab17,0xbefc3deb,4
+np.float32,0x3e87a133,0xbf13b0b7,4
+np.float32,0x3f0d9069,0xbe83bb19,4
+np.float32,0x3f7b9269,0xbbf84f47,4
+np.float32,0x3f7a9ffa,0xbc16fd97,4
+np.float32,0x7f535d34,0x4219cb66,4
+np.float32,0x3e79ad7c,0xbf1ce857,4
+np.float32,0x7e8bfd3b,0x4217dfe9,4
+np.float32,0x3f2d2ee9,0xbe2dcec6,4
+np.float32,0x572e04,0xc21862e4,4
+np.float32,0x7f36f8,0xc217bad5,4
+np.float32,0x3f7982fb,0xbc36aaed,4
+np.float32,0x45b019,0xc218c67c,4
+np.float32,0x3f521c46,0xbdafb3e3,4
+np.float32,0x80000001,0x7fc00000,4
+np.float32,0x3f336c81,0xbe1e107f,4
+np.float32,0x3eac92d7,0xbef1d0bb,4
+np.float32,0x47bdfc,0xc218b990,4
+np.float32,0x7f2d94c8,0x421973d1,4
+np.float32,0x7d53ff8d,0x4214fbb6,4
+np.float32,0x3f581e4e,0xbd96a079,4
+np.float32,0x7ddaf20d,0x42163e4e,4
+np.float32,0x3f341d3c,0xbe1c5b4c,4
+np.float32,0x7ef04ba9,0x4218d032,4
+np.float32,0x620ed2,0xc2182e99,4
+np.float32,0x507850,0xc2188682,4
+np.float32,0x7d08f9,0xc217c284,4
+np.float32,0x7f0cf2aa,0x42191734,4
+np.float32,0x3f109a17,0xbe7e04fe,4
+np.float32,0x7f426152,0x4219a625,4
+np.float32,0x7f32d5a3,0x42198113,4
+np.float32,0x2e14b2,0xc2197e6f,4
+np.float32,0x3a5acd,0xc219156a,4
+np.float32,0x50a565,0xc2188589,4
+np.float32,0x5b751c,0xc2184d97,4
+np.float32,0x7e4149f6,0x42173b22,4
+np.float32,0x3dc34bf9,0xbf82a42a,4
+np.float32,0x3d12bc28,0xbfb910d6,4
+np.float32,0x7ebd2584,0x421865c1,4
+np.float32,0x7f6b3375,0x4219faeb,4
+np.float32,0x7fa00000,0x7fe00000,4
+np.float32,0x3f35fe7d,0xbe17bd33,4
+np.float32,0x7db45c87,0x4215e818,4
+np.float32,0x3efff366,0xbe9a2b8d,4
+np.float32,0x3eb331d0,0xbee971a3,4
+np.float32,0x3f259d5f,0xbe41ae2e,4
+np.float32,0x3eab85ec,0xbef32c4a,4
+np.float32,0x7f194b8a,0x42193c8c,4
+np.float32,0x3f11a614,0xbe7acfc7,4
+np.float32,0x5b17,0xc221f16b,4
+np.float32,0x3f33dadc,0xbe1cff4d,4
+np.float32,0x3cda1506,0xbfc9920f,4
+np.float32,0x3f6856f1,0xbd2c8290,4
+np.float32,0x7f3357fb,0x42198257,4
+np.float32,0x7f56f329,0x4219d2e1,4
+np.float32,0x3ef84108,0xbea0f595,4
+np.float32,0x3f72340f,0xbcc51916,4
+np.float32,0x3daf28,0xc218fcbd,4
+np.float32,0x131035,0xc21b06f4,4
+np.float32,0x3f275c3b,0xbe3d0487,4
+np.float32,0x3ef06130,0xbea82069,4
+np.float32,0x3f57f3b0,0xbd974fef,4
+np.float32,0x7f6c4a78,0x4219fcfa,4
+np.float32,0x7e8421d0,0x4217c639,4
+np.float32,0x3f17a479,0xbe68e08e,4
+np.float32,0x7f03774e,0x4218f83b,4
+np.float32,0x441a33,0xc218d0b8,4
+np.float32,0x539158,0xc21875b6,4
+np.float32,0x3e8fcc75,0xbf0d3018,4
+np.float32,0x7ef74130,0x4218dce4,4
+np.float32,0x3ea6f4fa,0xbef92c38,4
+np.float32,0x7f3948ab,0x421990d5,4
+np.float32,0x7db6f8f5,0x4215ee7c,4
+np.float32,0x3ee44a2f,0xbeb399e5,4
+np.float32,0x156c59,0xc21ad30d,4
+np.float32,0x3f21ee53,0xbe4baf16,4
+np.float32,0x3f2c08f4,0xbe30c424,4
+np.float32,0x3f49885c,0xbdd4c6a9,4
+np.float32,0x3eae0b9c,0xbeefed54,4
+np.float32,0x1b5c1f,0xc21a6646,4
+np.float32,0x3e7330e2,0xbf1fd592,4
+np.float32,0x3ebbeb4c,0xbededf82,4
+np.float32,0x427154,0xc218dbb1,4
+np.float32,0x3f6b8b4b,0xbd142498,4
+np.float32,0x8e769,0xc21c5981,4
+np.float32,0x3e9db557,0xbf02ec1c,4
+np.float32,0x3f001bef,0xbe99f019,4
+np.float32,0x3e58b48c,0xbf2ca77a,4
+np.float32,0x3d46c16b,0xbfa8327c,4
+np.float32,0x7eeeb305,0x4218cd3b,4
+np.float32,0x3e3f163d,0xbf3aa446,4
+np.float32,0x3f66c872,0xbd3877d9,4
+np.float32,0x7f7162f8,0x421a0677,4
+np.float32,0x3edca3bc,0xbebb2e28,4
+np.float32,0x3dc1055b,0xbf834afa,4
+np.float32,0x12b16f,0xc21b0fad,4
+np.float32,0x3f733898,0xbcb62e16,4
+np.float32,0x3e617af8,0xbf283db0,4
+np.float32,0x7e86577a,0x4217cd99,4
+np.float32,0x3f0ba3c7,0xbe86c633,4
+np.float32,0x3f4cad25,0xbdc70247,4
+np.float32,0xb6cdf,0xc21bea9f,4
+np.float32,0x3f42971a,0xbdf3f49e,4
+np.float32,0x3e6ccad2,0xbf22cc78,4
+np.float32,0x7f2121b2,0x421952b8,4
+np.float32,0x3f6d3f55,0xbd075366,4
+np.float32,0x3f524f,0xc218f117,4
+np.float32,0x3e95b5d9,0xbf08b56a,4
+np.float32,0x7f6ae47d,0x4219fa56,4
+np.float32,0x267539,0xc219ceda,4
+np.float32,0x3ef72f6d,0xbea1eb2e,4
+np.float32,0x2100b2,0xc21a12e2,4
+np.float32,0x3d9777d1,0xbf90c4e7,4
+np.float32,0x44c6f5,0xc218cc56,4
+np.float32,0x7f2a613d,0x42196b8a,4
+np.float32,0x390a25,0xc2191f8d,4
+np.float32,0x3f1de5ad,0xbe56e703,4
+np.float32,0x2f59ce,0xc2197258,4
+np.float32,0x7f3b12a1,0x4219951b,4
+np.float32,0x3ecb66d4,0xbecd44ca,4
+np.float32,0x7e74ff,0xc217bd7d,4
+np.float32,0x7ed83f78,0x4218a14d,4
+np.float32,0x685994,0xc21812f1,4
+np.float32,0xbf800000,0x7fc00000,4
+np.float32,0x736f47,0xc217e60b,4
+np.float32,0x7f09c371,0x42190d0a,4
+np.float32,0x3f7ca51d,0xbbbbbce0,4
+np.float32,0x7f4b4d3b,0x4219ba1a,4
+np.float32,0x3f6c4471,0xbd0eb076,4
+np.float32,0xd944e,0xc21b9dcf,4
+np.float32,0x7cb06ffc,0x421375cd,4
+np.float32,0x586187,0xc2185cce,4
+np.float32,0x3f3cbf5b,0xbe078911,4
+np.float32,0x3f30b504,0xbe24d983,4
+np.float32,0x3f0a16ba,0xbe8941fd,4
+np.float32,0x5c43b0,0xc21849af,4
+np.float32,0x3dad74f6,0xbf893bd5,4
+np.float32,0x3c586958,0xbff087a6,4
+np.float32,0x3e8307a8,0xbf1786ba,4
+np.float32,0x7dcd1776,0x4216213d,4
+np.float32,0x3f44d107,0xbde9d662,4
+np.float32,0x3e2e6823,0xbf44cbec,4
+np.float32,0x3d87ea27,0xbf96caca,4
+np.float32,0x3e0c715b,0xbf5ce07e,4
+np.float32,0x7ec9cd5a,0x4218828e,4
+np.float32,0x3e26c0b4,0xbf49c93e,4
+np.float32,0x75b94e,0xc217dd50,4
+np.float32,0x3df7b9f5,0xbf6ad7f4,4
+np.float32,0x0,0xff800000,4
+np.float32,0x3f284795,0xbe3a94da,4
+np.float32,0x7ee49092,0x4218b9f0,4
+np.float32,0x7f4c20e0,0x4219bbe8,4
+np.float32,0x3efbbce8,0xbe9ddc4b,4
+np.float32,0x12274a,0xc21b1cb4,4
+np.float32,0x5fa1b1,0xc21839be,4
+np.float32,0x7f0b210e,0x4219116d,4
+np.float32,0x3f67092a,0xbd368545,4
+np.float32,0x3d572721,0xbfa3ca5b,4
+np.float32,0x3f7913ce,0xbc431028,4
+np.float32,0x3b0613,0xc2191059,4
+np.float32,0x3e1d16c0,0xbf506c6f,4
+np.float32,0xab130,0xc21c081d,4
+np.float32,0x3e23ac97,0xbf4bdb9d,4
+np.float32,0x7ef52368,0x4218d911,4
+np.float32,0x7f38e686,0x42198fe9,4
+np.float32,0x3f106a21,0xbe7e9897,4
+np.float32,0x3ecef8d5,0xbec96644,4
+np.float32,0x3ec37e02,0xbed61683,4
+np.float32,0x3efbd063,0xbe9dcb17,4
+np.float32,0x3f318fe3,0xbe22b402,4
+np.float32,0x7e5e5228,0x4217795d,4
+np.float32,0x72a046,0xc217e92c,4
+np.float32,0x7f6f970b,0x421a0324,4
+np.float32,0x3ed871b4,0xbebf72fb,4
+np.float32,0x7a2eaa,0xc217ccc8,4
+np.float32,0x3e819655,0xbf18c1d7,4
+np.float32,0x80800000,0x7fc00000,4
+np.float32,0x7eab0719,0x421838f9,4
+np.float32,0x7f0763cb,0x4219054f,4
+np.float32,0x3f191672,0xbe64a8af,4
+np.float32,0x7d4327,0xc217c1b6,4
+np.float32,0x3f724ba6,0xbcc3bea3,4
+np.float32,0x60fe06,0xc2183375,4
+np.float32,0x48cd59,0xc218b30b,4
+np.float32,0x3f7fec2b,0xb909d3f3,4
+np.float32,0x1c7bb9,0xc21a5460,4
+np.float32,0x24d8a8,0xc219e1e4,4
+np.float32,0x3e727c52,0xbf20283c,4
+np.float32,0x4bc460,0xc218a14a,4
+np.float32,0x63e313,0xc2182661,4
+np.float32,0x7f625581,0x4219e9d4,4
+np.float32,0x3eeb3e77,0xbeacedc0,4
+np.float32,0x7ef27a47,0x4218d437,4
+np.float32,0x27105a,0xc219c7e6,4
+np.float32,0x22a10b,0xc219fd7d,4
+np.float32,0x3f41e907,0xbdf711ab,4
+np.float32,0x7c1fbf95,0x4212155b,4
+np.float32,0x7e5acceb,0x42177244,4
+np.float32,0x3e0892fa,0xbf5ffb83,4
+np.float32,0x3ea0e51d,0xbf00b2c0,4
+np.float32,0x3e56fc29,0xbf2d8a51,4
+np.float32,0x7ee724ed,0x4218beed,4
+np.float32,0x7ebf142b,0x42186a46,4
+np.float32,0x7f6cf35c,0x4219fe37,4
+np.float32,0x3f11abf7,0xbe7abdcd,4
+np.float32,0x588d7a,0xc2185bf1,4
+np.float32,0x3f6e81d2,0xbcfbcf97,4
+np.float32,0x3f1b6be8,0xbe5dee2b,4
+np.float32,0x7f3815e0,0x42198df2,4
+np.float32,0x3f5bfc88,0xbd86d93d,4
+np.float32,0x3f3775d0,0xbe142bbc,4
+np.float32,0x78a958,0xc217d25a,4
+np.float32,0x2ff7c3,0xc2196c96,4
+np.float32,0x4b9c0,0xc21d733c,4
+np.float32,0x3ec025af,0xbed9ecf3,4
+np.float32,0x6443f0,0xc21824b3,4
+np.float32,0x3f754e28,0xbc97d299,4
+np.float32,0x3eaa91d3,0xbef4699d,4
+np.float32,0x3e5f2837,0xbf296478,4
+np.float32,0xe5676,0xc21b85a4,4
+np.float32,0x3f6859f2,0xbd2c6b90,4
+np.float32,0x3f68686b,0xbd2bfcc6,4
+np.float32,0x4b39b8,0xc218a47b,4
+np.float32,0x630ac4,0xc2182a28,4
+np.float32,0x160980,0xc21ac67d,4
+np.float32,0x3ed91c4d,0xbebec3fd,4
+np.float32,0x7ec27b0d,0x4218721f,4
+np.float32,0x3f3c0a5f,0xbe09344b,4
+np.float32,0x3dbff9c1,0xbf839841,4
+np.float32,0x7f0e8ea7,0x42191c40,4
+np.float32,0x3f36b162,0xbe1608e4,4
+np.float32,0x228bb3,0xc219fe90,4
+np.float32,0x2fdd30,0xc2196d8c,4
+np.float32,0x3e8fce8e,0xbf0d2e79,4
+np.float32,0x3f36acc7,0xbe16141a,4
+np.float32,0x7f44b51c,0x4219ab70,4
+np.float32,0x3ec3371c,0xbed66736,4
+np.float32,0x4388a2,0xc218d473,4
+np.float32,0x3f5aa6c3,0xbd8c4344,4
+np.float32,0x7f09fce4,0x42190dc3,4
+np.float32,0x7ed7854a,0x42189fce,4
+np.float32,0x7f4da83a,0x4219bf3a,4
+np.float32,0x3db8da28,0xbf85b25a,4
+np.float32,0x7f449686,0x4219ab2b,4
+np.float32,0x2eb25,0xc21e498c,4
+np.float32,0x3f2bcc08,0xbe3161bd,4
+np.float32,0x36c923,0xc219317b,4
+np.float32,0x3d52a866,0xbfa4f6d2,4
+np.float32,0x3f7d6688,0xbb913e4e,4
+np.float32,0x3f5a6ba4,0xbd8d33e3,4
+np.float32,0x719740,0xc217ed35,4
+np.float32,0x78a472,0xc217d26c,4
+np.float32,0x7ee33d0c,0x4218b759,4
+np.float32,0x7f668c1d,0x4219f208,4
+np.float32,0x3e29c600,0xbf47ca46,4
+np.float32,0x3f3cefc3,0xbe071712,4
+np.float32,0x3e224ebd,0xbf4cca41,4
+np.float32,0x7f1417be,0x42192d31,4
+np.float32,0x7f29d7d5,0x42196a23,4
+np.float32,0x3338ce,0xc2194f65,4
+np.float32,0x2a7897,0xc219a2b6,4
+np.float32,0x3d6bc3d8,0xbf9eb468,4
+np.float32,0x3f6bd7bf,0xbd11e392,4
+np.float32,0x7f6d26bf,0x4219fe98,4
+np.float32,0x3f52d378,0xbdacadb5,4
+np.float32,0x3efac453,0xbe9eb84a,4
+np.float32,0x3f692eb7,0xbd261184,4
+np.float32,0x3f6a0bb5,0xbd1f7ec1,4
+np.float32,0x3f037a49,0xbe942aa8,4
+np.float32,0x3f465bd4,0xbde2e530,4
+np.float32,0x7ef0f47b,0x4218d16a,4
+np.float32,0x637127,0xc218285e,4
+np.float32,0x3f41e511,0xbdf723d7,4
+np.float32,0x7f800000,0x7f800000,4
+np.float32,0x3f3342d5,0xbe1e77d5,4
+np.float32,0x7f57cfe6,0x4219d4a9,4
+np.float32,0x3e4358ed,0xbf3830a7,4
+np.float32,0x3ce25f15,0xbfc77f2b,4
+np.float32,0x7ed057e7,0x421890be,4
+np.float32,0x7ce154d9,0x4213e295,4
+np.float32,0x3ee91984,0xbeaef703,4
+np.float32,0x7e4e919c,0x421758af,4
+np.float32,0x6830e7,0xc218139e,4
+np.float32,0x3f12f08e,0xbe76e328,4
+np.float32,0x7f0a7a32,0x42190f56,4
+np.float32,0x7f38e,0xc21c8bd3,4
+np.float32,0x3e01def9,0xbf6593e3,4
+np.float32,0x3f5c8c6d,0xbd849432,4
+np.float32,0x3eed8747,0xbeaac7a3,4
+np.float32,0x3cadaa0e,0xbfd63b21,4
+np.float32,0x3f7532a9,0xbc996178,4
+np.float32,0x31f3ac,0xc2195a8f,4
+np.float32,0x3f0e0f97,0xbe82f3af,4
+np.float32,0x3f2a1f35,0xbe35bd3f,4
+np.float32,0x3f4547b2,0xbde7bebd,4
+np.float32,0x3f7988a6,0xbc36094c,4
+np.float32,0x74464c,0xc217e2d2,4
+np.float32,0x7f7518be,0x421a0d3f,4
+np.float32,0x7e97fa0a,0x42180473,4
+np.float32,0x584e3a,0xc2185d2f,4
+np.float32,0x3e7291f3,0xbf201e52,4
+np.float32,0xc0a05,0xc21bd359,4
+np.float32,0x3a3177,0xc21916a6,4
+np.float32,0x4f417f,0xc2188d45,4
+np.float32,0x263fce,0xc219d145,4
+np.float32,0x7e1d58,0xc217beb1,4
+np.float32,0x7f056af3,0x4218fec9,4
+np.float32,0x3f21c181,0xbe4c2a3f,4
+np.float32,0x7eca4956,0x4218839f,4
+np.float32,0x3e58afa8,0xbf2ca9fd,4
+np.float32,0x3f40d583,0xbdfc04ef,4
+np.float32,0x7f432fbb,0x4219a7fc,4
+np.float32,0x43aaa4,0xc218d393,4
+np.float32,0x7f2c9b62,0x42197150,4
+np.float32,0x5c3876,0xc21849e5,4
+np.float32,0x7f2034e8,0x42195029,4
+np.float32,0x7e5be772,0x42177481,4
+np.float32,0x80000000,0xff800000,4
+np.float32,0x3f5be03b,0xbd874bb0,4
+np.float32,0x3e32494f,0xbf4259be,4
+np.float32,0x3e1f4671,0xbf4ee30b,4
+np.float32,0x4606cc,0xc218c454,4
+np.float32,0x425cbc,0xc218dc3b,4
+np.float32,0x7dd9b8bf,0x42163bd0,4
+np.float32,0x3f0465d0,0xbe929db7,4
+np.float32,0x3f735077,0xbcb4d0fa,4
+np.float32,0x4d6a43,0xc21897b8,4
+np.float32,0x3e27d600,0xbf4910f5,4
+np.float32,0x3f06e0cc,0xbe8e7d24,4
+np.float32,0x3f3fd064,0xbe005e45,4
+np.float32,0x176f1,0xc21f7c2d,4
+np.float32,0x3eb64e6f,0xbee59d9c,4
+np.float32,0x7f0f075d,0x42191db8,4
+np.float32,0x3f718cbe,0xbcceb621,4
+np.float32,0x3ead7bda,0xbef0a54a,4
+np.float32,0x7f77c1a8,0x421a120c,4
+np.float32,0x3f6a79c5,0xbd1c3afd,4
+np.float32,0x3e992d1f,0xbf062a02,4
+np.float32,0x3e6f6335,0xbf219639,4
+np.float32,0x7f6d9a3e,0x4219ff70,4
+np.float32,0x557ed1,0xc2186b91,4
+np.float32,0x3f13a456,0xbe74c457,4
+np.float32,0x15c2dc,0xc21acc17,4
+np.float32,0x71f36f,0xc217ebcc,4
+np.float32,0x748dea,0xc217e1c1,4
+np.float32,0x7f0f32e0,0x42191e3f,4
+np.float32,0x5b1da8,0xc2184f41,4
+np.float32,0x3d865d3a,0xbf976e11,4
+np.float32,0x3f800000,0x0,4
+np.float32,0x7f67b56d,0x4219f444,4
+np.float32,0x6266a1,0xc2182d0c,4
+np.float32,0x3ec9c5e4,0xbecf0e6b,4
+np.float32,0x6a6a0e,0xc2180a3b,4
+np.float32,0x7e9db6fd,0x421814ef,4
+np.float32,0x3e7458f7,0xbf1f4e88,4
+np.float32,0x3ead8016,0xbef09fdc,4
+np.float32,0x3e263d1c,0xbf4a211e,4
+np.float32,0x7f6b3329,0x4219faeb,4
+np.float32,0x800000,0xc217b818,4
+np.float32,0x3f0654c7,0xbe8f6471,4
+np.float32,0x3f281b71,0xbe3b0990,4
+np.float32,0x7c4c8e,0xc217c524,4
+np.float32,0x7d113a87,0x4214537d,4
+np.float32,0x734b5f,0xc217e696,4
+np.float32,0x7f079d05,0x4219060b,4
+np.float32,0x3ee830b1,0xbeafd58b,4
+np.float32,0x3f1c3b8b,0xbe5b9d96,4
+np.float32,0x3f2bf0c6,0xbe3102aa,4
+np.float32,0x7ddffe22,0x42164871,4
+np.float32,0x3f1e58b4,0xbe55a37f,4
+np.float32,0x5f3edf,0xc2183b8a,4
+np.float32,0x7f1fb6ec,0x42194eca,4
+np.float32,0x3f78718e,0xbc55311e,4
+np.float32,0x3e574b7d,0xbf2d6152,4
+np.float32,0x7eab27c6,0x4218394e,4
+np.float32,0x7f34603c,0x421984e5,4
+np.float32,0x3f3a8b57,0xbe0cc1ca,4
+np.float32,0x3f744181,0xbca7134e,4
+np.float32,0x3f7e3bc4,0xbb45156b,4
+np.float32,0x93ab4,0xc21c498b,4
+np.float32,0x7ed5541e,0x42189b42,4
+np.float32,0x6bf8ec,0xc21803c4,4
+np.float32,0x757395,0xc217de58,4
+np.float32,0x7f177214,0x42193726,4
+np.float32,0x59935f,0xc21856d6,4
+np.float32,0x2cd9ba,0xc2198a78,4
+np.float32,0x3ef6fd5c,0xbea2183c,4
+np.float32,0x3ebb6c63,0xbedf75e0,4
+np.float32,0x7f43272c,0x4219a7e9,4
+np.float32,0x7f42e67d,0x4219a755,4
+np.float32,0x3f3f744f,0xbe0133f6,4
+np.float32,0x7f5fddaa,0x4219e4f4,4
+np.float32,0x3dc9874f,0xbf80e529,4
+np.float32,0x3f2efe64,0xbe292ec8,4
+np.float32,0x3e0406a6,0xbf63bf7c,4
+np.float32,0x3cdbb0aa,0xbfc92984,4
+np.float32,0x3e6597e7,0xbf263b30,4
+np.float32,0x3f0c1153,0xbe861807,4
+np.float32,0x7fce16,0xc217b8c6,4
+np.float32,0x3f5f4e5f,0xbd730dc6,4
+np.float32,0x3ed41ffa,0xbec3ee69,4
+np.float32,0x3f216c78,0xbe4d1446,4
+np.float32,0x3f123ed7,0xbe78fe4b,4
+np.float32,0x7f7e0ca9,0x421a1d34,4
+np.float32,0x7e318af4,0x42171558,4
+np.float32,0x7f1e1659,0x42194a3d,4
+np.float32,0x34d12a,0xc21941c2,4
+np.float32,0x3d9566ad,0xbf918870,4
+np.float32,0x3e799a47,0xbf1cf0e5,4
+np.float32,0x3e89dd6f,0xbf11df76,4
+np.float32,0x32f0d3,0xc21951d8,4
+np.float32,0x7e89d17e,0x4217d8f6,4
+np.float32,0x1f3b38,0xc21a2b6b,4
+np.float32,0x7ee9e060,0x4218c427,4
+np.float32,0x31a673,0xc2195d41,4
+np.float32,0x5180f1,0xc21880d5,4
+np.float32,0x3cd36f,0xc21902f8,4
+np.float32,0x3bb63004,0xc01050cb,4
+np.float32,0x3e8ee9d1,0xbf0ddfde,4
+np.float32,0x3d2a7da3,0xbfb0b970,4
+np.float32,0x3ea58107,0xbefb1dc3,4
+np.float32,0x7f6760b0,0x4219f3a2,4
+np.float32,0x7f7f9e08,0x421a1ff0,4
+np.float32,0x37e7f1,0xc219287b,4
+np.float32,0x3ef7eb53,0xbea14267,4
+np.float32,0x3e2eb581,0xbf449aa5,4
+np.float32,0x3da7671c,0xbf8b3568,4
+np.float32,0x7af36f7b,0x420f33ee,4
+np.float32,0x3eb3602c,0xbee93823,4
+np.float32,0x3f68bcff,0xbd2975de,4
+np.float32,0x3ea7cefb,0xbef80a9d,4
+np.float32,0x3f329689,0xbe202414,4
+np.float32,0x7f0c7c80,0x421915be,4
+np.float32,0x7f4739b8,0x4219b118,4
+np.float32,0x73af58,0xc217e515,4
+np.float32,0x7f13eb2a,0x42192cab,4
+np.float32,0x30f2d9,0xc2196395,4
+np.float32,0x7ea7066c,0x42182e71,4
+np.float32,0x669fec,0xc2181a5b,4
+np.float32,0x3f7d6876,0xbb90d1ef,4
+np.float32,0x3f08a4ef,0xbe8b9897,4
+np.float32,0x7f2a906c,0x42196c05,4
+np.float32,0x3ed3ca42,0xbec44856,4
+np.float32,0x9d27,0xc220fee2,4
+np.float32,0x3e4508a1,0xbf373c03,4
+np.float32,0x3e41f8de,0xbf38f9bb,4
+np.float32,0x3e912714,0xbf0c255b,4
+np.float32,0xff800000,0x7fc00000,4
+np.float32,0x7eefd13d,0x4218cf4f,4
+np.float32,0x3f491674,0xbdd6bded,4
+np.float32,0x3ef49512,0xbea445c9,4
+np.float32,0x3f045b79,0xbe92af15,4
+np.float32,0x3ef6c412,0xbea24bd5,4
+np.float32,0x3e6f3c28,0xbf21a85d,4
+np.float32,0x3ef71839,0xbea2000e,4
+np.float32,0x1,0xc23369f4,4
+np.float32,0x3e3fcfe4,0xbf3a3876,4
+np.float32,0x3e9d7a65,0xbf0315b2,4
+np.float32,0x20b7c4,0xc21a16bd,4
+np.float32,0x7f707b10,0x421a04cb,4
+np.float32,0x7fc00000,0x7fc00000,4
+np.float32,0x3f285ebd,0xbe3a57ac,4
+np.float32,0x74c9ea,0xc217e0dc,4
+np.float32,0x3f6501f2,0xbd4634ab,4
+np.float32,0x3f248959,0xbe4495cc,4
+np.float32,0x7e915ff0,0x4217f0b3,4
+np.float32,0x7edbb910,0x4218a864,4
+np.float32,0x3f7042dd,0xbce1bddb,4
+np.float32,0x6f08c9,0xc217f754,4
+np.float32,0x7f423993,0x4219a5ca,4
+np.float32,0x3f125704,0xbe78b4cd,4
+np.float32,0x7ef7f5ae,0x4218de28,4
+np.float32,0x3f2dd940,0xbe2c1a33,4
+np.float32,0x3f1ca78e,0xbe5a6a8b,4
+np.float32,0x244863,0xc219e8be,4
+np.float32,0x3f2614fe,0xbe406d6b,4
+np.float32,0x3e75e7a3,0xbf1e99b5,4
+np.float32,0x2bdd6e,0xc2199459,4
+np.float32,0x7e49e279,0x42174e7b,4
+np.float32,0x3e3bb09a,0xbf3ca2cd,4
+np.float32,0x649f06,0xc2182320,4
+np.float32,0x7f4a44e1,0x4219b7d6,4
+np.float32,0x400473,0xc218ec3a,4
+np.float32,0x3edb19ad,0xbebcbcad,4
+np.float32,0x3d8ee956,0xbf94006c,4
+np.float32,0x7e91c603,0x4217f1eb,4
+np.float32,0x221384,0xc21a04a6,4
+np.float32,0x7f7dd660,0x421a1cd5,4
+np.float32,0x7ef34609,0x4218d5ac,4
+np.float32,0x7f5ed529,0x4219e2e5,4
+np.float32,0x7f1bf685,0x42194438,4
+np.float32,0x3cdd094a,0xbfc8d294,4
+np.float32,0x7e87fc8e,0x4217d303,4
+np.float32,0x7f53d971,0x4219cc6b,4
+np.float32,0xabc8b,0xc21c0646,4
+np.float32,0x7f5011e6,0x4219c46a,4
+np.float32,0x7e460638,0x421745e5,4
+np.float32,0xa8126,0xc21c0ffd,4
+np.float32,0x3eec2a66,0xbeac0f2d,4
+np.float32,0x3f3a1213,0xbe0de340,4
+np.float32,0x7f5908db,0x4219d72c,4
+np.float32,0x7e0ad3c5,0x4216a7f3,4
+np.float32,0x3f2de40e,0xbe2bfe90,4
+np.float32,0x3d0463c5,0xbfbec8e4,4
+np.float32,0x7c7cde0b,0x4212e19a,4
+np.float32,0x74c24f,0xc217e0f9,4
+np.float32,0x3f14b4cb,0xbe71929b,4
+np.float32,0x3e94e192,0xbf09537f,4
+np.float32,0x3eebde71,0xbeac56bd,4
+np.float32,0x3f65e413,0xbd3f5b8a,4
+np.float32,0x7e109199,0x4216b9f9,4
+np.float32,0x3f22f5d0,0xbe48ddc0,4
+np.float32,0x3e22d3bc,0xbf4c6f4d,4
+np.float32,0x3f7a812f,0xbc1a680b,4
+np.float32,0x3f67f361,0xbd2f7d7c,4
+np.float32,0x3f1caa63,0xbe5a6281,4
+np.float32,0x3f306fde,0xbe2587ab,4
+np.float32,0x3e8df9d3,0xbf0e9b2f,4
+np.float32,0x3eaaccc4,0xbef41cd4,4
+np.float32,0x7f3f65ec,0x42199f45,4
+np.float32,0x3dc706e0,0xbf8196ec,4
+np.float32,0x3e14eaba,0xbf565cf6,4
+np.float32,0xcc60,0xc2208a09,4
+np.float32,0x358447,0xc2193be7,4
+np.float32,0x3dcecade,0xbf7eec70,4
+np.float32,0x3f20b4f8,0xbe4f0ef0,4
+np.float32,0x7e7c979f,0x4217b222,4
+np.float32,0x7f2387b9,0x4219594a,4
+np.float32,0x3f6f6e5c,0xbcee0e05,4
+np.float32,0x7f19ad81,0x42193da8,4
+np.float32,0x5635e1,0xc21867dd,4
+np.float32,0x4c5e97,0xc2189dc4,4
+np.float32,0x7f35f97f,0x421988d1,4
+np.float32,0x7f685224,0x4219f571,4
+np.float32,0x3eca0616,0xbecec7b8,4
+np.float32,0x3f436d0d,0xbdf024ca,4
+np.float32,0x12a97d,0xc21b106a,4
+np.float32,0x7f0fdc93,0x4219204d,4
+np.float32,0x3debfb42,0xbf703e65,4
+np.float32,0x3c6c54d2,0xbfeba291,4
+np.float32,0x7e5d7491,0x421777a1,4
+np.float32,0x3f4bd2f0,0xbdcab87d,4
+np.float32,0x3f7517f4,0xbc9ae510,4
+np.float32,0x3f71a59a,0xbccd480d,4
+np.float32,0x3f514653,0xbdb33f61,4
+np.float32,0x3f4e6ea4,0xbdbf694b,4
+np.float32,0x3eadadec,0xbef06526,4
+np.float32,0x3f3b41c1,0xbe0b0fbf,4
+np.float32,0xc35a,0xc2209e1e,4
+np.float32,0x384982,0xc2192575,4
+np.float32,0x3464c3,0xc2194556,4
+np.float32,0x7f5e20d9,0x4219e17d,4
+np.float32,0x3ea18b62,0xbf004016,4
+np.float32,0x63a02b,0xc218278c,4
+np.float32,0x7ef547ba,0x4218d953,4
+np.float32,0x3f2496fb,0xbe4470f4,4
+np.float32,0x7ea0c8c6,0x42181d81,4
+np.float32,0x3f42ba60,0xbdf35372,4
+np.float32,0x7e40d9,0xc217be34,4
+np.float32,0x3e95883b,0xbf08d750,4
+np.float32,0x3e0cddf3,0xbf5c8aa8,4
+np.float32,0x3f2305d5,0xbe48b20a,4
+np.float32,0x7f0d0941,0x4219177b,4
+np.float32,0x3f7b98d3,0xbbf6e477,4
+np.float32,0x3f687cdc,0xbd2b6057,4
+np.float32,0x3f42ce91,0xbdf2f73d,4
+np.float32,0x3ee00fc0,0xbeb7c217,4
+np.float32,0x7f3d483a,0x42199a53,4
+np.float32,0x3e1e08eb,0xbf4fc18d,4
+np.float32,0x7e202ff5,0x4216e798,4
+np.float32,0x582898,0xc2185ded,4
+np.float32,0x3e3552b1,0xbf40790c,4
+np.float32,0x3d3f7c87,0xbfaa44b6,4
+np.float32,0x669d8e,0xc2181a65,4
+np.float32,0x3f0e21b4,0xbe82d757,4
+np.float32,0x686f95,0xc2181293,4
+np.float32,0x3f48367f,0xbdda9ead,4
+np.float32,0x3dc27802,0xbf82e0a0,4
+np.float32,0x3f6ac40c,0xbd1a07d4,4
+np.float32,0x3bba6d,0xc2190b12,4
+np.float32,0x3ec7b6b0,0xbed15665,4
+np.float32,0x3f1f9ca4,0xbe521955,4
+np.float32,0x3ef2f147,0xbea5c4b8,4
+np.float32,0x7c65f769,0x4212b762,4
+np.float32,0x7e98e162,0x42180716,4
+np.float32,0x3f0f0c09,0xbe8169ea,4
+np.float32,0x3d67f03b,0xbf9f9d48,4
+np.float32,0x7f3751e4,0x42198c18,4
+np.float32,0x7f1fac61,0x42194ead,4
+np.float32,0x3e9b698b,0xbf048d89,4
+np.float32,0x7e66507b,0x42178913,4
+np.float32,0x7f5cb680,0x4219dea5,4
+np.float32,0x234700,0xc219f53e,4
+np.float32,0x3d9984ad,0xbf900591,4
+np.float32,0x3f33a3f2,0xbe1d872a,4
+np.float32,0x3eaf52b6,0xbeee4cf4,4
+np.float32,0x7f078930,0x421905ca,4
+np.float32,0x3f083b39,0xbe8c44df,4
+np.float32,0x3e3823f8,0xbf3ec231,4
+np.float32,0x3eef6f5d,0xbea9008c,4
+np.float32,0x6145e1,0xc218322c,4
+np.float32,0x16d9ae,0xc21ab65f,4
+np.float32,0x7e543376,0x421764a5,4
+np.float32,0x3ef77ccb,0xbea1a5a0,4
+np.float32,0x3f4a443f,0xbdd18af5,4
+np.float32,0x8f209,0xc21c5770,4
+np.float32,0x3ecac126,0xbecdfa33,4
+np.float32,0x3e8662f9,0xbf14b6c7,4
+np.float32,0x23759a,0xc219f2f4,4
+np.float32,0xf256d,0xc21b6d3f,4
+np.float32,0x3f579f93,0xbd98aaa2,4
+np.float32,0x3ed4cc8e,0xbec339cb,4
+np.float32,0x3ed25400,0xbec5d2a1,4
+np.float32,0x3ed6f8ba,0xbec0f795,4
+np.float32,0x7f36efd9,0x42198b2a,4
+np.float32,0x7f5169dd,0x4219c746,4
+np.float32,0x7de18a20,0x42164b80,4
+np.float32,0x3e8de526,0xbf0eab61,4
+np.float32,0x3de0cbcd,0xbf75a47e,4
+np.float32,0xe265f,0xc21b8b82,4
+np.float32,0x3df3cdbd,0xbf6c9e40,4
+np.float32,0x3f38a25a,0xbe115589,4
+np.float32,0x7f01f2c0,0x4218f311,4
+np.float32,0x3da7d5f4,0xbf8b10a5,4
+np.float32,0x4d4fe8,0xc2189850,4
+np.float32,0x3cc96d9d,0xbfcdfc8d,4
+np.float32,0x259a88,0xc219d8d7,4
+np.float32,0x7f1d5102,0x42194810,4
+np.float32,0x7e17ca91,0x4216cfa7,4
+np.float32,0x3f73d110,0xbcad7a8f,4
+np.float32,0x3f009383,0xbe9920ed,4
+np.float32,0x7e22af,0xc217be9f,4
+np.float32,0x3f7de2ce,0xbb6c0394,4
+np.float32,0x3edd0cd2,0xbebac45a,4
+np.float32,0x3ec9b5c1,0xbecf2035,4
+np.float32,0x3168c5,0xc2195f6b,4
+np.float32,0x3e935522,0xbf0a7d18,4
+np.float32,0x3e494077,0xbf34e120,4
+np.float32,0x3f52ed06,0xbdac41ec,4
+np.float32,0x3f73d51e,0xbcad3f65,4
+np.float32,0x3f03d453,0xbe939295,4
+np.float32,0x7ef4ee68,0x4218d8b1,4
+np.float32,0x3ed0e2,0xc218f4a7,4
+np.float32,0x4efab8,0xc2188ed3,4
+np.float32,0x3dbd5632,0xbf845d3b,4
+np.float32,0x7eecad4f,0x4218c972,4
+np.float32,0x9d636,0xc21c2d32,4
+np.float32,0x3e5f3b6b,0xbf295ae7,4
+np.float32,0x7f4932df,0x4219b57a,4
+np.float32,0x4b59b5,0xc218a3be,4
+np.float32,0x3e5de97f,0xbf2a03b4,4
+np.float32,0x3f1c479d,0xbe5b7b3c,4
+np.float32,0x3f42e7e4,0xbdf283a5,4
+np.float32,0x2445,0xc2238af2,4
+np.float32,0x7aa71b43,0x420e8c9e,4
+np.float32,0x3ede6e4e,0xbeb961e1,4
+np.float32,0x7f05dd3b,0x42190045,4
+np.float32,0x3ef5b55c,0xbea3404b,4
+np.float32,0x7f738624,0x421a0a62,4
+np.float32,0x3e7d50a1,0xbf1b4cb4,4
+np.float32,0x3f44cc4a,0xbde9ebcc,4
+np.float32,0x7e1a7b0b,0x4216d777,4
+np.float32,0x3f1d9868,0xbe57c0da,4
+np.float32,0x1ebee2,0xc21a3263,4
+np.float32,0x31685f,0xc2195f6e,4
+np.float32,0x368a8e,0xc2193379,4
+np.float32,0xa9847,0xc21c0c2e,4
+np.float32,0x3bd3b3,0xc2190a56,4
+np.float32,0x3961e4,0xc2191ce3,4
+np.float32,0x7e13a243,0x4216c34e,4
+np.float32,0x7f7b1790,0x421a17ff,4
+np.float32,0x3e55f020,0xbf2e1545,4
+np.float32,0x3f513861,0xbdb37aa8,4
+np.float32,0x3dd9e754,0xbf791ad2,4
+np.float32,0x5e8d86,0xc2183ec9,4
+np.float32,0x26b796,0xc219cbdd,4
+np.float32,0x429daa,0xc218da89,4
+np.float32,0x3f477caa,0xbdddd9ba,4
+np.float32,0x3f0e5114,0xbe828d45,4
+np.float32,0x3f54f362,0xbda3c286,4
+np.float32,0x6eac1c,0xc217f8c8,4
+np.float32,0x3f04c479,0xbe91fef5,4
+np.float32,0x3e993765,0xbf06228e,4
+np.float32,0x3eafd99f,0xbeeda21b,4
+np.float32,0x3f2a759e,0xbe34db96,4
+np.float32,0x3f05adfb,0xbe907937,4
+np.float32,0x3f6e2dfc,0xbd005980,4
+np.float32,0x3f2f2daa,0xbe28b6b5,4
+np.float32,0x15e746,0xc21ac931,4
+np.float32,0x7d34ca26,0x4214b4e5,4
+np.float32,0x7ebd175c,0x4218659f,4
+np.float32,0x7f1ed26b,0x42194c4c,4
+np.float32,0x2588b,0xc21eaab0,4
+np.float32,0x3f0065e3,0xbe996fe2,4
+np.float32,0x3f610376,0xbd658122,4
+np.float32,0x451995,0xc218ca41,4
+np.float32,0x70e083,0xc217f002,4
+np.float32,0x7e19821a,0x4216d4a8,4
+np.float32,0x3e7cd9a0,0xbf1b80fb,4
+np.float32,0x7f1a8f18,0x42194033,4
+np.float32,0x3f008fee,0xbe99271f,4
+np.float32,0xff7fffff,0x7fc00000,4
+np.float32,0x7f31d826,0x42197e9b,4
+np.float32,0x3f18cf12,0xbe657838,4
+np.float32,0x3e5c1bc7,0xbf2aebf9,4
+np.float32,0x3e3d3993,0xbf3bbaf8,4
+np.float32,0x68457a,0xc2181347,4
+np.float32,0x7ddf7561,0x42164761,4
+np.float32,0x7f47341b,0x4219b10c,4
+np.float32,0x4d3ecd,0xc21898b2,4
+np.float32,0x7f43dee8,0x4219a98b,4
+np.float32,0x3f0def7c,0xbe8325f5,4
+np.float32,0x3d5a551f,0xbfa2f994,4
+np.float32,0x7ed26602,0x4218951b,4
+np.float32,0x3ee7fa5b,0xbeb0099a,4
+np.float32,0x7ef74ea8,0x4218dcfc,4
+np.float32,0x6a3bb2,0xc2180afd,4
+np.float32,0x7f4c1e6e,0x4219bbe3,4
+np.float32,0x3e26f625,0xbf49a5a2,4
+np.float32,0xb8482,0xc21be70b,4
+np.float32,0x3f32f077,0xbe1f445b,4
+np.float32,0x7dd694b6,0x4216355a,4
+np.float32,0x7f3d62fd,0x42199a92,4
+np.float32,0x3f48e41a,0xbdd79cbf,4
+np.float32,0x338fc3,0xc2194c75,4
+np.float32,0x3e8355f0,0xbf174462,4
+np.float32,0x7f487e83,0x4219b3eb,4
+np.float32,0x2227f7,0xc21a039b,4
+np.float32,0x7e4383dd,0x4217403a,4
+np.float32,0x52d28b,0xc21879b2,4
+np.float32,0x12472c,0xc21b19a9,4
+np.float32,0x353530,0xc2193e7b,4
+np.float32,0x3f4e4728,0xbdc0137a,4
+np.float32,0x3bf169,0xc2190979,4
+np.float32,0x3eb3ee2e,0xbee8885f,4
+np.float32,0x3f03e3c0,0xbe937892,4
+np.float32,0x3c9f8408,0xbfdaf47f,4
+np.float32,0x40e792,0xc218e61b,4
+np.float32,0x5a6b29,0xc21852ab,4
+np.float32,0x7f268b83,0x4219616a,4
+np.float32,0x3ee25997,0xbeb57fa7,4
+np.float32,0x3f175324,0xbe69cf53,4
+np.float32,0x3f781d91,0xbc5e9827,4
+np.float32,0x7dba5210,0x4215f68c,4
+np.float32,0x7f1e66,0xc217bb2b,4
+np.float32,0x7f7fffff,0x421a209b,4
+np.float32,0x3f646202,0xbd4b10b8,4
+np.float32,0x575248,0xc218622b,4
+np.float32,0x7c67faa1,0x4212bb42,4
+np.float32,0x7f1683f2,0x42193469,4
+np.float32,0x1a3864,0xc21a7931,4
+np.float32,0x7f30ad75,0x42197bae,4
+np.float32,0x7f1c9d05,0x42194612,4
+np.float32,0x3e791795,0xbf1d2b2c,4
+np.float32,0x7e9ebc19,0x421817cd,4
+np.float32,0x4999b7,0xc218ae31,4
+np.float32,0x3d130e2c,0xbfb8f1cc,4
+np.float32,0x3f7e436f,0xbb41bb07,4
+np.float32,0x3ee00241,0xbeb7cf7d,4
+np.float32,0x7e496181,0x42174d5f,4
+np.float32,0x7efe58be,0x4218e978,4
+np.float32,0x3f5e5b0c,0xbd7aa43f,4
+np.float32,0x7ee4c6ab,0x4218ba59,4
+np.float32,0x3f6da8c6,0xbd043d7e,4
+np.float32,0x3e3e6e0f,0xbf3b064b,4
+np.float32,0x3f0143b3,0xbe97f10a,4
+np.float32,0x79170f,0xc217d0c6,4
+np.float32,0x517645,0xc218810f,4
+np.float32,0x3f1f9960,0xbe52226e,4
+np.float32,0x2a8df9,0xc219a1d6,4
+np.float32,0x2300a6,0xc219f8b8,4
+np.float32,0x3ee31355,0xbeb4c97a,4
+np.float32,0x3f20b05f,0xbe4f1ba9,4
+np.float32,0x3ee64249,0xbeb1b0ff,4
+np.float32,0x3a94b7,0xc21913b2,4
+np.float32,0x7ef7ef43,0x4218de1d,4
+np.float32,0x3f1abb5d,0xbe5fe872,4
+np.float32,0x7f65360b,0x4219ef72,4
+np.float32,0x3d315d,0xc219004c,4
+np.float32,0x3f26bbc4,0xbe3eafb9,4
+np.float32,0x3ee8c6e9,0xbeaf45de,4
+np.float32,0x7e5f1452,0x42177ae1,4
+np.float32,0x3f32e777,0xbe1f5aba,4
+np.float32,0x4d39a1,0xc21898d0,4
+np.float32,0x3e59ad15,0xbf2c2841,4
+np.float32,0x3f4be746,0xbdca5fc4,4
+np.float32,0x72e4fd,0xc217e821,4
+np.float32,0x1af0b8,0xc21a6d25,4
+np.float32,0x3f311147,0xbe23f18d,4
+np.float32,0x3f1ecebb,0xbe545880,4
+np.float32,0x7e90d293,0x4217ef02,4
+np.float32,0x3e3b366a,0xbf3ceb46,4
+np.float32,0x3f133239,0xbe761c96,4
+np.float32,0x7541ab,0xc217df15,4
+np.float32,0x3d8c8275,0xbf94f1a1,4
+np.float32,0x483b92,0xc218b689,4
+np.float32,0x3eb0dbed,0xbeec5c6b,4
+np.float32,0x3f00c676,0xbe98c8e2,4
+np.float32,0x3f445ac2,0xbdebed7c,4
+np.float32,0x3d2af4,0xc219007a,4
+np.float32,0x7f196ee1,0x42193cf2,4
+np.float32,0x290c94,0xc219b1db,4
+np.float32,0x3f5dbdc9,0xbd7f9019,4
+np.float32,0x3e80c62e,0xbf1974fc,4
+np.float32,0x3ec9ed2c,0xbecee326,4
+np.float32,0x7f469d60,0x4219afbb,4
+np.float32,0x3f698413,0xbd2386ce,4
+np.float32,0x42163f,0xc218de14,4
+np.float32,0x67a554,0xc21815f4,4
+np.float32,0x3f4bff74,0xbdc9f651,4
+np.float32,0x16a743,0xc21aba39,4
+np.float32,0x2eb8b0,0xc219784b,4
+np.float32,0x3eed9be1,0xbeaab45b,4
+np.float64,0x7fe0d76873e1aed0,0x40733f9d783bad7a,2
+np.float64,0x3fe22626bb244c4d,0xbfcf86a59864eea2,2
+np.float64,0x7f874113d02e8227,0x407324f54c4015b8,2
+np.float64,0x3fe40a46a9e8148d,0xbfca0411f533fcb9,2
+np.float64,0x3fd03932eea07266,0xbfe312bc9cf5649e,2
+np.float64,0x7fee5d2a1b3cba53,0x407343b5f56367a0,2
+np.float64,0x3feb7bda4a76f7b5,0xbfb0ea2c6edc784a,2
+np.float64,0x3fd6cd831a2d9b06,0xbfdcaf2e1a5faf51,2
+np.float64,0x98324e273064a,0xc0733e0e4c6d11c6,2
+np.float64,0x7fe1dd63b363bac6,0x4073400667c405c3,2
+np.float64,0x3fec5971f178b2e4,0xbfaaef32a7d94563,2
+np.float64,0x17abc07e2f579,0xc0734afca4da721e,2
+np.float64,0x3feec6ab5cfd8d57,0xbf9157f3545a8235,2
+np.float64,0x3fe3ae9622a75d2c,0xbfcb04b5ad254581,2
+np.float64,0x7fea73d854b4e7b0,0x407342c0a548f4c5,2
+np.float64,0x7fe29babf4653757,0x4073404eeb5fe714,2
+np.float64,0x7fd3a55d85a74aba,0x40733bde72e86c27,2
+np.float64,0x3fe83ce305f079c6,0xbfbee3511e85e0f1,2
+np.float64,0x3fd72087ea2e4110,0xbfdc4ab30802d7c2,2
+np.float64,0x7feb54ddab76a9ba,0x407342facb6f3ede,2
+np.float64,0xc57e34a18afd,0xc0734f82ec815baa,2
+np.float64,0x7a8cb97ef5198,0xc0733f8fb3777a67,2
+np.float64,0x7fe801032c300205,0x40734213dbe4eda9,2
+np.float64,0x3aefb1f475df7,0xc07344a5f08a0584,2
+np.float64,0x7fee85f1dd3d0be3,0x407343bf4441c2a7,2
+np.float64,0x3fdc7f1055b8fe21,0xbfd67d300630e893,2
+np.float64,0xe8ecddb3d1d9c,0xc0733b194f18f466,2
+np.float64,0x3fdf2b23c73e5648,0xbfd3ff6872c1f887,2
+np.float64,0x3fdba4aef2b7495e,0xbfd7557205e18b7b,2
+np.float64,0x3fe2ac34c6e5586a,0xbfcdf1dac69bfa08,2
+np.float64,0x3fc9852628330a4c,0xbfe66914f0fb9b0a,2
+np.float64,0x7fda211acf344235,0x40733dd9c2177aeb,2
+np.float64,0x3fe9420eb432841d,0xbfba4dd969a32575,2
+np.float64,0xb2f9d1ed65f3a,0xc0733cedfb6527ff,2
+np.float64,0x3fe9768a68f2ed15,0xbfb967c39c35c435,2
+np.float64,0x7fe8268462b04d08,0x4073421eaed32734,2
+np.float64,0x3fcf331f063e663e,0xbfe39e2f4b427ca9,2
+np.float64,0x7fd4eb9e2b29d73b,0x40733c4e4141418d,2
+np.float64,0x7fd2bba658a5774c,0x40733b89cd53d5b1,2
+np.float64,0x3fdfdf04913fbe09,0xbfd360c7fd9d251b,2
+np.float64,0x3fca5bfd0534b7fa,0xbfe5f5f844b2b20c,2
+np.float64,0x3feacd5032f59aa0,0xbfb3b5234ba8bf7b,2
+np.float64,0x7fe9241cec724839,0x4073426631362cec,2
+np.float64,0x3fe57aca20eaf594,0xbfc628e3ac2c6387,2
+np.float64,0x3fec6553ca38caa8,0xbfaa921368d3b222,2
+np.float64,0x3fe1e9676563d2cf,0xbfd020f866ba9b24,2
+np.float64,0x3fd5590667aab20d,0xbfde8458af5a4fd6,2
+np.float64,0x3fdf7528f43eea52,0xbfd3bdb438d6ba5e,2
+np.float64,0xb8dddc5571bbc,0xc0733cb4601e5bb2,2
+np.float64,0xe6d4e1fbcda9c,0xc0733b295ef4a4ba,2
+np.float64,0x3fe7019d962e033b,0xbfc257c0a6e8de16,2
+np.float64,0x3f94ef585029deb1,0xbffb07e5dfb0e936,2
+np.float64,0x7fc863b08030c760,0x4073388e28d7b354,2
+np.float64,0xf684443bed089,0xc0733ab46cfbff9a,2
+np.float64,0x7fe00e901d201d1f,0x40733f489c05a0f0,2
+np.float64,0x9e5c0a273cb82,0xc0733dc7af797e19,2
+np.float64,0x7fe49734f0692e69,0x4073410303680df0,2
+np.float64,0x7fb7b584442f6b08,0x4073338acff72502,2
+np.float64,0x3f99984c30333098,0xbff9a2642a6ed8cc,2
+np.float64,0x7fea2fcda8745f9a,0x407342aeae7f5e64,2
+np.float64,0xe580caadcb01a,0xc0733b33a3639217,2
+np.float64,0x1899ab3831336,0xc0734ab823729417,2
+np.float64,0x39bd4c76737aa,0xc07344ca6fac6d21,2
+np.float64,0xd755b2dbaeab7,0xc0733ba4fe19f2cc,2
+np.float64,0x3f952bebf82a57d8,0xbffaf3e7749c2512,2
+np.float64,0x3fe62ee5d72c5dcc,0xbfc45e3cb5baad08,2
+np.float64,0xb1264a7d624ca,0xc0733d003a1d0a66,2
+np.float64,0x3fc4bd1bcd297a38,0xbfe94b3058345c46,2
+np.float64,0x7fc5758bb32aeb16,0x407337aa7805497f,2
+np.float64,0x3fb0edcaf421db96,0xbff2dfb09c405294,2
+np.float64,0x3fd240fceaa481fa,0xbfe16f356bb36134,2
+np.float64,0x38c0c62a7181a,0xc07344e916d1e9b7,2
+np.float64,0x3fe98f2b3bf31e56,0xbfb8fc6eb622a820,2
+np.float64,0x3fe2bdf99c257bf3,0xbfcdbd0dbbae4d0b,2
+np.float64,0xce4b390d9c967,0xc0733bf14ada3134,2
+np.float64,0x3fd2ad607ba55ac1,0xbfe11da15167b37b,2
+np.float64,0x3fd8154f11b02a9e,0xbfdb2a6fabb9a026,2
+np.float64,0xf37849fde6f09,0xc0733aca8c64344c,2
+np.float64,0x3fcbae43b2375c87,0xbfe547f267c8e570,2
+np.float64,0x3fcd46fd7d3a8dfb,0xbfe48070f7232929,2
+np.float64,0x7fcdd245273ba489,0x407339f3d907b101,2
+np.float64,0x3fac75cd0838eb9a,0xbff4149d177b057b,2
+np.float64,0x7fe8ff3fd7f1fe7f,0x4073425bf968ba6f,2
+np.float64,0x7febadaa4df75b54,0x407343113a91f0e9,2
+np.float64,0x7fd5e4649c2bc8c8,0x40733c9f0620b065,2
+np.float64,0x903429812069,0xc07351b255e27887,2
+np.float64,0x3fe1d8c51c63b18a,0xbfd03ad448c1f1ee,2
+np.float64,0x3fe573ea646ae7d5,0xbfc63ab0bfd0e601,2
+np.float64,0x3f83b3f3c02767e8,0xc00022677e310649,2
+np.float64,0x7fd15d1582a2ba2a,0x40733b02c469c1d6,2
+np.float64,0x3fe63d3dabec7a7b,0xbfc43a56ee97b27e,2
+np.float64,0x7fe3a452fb2748a5,0x407340af1973c228,2
+np.float64,0x3fafac6b303f58d6,0xbff35651703ae9f2,2
+np.float64,0x513ddd24a27bc,0xc073426af96aaebb,2
+np.float64,0x3fef152246be2a45,0xbf89df79d7719282,2
+np.float64,0x3fe8c923e9f19248,0xbfbc67228e8db5f6,2
+np.float64,0x3fd6e2325fadc465,0xbfdc9602fb0b950f,2
+np.float64,0x3fe9616815f2c2d0,0xbfb9c4311a3b415b,2
+np.float64,0x2fe4e4005fc9d,0xc0734616fe294395,2
+np.float64,0x3fbceb02dc39d606,0xbfee4e68f1c7886f,2
+np.float64,0x7fe35e843d66bd07,0x407340963b066ad6,2
+np.float64,0x7fecd6c648f9ad8c,0x4073435a4c176e94,2
+np.float64,0x7fcbd72bf437ae57,0x4073397994b85665,2
+np.float64,0x3feff6443b3fec88,0xbf40eb380d5318ae,2
+np.float64,0x7fb9373cf6326e79,0x407333f869edef08,2
+np.float64,0x63790d9cc6f22,0xc0734102d4793cda,2
+np.float64,0x3f9de6efe83bcde0,0xbff88db6f0a6b56e,2
+np.float64,0xe00f2dc1c01f,0xc0734ea26ab84ff2,2
+np.float64,0xd7a9aa8baf536,0xc0733ba248fa33ab,2
+np.float64,0x3fee0089ea7c0114,0xbf9cab936ac31c4b,2
+np.float64,0x3fdec0d51cbd81aa,0xbfd45ed8878c5860,2
+np.float64,0x7fe91bf5e9f237eb,0x40734263f005081d,2
+np.float64,0x34ea7d1e69d50,0xc07345659dde7444,2
+np.float64,0x7fe67321a3ace642,0x4073419cc8130d95,2
+np.float64,0x9d1aeb2f3a35e,0xc0733dd5d506425c,2
+np.float64,0x7fbb01df003603bd,0x4073347282f1391d,2
+np.float64,0x42b945b285729,0xc07343c92d1bbef9,2
+np.float64,0x7fc92799b8324f32,0x407338c51e3f0733,2
+np.float64,0x3fe119c19b223383,0xbfd16ab707f65686,2
+np.float64,0x3fc9f9ac5333f359,0xbfe62a2f91ec0dff,2
+np.float64,0x3fd820d5a8b041ab,0xbfdb1d2586fe7b18,2
+np.float64,0x10000000000000,0xc0733a7146f72a42,2
+np.float64,0x3fe7e1543eafc2a8,0xbfc045362889592d,2
+np.float64,0xcbc0e1819783,0xc0734f4b68e05b1c,2
+np.float64,0xeb57e411d6afd,0xc0733b06efec001a,2
+np.float64,0xa9b74b47536ea,0xc0733d4c7bd06ddc,2
+np.float64,0x3fe56d4022eada80,0xbfc64bf8c7e3dd59,2
+np.float64,0x3fd445ca27288b94,0xbfdff40aecd0f882,2
+np.float64,0x3fe5af1cf5ab5e3a,0xbfc5a21d83699a04,2
+np.float64,0x7fed3431eb7a6863,0x40734370aa6131e1,2
+np.float64,0x3fd878dea1b0f1bd,0xbfdab8730dc00517,2
+np.float64,0x7ff8000000000000,0x7ff8000000000000,2
+np.float64,0x3feba9fcc1f753fa,0xbfb03027dcecbf65,2
+np.float64,0x7fca4feed6349fdd,0x4073391526327eb0,2
+np.float64,0x3fe7748ddbaee91c,0xbfc144b438218065,2
+np.float64,0x3fb5fbd94c2bf7b3,0xbff10ee6342c21a0,2
+np.float64,0x3feb603b97f6c077,0xbfb15a1f99d6d25e,2
+np.float64,0x3fe2e6fc8ce5cdf9,0xbfcd43edd7f3b4e6,2
+np.float64,0x7feb2b31f7765663,0x407342f02b306688,2
+np.float64,0x3fe290e2282521c4,0xbfce436deb8dbcf3,2
+np.float64,0x3fe3d5adf9e7ab5c,0xbfca96b8aa55d942,2
+np.float64,0x691899f2d2314,0xc07340a1026897c8,2
+np.float64,0x7fe468b008e8d15f,0x407340f33eadc628,2
+np.float64,0x3fb3a4c416274988,0xbff1d71da539a56e,2
+np.float64,0x3fe2442b29e48856,0xbfcf2b0037322661,2
+np.float64,0x3f376fbc7e6ef,0xc073442939a84643,2
+np.float64,0x3fe7c78d65ef8f1b,0xbfc08157cff411de,2
+np.float64,0xd4f27acba9e50,0xc0733bb8d38daa50,2
+np.float64,0x5198919ea3313,0xc07342633ba7cbea,2
+np.float64,0x7fd09f66f0a13ecd,0x40733ab5310b4385,2
+np.float64,0x3fdfe5531dbfcaa6,0xbfd35b487c7e739f,2
+np.float64,0x3fc4b0fecc2961fe,0xbfe95350c38c1640,2
+np.float64,0x7fd5ae21962b5c42,0x40733c8db78b7250,2
+np.float64,0x3fa4a8fcd42951fa,0xbff64e62fe602b72,2
+np.float64,0x7fc8e0e25831c1c4,0x407338b179b91223,2
+np.float64,0x7fdde1df6f3bc3be,0x40733ec87f9f027e,2
+np.float64,0x3fd8b9ad86b1735b,0xbfda6f385532c41b,2
+np.float64,0x3fd9f20ee933e41e,0xbfd91872fd858597,2
+np.float64,0x7feb35332df66a65,0x407342f2b9c715f0,2
+np.float64,0x7fe783dc7eaf07b8,0x407341ef41873706,2
+np.float64,0x7fceee929f3ddd24,0x40733a34e3c660fd,2
+np.float64,0x985b58d730b6b,0xc0733e0c6cfbb6f8,2
+np.float64,0x3fef4bb55cfe976b,0xbf83cb246c6f2a78,2
+np.float64,0x3fe218014f243003,0xbfcfb20ac683e1f6,2
+np.float64,0x7fe43b9fbea8773e,0x407340e3d5d5d29e,2
+np.float64,0x7fe148c74c62918e,0x40733fcba4367b8b,2
+np.float64,0x3feea4ad083d495a,0xbf93443917f3c991,2
+np.float64,0x8bcf6311179ed,0xc0733ea54d59dd31,2
+np.float64,0xf4b7a2dbe96f5,0xc0733ac175182401,2
+np.float64,0x543338baa8668,0xc073422b59165fe4,2
+np.float64,0x3fdb467317368ce6,0xbfd7b4d515929635,2
+np.float64,0x7fe3bbbc89e77778,0x407340b75cdf3de7,2
+np.float64,0x7fe693377aad266e,0x407341a6af60a0f1,2
+np.float64,0x3fc66210502cc421,0xbfe83bb940610a24,2
+np.float64,0x7fa75638982eac70,0x40732e9da476b816,2
+np.float64,0x3fe0d72a4761ae55,0xbfd1d7c82c479fab,2
+np.float64,0x97dec0dd2fbd8,0xc0733e121e072804,2
+np.float64,0x3fef33ec8c7e67d9,0xbf86701be6be8df1,2
+np.float64,0x7fcfca9b423f9536,0x40733a65a51efb94,2
+np.float64,0x9f2215633e443,0xc0733dbf043de9ed,2
+np.float64,0x2469373e48d28,0xc07347fe9e904b77,2
+np.float64,0x7fecc2e18cb985c2,0x407343557f58dfa2,2
+np.float64,0x3fde4acbfdbc9598,0xbfd4ca559e575e74,2
+np.float64,0x3fd6b11cf1ad623a,0xbfdcd1e17ef36114,2
+np.float64,0x3fc19ec494233d89,0xbfeb8ef228e8826a,2
+np.float64,0x4c89ee389913e,0xc07342d50c904f61,2
+np.float64,0x88c2046f11841,0xc0733ecc91369431,2
+np.float64,0x7fc88c13fd311827,0x40733899a125b392,2
+np.float64,0x3fcebd893a3d7b12,0xbfe3d2f35ab93765,2
+np.float64,0x3feb582a1476b054,0xbfb17ae8ec6a0465,2
+np.float64,0x7fd4369e5da86d3c,0x40733c1118b8cd67,2
+np.float64,0x3fda013fc1340280,0xbfd90831b85e98b2,2
+np.float64,0x7fed33d73fba67ad,0x4073437094ce1bd9,2
+np.float64,0x3fed3191053a6322,0xbfa468cc26a8f685,2
+np.float64,0x3fc04ed51c209daa,0xbfeca24a6f093bca,2
+np.float64,0x3fee4ac8763c9591,0xbf986458abbb90b5,2
+np.float64,0xa2d39dd145a74,0xc0733d9633651fbc,2
+np.float64,0x3fe7d9f86f2fb3f1,0xbfc0565a0b059f1c,2
+np.float64,0x3fe3250144e64a03,0xbfcc8eb2b9ae494b,2
+np.float64,0x7fe2b29507a56529,0x4073405774492075,2
+np.float64,0x7fdcdfcbe2b9bf97,0x40733e8b736b1bd8,2
+np.float64,0x3fc832730f3064e6,0xbfe7267ac9b2e7c3,2
+np.float64,0x3fc7e912e52fd226,0xbfe750dfc0aeae57,2
+np.float64,0x7fc960472f32c08d,0x407338d4b4cb3957,2
+np.float64,0x3fbdf182ea3be306,0xbfedd27150283ffb,2
+np.float64,0x3fd1e9359823d26b,0xbfe1b2ac7fd25f8d,2
+np.float64,0x7fbcf75f6039eebe,0x407334ef13eb16f8,2
+np.float64,0x3fe5a3c910eb4792,0xbfc5bf2f57c5d643,2
+np.float64,0x3fcf4f2a6e3e9e55,0xbfe391b6f065c4b8,2
+np.float64,0x3fee067873fc0cf1,0xbf9c53af0373fc0e,2
+np.float64,0xd3f08b85a7e12,0xc0733bc14357e686,2
+np.float64,0x7ff0000000000000,0x7ff0000000000000,2
+np.float64,0x3fc8635f6430c6bf,0xbfe70a7dc77749a7,2
+np.float64,0x3fe3ff5c52a7feb9,0xbfca22617c6636d5,2
+np.float64,0x3fbbae91fa375d24,0xbfeee9d4c300543f,2
+np.float64,0xe3f71b59c7ee4,0xc0733b3f99187375,2
+np.float64,0x7fca93d3be3527a6,0x40733926fd48ecd6,2
+np.float64,0x3fcd29f7223a53ee,0xbfe48e3edf32fe57,2
+np.float64,0x7fdc4ef6f8389ded,0x40733e68401cf2a6,2
+np.float64,0xe009bc81c014,0xc0734ea295ee3e5b,2
+np.float64,0x61f56c78c3eae,0xc073411e1dbd7c54,2
+np.float64,0x3fde131928bc2632,0xbfd4fda024f6927c,2
+np.float64,0x3fb21ee530243dca,0xbff266aaf0358129,2
+np.float64,0x7feaac82a4f55904,0x407342cf7809d9f9,2
+np.float64,0x3fe66ab177ecd563,0xbfc3c92d4d522819,2
+np.float64,0xfe9f9c2bfd3f4,0xc0733a7ade3a88a7,2
+np.float64,0x7fd0c5217c218a42,0x40733ac4e4c6dfa5,2
+np.float64,0x430f4ae6861ea,0xc07343c03d8a9442,2
+np.float64,0x494bff2a92981,0xc073432209d2fd16,2
+np.float64,0x3f8860e9d030c1d4,0xbffeca059ebf5e89,2
+np.float64,0x3fe43732dc286e66,0xbfc98800388bad2e,2
+np.float64,0x6443b60ec8877,0xc07340f4bab11827,2
+np.float64,0x3feda9be6d7b537d,0xbfa0dcb9a6914069,2
+np.float64,0x3fc5ceb6772b9d6d,0xbfe89868c881db70,2
+np.float64,0x3fbdf153023be2a6,0xbfedd2878c3b4949,2
+np.float64,0x7fe8f6b8e8f1ed71,0x407342599a30b273,2
+np.float64,0x3fea6fbdb8b4df7b,0xbfb53bf66f71ee96,2
+np.float64,0xc7ac3dbb8f588,0xc0733c2b525b7963,2
+np.float64,0x3fef3a91f77e7524,0xbf85b2bd3adbbe31,2
+np.float64,0x3f887cb97030f973,0xbffec21ccbb5d22a,2
+np.float64,0x8b2f1c9f165e4,0xc0733ead49300951,2
+np.float64,0x2c1cb32058397,0xc07346a951bd8d2b,2
+np.float64,0x3fe057edd620afdc,0xbfd2acf1881b7e99,2
+np.float64,0x7f82e9530025d2a5,0x4073238591dd52ce,2
+np.float64,0x3fe4e03dff69c07c,0xbfc7be96c5c006fc,2
+np.float64,0x52727b4aa4e50,0xc0734250c58ebbc1,2
+np.float64,0x3f99a62160334c43,0xbff99ea3ca09d8f9,2
+np.float64,0x3fd5314b4faa6297,0xbfdeb843daf01e03,2
+np.float64,0x3fefde89e13fbd14,0xbf5d1facb7a1e9de,2
+np.float64,0x7fb460f1a228c1e2,0x4073327d8cbc5f86,2
+np.float64,0xeb93efb3d727e,0xc0733b052a4990e4,2
+np.float64,0x3fe884baecf10976,0xbfbd9ba9cfe23713,2
+np.float64,0x7fefffffffffffff,0x40734413509f79ff,2
+np.float64,0x149dc7c6293ba,0xc0734bf26b1df025,2
+np.float64,0x64188f88c8313,0xc07340f7b8e6f4b5,2
+np.float64,0x3fdfac314abf5863,0xbfd38d3e9dba1b0e,2
+np.float64,0x3fd72052a42e40a5,0xbfdc4af30ee0b245,2
+np.float64,0x7fdd951f743b2a3e,0x40733eb68fafa838,2
+np.float64,0x65a2dd5acb45c,0xc07340dc8ed625e1,2
+np.float64,0x7fe89a79997134f2,0x4073423fbceb1cbe,2
+np.float64,0x3fe70a000d6e1400,0xbfc24381e09d02f7,2
+np.float64,0x3fe2cec160259d83,0xbfcd8b5e92354129,2
+np.float64,0x3feb9ef77a773def,0xbfb05c7b2ee6f388,2
+np.float64,0xe0d66689c1acd,0xc0733b582c779620,2
+np.float64,0x3fee86bd0ffd0d7a,0xbf94f7870502c325,2
+np.float64,0x186afc6230d60,0xc0734ac55fb66d5d,2
+np.float64,0xc0631f4b80c64,0xc0733c6d7149d373,2
+np.float64,0x3fdad1b87735a371,0xbfd82cca73ec663b,2
+np.float64,0x7fe7f6d313efeda5,0x40734210e84576ab,2
+np.float64,0x7fd7b7fce6af6ff9,0x40733d2d92ffdaaf,2
+np.float64,0x3fe6f35a28ade6b4,0xbfc27a4239b540c3,2
+np.float64,0x7fdb0b834eb61706,0x40733e17073a61f3,2
+np.float64,0x82f4661105e8d,0xc0733f19b34adeed,2
+np.float64,0x3fc77230112ee460,0xbfe796a7603c0d16,2
+np.float64,0x8000000000000000,0xfff0000000000000,2
+np.float64,0x7fb8317bc63062f7,0x407333aec761a739,2
+np.float64,0x7fd165609a22cac0,0x40733b061541ff15,2
+np.float64,0x3fed394768fa728f,0xbfa42e1596e1faf6,2
+np.float64,0x7febab693d7756d1,0x40734310a9ac828e,2
+np.float64,0x7fe809a69230134c,0x407342165b9acb69,2
+np.float64,0x3fc091d38f2123a7,0xbfec69a70fc23548,2
+np.float64,0x3fb2a8f5dc2551ec,0xbff2327f2641dd0d,2
+np.float64,0x7fc60b6fe02c16df,0x407337da5adc342c,2
+np.float64,0x3fefa53c3bbf4a78,0xbf73d1be15b73b00,2
+np.float64,0x7fee09c1717c1382,0x407343a2c479e1cb,2
+np.float64,0x8000000000000001,0x7ff8000000000000,2
+np.float64,0x3fede0b2733bc165,0xbf9e848ac2ecf604,2
+np.float64,0x3fee2ac331bc5586,0xbf9a3b699b721c9a,2
+np.float64,0x3fd4db12d829b626,0xbfdf2a413d1e453a,2
+np.float64,0x7fe605230dec0a45,0x4073417a67db06be,2
+np.float64,0x3fe378b2bf26f165,0xbfcb9dbb2b6d6832,2
+np.float64,0xc1d4c1ab83a98,0xc0733c60244cadbf,2
+np.float64,0x3feb15500e762aa0,0xbfb28c071d5efc22,2
+np.float64,0x3fe36225a626c44b,0xbfcbde4259e9047e,2
+np.float64,0x3fe7c586a72f8b0d,0xbfc08614b13ed4b2,2
+np.float64,0x7fb0f2d8cc21e5b1,0x40733135b2c7dd99,2
+np.float64,0x5957f3feb2aff,0xc07341c1df75638c,2
+np.float64,0x3fca4851bd3490a3,0xbfe6005ae5279485,2
+np.float64,0x824217d904843,0xc0733f232fd58f0f,2
+np.float64,0x4f9332269f267,0xc073428fd8e9cb32,2
+np.float64,0x3fea6f087374de11,0xbfb53ef0d03918b2,2
+np.float64,0x3fd9409ab4328135,0xbfd9d9231381e2b8,2
+np.float64,0x3fdba03b00374076,0xbfd759ec94a7ab5b,2
+np.float64,0x3fe0ce3766619c6f,0xbfd1e6912582ccf0,2
+np.float64,0x3fabd45ddc37a8bc,0xbff43c78d3188423,2
+np.float64,0x3fc3cadd592795bb,0xbfe9f1576c9b2c79,2
+np.float64,0x3fe10df049621be1,0xbfd17df2f2c28022,2
+np.float64,0x945b5d1328b6c,0xc0733e3bc06f1e75,2
+np.float64,0x7fc1c3742b2386e7,0x4073365a403d1051,2
+np.float64,0x7fdc957138b92ae1,0x40733e7977717586,2
+np.float64,0x7f943fa1a0287f42,0x407328d01de143f5,2
+np.float64,0x3fec9631c4392c64,0xbfa914b176d8f9d2,2
+np.float64,0x3fd8e7c008b1cf80,0xbfda3b9d9b6da8f4,2
+np.float64,0x7222f9fee4460,0xc073400e371516cc,2
+np.float64,0x3fe890e43eb121c8,0xbfbd64921462e823,2
+np.float64,0x3fcfd7fe2a3faffc,0xbfe3557e2f207800,2
+np.float64,0x3fed5dd1c1babba4,0xbfa318bb20db64e6,2
+np.float64,0x3fe6aa34c66d546a,0xbfc32c8a8991c11e,2
+np.float64,0x8ca79801196,0xc0736522bd5adf6a,2
+np.float64,0x3feb274079364e81,0xbfb2427b24b0ca20,2
+np.float64,0x7fe04927e4a0924f,0x40733f61c96f7f89,2
+np.float64,0x7c05f656f80bf,0xc0733f7a70555b4e,2
+np.float64,0x7fe97819eff2f033,0x4073427d4169b0f8,2
+np.float64,0x9def86e33bdf1,0xc0733dcc740b7175,2
+np.float64,0x7fedd1ef3f3ba3dd,0x40734395ceab8238,2
+np.float64,0x77bed86cef7dc,0xc0733fb8e0e9bf73,2
+np.float64,0x9274b41b24e97,0xc0733e52b16dff71,2
+np.float64,0x8010000000000000,0x7ff8000000000000,2
+np.float64,0x9c977855392ef,0xc0733ddba7d421d9,2
+np.float64,0xfb4560a3f68ac,0xc0733a9271e6a118,2
+np.float64,0xa67d9f394cfb4,0xc0733d6e9d58cc94,2
+np.float64,0x3fbfa766b03f4ecd,0xbfed0cccfecfc900,2
+np.float64,0x3fe177417522ee83,0xbfd0d45803bff01a,2
+np.float64,0x7fe85e077bb0bc0e,0x4073422e957a4aa3,2
+np.float64,0x7feeb0a6883d614c,0x407343c8f6568f7c,2
+np.float64,0xbab82edb75706,0xc0733ca2a2b20094,2
+np.float64,0xfadb44bdf5b69,0xc0733a9561b7ec04,2
+np.float64,0x3fefb9b82b3f7370,0xbf6ea776b2dcc3a9,2
+np.float64,0x7fe080ba8a610174,0x40733f795779b220,2
+np.float64,0x3f87faa1c02ff544,0xbffee76acafc92b7,2
+np.float64,0x7fed474108fa8e81,0x4073437531d4313e,2
+np.float64,0x3fdb7b229336f645,0xbfd77f583a4a067f,2
+np.float64,0x256dbf0c4adb9,0xc07347cd94e6fa81,2
+np.float64,0x3fd034ae25a0695c,0xbfe3169c15decdac,2
+np.float64,0x3a72177274e44,0xc07344b4cf7d68cd,2
+np.float64,0x7fa2522d5c24a45a,0x40732cef2f793470,2
+np.float64,0x3fb052bdde20a57c,0xbff3207fd413c848,2
+np.float64,0x3fdccfecbbb99fd9,0xbfd62ec04a1a687a,2
+np.float64,0x3fd403ac53280759,0xbfe027a31df2c8cc,2
+np.float64,0x3fab708e4036e11d,0xbff45591df4f2e8b,2
+np.float64,0x7fcfc001993f8002,0x40733a63539acf9d,2
+np.float64,0x3fd2b295dfa5652c,0xbfe119c1b476c536,2
+np.float64,0x7fe8061262b00c24,0x4073421552ae4538,2
+np.float64,0xffefffffffffffff,0x7ff8000000000000,2
+np.float64,0x7fed52093ffaa411,0x40734377c072a7e8,2
+np.float64,0xf3df902fe7bf2,0xc0733ac79a75ff7a,2
+np.float64,0x7fe13d382e227a6f,0x40733fc6fd0486bd,2
+np.float64,0x3621d5086c43b,0xc073453d31effbcd,2
+np.float64,0x3ff0000000000000,0x0,2
+np.float64,0x3fdaffea27b5ffd4,0xbfd7fd139dc1c2c5,2
+np.float64,0x7fea6536dc34ca6d,0x407342bccc564fdd,2
+np.float64,0x7fd478f00c28f1df,0x40733c27c0072fde,2
+np.float64,0x7fa72ef0502e5de0,0x40732e91e83db75c,2
+np.float64,0x7fd302970626052d,0x40733ba3ec6775f6,2
+np.float64,0x7fbb57ab0036af55,0x407334887348e613,2
+np.float64,0x3fda0ff722b41fee,0xbfd8f87b77930330,2
+np.float64,0x1e983ce23d309,0xc073493438f57e61,2
+np.float64,0x7fc90de97c321bd2,0x407338be01ffd4bd,2
+np.float64,0x7fe074b09c20e960,0x40733f7443f0dbe1,2
+np.float64,0x3fed5dec9fbabbd9,0xbfa317efb1fe8a95,2
+np.float64,0x7fdb877632b70eeb,0x40733e3697c88ba8,2
+np.float64,0x7fe4fb0067e9f600,0x40734124604b99e8,2
+np.float64,0x7fd447dc96288fb8,0x40733c1703ab2cce,2
+np.float64,0x3feb2d1e64f65a3d,0xbfb22a781df61c05,2
+np.float64,0xb6c8e6676d91d,0xc0733cc8859a0b91,2
+np.float64,0x3fdc3c2418387848,0xbfd6bec3a3c3cdb5,2
+np.float64,0x3fdecb9ccdbd973a,0xbfd4551c05721a8e,2
+np.float64,0x3feb1100e7762202,0xbfb29db911fe6768,2
+np.float64,0x3fe0444bc2a08898,0xbfd2ce69582e78c1,2
+np.float64,0x7fda403218b48063,0x40733de201d8340c,2
+np.float64,0x3fdc70421238e084,0xbfd68ba4bd48322b,2
+np.float64,0x3fe06e747c60dce9,0xbfd286bcac34a981,2
+np.float64,0x7fc1931d9623263a,0x407336473da54de4,2
+np.float64,0x229914da45323,0xc073485979ff141c,2
+np.float64,0x3fe142f92da285f2,0xbfd1280909992cb6,2
+np.float64,0xf1d02fa9e3a06,0xc0733ad6b19d71a0,2
+np.float64,0x3fb1fe9b0023fd36,0xbff27317d8252c16,2
+np.float64,0x3fa544b9242a8972,0xbff61ac38569bcfc,2
+np.float64,0x3feeb129d4fd6254,0xbf928f23ad20c1ee,2
+np.float64,0xa2510b7f44a22,0xc0733d9bc81ea0a1,2
+np.float64,0x3fca75694d34ead3,0xbfe5e8975b3646c2,2
+np.float64,0x7fece10621b9c20b,0x4073435cc3dd9a1b,2
+np.float64,0x7fe98a57d3b314af,0x4073428239b6a135,2
+np.float64,0x3fe259c62a64b38c,0xbfcee96682a0f355,2
+np.float64,0x3feaaa9b9d755537,0xbfb445779f3359af,2
+np.float64,0xdaadecfdb55be,0xc0733b899338432a,2
+np.float64,0x3fed00eae4fa01d6,0xbfa5dc8d77be5991,2
+np.float64,0x7fcc96c773392d8e,0x407339a8c5cd786e,2
+np.float64,0x3fef7b8b203ef716,0xbf7cff655ecb6424,2
+np.float64,0x7fd4008113a80101,0x40733bfe6552acb7,2
+np.float64,0x7fe99ff035b33fdf,0x407342881753ee2e,2
+np.float64,0x3ee031e87dc07,0xc0734432d736e492,2
+np.float64,0x3fddfe390f3bfc72,0xbfd510f1d9ec3e36,2
+np.float64,0x3fd9ddce74b3bb9d,0xbfd92e2d75a061bb,2
+np.float64,0x7fe5f742edebee85,0x40734176058e3a77,2
+np.float64,0x3fdb04185b360831,0xbfd7f8c63aa5e1c4,2
+np.float64,0xea2b0f43d4562,0xc0733b0fd77c8118,2
+np.float64,0x7fc3f4973527e92d,0x407337293bbb22c4,2
+np.float64,0x3fb9adfb38335bf6,0xbfeff4f3ea85821a,2
+np.float64,0x87fb98750ff73,0xc0733ed6ad83c269,2
+np.float64,0x3fe005721a200ae4,0xbfd33a9f1ebfb0ac,2
+np.float64,0xd9e04fe7b3c0a,0xc0733b901ee257f3,2
+np.float64,0x2c39102658723,0xc07346a4db63bf55,2
+np.float64,0x3f7dc28e003b851c,0xc0011c1d1233d948,2
+np.float64,0x3430fd3868620,0xc073457e24e0b70d,2
+np.float64,0xbff0000000000000,0x7ff8000000000000,2
+np.float64,0x3fd23e45e0247c8c,0xbfe17146bcf87b57,2
+np.float64,0x6599df3ecb33d,0xc07340dd2c41644c,2
+np.float64,0x3fdf074f31be0e9e,0xbfd41f6e9dbb68a5,2
+np.float64,0x7fdd6233f3bac467,0x40733eaa8f674b72,2
+np.float64,0x7fe03e8481607d08,0x40733f5d3df3b087,2
+np.float64,0x3fcc3b79f13876f4,0xbfe501bf3b379b77,2
+np.float64,0xe5d97ae3cbb30,0xc0733b30f47cbd12,2
+np.float64,0x8acbc4a115979,0xc0733eb240a4d2c6,2
+np.float64,0x3fedbdbc48bb7b79,0xbfa0470fd70c4359,2
+np.float64,0x3fde1611103c2c22,0xbfd4fae1fa8e7e5e,2
+np.float64,0x3fe09478bd2128f1,0xbfd246b7e85711dc,2
+np.float64,0x3fd6dfe8f3adbfd2,0xbfdc98ca2f32c1ad,2
+np.float64,0x72ccf274e599f,0xc0734003e5b0da63,2
+np.float64,0xe27c7265c4f8f,0xc0733b4b2d808566,2
+np.float64,0x7fee3161703c62c2,0x407343abe90f5649,2
+np.float64,0xf54fb5c1eaa0,0xc0734e01384fcf78,2
+np.float64,0xcde5924d9bcb3,0xc0733bf4b83c66c2,2
+np.float64,0x3fc46fdbe528dfb8,0xbfe97f55ef5e9683,2
+np.float64,0x7fe513528a2a26a4,0x4073412c69baceca,2
+np.float64,0x3fd29eca4aa53d95,0xbfe128801cd33ed0,2
+np.float64,0x7febb21718b7642d,0x4073431256def857,2
+np.float64,0x3fcab536c0356a6e,0xbfe5c73c59f41578,2
+np.float64,0x7fc7e9f0d82fd3e1,0x4073386b213e5dfe,2
+np.float64,0xb5b121276b624,0xc0733cd33083941c,2
+np.float64,0x7e0dd9bcfc1bc,0xc0733f5d8bf35050,2
+np.float64,0x3fd1c75106238ea2,0xbfe1cd11cccda0f4,2
+np.float64,0x9f060e673e0c2,0xc0733dc03da71909,2
+np.float64,0x7fd915a2f3322b45,0x40733d912af07189,2
+np.float64,0x3fd8cbae4431975d,0xbfda5b02ca661139,2
+np.float64,0x3fde8b411f3d1682,0xbfd48f6f710a53b6,2
+np.float64,0x3fc17a780622f4f0,0xbfebabb10c55255f,2
+np.float64,0x3fde5cbe5f3cb97d,0xbfd4b9e2e0101fb1,2
+np.float64,0x7fd859036530b206,0x40733d5c2252ff81,2
+np.float64,0xb0f5040f61ea1,0xc0733d02292f527b,2
+np.float64,0x3fde5c49ae3cb893,0xbfd4ba4db3ce2cf3,2
+np.float64,0x3fecc4518df988a3,0xbfa7af0bfc98bc65,2
+np.float64,0x3feffee03cbffdc0,0xbf0f3ede6ca7d695,2
+np.float64,0xbc5eac9b78bd6,0xc0733c92fb51c8ae,2
+np.float64,0x3fe2bb4ef765769e,0xbfcdc4f70a65dadc,2
+np.float64,0x5089443ca1129,0xc073427a7d0cde4a,2
+np.float64,0x3fd0d6e29121adc5,0xbfe28e28ece1db86,2
+np.float64,0xbe171e397c2e4,0xc0733c82cede5d02,2
+np.float64,0x4ede27be9dbc6,0xc073429fba1a4af1,2
+np.float64,0x3fe2aff3af655fe7,0xbfcde6b52a8ed3c1,2
+np.float64,0x7fd85ca295b0b944,0x40733d5d2adcccf1,2
+np.float64,0x24919bba49234,0xc07347f6ed704a6f,2
+np.float64,0x7fd74bc1eeae9783,0x40733d0d94a89011,2
+np.float64,0x3fc1cd12cb239a26,0xbfeb6a9c25c2a11d,2
+np.float64,0x3fdafbc0ac35f781,0xbfd8015ccf1f1b51,2
+np.float64,0x3fee01327c3c0265,0xbf9ca1d0d762dc18,2
+np.float64,0x3fe65bd7702cb7af,0xbfc3ee0de5c36b8d,2
+np.float64,0x7349c82ee693a,0xc0733ffc5b6eccf2,2
+np.float64,0x3fdc5906f738b20e,0xbfd6a26288eb5933,2
+np.float64,0x1,0xc07434e6420f4374,2
+np.float64,0x3fb966128a32cc25,0xbff00e0aa7273838,2
+np.float64,0x3fd501ff9a2a03ff,0xbfdef69133482121,2
+np.float64,0x194d4f3c329ab,0xc0734a861b44cfbe,2
+np.float64,0x3fec5d34f8f8ba6a,0xbfaad1b31510e70b,2
+np.float64,0x1635e4c22c6be,0xc0734b6dec650943,2
+np.float64,0x3fead2f8edb5a5f2,0xbfb39dac30a962cf,2
+np.float64,0x3f7dfa4ce03bf49a,0xc00115a112141aa7,2
+np.float64,0x3fef6827223ed04e,0xbf80a42c9edebfe9,2
+np.float64,0xe771f303cee3f,0xc0733b24a6269fe4,2
+np.float64,0x1160ccc622c1b,0xc0734d22604eacb9,2
+np.float64,0x3fc485cd08290b9a,0xbfe970723008c8c9,2
+np.float64,0x7fef99c518bf3389,0x407343fcf9ed202f,2
+np.float64,0x7fd8c1447a318288,0x40733d79a440b44d,2
+np.float64,0xaf219f955e434,0xc0733d149c13f440,2
+np.float64,0xcf45f6239e8bf,0xc0733be8ddda045d,2
+np.float64,0x7599394aeb328,0xc0733fd90fdbb0ea,2
+np.float64,0xc7f6390f8fec7,0xc0733c28bfbc66a3,2
+np.float64,0x3fd39ae96c2735d3,0xbfe0712274a8742b,2
+np.float64,0xa4d6c18f49ad8,0xc0733d805a0528f7,2
+np.float64,0x7fd9ea78d7b3d4f1,0x40733dcb2b74802a,2
+np.float64,0x3fecd251cb39a4a4,0xbfa742ed41d4ae57,2
+np.float64,0x7fed7a07cd7af40f,0x407343813476027e,2
+np.float64,0x3fd328ae7f26515d,0xbfe0c30b56a83c64,2
+np.float64,0x7fc937ff7a326ffe,0x407338c9a45b9140,2
+np.float64,0x3fcf1d31143e3a62,0xbfe3a7f760fbd6a8,2
+np.float64,0x7fb911dcbc3223b8,0x407333ee158cccc7,2
+np.float64,0x3fd352fc83a6a5f9,0xbfe0a47d2f74d283,2
+np.float64,0x7fd310753fa620e9,0x40733ba8fc4300dd,2
+np.float64,0x3febd64b4577ac97,0xbfaefd4a79f95c4b,2
+np.float64,0x6a6961a4d4d2d,0xc073408ae1687943,2
+np.float64,0x3fe4ba73d16974e8,0xbfc8239341b9e457,2
+np.float64,0x3fed8e7cac3b1cf9,0xbfa1a96a0cc5fcdc,2
+np.float64,0x7fd505ec04aa0bd7,0x40733c56f86e3531,2
+np.float64,0x3fdf166e9abe2cdd,0xbfd411e5f8569d70,2
+np.float64,0x7fe1bc6434e378c7,0x40733ff9861bdabb,2
+np.float64,0x3fd3b0b175a76163,0xbfe061ba5703f3c8,2
+np.float64,0x7fed75d7ffbaebaf,0x4073438037ba6f19,2
+np.float64,0x5a9e109cb53c3,0xc07341a8b04819c8,2
+np.float64,0x3fe14786b4e28f0d,0xbfd120b541bb880e,2
+np.float64,0x3fed4948573a9291,0xbfa3b471ff91614b,2
+np.float64,0x66aac5d8cd559,0xc07340ca9b18af46,2
+np.float64,0x3fdb48efd23691e0,0xbfd7b24c5694838b,2
+np.float64,0x7fe6da7d1eadb4f9,0x407341bc7d1fae43,2
+np.float64,0x7feb702cf336e059,0x40734301b96cc3c0,2
+np.float64,0x3fd1e60987a3cc13,0xbfe1b522cfcc3d0e,2
+np.float64,0x3feca57f50794aff,0xbfa89dc90625d39c,2
+np.float64,0x7fdc46dc56b88db8,0x40733e664294a0f9,2
+np.float64,0x8dc8fd811b920,0xc0733e8c5955df06,2
+np.float64,0xf01634abe02c7,0xc0733ae370a76d0c,2
+np.float64,0x3fc6f8d8ab2df1b1,0xbfe7df5093829464,2
+np.float64,0xda3d7597b47af,0xc0733b8d2702727a,2
+np.float64,0x7feefd53227dfaa5,0x407343da3d04db28,2
+np.float64,0x3fe2fbca3525f794,0xbfcd06e134417c08,2
+np.float64,0x7fd36d3ce226da79,0x40733bca7c322df1,2
+np.float64,0x7fec37e00b786fbf,0x4073433397b48a5b,2
+np.float64,0x3fbf133f163e267e,0xbfed4e72f1362a77,2
+np.float64,0x3fc11efbb9223df7,0xbfebf53002a561fe,2
+np.float64,0x3fc89c0e5431381d,0xbfe6ea562364bf81,2
+np.float64,0x3f9cd45da839a8bb,0xbff8ceb14669ee4b,2
+np.float64,0x23dc8fa647b93,0xc0734819aaa9b0ee,2
+np.float64,0x3fe829110d305222,0xbfbf3e60c45e2399,2
+np.float64,0x7fed8144e57b0289,0x40734382e917a02a,2
+np.float64,0x7fe033fbf7a067f7,0x40733f58bb00b20f,2
+np.float64,0xe3807f45c7010,0xc0733b43379415d1,2
+np.float64,0x3fd708fb342e11f6,0xbfdc670ef9793782,2
+np.float64,0x3fe88c924b311925,0xbfbd78210d9e7164,2
+np.float64,0x3fe0a2a7c7614550,0xbfd22efaf0472c4a,2
+np.float64,0x7fe3a37501a746e9,0x407340aecaeade41,2
+np.float64,0x3fd05077ec20a0f0,0xbfe2fedbf07a5302,2
+np.float64,0x7fd33bf61da677eb,0x40733bb8c58912aa,2
+np.float64,0x3feb29bdae76537b,0xbfb2384a8f61b5f9,2
+np.float64,0x3fec0fc14ff81f83,0xbfad3423e7ade174,2
+np.float64,0x3fd0f8b1a1a1f163,0xbfe2725dd4ccea8b,2
+np.float64,0x3fe382d26a6705a5,0xbfcb80dba4218bdf,2
+np.float64,0x3fa873f2cc30e7e6,0xbff522911cb34279,2
+np.float64,0x7fed7fd7377affad,0x4073438292f6829b,2
+np.float64,0x3feeacd8067d59b0,0xbf92cdbeda94b35e,2
+np.float64,0x7fe464d62228c9ab,0x407340f1eee19aa9,2
+np.float64,0xe997648bd32ed,0xc0733b143aa0fad3,2
+np.float64,0x7fea4869f13490d3,0x407342b5333b54f7,2
+np.float64,0x935b871926b71,0xc0733e47c6683319,2
+np.float64,0x28a9d0c05155,0xc0735a7e3532af83,2
+np.float64,0x79026548f204d,0xc0733fa6339ffa2f,2
+np.float64,0x3fdb1daaabb63b55,0xbfd7de839c240ace,2
+np.float64,0x3fc0db73b421b6e7,0xbfec2c6e36c4f416,2
+np.float64,0xb8b50ac1716b,0xc0734ff9fc60ebce,2
+np.float64,0x7fdf13e0c6be27c1,0x40733f0e44f69437,2
+np.float64,0x3fcd0cb97b3a1973,0xbfe49c34ff531273,2
+np.float64,0x3fcbac034b375807,0xbfe54913d73f180d,2
+np.float64,0x3fe091d2a2e123a5,0xbfd24b290a9218de,2
+np.float64,0xede43627dbc87,0xc0733af3c7c7f716,2
+np.float64,0x7fc037e7ed206fcf,0x407335b85fb0fedb,2
+np.float64,0x3fce7ae4c63cf5ca,0xbfe3f1350fe03f28,2
+np.float64,0x7fcdd862263bb0c3,0x407339f5458bb20e,2
+np.float64,0x4d7adf709af5d,0xc07342bf4edfadb2,2
+np.float64,0xdc6c03f3b8d81,0xc0733b7b74d6a635,2
+np.float64,0x3fe72ae0a4ee55c1,0xbfc1f4665608b21f,2
+np.float64,0xcd62f19d9ac5e,0xc0733bf92235e4d8,2
+np.float64,0xe3a7b8fdc74f7,0xc0733b4204f8e166,2
+np.float64,0x3fdafd35adb5fa6b,0xbfd7ffdca0753b36,2
+np.float64,0x3fa023e8702047d1,0xbff8059150ea1464,2
+np.float64,0x99ff336933fe7,0xc0733df961197517,2
+np.float64,0x7feeb365b9bd66ca,0x407343c995864091,2
+np.float64,0x7fe449b49f689368,0x407340e8aa3369e3,2
+np.float64,0x7faf5843043eb085,0x407330aa700136ca,2
+np.float64,0x3fd47b2922a8f652,0xbfdfab3de86f09ee,2
+np.float64,0x7fd9fc3248b3f864,0x40733dcfea6f9b3e,2
+np.float64,0xe20b0d8dc4162,0xc0733b4ea8fe7b3f,2
+np.float64,0x7feff8e0e23ff1c1,0x40734411c490ed70,2
+np.float64,0x7fa58382d02b0705,0x40732e0cf28e14fe,2
+np.float64,0xb8ad9a1b715b4,0xc0733cb630b8f2d4,2
+np.float64,0xe90abcf1d2158,0xc0733b186b04eeee,2
+np.float64,0x7fd6aa6f32ad54dd,0x40733cdccc636604,2
+np.float64,0x3fd8f84eedb1f09e,0xbfda292909a5298a,2
+np.float64,0x7fecd6b1d9f9ad63,0x4073435a472b05b5,2
+np.float64,0x3fd9f47604b3e8ec,0xbfd915e028cbf4a6,2
+np.float64,0x3fd20d9398241b27,0xbfe19691363dd508,2
+np.float64,0x3fe5ed09bbabda13,0xbfc5043dfc9c8081,2
+np.float64,0x7fbe5265363ca4c9,0x407335406f8e4fac,2
+np.float64,0xac2878af5850f,0xc0733d3311be9786,2
+np.float64,0xac2074555840f,0xc0733d3364970018,2
+np.float64,0x3fcd49b96b3a9373,0xbfe47f24c8181d9c,2
+np.float64,0x3fd10caca6a21959,0xbfe2620ae5594f9a,2
+np.float64,0xec5b87e9d8b71,0xc0733aff499e72ca,2
+np.float64,0x9d5e9fad3abd4,0xc0733dd2d70eeb4a,2
+np.float64,0x7fe3d3a24227a744,0x407340bfc2072fdb,2
+np.float64,0x3fc5f7a77c2bef4f,0xbfe87e69d502d784,2
+np.float64,0x33161a66662c4,0xc07345a436308244,2
+np.float64,0xa27acdc744f5a,0xc0733d99feb3d8ea,2
+np.float64,0x3fe2d9301565b260,0xbfcd6c914e204437,2
+np.float64,0x7fd5d111e12ba223,0x40733c98e14a6fd0,2
+np.float64,0x6c3387bed8672,0xc073406d3648171a,2
+np.float64,0x24d89fe849b15,0xc07347e97bec008c,2
+np.float64,0x3fefd763677faec7,0xbf61ae69caa9cad9,2
+np.float64,0x7fe0a4684ba148d0,0x40733f884d32c464,2
+np.float64,0x3fd5c3c939ab8792,0xbfddfaaefc1c7fca,2
+np.float64,0x3fec9b87a6b9370f,0xbfa8eb34efcc6b9b,2
+np.float64,0x3feb062431f60c48,0xbfb2ca6036698877,2
+np.float64,0x3fef97f6633f2fed,0xbf76bc742860a340,2
+np.float64,0x74477490e88ef,0xc0733fed220986bc,2
+np.float64,0x3fe4bea67ce97d4d,0xbfc818525292b0f6,2
+np.float64,0x3fc6add3a92d5ba7,0xbfe80cfdc9a90bda,2
+np.float64,0x847c9ce308f94,0xc0733f05026f5965,2
+np.float64,0x7fea53fd2eb4a7f9,0x407342b841fc4723,2
+np.float64,0x3fc55a16fc2ab42e,0xbfe8e3849130da34,2
+np.float64,0x3fbdf7d07c3befa1,0xbfedcf84b9c6c161,2
+np.float64,0x3fe5fb25aa6bf64b,0xbfc4e083ff96b116,2
+np.float64,0x61c776a8c38ef,0xc0734121611d84d7,2
+np.float64,0x3fec413164f88263,0xbfabadbd05131546,2
+np.float64,0x9bf06fe137e0e,0xc0733de315469ee0,2
+np.float64,0x2075eefc40ebf,0xc07348cae84de924,2
+np.float64,0x3fdd42e0143a85c0,0xbfd5c0b6f60b3cea,2
+np.float64,0xdbb1ab45b7636,0xc0733b8157329daf,2
+np.float64,0x3feac6d56bf58dab,0xbfb3d00771b28621,2
+np.float64,0x7fb2dc825025b904,0x407331f3e950751a,2
+np.float64,0x3fecea6efd79d4de,0xbfa689309cc0e3fe,2
+np.float64,0x3fd83abec7b0757e,0xbfdaff5c674a9c59,2
+np.float64,0x3fd396f7c0272df0,0xbfe073ee75c414ba,2
+np.float64,0x3fe10036c162006e,0xbfd1945a38342ae1,2
+np.float64,0x3fd5bbded52b77be,0xbfde04cca40d4156,2
+np.float64,0x3fe870945ab0e129,0xbfbdf72f0e6206fa,2
+np.float64,0x3fef72fddcbee5fc,0xbf7ee2dba88b1bad,2
+np.float64,0x4e111aa09c224,0xc07342b1e2b29643,2
+np.float64,0x3fd926d8b5b24db1,0xbfd9f58b78d6b061,2
+np.float64,0x3fc55679172aacf2,0xbfe8e5df687842e2,2
+np.float64,0x7f5f1749803e2e92,0x40731886e16cfc4d,2
+np.float64,0x7fea082b53b41056,0x407342a42227700e,2
+np.float64,0x3fece1d1d039c3a4,0xbfa6cb780988a469,2
+np.float64,0x3b2721d8764e5,0xc073449f6a5a4832,2
+np.float64,0x365cb7006cba,0xc0735879ba5f0b6e,2
+np.float64,0x7ff4000000000000,0x7ffc000000000000,2
+np.float64,0x7fe606ce92ac0d9c,0x4073417aeebe97e8,2
+np.float64,0x3fe237b544a46f6b,0xbfcf50f8f76d7df9,2
+np.float64,0x3fe7265e5eee4cbd,0xbfc1ff39089ec8d0,2
+np.float64,0x7fe2bb3c5ea57678,0x4073405aaad81cf2,2
+np.float64,0x3fd811df84b023bf,0xbfdb2e670ea8d8de,2
+np.float64,0x3f6a0efd00341dfa,0xc003fac1ae831241,2
+np.float64,0x3fd0d214afa1a429,0xbfe2922080a91c72,2
+np.float64,0x3feca6a350b94d47,0xbfa894eea3a96809,2
+np.float64,0x7fe23e5c76247cb8,0x4073402bbaaf71c7,2
+np.float64,0x3fe739a1fdae7344,0xbfc1d109f66efb5d,2
+np.float64,0x3fdf4b8e283e971c,0xbfd3e28f46169cc5,2
+np.float64,0x38f2535271e4b,0xc07344e3085219fa,2
+np.float64,0x7fd263a0f9a4c741,0x40733b68d945dae0,2
+np.float64,0x7fdd941863bb2830,0x40733eb651e3dca9,2
+np.float64,0xace7279159ce5,0xc0733d2b63b5947e,2
+np.float64,0x7fe34670b2268ce0,0x4073408d92770cb5,2
+np.float64,0x7fd11fa6dfa23f4d,0x40733aea02e76ea3,2
+np.float64,0x3fe6d9cbca6db398,0xbfc2b84b5c8c7eab,2
+np.float64,0x3fd69a0274ad3405,0xbfdcee3c7e52c463,2
+np.float64,0x3feb5af671f6b5ed,0xbfb16f88d739477f,2
+np.float64,0x3feea400163d4800,0xbf934e071c64fd0b,2
+np.float64,0x3fefd6bcf17fad7a,0xbf61f711c392b119,2
+np.float64,0x3fe148d43da291a8,0xbfd11e9cd3f91cd3,2
+np.float64,0x7fedf1308b7be260,0x4073439d135656da,2
+np.float64,0x3fe614c99c6c2993,0xbfc49fd1984dfd6d,2
+np.float64,0xd6e8d4e5add1b,0xc0733ba88256026e,2
+np.float64,0xfff0000000000000,0x7ff8000000000000,2
+np.float64,0x3fb530b5562a616b,0xbff1504bcc5c8f73,2
+np.float64,0xb7da68396fb4d,0xc0733cbe2790f52e,2
+np.float64,0x7fad78e26c3af1c4,0x4073303cdbfb0a15,2
+np.float64,0x7fee5698447cad30,0x407343b474573a8b,2
+np.float64,0x3fd488325c291065,0xbfdf999296d901e7,2
+np.float64,0x2669283a4cd26,0xc073479f823109a4,2
+np.float64,0x7fef3b090afe7611,0x407343e805a3b264,2
+np.float64,0x7fe8b96ae0f172d5,0x4073424874a342ab,2
+np.float64,0x7fef409f56fe813e,0x407343e943c3cd44,2
+np.float64,0x3fed28073dfa500e,0xbfa4b17e4cd31a3a,2
+np.float64,0x7f87ecc4802fd988,0x40732527e027b24b,2
+np.float64,0x3fdda24da0bb449b,0xbfd566a43ac035af,2
+np.float64,0x179fc9e62f3fa,0xc0734b0028c80fc1,2
+np.float64,0x3fef85b0927f0b61,0xbf7ac27565d5ab4f,2
+np.float64,0x5631501aac62b,0xc0734201be12c5d4,2
+np.float64,0x3fd782e424af05c8,0xbfdbd57544f8a7c3,2
+np.float64,0x3fe603a9a6ac0753,0xbfc4caff04dc3caf,2
+np.float64,0x7fbd5225163aa449,0x40733504b88f0a56,2
+np.float64,0x3fecd27506b9a4ea,0xbfa741dd70e6b08c,2
+np.float64,0x9c99603b3932c,0xc0733ddb922dc5db,2
+np.float64,0x3fbeb57f1a3d6afe,0xbfed789ff217aa08,2
+np.float64,0x3fef9c0f85bf381f,0xbf75d5c3d6cb281a,2
+np.float64,0x3fde4afb613c95f7,0xbfd4ca2a231c9005,2
+np.float64,0x396233d472c47,0xc07344d56ee70631,2
+np.float64,0x3fb31ea1c6263d44,0xbff207356152138d,2
+np.float64,0x3fe50bdf78aa17bf,0xbfc74ae0cbffb735,2
+np.float64,0xef74c701dee99,0xc0733ae81e4bb443,2
+np.float64,0x9a3e13a1347c3,0xc0733df68b60afc7,2
+np.float64,0x33ba4f886774b,0xc073458e03f0c13e,2
+np.float64,0x3fe8ba0e9931741d,0xbfbcaadf974e8f64,2
+np.float64,0x3fe090a4cd61214a,0xbfd24d236cf365d6,2
+np.float64,0x7fd87d992930fb31,0x40733d668b73b820,2
+np.float64,0x3fe6422b296c8456,0xbfc42e070b695d01,2
+np.float64,0x3febe9334677d267,0xbfae667864606cfe,2
+np.float64,0x771a3ce4ee348,0xc0733fc274d12c97,2
+np.float64,0x3fe0413542e0826b,0xbfd2d3b08fb5b8a6,2
+np.float64,0x3fd00870ea2010e2,0xbfe33cc04cbd42e0,2
+np.float64,0x3fe74fb817ae9f70,0xbfc19c45dbf919e1,2
+np.float64,0x40382fa08071,0xc07357514ced5577,2
+np.float64,0xa14968474292d,0xc0733da71a990f3a,2
+np.float64,0x5487c740a90fa,0xc0734224622d5801,2
+np.float64,0x3fed7d8d14fafb1a,0xbfa228f7ecc2ac03,2
+np.float64,0x3fe39bb485e73769,0xbfcb3a235a722960,2
+np.float64,0x3fd01090b2202121,0xbfe335b752589a22,2
+np.float64,0x3fd21a3e7da4347d,0xbfe18cd435a7c582,2
+np.float64,0x3fe7fa855a2ff50b,0xbfc00ab0665709fe,2
+np.float64,0x3fedc0d4577b81a9,0xbfa02fef3ff553fc,2
+np.float64,0x3fe99d4906333a92,0xbfb8bf18220e5e8e,2
+np.float64,0x3fd944ee3c3289dc,0xbfd9d46071675e73,2
+np.float64,0x3fe3ed8d52e7db1b,0xbfca53f8d4aef484,2
+np.float64,0x7fe748623a6e90c3,0x407341dd97c9dd79,2
+np.float64,0x3fea1b4b98343697,0xbfb6a1560a56927f,2
+np.float64,0xe1215715c242b,0xc0733b55dbf1f0a8,2
+np.float64,0x3fd0d5bccca1ab7a,0xbfe28f1b66d7a470,2
+np.float64,0x881a962710353,0xc0733ed51848a30d,2
+np.float64,0x3fcf022afe3e0456,0xbfe3b40eabf24501,2
+np.float64,0x3fdf1ac6bbbe358d,0xbfd40e03e888288d,2
+np.float64,0x3fa51a5eac2a34bd,0xbff628a7c34d51b3,2
+np.float64,0x3fdbaf408d375e81,0xbfd74ad39d97c92a,2
+np.float64,0x3fcd2418ea3a4832,0xbfe4910b009d8b11,2
+np.float64,0x3fc7b3062a2f660c,0xbfe7706dc47993e1,2
+np.float64,0x7fb8232218304643,0x407333aaa7041a9f,2
+np.float64,0x7fd5f186362be30b,0x40733ca32fdf9cc6,2
+np.float64,0x3fe57ef1d6aafde4,0xbfc61e23d00210c7,2
+np.float64,0x7c6830baf8d07,0xc0733f74f19e9dad,2
+np.float64,0xcacbfd5595980,0xc0733c0fb49edca7,2
+np.float64,0x3fdfdeac873fbd59,0xbfd36114c56bed03,2
+np.float64,0x3fd31f0889263e11,0xbfe0ca0cc1250169,2
+np.float64,0x3fe839fbe47073f8,0xbfbef0a2abc3d63f,2
+np.float64,0x3fc36af57e26d5eb,0xbfea3553f38770b7,2
+np.float64,0x3fe73dbc44ee7b79,0xbfc1c738f8fa6b3d,2
+np.float64,0x3fd3760e4da6ec1d,0xbfe08b5b609d11e5,2
+np.float64,0x3fee1cfa297c39f4,0xbf9b06d081bc9d5b,2
+np.float64,0xdfb01561bf61,0xc0734ea55e559888,2
+np.float64,0x687bd01cd0f7b,0xc07340ab67fe1816,2
+np.float64,0x3fefc88f4cbf911f,0xbf6828c359cf19dc,2
+np.float64,0x8ad34adb15a6a,0xc0733eb1e03811e5,2
+np.float64,0x3fe2b49c12e56938,0xbfcdd8dbdbc0ce59,2
+np.float64,0x6e05037adc0a1,0xc073404f91261635,2
+np.float64,0x3fe2fd737fe5fae7,0xbfcd020407ef4d78,2
+np.float64,0x3fd0f3c0dc21e782,0xbfe2766a1ab02eae,2
+np.float64,0x28564d9850acb,0xc073474875f87c5e,2
+np.float64,0x3fe4758015a8eb00,0xbfc8ddb45134a1bd,2
+np.float64,0x7fe7f19306efe325,0x4073420f626141a7,2
+np.float64,0x7fd27f34c0a4fe69,0x40733b733d2a5b50,2
+np.float64,0x92c2366325847,0xc0733e4f04f8195a,2
+np.float64,0x3fc21f8441243f09,0xbfeb2ad23bc1ab0b,2
+np.float64,0x3fc721d3e42e43a8,0xbfe7c69bb47b40c2,2
+np.float64,0x3fe2f11a1625e234,0xbfcd26363b9c36c3,2
+np.float64,0x3fdcb585acb96b0b,0xbfd648446237cb55,2
+np.float64,0x3fd4060bf2280c18,0xbfe025fd4c8a658b,2
+np.float64,0x7fb8ae2750315c4e,0x407333d23b025d08,2
+np.float64,0x3fe3a03119a74062,0xbfcb2d6c91b38552,2
+np.float64,0x7fdd2af92bba55f1,0x40733e9d737e16e6,2
+np.float64,0x3fe50b05862a160b,0xbfc74d20815fe36b,2
+np.float64,0x164409f82c882,0xc0734b6980e19c03,2
+np.float64,0x3fe4093712a8126e,0xbfca070367fda5e3,2
+np.float64,0xae3049935c609,0xc0733d1e3608797b,2
+np.float64,0x3fd71df4b4ae3be9,0xbfdc4dcb7637600d,2
+np.float64,0x7fca01e8023403cf,0x407339006c521c49,2
+np.float64,0x3fb0c5c43e218b88,0xbff2f03211c63f25,2
+np.float64,0x3fee757af83ceaf6,0xbf95f33a6e56b454,2
+np.float64,0x3f865f1f402cbe3f,0xbfff62d9c9072bd7,2
+np.float64,0x89864e95130ca,0xc0733ec29f1e32c6,2
+np.float64,0x3fe51482bcea2905,0xbfc73414ddc8f1b7,2
+np.float64,0x7fd802f8fa3005f1,0x40733d43684e460a,2
+np.float64,0x3fbeb86ca63d70d9,0xbfed774ccca9b8f5,2
+np.float64,0x3fb355dcc826abba,0xbff1f33f9339e7a3,2
+np.float64,0x3fe506c61eaa0d8c,0xbfc7585a3f7565a6,2
+np.float64,0x7fe393f25ba727e4,0x407340a94bcea73b,2
+np.float64,0xf66f532decdeb,0xc0733ab5041feb0f,2
+np.float64,0x3fe26e872be4dd0e,0xbfceaaab466f32e0,2
+np.float64,0x3fefd9e290bfb3c5,0xbf60977d24496295,2
+np.float64,0x7fe19c5f692338be,0x40733fecef53ad95,2
+np.float64,0x3fe80365ab3006cb,0xbfbfec4090ef76ec,2
+np.float64,0x3fe88ab39eb11567,0xbfbd8099388d054d,2
+np.float64,0x3fe68fb09fad1f61,0xbfc36db9de38c2c0,2
+np.float64,0x3fe9051883b20a31,0xbfbb5b75b8cb8f24,2
+np.float64,0x3fd4708683a8e10d,0xbfdfb9b085dd8a83,2
+np.float64,0x3fe00ac11a601582,0xbfd3316af3e43500,2
+np.float64,0xd16af30ba2d5f,0xc0733bd68e8252f9,2
+np.float64,0x3fb97d654632facb,0xbff007ac1257f575,2
+np.float64,0x7fd637c10fac6f81,0x40733cb949d76546,2
+np.float64,0x7fed2cab6dba5956,0x4073436edfc3764e,2
+np.float64,0x3fed04afbbba095f,0xbfa5bfaa5074b7f4,2
+np.float64,0x0,0xfff0000000000000,2
+np.float64,0x389a1dc671345,0xc07344edd4206338,2
+np.float64,0x3fbc9ba25a393745,0xbfee74c34f49b921,2
+np.float64,0x3feee749947dce93,0xbf8f032d9cf6b5ae,2
+np.float64,0xedc4cf89db89a,0xc0733af4b2a57920,2
+np.float64,0x3fe41629eba82c54,0xbfc9e321faf79e1c,2
+np.float64,0x3feb0bcbf7b61798,0xbfb2b31e5d952869,2
+np.float64,0xad60654b5ac0d,0xc0733d26860df676,2
+np.float64,0x3fe154e1ff22a9c4,0xbfd10b416e58c867,2
+np.float64,0x7fb20e9c8a241d38,0x407331a66453b8bc,2
+np.float64,0x7fcbbaaf7d37755e,0x4073397274f28008,2
+np.float64,0x187d0fbc30fa3,0xc0734ac03cc98cc9,2
+np.float64,0x7fd153afeaa2a75f,0x40733aff00b4311d,2
+np.float64,0x3fe05310a5e0a621,0xbfd2b5386aeecaac,2
+np.float64,0x7fea863b2b750c75,0x407342c57807f700,2
+np.float64,0x3fed5f0c633abe19,0xbfa30f6cfbc4bf94,2
+np.float64,0xf227c8b3e44f9,0xc0733ad42daaec9f,2
+np.float64,0x3fe956524772aca5,0xbfb9f4cabed7081d,2
+np.float64,0xefd11af7dfa24,0xc0733ae570ed2552,2
+np.float64,0x1690fff02d221,0xc0734b51a56c2980,2
+np.float64,0x7fd2e547a825ca8e,0x40733b992d6d9635,2
diff --git a/numpy/core/tests/data/umath-validation-set-log1p.csv b/numpy/core/tests/data/umath-validation-set-log1p.csv
new file mode 100644
index 000000000..6e4f88b34
--- /dev/null
+++ b/numpy/core/tests/data/umath-validation-set-log1p.csv
@@ -0,0 +1,1429 @@
+dtype,input,output,ulperrortol
+np.float32,0x3e10aca8,0x3e075347,2
+np.float32,0x3f776e66,0x3f2d2003,2
+np.float32,0xbf34e8ce,0xbf9cfd5c,2
+np.float32,0xbf0260ee,0xbf363f69,2
+np.float32,0x3ed285e8,0x3eb05870,2
+np.float32,0x262b88,0x262b88,2
+np.float32,0x3eeffd6c,0x3ec4cfdb,2
+np.float32,0x3ee86808,0x3ebf9f54,2
+np.float32,0x3f36eba8,0x3f0a0524,2
+np.float32,0xbf1c047a,0xbf70afc7,2
+np.float32,0x3ead2916,0x3e952902,2
+np.float32,0x61c9c9,0x61c9c9,2
+np.float32,0xff7fffff,0xffc00000,2
+np.float32,0x7f64ee52,0x42b138e0,2
+np.float32,0x7ed00b1e,0x42afa4ff,2
+np.float32,0x3db53340,0x3dada0b2,2
+np.float32,0x3e6b0a4a,0x3e5397a4,2
+np.float32,0x7ed5d64f,0x42afb310,2
+np.float32,0xbf12bc5f,0xbf59f5ee,2
+np.float32,0xbda12710,0xbda7d8b5,2
+np.float32,0xbe2e89d8,0xbe3f5a9f,2
+np.float32,0x3f5bee75,0x3f1ebea4,2
+np.float32,0x9317a,0x9317a,2
+np.float32,0x7ee00130,0x42afcad8,2
+np.float32,0x7ef0d16d,0x42afefe7,2
+np.float32,0xbec7463a,0xbefc6a44,2
+np.float32,0xbf760ecc,0xc04fe59c,2
+np.float32,0xbecacb3c,0xbf011ae3,2
+np.float32,0x3ead92be,0x3e9577f0,2
+np.float32,0xbf41510d,0xbfb41b3a,2
+np.float32,0x7f71d489,0x42b154f1,2
+np.float32,0x8023bcd5,0x8023bcd5,2
+np.float32,0x801d33d8,0x801d33d8,2
+np.float32,0x3f3f545d,0x3f0ee0d4,2
+np.float32,0xbf700682,0xc0318c25,2
+np.float32,0xbe54e990,0xbe6eb0a3,2
+np.float32,0x7f0289bf,0x42b01941,2
+np.float32,0xbd61ac90,0xbd682113,2
+np.float32,0xbf2ff310,0xbf94cd6f,2
+np.float32,0x7f10064a,0x42b04b98,2
+np.float32,0x804d0d6d,0x804d0d6d,2
+np.float32,0x80317b0a,0x80317b0a,2
+np.float32,0xbddfef18,0xbded2640,2
+np.float32,0x3f00c9ab,0x3ed0a5bd,2
+np.float32,0x7f04b905,0x42b021c1,2
+np.float32,0x7fc00000,0x7fc00000,2
+np.float32,0x6524c4,0x6524c4,2
+np.float32,0x3da08ae0,0x3d9a8f88,2
+np.float32,0x293ea9,0x293ea9,2
+np.float32,0x71499e,0x71499e,2
+np.float32,0xbf14f54d,0xbf5f38a5,2
+np.float32,0x806e60f5,0x806e60f5,2
+np.float32,0x3f5f34bb,0x3f207fff,2
+np.float32,0x80513427,0x80513427,2
+np.float32,0x7f379670,0x42b0c7dc,2
+np.float32,0x3efba888,0x3eccb20b,2
+np.float32,0x3eeadd1b,0x3ec14f4b,2
+np.float32,0x7ec5a27f,0x42af8ab8,2
+np.float32,0x3f2afe4e,0x3f02f7a2,2
+np.float32,0x5591c8,0x5591c8,2
+np.float32,0x3dbb7240,0x3db35bab,2
+np.float32,0x805b911b,0x805b911b,2
+np.float32,0x800000,0x800000,2
+np.float32,0x7e784c04,0x42ae9cab,2
+np.float32,0x7ebaae14,0x42af6d86,2
+np.float32,0xbec84f7a,0xbefe1d42,2
+np.float32,0x7cea8281,0x42aa56bf,2
+np.float32,0xbf542cf6,0xbfe1eb1b,2
+np.float32,0xbf6bfb13,0xc0231a5b,2
+np.float32,0x7d6eeaef,0x42abc32c,2
+np.float32,0xbf062f6b,0xbf3e2000,2
+np.float32,0x8073d8e9,0x8073d8e9,2
+np.float32,0xbea4db14,0xbec6f485,2
+np.float32,0x7d7e8d62,0x42abe3a0,2
+np.float32,0x7e8fc34e,0x42aee7c6,2
+np.float32,0x7dcbb0c3,0x42acd464,2
+np.float32,0x7e123c,0x7e123c,2
+np.float32,0x3d77af62,0x3d707c34,2
+np.float32,0x498cc8,0x498cc8,2
+np.float32,0x7f4e2206,0x42b1032a,2
+np.float32,0x3f734e0a,0x3f2b04a1,2
+np.float32,0x8053a9d0,0x8053a9d0,2
+np.float32,0xbe8a67e0,0xbea15be9,2
+np.float32,0xbf78e0ea,0xc065409e,2
+np.float32,0x352bdd,0x352bdd,2
+np.float32,0x3ee42be7,0x3ebcb38a,2
+np.float32,0x7f482d10,0x42b0f427,2
+np.float32,0xbf23155e,0xbf81b993,2
+np.float32,0x594920,0x594920,2
+np.float32,0x63f53f,0x63f53f,2
+np.float32,0x363592,0x363592,2
+np.float32,0x7dafbb78,0x42ac88cc,2
+np.float32,0x7f69516c,0x42b14298,2
+np.float32,0x3e1d5be2,0x3e126131,2
+np.float32,0x410c23,0x410c23,2
+np.float32,0x7ec9563c,0x42af9439,2
+np.float32,0xbedd3a0e,0xbf10d705,2
+np.float32,0x7f7c4f1f,0x42b16aa8,2
+np.float32,0xbe99b34e,0xbeb6c2d3,2
+np.float32,0x6cdc84,0x6cdc84,2
+np.float32,0x5b3bbe,0x5b3bbe,2
+np.float32,0x252178,0x252178,2
+np.float32,0x7d531865,0x42ab83c8,2
+np.float32,0xbf565b44,0xbfe873bf,2
+np.float32,0x5977ce,0x5977ce,2
+np.float32,0x588a58,0x588a58,2
+np.float32,0x3eae7054,0x3e961d51,2
+np.float32,0x725049,0x725049,2
+np.float32,0x7f2b9386,0x42b0a538,2
+np.float32,0xbe674714,0xbe831245,2
+np.float32,0x8044f0d8,0x8044f0d8,2
+np.float32,0x800a3c21,0x800a3c21,2
+np.float32,0x807b275b,0x807b275b,2
+np.float32,0xbf2463b6,0xbf83896e,2
+np.float32,0x801cca42,0x801cca42,2
+np.float32,0xbf28f2d0,0xbf8a121a,2
+np.float32,0x3f4168c2,0x3f1010ce,2
+np.float32,0x6f91a1,0x6f91a1,2
+np.float32,0xbf2b9eeb,0xbf8e0fc5,2
+np.float32,0xbea4c858,0xbec6d8e4,2
+np.float32,0xbf7abba0,0xc0788e88,2
+np.float32,0x802f18f7,0x802f18f7,2
+np.float32,0xbf7f6c75,0xc0c3145c,2
+np.float32,0xbe988210,0xbeb50f5e,2
+np.float32,0xbf219b7e,0xbf7f6a3b,2
+np.float32,0x7f800000,0x7f800000,2
+np.float32,0x7f7fffff,0x42b17218,2
+np.float32,0xbdca8d90,0xbdd5487e,2
+np.float32,0xbef683b0,0xbf2821b0,2
+np.float32,0x8043e648,0x8043e648,2
+np.float32,0xbf4319a4,0xbfb7cd1b,2
+np.float32,0x62c2b2,0x62c2b2,2
+np.float32,0xbf479ccd,0xbfc1a7b1,2
+np.float32,0x806c8a32,0x806c8a32,2
+np.float32,0x7f004447,0x42b01045,2
+np.float32,0x3f737d36,0x3f2b1ccf,2
+np.float32,0x3ee71f24,0x3ebebced,2
+np.float32,0x3ea0b6b4,0x3e8bc606,2
+np.float32,0x358fd7,0x358fd7,2
+np.float32,0xbe69780c,0xbe847d17,2
+np.float32,0x7f6bed18,0x42b14849,2
+np.float32,0xbf6a5113,0xc01dfe1d,2
+np.float32,0xbf255693,0xbf84de88,2
+np.float32,0x7f34acac,0x42b0bfac,2
+np.float32,0xbe8a3b6a,0xbea11efe,2
+np.float32,0x3f470d84,0x3f1342ab,2
+np.float32,0xbf2cbde3,0xbf8fc602,2
+np.float32,0x47c103,0x47c103,2
+np.float32,0xe3c94,0xe3c94,2
+np.float32,0xbec07afa,0xbef1693a,2
+np.float32,0x6a9cfe,0x6a9cfe,2
+np.float32,0xbe4339e0,0xbe5899da,2
+np.float32,0x7ea9bf1e,0x42af3cd6,2
+np.float32,0x3f6378b4,0x3f22c4c4,2
+np.float32,0xbd989ff0,0xbd9e9c77,2
+np.float32,0xbe6f2f50,0xbe88343d,2
+np.float32,0x3f7f2ac5,0x3f310764,2
+np.float32,0x3f256704,0x3eff2fb2,2
+np.float32,0x80786aca,0x80786aca,2
+np.float32,0x65d02f,0x65d02f,2
+np.float32,0x50d1c3,0x50d1c3,2
+np.float32,0x3f4a9d76,0x3f1541b4,2
+np.float32,0x802cf491,0x802cf491,2
+np.float32,0x3e935cec,0x3e81829b,2
+np.float32,0x3e2ad478,0x3e1dfd81,2
+np.float32,0xbf107cbd,0xbf54bef2,2
+np.float32,0xbf58c02e,0xbff007fe,2
+np.float32,0x80090808,0x80090808,2
+np.float32,0x805d1f66,0x805d1f66,2
+np.float32,0x6aec95,0x6aec95,2
+np.float32,0xbee3fc6e,0xbf16dc73,2
+np.float32,0x7f63314b,0x42b134f9,2
+np.float32,0x550443,0x550443,2
+np.float32,0xbefa8174,0xbf2c026e,2
+np.float32,0x3f7fb380,0x3f314bd5,2
+np.float32,0x80171f2c,0x80171f2c,2
+np.float32,0x3f2f56ae,0x3f058f2d,2
+np.float32,0x3eacaecb,0x3e94cd97,2
+np.float32,0xbe0c4f0c,0xbe16e69d,2
+np.float32,0x3f48e4cb,0x3f144b42,2
+np.float32,0x7f03efe2,0x42b01eb7,2
+np.float32,0xbf1019ac,0xbf53dbe9,2
+np.float32,0x3e958524,0x3e832eb5,2
+np.float32,0xbf1b23c6,0xbf6e72f2,2
+np.float32,0x12c554,0x12c554,2
+np.float32,0x7dee588c,0x42ad24d6,2
+np.float32,0xbe8c216c,0xbea3ba70,2
+np.float32,0x804553cb,0x804553cb,2
+np.float32,0xbe446324,0xbe5a0966,2
+np.float32,0xbef7150a,0xbf28adff,2
+np.float32,0xbf087282,0xbf42ec6e,2
+np.float32,0x3eeef15c,0x3ec41937,2
+np.float32,0x61bbd2,0x61bbd2,2
+np.float32,0x3e51b28d,0x3e3ec538,2
+np.float32,0x57e869,0x57e869,2
+np.float32,0x7e5e7711,0x42ae646c,2
+np.float32,0x8050b173,0x8050b173,2
+np.float32,0xbf63c90c,0xc00d2438,2
+np.float32,0xbeba774c,0xbee7dcf8,2
+np.float32,0x8016faac,0x8016faac,2
+np.float32,0xbe8b448c,0xbea28aaf,2
+np.float32,0x3e8cd448,0x3e78d29e,2
+np.float32,0x80484e02,0x80484e02,2
+np.float32,0x3f63ba68,0x3f22e78c,2
+np.float32,0x2e87bb,0x2e87bb,2
+np.float32,0x230496,0x230496,2
+np.float32,0x1327b2,0x1327b2,2
+np.float32,0xbf046c56,0xbf3a72d2,2
+np.float32,0x3ecefe60,0x3eadd69a,2
+np.float32,0x49c56e,0x49c56e,2
+np.float32,0x3df22d60,0x3de4e550,2
+np.float32,0x3f67c19d,0x3f250707,2
+np.float32,0x3f20eb9c,0x3ef9b624,2
+np.float32,0x3f05ca75,0x3ed742fa,2
+np.float32,0xbe8514f8,0xbe9a1d45,2
+np.float32,0x8070a003,0x8070a003,2
+np.float32,0x7e49650e,0x42ae317a,2
+np.float32,0x3de16ce9,0x3dd5dc3e,2
+np.float32,0xbf4ae952,0xbfc95f1f,2
+np.float32,0xbe44dd84,0xbe5aa0db,2
+np.float32,0x803c3bc0,0x803c3bc0,2
+np.float32,0x3eebb9e8,0x3ec1e692,2
+np.float32,0x80588275,0x80588275,2
+np.float32,0xbea1e69a,0xbec29d86,2
+np.float32,0x3f7b4bf8,0x3f2f154c,2
+np.float32,0x7eb47ecc,0x42af5c46,2
+np.float32,0x3d441e00,0x3d3f911a,2
+np.float32,0x7f54d40e,0x42b11388,2
+np.float32,0xbf47f17e,0xbfc26882,2
+np.float32,0x3ea7da57,0x3e912db4,2
+np.float32,0x3f59cc7b,0x3f1d984e,2
+np.float32,0x570e08,0x570e08,2
+np.float32,0x3e99560c,0x3e8620a2,2
+np.float32,0x3ecfbd14,0x3eae5e55,2
+np.float32,0x7e86be08,0x42aec698,2
+np.float32,0x3f10f28a,0x3ee5b5d3,2
+np.float32,0x7f228722,0x42b0897a,2
+np.float32,0x3f4b979b,0x3f15cd30,2
+np.float32,0xbf134283,0xbf5b30f9,2
+np.float32,0x3f2ae16a,0x3f02e64f,2
+np.float32,0x3e98e158,0x3e85c6cc,2
+np.float32,0x7ec39f27,0x42af857a,2
+np.float32,0x3effedb0,0x3ecf8cea,2
+np.float32,0xbd545620,0xbd5a09c1,2
+np.float32,0x503a28,0x503a28,2
+np.float32,0x3f712744,0x3f29e9a1,2
+np.float32,0x3edc6194,0x3eb748b1,2
+np.float32,0xbf4ec1e5,0xbfd2ff5f,2
+np.float32,0x3f46669e,0x3f12e4b5,2
+np.float32,0xabad3,0xabad3,2
+np.float32,0x80000000,0x80000000,2
+np.float32,0x803f2e6d,0x803f2e6d,2
+np.float32,0xbf431542,0xbfb7c3e6,2
+np.float32,0x3f6f2d53,0x3f28e496,2
+np.float32,0x546bd8,0x546bd8,2
+np.float32,0x25c80a,0x25c80a,2
+np.float32,0x3e50883c,0x3e3dcd7e,2
+np.float32,0xbf5fa2ba,0xc0045c14,2
+np.float32,0x80271c07,0x80271c07,2
+np.float32,0x8043755d,0x8043755d,2
+np.float32,0xbf3c5cea,0xbfaa5ee9,2
+np.float32,0x3f2fea38,0x3f05e6af,2
+np.float32,0x6da3dc,0x6da3dc,2
+np.float32,0xbf095945,0xbf44dc70,2
+np.float32,0xbe33d584,0xbe45c1f5,2
+np.float32,0x7eb41b2e,0x42af5b2b,2
+np.float32,0xbf0feb74,0xbf537242,2
+np.float32,0xbe96225a,0xbeb1b0b1,2
+np.float32,0x3f63b95f,0x3f22e700,2
+np.float32,0x0,0x0,2
+np.float32,0x3e20b0cc,0x3e154374,2
+np.float32,0xbf79880c,0xc06b6801,2
+np.float32,0xbea690b6,0xbec97b93,2
+np.float32,0xbf3e11ca,0xbfada449,2
+np.float32,0x7e7e6292,0x42aea912,2
+np.float32,0x3e793350,0x3e5f0b7b,2
+np.float32,0x802e7183,0x802e7183,2
+np.float32,0x3f1b3695,0x3ef2a788,2
+np.float32,0x801efa20,0x801efa20,2
+np.float32,0x3f1ec43a,0x3ef70f42,2
+np.float32,0xbf12c5ed,0xbf5a0c52,2
+np.float32,0x8005e99c,0x8005e99c,2
+np.float32,0xbf79f5e7,0xc06fcca5,2
+np.float32,0x3ecbaf50,0x3eab7a03,2
+np.float32,0x46b0fd,0x46b0fd,2
+np.float32,0x3edb9023,0x3eb6b631,2
+np.float32,0x7f24bc41,0x42b09063,2
+np.float32,0xbd8d9328,0xbd92b4c6,2
+np.float32,0x3f2c5d7f,0x3f03c9d9,2
+np.float32,0x807bebc9,0x807bebc9,2
+np.float32,0x7f797a99,0x42b164e2,2
+np.float32,0x756e3c,0x756e3c,2
+np.float32,0x80416f8a,0x80416f8a,2
+np.float32,0x3e0d512a,0x3e04611a,2
+np.float32,0x3f7be3e6,0x3f2f61ec,2
+np.float32,0x80075c41,0x80075c41,2
+np.float32,0xbe850294,0xbe9a046c,2
+np.float32,0x684679,0x684679,2
+np.float32,0x3eb393c4,0x3e99eed2,2
+np.float32,0x3f4177c6,0x3f10195b,2
+np.float32,0x3dd1f402,0x3dc7dfe5,2
+np.float32,0x3ef484d4,0x3ec7e2e1,2
+np.float32,0x53eb8f,0x53eb8f,2
+np.float32,0x7f072cb6,0x42b02b20,2
+np.float32,0xbf1b6b55,0xbf6f28d4,2
+np.float32,0xbd8a98d8,0xbd8f827d,2
+np.float32,0x3eafb418,0x3e970e96,2
+np.float32,0x6555af,0x6555af,2
+np.float32,0x7dd5118e,0x42aceb6f,2
+np.float32,0x800a13f7,0x800a13f7,2
+np.float32,0x331a9d,0x331a9d,2
+np.float32,0x8063773f,0x8063773f,2
+np.float32,0x3e95e068,0x3e837553,2
+np.float32,0x80654b32,0x80654b32,2
+np.float32,0x3dabe0e0,0x3da50bb3,2
+np.float32,0xbf6283c3,0xc00a5280,2
+np.float32,0x80751cc5,0x80751cc5,2
+np.float32,0x3f668eb6,0x3f2465c0,2
+np.float32,0x3e13c058,0x3e0a048c,2
+np.float32,0x77780c,0x77780c,2
+np.float32,0x3f7d6e48,0x3f302868,2
+np.float32,0x7e31f9e3,0x42adf22f,2
+np.float32,0x246c7b,0x246c7b,2
+np.float32,0xbe915bf0,0xbeaafa6c,2
+np.float32,0xbf800000,0xff800000,2
+np.float32,0x3f698f42,0x3f25f8e0,2
+np.float32,0x7e698885,0x42ae7d48,2
+np.float32,0x3f5bbd42,0x3f1ea42c,2
+np.float32,0x5b8444,0x5b8444,2
+np.float32,0xbf6065f6,0xc005e2c6,2
+np.float32,0xbeb95036,0xbee60dad,2
+np.float32,0xbf44f846,0xbfbbcade,2
+np.float32,0xc96e5,0xc96e5,2
+np.float32,0xbf213e90,0xbf7e6eae,2
+np.float32,0xbeb309cc,0xbedc4fe6,2
+np.float32,0xbe781cf4,0xbe8e0fe6,2
+np.float32,0x7f0cf0db,0x42b04083,2
+np.float32,0xbf7b6143,0xc08078f9,2
+np.float32,0x80526fc6,0x80526fc6,2
+np.float32,0x3f092bf3,0x3edbaeec,2
+np.float32,0x3ecdf154,0x3ead16df,2
+np.float32,0x2fe85b,0x2fe85b,2
+np.float32,0xbf5100a0,0xbfd8f871,2
+np.float32,0xbec09d40,0xbef1a028,2
+np.float32,0x5e6a85,0x5e6a85,2
+np.float32,0xbec0e2a0,0xbef20f6b,2
+np.float32,0x3f72e788,0x3f2ad00d,2
+np.float32,0x880a6,0x880a6,2
+np.float32,0x3d9e90bf,0x3d98b9fc,2
+np.float32,0x15cf25,0x15cf25,2
+np.float32,0x10171b,0x10171b,2
+np.float32,0x805cf1aa,0x805cf1aa,2
+np.float32,0x3f19bd36,0x3ef0d0d2,2
+np.float32,0x3ebe2bda,0x3ea1b774,2
+np.float32,0xbecd8192,0xbf035c49,2
+np.float32,0x3e2ce508,0x3e1fc21b,2
+np.float32,0x290f,0x290f,2
+np.float32,0x803b679f,0x803b679f,2
+np.float32,0x1,0x1,2
+np.float32,0x807a9c76,0x807a9c76,2
+np.float32,0xbf65fced,0xc01257f8,2
+np.float32,0x3f783414,0x3f2d8475,2
+np.float32,0x3f2d9d92,0x3f0488da,2
+np.float32,0xbddb5798,0xbde80018,2
+np.float32,0x3e91afb8,0x3e8034e7,2
+np.float32,0xbf1b775a,0xbf6f476d,2
+np.float32,0xbf73a32c,0xc041f3ba,2
+np.float32,0xbea39364,0xbec5121b,2
+np.float32,0x80375b94,0x80375b94,2
+np.float32,0x3f331252,0x3f07c3e9,2
+np.float32,0xbf285774,0xbf892e74,2
+np.float32,0x3e699bb8,0x3e526d55,2
+np.float32,0x3f08208a,0x3eda523a,2
+np.float32,0xbf42fb4a,0xbfb78d60,2
+np.float32,0x8029c894,0x8029c894,2
+np.float32,0x3e926c0c,0x3e80c76e,2
+np.float32,0x801e4715,0x801e4715,2
+np.float32,0x3e4b36d8,0x3e395ffd,2
+np.float32,0x8041556b,0x8041556b,2
+np.float32,0xbf2d99ba,0xbf9119bd,2
+np.float32,0x3ed83ea8,0x3eb46250,2
+np.float32,0xbe94a280,0xbeaf92b4,2
+np.float32,0x7f4c7a64,0x42b0ff0a,2
+np.float32,0x806d4022,0x806d4022,2
+np.float32,0xbed382f8,0xbf086d26,2
+np.float32,0x1846fe,0x1846fe,2
+np.float32,0xbe702558,0xbe88d4d8,2
+np.float32,0xbe650ee0,0xbe81a3cc,2
+np.float32,0x3ee9d088,0x3ec0970c,2
+np.float32,0x7f6d4498,0x42b14b30,2
+np.float32,0xbef9f9e6,0xbf2b7ddb,2
+np.float32,0xbf70c384,0xc0349370,2
+np.float32,0xbeff9e9e,0xbf3110c8,2
+np.float32,0xbef06372,0xbf224aa9,2
+np.float32,0xbf15a692,0xbf60e1fa,2
+np.float32,0x8058c117,0x8058c117,2
+np.float32,0xbd9f74b8,0xbda6017b,2
+np.float32,0x801bf130,0x801bf130,2
+np.float32,0x805da84c,0x805da84c,2
+np.float32,0xff800000,0xffc00000,2
+np.float32,0xbeb01de2,0xbed7d6d6,2
+np.float32,0x8077de08,0x8077de08,2
+np.float32,0x3e327668,0x3e2482c1,2
+np.float32,0xbe7add88,0xbe8fe1ab,2
+np.float32,0x805a3c2e,0x805a3c2e,2
+np.float32,0x80326a73,0x80326a73,2
+np.float32,0x800b8a34,0x800b8a34,2
+np.float32,0x8048c83a,0x8048c83a,2
+np.float32,0xbf3799d6,0xbfa1a975,2
+np.float32,0x807649c7,0x807649c7,2
+np.float32,0x3dfdbf90,0x3def3798,2
+np.float32,0xbf1b538a,0xbf6eec4c,2
+np.float32,0xbf1e5989,0xbf76baa0,2
+np.float32,0xc7a80,0xc7a80,2
+np.float32,0x8001be54,0x8001be54,2
+np.float32,0x3f435bbc,0x3f112c6d,2
+np.float32,0xbeabcff8,0xbed151d1,2
+np.float32,0x7de20c78,0x42ad09b7,2
+np.float32,0x3f0e6d2e,0x3ee27b1e,2
+np.float32,0xbf0cb352,0xbf4c3267,2
+np.float32,0x7f6ec06f,0x42b14e61,2
+np.float32,0x7f6fa8ef,0x42b15053,2
+np.float32,0xbf3d2a6a,0xbfabe623,2
+np.float32,0x7f077a4c,0x42b02c46,2
+np.float32,0xbf2a68dc,0xbf8c3cc4,2
+np.float32,0x802a5dbe,0x802a5dbe,2
+np.float32,0x807f631c,0x807f631c,2
+np.float32,0x3dc9b8,0x3dc9b8,2
+np.float32,0x3ebdc1b7,0x3ea16a0a,2
+np.float32,0x7ef29dab,0x42aff3b5,2
+np.float32,0x3e8ab1cc,0x3e757806,2
+np.float32,0x3f27e88e,0x3f011c6d,2
+np.float32,0x3cfd1455,0x3cf93fb5,2
+np.float32,0x7f7eebf5,0x42b16fef,2
+np.float32,0x3c9b2140,0x3c99ade9,2
+np.float32,0x7e928601,0x42aef183,2
+np.float32,0xbd7d2db0,0xbd82abae,2
+np.float32,0x3e6f0df3,0x3e56da20,2
+np.float32,0x7d36a2fc,0x42ab39a3,2
+np.float32,0xbf49d3a2,0xbfc6c859,2
+np.float32,0x7ee541d3,0x42afd6b6,2
+np.float32,0x80753dc0,0x80753dc0,2
+np.float32,0x3f4ce486,0x3f16865d,2
+np.float32,0x39e701,0x39e701,2
+np.float32,0x3f3d9ede,0x3f0de5fa,2
+np.float32,0x7fafb2,0x7fafb2,2
+np.float32,0x3e013fdc,0x3df37090,2
+np.float32,0x807b6a2c,0x807b6a2c,2
+np.float32,0xbe86800a,0xbe9c08c7,2
+np.float32,0x7f40f080,0x42b0e14d,2
+np.float32,0x7eef5afe,0x42afecc8,2
+np.float32,0x7ec30052,0x42af83da,2
+np.float32,0x3eacf768,0x3e9503e1,2
+np.float32,0x7f13ef0e,0x42b0594e,2
+np.float32,0x80419f4a,0x80419f4a,2
+np.float32,0xbf485932,0xbfc3562a,2
+np.float32,0xbe8a24d6,0xbea10011,2
+np.float32,0xbda791c0,0xbdaed2bc,2
+np.float32,0x3e9b5169,0x3e87a67d,2
+np.float32,0x807dd882,0x807dd882,2
+np.float32,0x7f40170e,0x42b0df0a,2
+np.float32,0x7f02f7f9,0x42b01af1,2
+np.float32,0x3ea38bf9,0x3e8decde,2
+np.float32,0x3e2e7ce8,0x3e211ed4,2
+np.float32,0x70a7a6,0x70a7a6,2
+np.float32,0x7d978592,0x42ac3ce7,2
+np.float32,0x804d12d0,0x804d12d0,2
+np.float32,0x80165dc8,0x80165dc8,2
+np.float32,0x80000001,0x80000001,2
+np.float32,0x3e325da0,0x3e246da6,2
+np.float32,0xbe063bb8,0xbe0fe281,2
+np.float32,0x160b8,0x160b8,2
+np.float32,0xbe5687a4,0xbe70bbef,2
+np.float32,0x7f11ab34,0x42b05168,2
+np.float32,0xc955c,0xc955c,2
+np.float32,0xbea0003a,0xbebfd826,2
+np.float32,0x3f7fbdd9,0x3f315102,2
+np.float32,0xbe61aefc,0xbe7ef121,2
+np.float32,0xbf1b9873,0xbf6f9bc3,2
+np.float32,0x3a6d14,0x3a6d14,2
+np.float32,0xbf1ad3b4,0xbf6da808,2
+np.float32,0x3ed2dd24,0x3eb0963d,2
+np.float32,0xbe81a4ca,0xbe957d52,2
+np.float32,0x7f1be3e9,0x42b07421,2
+np.float32,0x7f5ce943,0x42b1269e,2
+np.float32,0x7eebcbdf,0x42afe51d,2
+np.float32,0x807181b5,0x807181b5,2
+np.float32,0xbecb03ba,0xbf0149ad,2
+np.float32,0x42edb8,0x42edb8,2
+np.float32,0xbf3aeec8,0xbfa7b13f,2
+np.float32,0xbd0c4f00,0xbd0ec4a0,2
+np.float32,0x3e48d260,0x3e376070,2
+np.float32,0x1a9731,0x1a9731,2
+np.float32,0x7f323be4,0x42b0b8b5,2
+np.float32,0x1a327f,0x1a327f,2
+np.float32,0x17f1fc,0x17f1fc,2
+np.float32,0xbf2f4f9b,0xbf93c91a,2
+np.float32,0x3ede8934,0x3eb8c9c3,2
+np.float32,0xbf56aaac,0xbfe968bb,2
+np.float32,0x3e22cb5a,0x3e17148c,2
+np.float32,0x7d9def,0x7d9def,2
+np.float32,0x8045b963,0x8045b963,2
+np.float32,0x77404f,0x77404f,2
+np.float32,0x7e2c9efb,0x42ade28b,2
+np.float32,0x8058ad89,0x8058ad89,2
+np.float32,0x7f4139,0x7f4139,2
+np.float32,0x8020e12a,0x8020e12a,2
+np.float32,0x800c9daa,0x800c9daa,2
+np.float32,0x7f2c5ac5,0x42b0a789,2
+np.float32,0x3f04a47b,0x3ed5c043,2
+np.float32,0x804692d5,0x804692d5,2
+np.float32,0xbf6e7fa4,0xc02bb493,2
+np.float32,0x80330756,0x80330756,2
+np.float32,0x7f3e29ad,0x42b0d9e1,2
+np.float32,0xbebf689a,0xbeefb24d,2
+np.float32,0x3f29a86c,0x3f022a56,2
+np.float32,0x3e3bd1c0,0x3e2c72b3,2
+np.float32,0x3f78f2e8,0x3f2de546,2
+np.float32,0x3f3709be,0x3f0a16af,2
+np.float32,0x3e11f150,0x3e086f97,2
+np.float32,0xbf5867ad,0xbfeee8a0,2
+np.float32,0xbebfb328,0xbef0296c,2
+np.float32,0x2f7f15,0x2f7f15,2
+np.float32,0x805cfe84,0x805cfe84,2
+np.float32,0xbf504e01,0xbfd71589,2
+np.float32,0x3ee0903c,0x3eba330c,2
+np.float32,0xbd838990,0xbd87f399,2
+np.float32,0x3f14444e,0x3ee9ee7d,2
+np.float32,0x7e352583,0x42adfb3a,2
+np.float32,0x7e76f824,0x42ae99ec,2
+np.float32,0x3f772d00,0x3f2cfebf,2
+np.float32,0x801f7763,0x801f7763,2
+np.float32,0x3f760bf5,0x3f2c6b87,2
+np.float32,0xbf0bb696,0xbf4a03a5,2
+np.float32,0x3f175d2c,0x3eedd6d2,2
+np.float32,0xbf5723f8,0xbfeae288,2
+np.float32,0x24de0a,0x24de0a,2
+np.float32,0x3cd73f80,0x3cd47801,2
+np.float32,0x7f013305,0x42b013fa,2
+np.float32,0x3e3ad425,0x3e2b9c50,2
+np.float32,0x7d3d16,0x7d3d16,2
+np.float32,0x3ef49738,0x3ec7ef54,2
+np.float32,0x3f5b8612,0x3f1e8678,2
+np.float32,0x7f0eeb5c,0x42b047a7,2
+np.float32,0x7e9d7cb0,0x42af1675,2
+np.float32,0xbdd1cfb0,0xbddd5aa0,2
+np.float32,0xbf645dba,0xc00e78fe,2
+np.float32,0x3f511174,0x3f18d56c,2
+np.float32,0x3d91ad00,0x3d8cba62,2
+np.float32,0x805298da,0x805298da,2
+np.float32,0xbedb6af4,0xbf0f4090,2
+np.float32,0x3d23b1ba,0x3d208205,2
+np.float32,0xbea5783e,0xbec7dc87,2
+np.float32,0x79d191,0x79d191,2
+np.float32,0x3e894413,0x3e7337da,2
+np.float32,0x80800000,0x80800000,2
+np.float32,0xbf34a8d3,0xbf9c907b,2
+np.float32,0x3bae779a,0x3bae011f,2
+np.float32,0x8049284d,0x8049284d,2
+np.float32,0x3eb42cc4,0x3e9a600b,2
+np.float32,0x3da1e2d0,0x3d9bce5f,2
+np.float32,0x3f364b8a,0x3f09a7af,2
+np.float32,0x3d930b10,0x3d8e0118,2
+np.float32,0x8061f8d7,0x8061f8d7,2
+np.float32,0x3f473213,0x3f13573b,2
+np.float32,0x3f1e2a38,0x3ef65102,2
+np.float32,0x8068f7d9,0x8068f7d9,2
+np.float32,0x3f181ef8,0x3eeeca2c,2
+np.float32,0x3eeb6168,0x3ec1a9f5,2
+np.float32,0xc2db6,0xc2db6,2
+np.float32,0x3ef7b578,0x3eca0a69,2
+np.float32,0xbf5b5a84,0xbff8d075,2
+np.float32,0x7f479d5f,0x42b0f2b7,2
+np.float32,0x3e6f3c24,0x3e56ff92,2
+np.float32,0x3f45543a,0x3f1249f0,2
+np.float32,0xbea7c1fa,0xbecb40d2,2
+np.float32,0x7de082,0x7de082,2
+np.float32,0x383729,0x383729,2
+np.float32,0xbd91cb90,0xbd973eb3,2
+np.float32,0x7f320218,0x42b0b80f,2
+np.float32,0x5547f2,0x5547f2,2
+np.float32,0x291fe4,0x291fe4,2
+np.float32,0xbe078ba0,0xbe11655f,2
+np.float32,0x7e0c0658,0x42ad7764,2
+np.float32,0x7e129a2b,0x42ad8ee5,2
+np.float32,0x3f7c96d4,0x3f2fbc0c,2
+np.float32,0x3f800000,0x3f317218,2
+np.float32,0x7f131754,0x42b05662,2
+np.float32,0x15f833,0x15f833,2
+np.float32,0x80392ced,0x80392ced,2
+np.float32,0x3f7c141a,0x3f2f7a36,2
+np.float32,0xbf71c03f,0xc038dcfd,2
+np.float32,0xbe14fb2c,0xbe20fff3,2
+np.float32,0xbee0bac6,0xbf13f14c,2
+np.float32,0x801a32dd,0x801a32dd,2
+np.float32,0x8e12d,0x8e12d,2
+np.float32,0x3f48c606,0x3f143a04,2
+np.float32,0x7f418af5,0x42b0e2e6,2
+np.float32,0x3f1f2918,0x3ef78bb7,2
+np.float32,0x11141b,0x11141b,2
+np.float32,0x3e9fc9e8,0x3e8b11ad,2
+np.float32,0xbea5447a,0xbec79010,2
+np.float32,0xbe31d904,0xbe4359db,2
+np.float32,0x80184667,0x80184667,2
+np.float32,0xbf00503c,0xbf3212c2,2
+np.float32,0x3e0328cf,0x3df6d425,2
+np.float32,0x7ee8e1b7,0x42afdebe,2
+np.float32,0xbef95e24,0xbf2ae5db,2
+np.float32,0x7f3e4eed,0x42b0da45,2
+np.float32,0x3f43ee85,0x3f117fa0,2
+np.float32,0xbcfa2ac0,0xbcfe10fe,2
+np.float32,0x80162774,0x80162774,2
+np.float32,0x372e8b,0x372e8b,2
+np.float32,0x3f263802,0x3f0016b0,2
+np.float32,0x8008725f,0x8008725f,2
+np.float32,0x800beb40,0x800beb40,2
+np.float32,0xbe93308e,0xbead8a77,2
+np.float32,0x3d8a4240,0x3d85cab8,2
+np.float32,0x80179de0,0x80179de0,2
+np.float32,0x7f4a98f2,0x42b0fa4f,2
+np.float32,0x3f0d214e,0x3ee0cff1,2
+np.float32,0x80536c2c,0x80536c2c,2
+np.float32,0x7e7038ed,0x42ae8bbe,2
+np.float32,0x7f345af9,0x42b0bec4,2
+np.float32,0xbf243219,0xbf83442f,2
+np.float32,0x7e0d5555,0x42ad7c27,2
+np.float32,0x762e95,0x762e95,2
+np.float32,0x7ebf4548,0x42af79f6,2
+np.float32,0x8079639e,0x8079639e,2
+np.float32,0x3ef925c0,0x3ecb0260,2
+np.float32,0x3f708695,0x3f2996d6,2
+np.float32,0xfca9f,0xfca9f,2
+np.float32,0x8060dbf4,0x8060dbf4,2
+np.float32,0x4c8840,0x4c8840,2
+np.float32,0xbea922ee,0xbecd4ed5,2
+np.float32,0xbf4f28a9,0xbfd40b98,2
+np.float32,0xbe25ad48,0xbe34ba1b,2
+np.float32,0x3f2fb254,0x3f05c58c,2
+np.float32,0x3f73bcc2,0x3f2b3d5f,2
+np.float32,0xbf479a07,0xbfc1a165,2
+np.float32,0xbeb9a808,0xbee69763,2
+np.float32,0x7eb16a65,0x42af5376,2
+np.float32,0xbeb3e442,0xbedda042,2
+np.float32,0x3d8f439c,0x3d8a79ac,2
+np.float32,0x80347516,0x80347516,2
+np.float32,0x3e8a0c5d,0x3e74738c,2
+np.float32,0xbf0383a4,0xbf389289,2
+np.float32,0x806be8f5,0x806be8f5,2
+np.float32,0x8023f0c5,0x8023f0c5,2
+np.float32,0x2060e9,0x2060e9,2
+np.float32,0xbf759eba,0xc04d239f,2
+np.float32,0x3d84cc5a,0x3d80ab96,2
+np.float32,0xbf57746b,0xbfebdf87,2
+np.float32,0x3e418417,0x3e31401f,2
+np.float32,0xaecce,0xaecce,2
+np.float32,0x3cd1766f,0x3cced45c,2
+np.float32,0x53724a,0x53724a,2
+np.float32,0x3f773710,0x3f2d03de,2
+np.float32,0x8013d040,0x8013d040,2
+np.float32,0x4d0eb2,0x4d0eb2,2
+np.float32,0x8014364a,0x8014364a,2
+np.float32,0x7f3c56c9,0x42b0d4f2,2
+np.float32,0x3eee1e1c,0x3ec3891a,2
+np.float32,0xbdda3eb8,0xbde6c5a0,2
+np.float32,0x26ef4a,0x26ef4a,2
+np.float32,0x7ed3370c,0x42afacbf,2
+np.float32,0xbf06e31b,0xbf3f9ab7,2
+np.float32,0xbe3185f0,0xbe42f556,2
+np.float32,0x3dcf9abe,0x3dc5be41,2
+np.float32,0xbf3696d9,0xbf9fe2bd,2
+np.float32,0x3e68ee50,0x3e51e01a,2
+np.float32,0x3f3d4cc2,0x3f0db6ca,2
+np.float32,0x7fa00000,0x7fe00000,2
+np.float32,0xbf03070c,0xbf3792d0,2
+np.float32,0x3ea79e6c,0x3e910092,2
+np.float32,0xbf1a393a,0xbf6c2251,2
+np.float32,0x3f41eb0e,0x3f105afc,2
+np.float32,0x3ceadb2f,0x3ce78d79,2
+np.float32,0xbf5dc105,0xc000be2c,2
+np.float32,0x7ebb5a0e,0x42af6f5c,2
+np.float32,0xbf7c44eb,0xc0875058,2
+np.float32,0x6aaaf4,0x6aaaf4,2
+np.float32,0x807d8f23,0x807d8f23,2
+np.float32,0xbee6b142,0xbf194fef,2
+np.float32,0xbe83f256,0xbe989526,2
+np.float32,0x7d588e,0x7d588e,2
+np.float32,0x7cc80131,0x42aa0542,2
+np.float32,0x3e0ab198,0x3e02124f,2
+np.float32,0xbf6e64db,0xc02b52eb,2
+np.float32,0x3d238b56,0x3d205d1b,2
+np.float32,0xbeb408e2,0xbeddd8bc,2
+np.float32,0x3f78340d,0x3f2d8471,2
+np.float32,0x806162a3,0x806162a3,2
+np.float32,0x804e484f,0x804e484f,2
+np.float32,0xbeb8c576,0xbee53466,2
+np.float32,0x807aab15,0x807aab15,2
+np.float32,0x3f523e20,0x3f197ab8,2
+np.float32,0xbf009190,0xbf3295de,2
+np.float32,0x3df43da5,0x3de6bd82,2
+np.float32,0x7f639aea,0x42b135e6,2
+np.float32,0x3f1e638a,0x3ef697da,2
+np.float32,0xbf4884de,0xbfc3bac3,2
+np.float32,0xbe9336b6,0xbead931b,2
+np.float32,0x6daf7f,0x6daf7f,2
+np.float32,0xbf1fc152,0xbf7a70b1,2
+np.float32,0x3f103720,0x3ee4c649,2
+np.float32,0x3eeaa227,0x3ec126df,2
+np.float32,0x7f7ea945,0x42b16f69,2
+np.float32,0x3d3cd800,0x3d389ead,2
+np.float32,0x3f3d7268,0x3f0dcc6e,2
+np.float32,0xbf3c1b41,0xbfa9e2e3,2
+np.float32,0x3ecf3818,0x3eadffb2,2
+np.float32,0x3f1af312,0x3ef25372,2
+np.float32,0x48fae4,0x48fae4,2
+np.float64,0x7fedaa1ee4fb543d,0x40862da7ca7c308e,2
+np.float64,0x8007d2d810efa5b1,0x8007d2d810efa5b1,2
+np.float64,0x3fc385e069270bc0,0x3fc22b8884cf2c3b,2
+np.float64,0x68ed4130d1da9,0x68ed4130d1da9,2
+np.float64,0x8008e93e58d1d27d,0x8008e93e58d1d27d,2
+np.float64,0xbfd3d62852a7ac50,0xbfd7be3a7ad1af02,2
+np.float64,0xbfc1fa0ba923f418,0xbfc35f0f19447df7,2
+np.float64,0xbfe01b8cec20371a,0xbfe6658c7e6c8e50,2
+np.float64,0xbfeda81a147b5034,0xc004e9c94f2b91c1,2
+np.float64,0xbfe1c36a97e386d5,0xbfe9ead4d6beaa92,2
+np.float64,0x3fe50be51f2a17ca,0x3fe02c8067d9e5c5,2
+np.float64,0x3febed4d3337da9a,0x3fe413956466134f,2
+np.float64,0x80068ea59ced1d4c,0x80068ea59ced1d4c,2
+np.float64,0x3febe77d5877cefb,0x3fe4107ac088bc71,2
+np.float64,0x800ae77617d5ceed,0x800ae77617d5ceed,2
+np.float64,0x3fd0546b60a0a8d7,0x3fcd16c2e995ab23,2
+np.float64,0xbfe33e1476667c29,0xbfed6d7faec4db2f,2
+np.float64,0x3fe9d2fd51b3a5fb,0x3fe2eef834310219,2
+np.float64,0x8004249878284932,0x8004249878284932,2
+np.float64,0xbfd5b485c72b690c,0xbfda828ccc6a7a5c,2
+np.float64,0x7fcd6e6b6b3adcd6,0x408622807f04768e,2
+np.float64,0x3fd7f9c32caff386,0x3fd45d024514b8da,2
+np.float64,0x7f87eb9d702fd73a,0x40860aa99fcff27f,2
+np.float64,0xbfc5d1f6fb2ba3ec,0xbfc7ec367cb3fecc,2
+np.float64,0x8008316a44d062d5,0x8008316a44d062d5,2
+np.float64,0xbfd54e4358aa9c86,0xbfd9e889d2998a4a,2
+np.float64,0xda65facdb4cc0,0xda65facdb4cc0,2
+np.float64,0x3fc5b4f6f32b69f0,0x3fc40d13aa8e248b,2
+np.float64,0x3fd825a5d5b04b4c,0x3fd47ce73e04d3ff,2
+np.float64,0x7ac9d56ef593b,0x7ac9d56ef593b,2
+np.float64,0xbfd0a51977214a32,0xbfd34702071428be,2
+np.float64,0x3fd21f620b243ec4,0x3fcfea0c02193640,2
+np.float64,0x3fe6fb3f1b2df67e,0x3fe151ffb18c983b,2
+np.float64,0x700de022e01bd,0x700de022e01bd,2
+np.float64,0xbfbb76b81236ed70,0xbfbd0d31deea1ec7,2
+np.float64,0x3fecfc3856f9f870,0x3fe4a2fcadf221e0,2
+np.float64,0x3fede286517bc50c,0x3fe51af2fbd6ef63,2
+np.float64,0x7fdc8da96c391b52,0x408627ce09cfef2b,2
+np.float64,0x8000edfcfb81dbfb,0x8000edfcfb81dbfb,2
+np.float64,0x8009ebc42af3d789,0x8009ebc42af3d789,2
+np.float64,0x7fd658aaf8acb155,0x408625d80cd1ccc9,2
+np.float64,0x3feea584a37d4b09,0x3fe57f29a73729cd,2
+np.float64,0x4cfe494699fca,0x4cfe494699fca,2
+np.float64,0xbfe9d96460b3b2c9,0xbffa62ecfa026c77,2
+np.float64,0x7fdb3852c3b670a5,0x4086276c191dc9b1,2
+np.float64,0xbfe4d1fc9ee9a3f9,0xbff0d37ce37cf479,2
+np.float64,0xffefffffffffffff,0xfff8000000000000,2
+np.float64,0xbfd1c43d7fa3887a,0xbfd4cfbefb5f2c43,2
+np.float64,0x3fec4a8e0d78951c,0x3fe4453a82ca2570,2
+np.float64,0x7fafed74583fdae8,0x4086181017b8dac9,2
+np.float64,0x80076c4ebcced89e,0x80076c4ebcced89e,2
+np.float64,0x8001a9aa7b235356,0x8001a9aa7b235356,2
+np.float64,0x121260fe2424d,0x121260fe2424d,2
+np.float64,0x3fddd028e3bba052,0x3fd87998c4c43c5b,2
+np.float64,0x800ed1cf4a9da39f,0x800ed1cf4a9da39f,2
+np.float64,0xbfef2e63d7fe5cc8,0xc00d53480b16971b,2
+np.float64,0xbfedde3309fbbc66,0xc005ab55b7a7c127,2
+np.float64,0x3fda3e1e85b47c3d,0x3fd5fddafd8d6729,2
+np.float64,0x8007c6443c6f8c89,0x8007c6443c6f8c89,2
+np.float64,0xbfe101705f2202e0,0xbfe8420817665121,2
+np.float64,0x7fe0bff3c1e17fe7,0x4086291539c56d80,2
+np.float64,0x7fe6001dab6c003a,0x40862b43aa7cb060,2
+np.float64,0x7fbdecf7de3bd9ef,0x40861d170b1c51a5,2
+np.float64,0xbfc0fd508c21faa0,0xbfc23a5876e99fa3,2
+np.float64,0xbfcf6eb14f3edd64,0xbfd208cbf742c8ea,2
+np.float64,0x3f6d40ea403a81d5,0x3f6d33934ab8e799,2
+np.float64,0x7fc32600b6264c00,0x40861f10302357e0,2
+np.float64,0x3fd05870baa0b0e0,0x3fcd1d2af420fac7,2
+np.float64,0x80051d5120aa3aa3,0x80051d5120aa3aa3,2
+np.float64,0x3fdb783fcfb6f080,0x3fd6db229658c083,2
+np.float64,0x3fe0b61199e16c24,0x3fdae41e277be2eb,2
+np.float64,0x3daf62167b5ed,0x3daf62167b5ed,2
+np.float64,0xbfec3c53b6f878a7,0xc0011f0ce7a78a2a,2
+np.float64,0x800fc905161f920a,0x800fc905161f920a,2
+np.float64,0x3fdc7b9cc138f73a,0x3fd78f9c2360e661,2
+np.float64,0x7fe4079e97a80f3c,0x40862a83795f2443,2
+np.float64,0x8010000000000000,0x8010000000000000,2
+np.float64,0x7fe6da5345adb4a6,0x40862b9183c1e4b0,2
+np.float64,0xbfd0a76667214ecc,0xbfd34a1e0c1f6186,2
+np.float64,0x37fb0b906ff62,0x37fb0b906ff62,2
+np.float64,0x7fe170e59fa2e1ca,0x408629680a55e5c5,2
+np.float64,0x3fea900c77752019,0x3fe356eec75aa345,2
+np.float64,0x3fc575c63a2aeb8c,0x3fc3d701167d76b5,2
+np.float64,0x3fe8b45da87168bc,0x3fe24ecbb778fd44,2
+np.float64,0xbfcb990ab5373214,0xbfcf1596c076813c,2
+np.float64,0xf146fdfbe28e0,0xf146fdfbe28e0,2
+np.float64,0x8001fcd474c3f9aa,0x8001fcd474c3f9aa,2
+np.float64,0xbfe9b555eeb36aac,0xbffa0630c3bb485b,2
+np.float64,0x800f950be83f2a18,0x800f950be83f2a18,2
+np.float64,0x7feb0e03ab761c06,0x40862ceb30e36887,2
+np.float64,0x7fca51bd4a34a37a,0x4086219b9dfd35c9,2
+np.float64,0xbfdc27c34cb84f86,0xbfe28ccde8d6bc08,2
+np.float64,0x80009ce1714139c4,0x80009ce1714139c4,2
+np.float64,0x8005290fb1ea5220,0x8005290fb1ea5220,2
+np.float64,0xbfee81e6473d03cd,0xc00885972ca1699b,2
+np.float64,0x7fcfb11a373f6233,0x408623180b8f75d9,2
+np.float64,0xbfcb9c4bfd373898,0xbfcf19bd25881928,2
+np.float64,0x7feaec5885f5d8b0,0x40862ce136050e6c,2
+np.float64,0x8009e17a4a53c2f5,0x8009e17a4a53c2f5,2
+np.float64,0xbfe1cceb9e6399d7,0xbfea0038bd3def20,2
+np.float64,0x8009170bd7122e18,0x8009170bd7122e18,2
+np.float64,0xb2b6f7f1656df,0xb2b6f7f1656df,2
+np.float64,0x3fc75bfd1f2eb7f8,0x3fc574c858332265,2
+np.float64,0x3fa24c06ec249800,0x3fa1fa462ffcb8ec,2
+np.float64,0xaa9a4d2d5534a,0xaa9a4d2d5534a,2
+np.float64,0xbfd7b76208af6ec4,0xbfdda0c3200dcc9f,2
+np.float64,0x7f8cbab73039756d,0x40860c20cba57a94,2
+np.float64,0x3fdbcf9f48b79f3f,0x3fd71827a60e8b6d,2
+np.float64,0xbfdd60f71a3ac1ee,0xbfe3a94bc8cf134d,2
+np.float64,0xb9253589724a7,0xb9253589724a7,2
+np.float64,0xbfcf28e37e3e51c8,0xbfd1da9977b741e3,2
+np.float64,0x80011457f7e228b1,0x80011457f7e228b1,2
+np.float64,0x7fec33df737867be,0x40862d404a897122,2
+np.float64,0xae55f8f95cabf,0xae55f8f95cabf,2
+np.float64,0xbfc1ab9397235728,0xbfc303e5533d4a5f,2
+np.float64,0x7fef0f84b3be1f08,0x40862e05f9ba7118,2
+np.float64,0x7fdc94f328b929e5,0x408627d01449d825,2
+np.float64,0x3fee1b598c7c36b3,0x3fe53847be166834,2
+np.float64,0x3fee8326f37d064e,0x3fe56d96f3fbcf43,2
+np.float64,0x3fe7b18a83ef6316,0x3fe1bb6a6d48c675,2
+np.float64,0x3fe5db969c6bb72e,0x3fe0a8d7d151996c,2
+np.float64,0x3e3391d27c673,0x3e3391d27c673,2
+np.float64,0x3fe79a46d76f348e,0x3fe1ae09a96ea628,2
+np.float64,0x7ff4000000000000,0x7ffc000000000000,2
+np.float64,0x7fe57d6505aafac9,0x40862b13925547f1,2
+np.float64,0x3fc433371d28666e,0x3fc2c196a764c47b,2
+np.float64,0x8008dbf69cd1b7ee,0x8008dbf69cd1b7ee,2
+np.float64,0xbfe744f459ee89e8,0xbff4c847ad3ee152,2
+np.float64,0x80098aa245331545,0x80098aa245331545,2
+np.float64,0x6747112ece8e3,0x6747112ece8e3,2
+np.float64,0x5d342a40ba69,0x5d342a40ba69,2
+np.float64,0xf7a17739ef42f,0xf7a17739ef42f,2
+np.float64,0x3fe1b34a9d236695,0x3fdc2d7c4e2c347a,2
+np.float64,0x7fb53bf5ec2a77eb,0x40861a585ec8f7ff,2
+np.float64,0xbfe6256f1cec4ade,0xbff2d89a36be65ae,2
+np.float64,0xb783bc9b6f078,0xb783bc9b6f078,2
+np.float64,0xbfedf74a3bfbee94,0xc0060bb6f2bc11ef,2
+np.float64,0x3fda2a5eccb454be,0x3fd5efd7f18b8e81,2
+np.float64,0xbfb3838ab2270718,0xbfb44c337fbca3c3,2
+np.float64,0x3fb4ac6dc22958e0,0x3fb3e194ca01a502,2
+np.float64,0x76c11aaaed824,0x76c11aaaed824,2
+np.float64,0x80025bb1af04b764,0x80025bb1af04b764,2
+np.float64,0x3fdc02740ab804e8,0x3fd73b8cd6f95f19,2
+np.float64,0x3fe71856f5ee30ae,0x3fe162e9fafb4428,2
+np.float64,0x800236f332646de7,0x800236f332646de7,2
+np.float64,0x7fe13fd9d2e27fb3,0x408629516b42a317,2
+np.float64,0x7fdf6bbd34bed779,0x40862892069d805c,2
+np.float64,0x3fd4727beba8e4f8,0x3fd1be5b48d9e282,2
+np.float64,0x800e0fac9e5c1f59,0x800e0fac9e5c1f59,2
+np.float64,0xfb54423ff6a89,0xfb54423ff6a89,2
+np.float64,0x800fbf7ed47f7efe,0x800fbf7ed47f7efe,2
+np.float64,0x3fe9d41fa2f3a840,0x3fe2ef98dc1fd463,2
+np.float64,0x800d733e805ae67d,0x800d733e805ae67d,2
+np.float64,0x3feebe4c46fd7c98,0x3fe58bcf7f47264e,2
+np.float64,0x7fe1ab77b5e356ee,0x40862982bb3dce34,2
+np.float64,0xbfdddac05abbb580,0xbfe41aa45f72d5a2,2
+np.float64,0x3fe14219dee28434,0x3fdb9b137d1f1220,2
+np.float64,0x3fe25d3d5a24ba7b,0x3fdd06e1cf32d35a,2
+np.float64,0x8000fa4fbe81f4a0,0x8000fa4fbe81f4a0,2
+np.float64,0x3fe303e23e6607c4,0x3fddd94982efa9f1,2
+np.float64,0x3fe89cf5d83139ec,0x3fe24193a2e12f75,2
+np.float64,0x3fe9b36ef87366de,0x3fe2dd7cdc25a4a5,2
+np.float64,0xbfdb8b38f8371672,0xbfe2023ba7e002bb,2
+np.float64,0xafc354955f86b,0xafc354955f86b,2
+np.float64,0xbfe2f3d49e65e7a9,0xbfecb557a94123d3,2
+np.float64,0x800496617c092cc4,0x800496617c092cc4,2
+np.float64,0x32db0cfa65b62,0x32db0cfa65b62,2
+np.float64,0xbfd893bfa2b12780,0xbfdf02a8c1e545aa,2
+np.float64,0x7fd5ac927d2b5924,0x408625997e7c1f9b,2
+np.float64,0x3fde9defb8bd3be0,0x3fd9056190986349,2
+np.float64,0x80030cfeb54619fe,0x80030cfeb54619fe,2
+np.float64,0x3fcba85b273750b8,0x3fc90a5ca976594f,2
+np.float64,0x3fe98f6f5cf31edf,0x3fe2c97fcb4eca25,2
+np.float64,0x3fe33dbf90667b80,0x3fde21b83321b993,2
+np.float64,0x3fe4686636e8d0cc,0x3fdf928cdca751b3,2
+np.float64,0x80018ade6ce315be,0x80018ade6ce315be,2
+np.float64,0x7fa9af70c8335ee1,0x408616528cd5a906,2
+np.float64,0x3fbeb460aa3d68c0,0x3fbcff96b00a2193,2
+np.float64,0x7fa82c869830590c,0x408615d6598d9368,2
+np.float64,0xd08c0e6fa1182,0xd08c0e6fa1182,2
+np.float64,0x3fef4eb750fe9d6f,0x3fe5d522fd4e7f64,2
+np.float64,0xbfc586f5492b0dec,0xbfc791eaae92aad1,2
+np.float64,0x7fede64ac7bbcc95,0x40862db7f444fa7b,2
+np.float64,0x3fe540003d6a8000,0x3fe04bdfc2916a0b,2
+np.float64,0x8009417fe6f28300,0x8009417fe6f28300,2
+np.float64,0x3fe6959cf16d2b3a,0x3fe116a1ce01887b,2
+np.float64,0x3fb0a40036214800,0x3fb01f447778219a,2
+np.float64,0x3feff26e91ffe4dd,0x3fe627798fc859a7,2
+np.float64,0x7fed8e46cd7b1c8d,0x40862da044a1d102,2
+np.float64,0x7fec4eb774f89d6e,0x40862d47e43edb53,2
+np.float64,0x3fe800e5e07001cc,0x3fe1e8e2b9105fc2,2
+np.float64,0x800f4eb2f9be9d66,0x800f4eb2f9be9d66,2
+np.float64,0x800611659bcc22cc,0x800611659bcc22cc,2
+np.float64,0x3fd66e65d2acdccc,0x3fd33ad63a5e1000,2
+np.float64,0x800a9085b7f5210c,0x800a9085b7f5210c,2
+np.float64,0x7fdf933a3fbf2673,0x4086289c0e292f2b,2
+np.float64,0x1cd1ba7a39a38,0x1cd1ba7a39a38,2
+np.float64,0xbfefd0b10fffa162,0xc0149ded900ed851,2
+np.float64,0xbfe8c63485b18c69,0xbff7cf3078b1574f,2
+np.float64,0x3fecde56ca79bcae,0x3fe4934afbd7dda9,2
+np.float64,0x8006cd6888cd9ad2,0x8006cd6888cd9ad2,2
+np.float64,0x3fd7a391c2af4724,0x3fd41e2f74df2329,2
+np.float64,0x3fe6a8ad58ed515a,0x3fe121ccfb28e6f5,2
+np.float64,0x7fe18a80dd631501,0x40862973c09086b9,2
+np.float64,0xbf74fd6d8029fb00,0xbf750b3e368ebe6b,2
+np.float64,0x3fdd35e93dba6bd4,0x3fd810071faaffad,2
+np.float64,0x3feb0d8f57361b1f,0x3fe39b3abdef8b7a,2
+np.float64,0xbfd5ec7288abd8e6,0xbfdad764df0d2ca1,2
+np.float64,0x7fdc848272b90904,0x408627cb78f3fb9e,2
+np.float64,0x800ed3eda91da7db,0x800ed3eda91da7db,2
+np.float64,0x3fefac64857f58c9,0x3fe60459dbaad1ba,2
+np.float64,0x3fd1df7a5ba3bef4,0x3fcf864a39b926ff,2
+np.float64,0xfe26ca4bfc4da,0xfe26ca4bfc4da,2
+np.float64,0xbfd1099f8da21340,0xbfd3cf6e6efe934b,2
+np.float64,0xbfe15de9a7a2bbd4,0xbfe909cc895f8795,2
+np.float64,0x3fe89714ed712e2a,0x3fe23e40d31242a4,2
+np.float64,0x800387113e470e23,0x800387113e470e23,2
+np.float64,0x3fe4f80730e9f00e,0x3fe0208219314cf1,2
+np.float64,0x2f95a97c5f2b6,0x2f95a97c5f2b6,2
+np.float64,0x800ea7cdd87d4f9c,0x800ea7cdd87d4f9c,2
+np.float64,0xbf64b967c0297300,0xbf64c020a145b7a5,2
+np.float64,0xbfc5a91a342b5234,0xbfc7bafd77a61d81,2
+np.float64,0xbfe2226fe76444e0,0xbfeac33eb1d1b398,2
+np.float64,0x3fc6aaa8d42d5552,0x3fc4de79f5c68cd4,2
+np.float64,0x3fe54fd4c1ea9faa,0x3fe05561a9a5922b,2
+np.float64,0x80029c1f75653840,0x80029c1f75653840,2
+np.float64,0xbfcb4a84a2369508,0xbfceb1a23bac3995,2
+np.float64,0x80010abeff02157f,0x80010abeff02157f,2
+np.float64,0x7f92d12cf825a259,0x40860e49bde3a5b6,2
+np.float64,0x800933e7027267ce,0x800933e7027267ce,2
+np.float64,0x3fc022b12e204562,0x3fbe64acc53ed887,2
+np.float64,0xbfe35f938de6bf27,0xbfedc1f3e443c016,2
+np.float64,0x1f8d9bae3f1b4,0x1f8d9bae3f1b4,2
+np.float64,0x3fe552f22ceaa5e4,0x3fe057404072350f,2
+np.float64,0xbfa73753442e6ea0,0xbfa7c24a100190f1,2
+np.float64,0x7fb3e2982827c52f,0x408619d1efa676b6,2
+np.float64,0xbfd80cb7a5301970,0xbfde28e65f344f33,2
+np.float64,0xbfcde835973bd06c,0xbfd10806fba46c8f,2
+np.float64,0xbfd4e3c749a9c78e,0xbfd949aff65de39c,2
+np.float64,0x3fcb4b9d6f36973b,0x3fc8be02ad6dc0d3,2
+np.float64,0x1a63000034c7,0x1a63000034c7,2
+np.float64,0x7fdc9c751e3938e9,0x408627d22df71959,2
+np.float64,0x3fd74f3f712e9e7f,0x3fd3e07df0c37ec1,2
+np.float64,0xbfceab74d33d56e8,0xbfd187e99bf82903,2
+np.float64,0x7ff0000000000000,0x7ff0000000000000,2
+np.float64,0xbfb2cca466259948,0xbfb3868208e8de30,2
+np.float64,0x800204688b8408d2,0x800204688b8408d2,2
+np.float64,0x3e4547407c8aa,0x3e4547407c8aa,2
+np.float64,0xbfe4668846e8cd10,0xbff03c85189f3818,2
+np.float64,0x800dd350245ba6a0,0x800dd350245ba6a0,2
+np.float64,0xbfbc13c160382780,0xbfbdbd56ce996d16,2
+np.float64,0x7fe25a628a24b4c4,0x408629d06eb2d64d,2
+np.float64,0x3fd19dabbc233b57,0x3fcf1f3ed1d34c8c,2
+np.float64,0x547e20faa8fc5,0x547e20faa8fc5,2
+np.float64,0xbfe19392c6232726,0xbfe97ffe4f303335,2
+np.float64,0x3f87f9f6702ff400,0x3f87d64fb471bb04,2
+np.float64,0x9dfc52db3bf8b,0x9dfc52db3bf8b,2
+np.float64,0x800e1f5a9adc3eb5,0x800e1f5a9adc3eb5,2
+np.float64,0xbfddbd09c8bb7a14,0xbfe3fed7d7cffc70,2
+np.float64,0xbfeda71af87b4e36,0xc004e6631c514544,2
+np.float64,0xbfdbfcfe1bb7f9fc,0xbfe266b5d4a56265,2
+np.float64,0x3fe4ee78cd69dcf2,0x3fe01abba4e81fc9,2
+np.float64,0x800f13b820de2770,0x800f13b820de2770,2
+np.float64,0x3f861e09702c3c00,0x3f85ffae83b02c4f,2
+np.float64,0xbfc0972479212e48,0xbfc1c4bf70b30cbc,2
+np.float64,0x7fef057ef57e0afd,0x40862e036479f6a9,2
+np.float64,0x8bdbabe517b76,0x8bdbabe517b76,2
+np.float64,0xbfec495417f892a8,0xc0013ade88746d18,2
+np.float64,0x3fec680ab3f8d015,0x3fe454dd304b560d,2
+np.float64,0xbfae7ce60c3cf9d0,0xbfaf6eef15bbe56b,2
+np.float64,0x3fec314124786282,0x3fe437ca06294f5a,2
+np.float64,0x7fd5ed05b82bda0a,0x408625b125518e58,2
+np.float64,0x3feac9f02f3593e0,0x3fe3768104dd5cb7,2
+np.float64,0x0,0x0,2
+np.float64,0xbfddd2abd5bba558,0xbfe41312b8ea20de,2
+np.float64,0xbfedf9558c7bf2ab,0xc00613c53e0bb33a,2
+np.float64,0x3fef245ffefe48c0,0x3fe5bfb4dfe3b7a5,2
+np.float64,0x7fe178604922f0c0,0x4086296b77d5eaef,2
+np.float64,0x10000000000000,0x10000000000000,2
+np.float64,0x7fed026766ba04ce,0x40862d7a0dc45643,2
+np.float64,0xbfde27d8c3bc4fb2,0xbfe46336b6447697,2
+np.float64,0x3fe9485d9cb290bb,0x3fe2a1e4b6419423,2
+np.float64,0xbfe27b8a7464f715,0xbfeb9382f5b16f65,2
+np.float64,0x5c34d274b869b,0x5c34d274b869b,2
+np.float64,0xbfeee0b7453dc16f,0xc00acdb46459b6e6,2
+np.float64,0x7fe3dfb4d4e7bf69,0x40862a73785fdf12,2
+np.float64,0xb4635eef68c6c,0xb4635eef68c6c,2
+np.float64,0xbfe522a2c82a4546,0xbff148912a59a1d6,2
+np.float64,0x8009ba38a9737472,0x8009ba38a9737472,2
+np.float64,0xbfc056ff3820ae00,0xbfc17b2205fa180d,2
+np.float64,0x7fe1c8b8a0239170,0x4086298feeee6133,2
+np.float64,0x3fe2d2c6b9e5a58e,0x3fdd9b907471031b,2
+np.float64,0x3fa0a161bc2142c0,0x3fa05db36f6a073b,2
+np.float64,0x3fdef4268ebde84c,0x3fd93f980794d1e7,2
+np.float64,0x800ecd9fe2fd9b40,0x800ecd9fe2fd9b40,2
+np.float64,0xbfc9fbd45e33f7a8,0xbfcd0afc47c340f6,2
+np.float64,0x3fe8c3035b718606,0x3fe2570eb65551a1,2
+np.float64,0xbfe78c4ad2ef1896,0xbff54d25b3328742,2
+np.float64,0x8006f5dcf8adebbb,0x8006f5dcf8adebbb,2
+np.float64,0x800301dca2a603ba,0x800301dca2a603ba,2
+np.float64,0xad4289e55a851,0xad4289e55a851,2
+np.float64,0x80037764f9e6eecb,0x80037764f9e6eecb,2
+np.float64,0xbfe73575b26e6aec,0xbff4abfb5e985c62,2
+np.float64,0xbfc6cb91652d9724,0xbfc91a8001b33ec2,2
+np.float64,0xbfe3a918ffe75232,0xbfee7e6e4fd34c53,2
+np.float64,0x9bc84e2b3790a,0x9bc84e2b3790a,2
+np.float64,0x7fdeec303cbdd85f,0x408628714a49d996,2
+np.float64,0x3fe1d1dcb763a3ba,0x3fdc54ce060dc7f4,2
+np.float64,0x8008ae6432b15cc9,0x8008ae6432b15cc9,2
+np.float64,0x3fd8022fa2b00460,0x3fd46322bf02a609,2
+np.float64,0xbfc55b64472ab6c8,0xbfc75d9568f462e0,2
+np.float64,0xbfe8b165437162ca,0xbff7a15e2ead645f,2
+np.float64,0x7f759330feeb3,0x7f759330feeb3,2
+np.float64,0xbfd504f68eaa09ee,0xbfd97b06c01d7473,2
+np.float64,0x54702d5aa8e06,0x54702d5aa8e06,2
+np.float64,0xbfed1779337a2ef2,0xc0032f7109ef5a51,2
+np.float64,0xe248bd4dc4918,0xe248bd4dc4918,2
+np.float64,0xbfd8c59150318b22,0xbfdf53bca6ca8b1e,2
+np.float64,0xbfe3b9d942e773b2,0xbfeea9fcad277ba7,2
+np.float64,0x800934ec127269d9,0x800934ec127269d9,2
+np.float64,0xbfbb7f535a36fea8,0xbfbd16d61b6c52b8,2
+np.float64,0xccb185a199631,0xccb185a199631,2
+np.float64,0x3fe3dda76fe7bb4e,0x3fdee83bc6094301,2
+np.float64,0xbfe0c902f5e19206,0xbfe7ca7c0e888006,2
+np.float64,0xbfefeed08cbfdda1,0xc018aadc483c8724,2
+np.float64,0x7fd0c05c52a180b8,0x40862389daf64aac,2
+np.float64,0xbfd28e3323a51c66,0xbfd5e9ba278fb685,2
+np.float64,0xbef4103b7de82,0xbef4103b7de82,2
+np.float64,0x3fe7661fd12ecc40,0x3fe18ff7dfb696e2,2
+np.float64,0x3fddd5f2f0bbabe4,0x3fd87d8bb6719c3b,2
+np.float64,0x800b3914cfd6722a,0x800b3914cfd6722a,2
+np.float64,0xf3f09a97e7e14,0xf3f09a97e7e14,2
+np.float64,0x7f97092b502e1256,0x40860fe8054cf54e,2
+np.float64,0xbfdbec7917b7d8f2,0xbfe2580b4b792c79,2
+np.float64,0x7fe7ff215aaffe42,0x40862bf5887fa062,2
+np.float64,0x80080186e570030e,0x80080186e570030e,2
+np.float64,0xbfc27f05e624fe0c,0xbfc3fa214be4adc4,2
+np.float64,0x3fe4481be1689038,0x3fdf6b11e9c4ca72,2
+np.float64,0x3fd642cc9cac8598,0x3fd31a857fe70227,2
+np.float64,0xbef8782d7df0f,0xbef8782d7df0f,2
+np.float64,0x8003077dc2e60efc,0x8003077dc2e60efc,2
+np.float64,0x80083eb5a2507d6c,0x80083eb5a2507d6c,2
+np.float64,0x800e8d1eb77d1a3e,0x800e8d1eb77d1a3e,2
+np.float64,0xbfc7737cd22ee6f8,0xbfc9e7716f03f1fc,2
+np.float64,0xbfe9a2b4ddf3456a,0xbff9d71664a8fc78,2
+np.float64,0x7fe67c7d322cf8f9,0x40862b7066465194,2
+np.float64,0x3fec080ce2b8101a,0x3fe421dac225be46,2
+np.float64,0xbfe6d27beb6da4f8,0xbff3fbb1add521f7,2
+np.float64,0x3fdd4f96ceba9f2e,0x3fd821a638986dbe,2
+np.float64,0x3fbd89f1303b13e2,0x3fbbf49223a9d002,2
+np.float64,0xbfe94e2b9d329c57,0xbff907e549c534f5,2
+np.float64,0x3fe2f2cc51e5e599,0x3fddc3d6b4a834a1,2
+np.float64,0xfdcb5b49fb96c,0xfdcb5b49fb96c,2
+np.float64,0xbfea7108fa74e212,0xbffc01b392f4897b,2
+np.float64,0x3fd38baef7a7175c,0x3fd10e7fd3b958dd,2
+np.float64,0x3fa75bf9cc2eb800,0x3fa6d792ecdedb8e,2
+np.float64,0x7fd19fd20aa33fa3,0x408623f1e2cd04c3,2
+np.float64,0x3fd62c708dac58e0,0x3fd309ec7818d16e,2
+np.float64,0x3fdf489047be9120,0x3fd978640617c758,2
+np.float64,0x1,0x1,2
+np.float64,0xbfe21e7c3ea43cf8,0xbfeaba21320697d3,2
+np.float64,0xbfd3649047a6c920,0xbfd71a6f14223744,2
+np.float64,0xbfd68ca68c2d194e,0xbfdbcce6784e5d44,2
+np.float64,0x3fdb26b0ea364d62,0x3fd6a1f86f64ff74,2
+np.float64,0xbfd843821cb08704,0xbfde80e90805ab3f,2
+np.float64,0x3fd508a27aaa1144,0x3fd22fc203a7b9d8,2
+np.float64,0xbfdb951c7eb72a38,0xbfe20aeaec13699b,2
+np.float64,0x3fef556ba57eaad7,0x3fe5d8865cce0a6d,2
+np.float64,0x3fd0d224b3a1a448,0x3fcdde7be5d7e21e,2
+np.float64,0x8007ff272baffe4f,0x8007ff272baffe4f,2
+np.float64,0x3fe1c7bddf638f7c,0x3fdc47cc6cf2f5cd,2
+np.float64,0x7ff8000000000000,0x7ff8000000000000,2
+np.float64,0x2016d560402f,0x2016d560402f,2
+np.float64,0xbfcca10be9394218,0xbfd033f36b94fc54,2
+np.float64,0xbfdb833628b7066c,0xbfe1fb344b840c70,2
+np.float64,0x3fd8529cb3b0a539,0x3fd49d847fe77218,2
+np.float64,0xbfc0b0ebab2161d8,0xbfc1e260c60ffd1b,2
+np.float64,0xbfea8b9a79f51735,0xbffc4ee6be8a0fa2,2
+np.float64,0x7feca8fab7f951f4,0x40862d613e454646,2
+np.float64,0x7fd8c52d82318a5a,0x408626aaf37423a3,2
+np.float64,0xbfe364ad4526c95a,0xbfedcee39bc93ff5,2
+np.float64,0x800b78161256f02d,0x800b78161256f02d,2
+np.float64,0xbfd55f0153aabe02,0xbfda01a78f72d494,2
+np.float64,0x800315a5f0662b4d,0x800315a5f0662b4d,2
+np.float64,0x7fe4c0dca02981b8,0x40862acc27e4819f,2
+np.float64,0x8009825c703304b9,0x8009825c703304b9,2
+np.float64,0x3fe6e94e1cadd29c,0x3fe1478ccc634f49,2
+np.float64,0x7fe622d8586c45b0,0x40862b504177827e,2
+np.float64,0x3fe4458600688b0c,0x3fdf67e79a84b953,2
+np.float64,0xbfdd75d8a1baebb2,0xbfe3bc9e6ca1bbb5,2
+np.float64,0x3fde789c6bbcf138,0x3fd8ec1d435531b3,2
+np.float64,0x3fe7052b94ee0a58,0x3fe157c5c4418dc1,2
+np.float64,0x7fef31652abe62c9,0x40862e0eaeabcfc0,2
+np.float64,0x3fe279691ee4f2d2,0x3fdd2aa41eb43cd4,2
+np.float64,0xbfd533fa95aa67f6,0xbfd9c12f516d29d7,2
+np.float64,0x3fe6d057f96da0b0,0x3fe138fd96693a6a,2
+np.float64,0x800bad984f775b31,0x800bad984f775b31,2
+np.float64,0x7fdd6fdba4badfb6,0x4086280c73d8ef97,2
+np.float64,0x7fe9b5c0eef36b81,0x40862c82c6f57a53,2
+np.float64,0x8000bc02ece17807,0x8000bc02ece17807,2
+np.float64,0xbff0000000000000,0xfff0000000000000,2
+np.float64,0xbfed430be3fa8618,0xc003aaf338c75b3c,2
+np.float64,0x3fee17b759fc2f6f,0x3fe53668696bf48b,2
+np.float64,0x3f8d4cf9d03a9a00,0x3f8d17d2f532afdc,2
+np.float64,0x8005d6257b8bac4c,0x8005d6257b8bac4c,2
+np.float64,0xbfd17a6df9a2f4dc,0xbfd469e3848adc6e,2
+np.float64,0xb28a293965145,0xb28a293965145,2
+np.float64,0xbfe7d011e42fa024,0xbff5cf818998c8ec,2
+np.float64,0xbfe74f0f136e9e1e,0xbff4dad6ebb0443c,2
+np.float64,0x800f249fc9be4940,0x800f249fc9be4940,2
+np.float64,0x2542f8fe4a860,0x2542f8fe4a860,2
+np.float64,0xc48d40cd891a8,0xc48d40cd891a8,2
+np.float64,0x3fe4e64bc8e9cc98,0x3fe015c9eb3caa53,2
+np.float64,0x3fd33881eca67104,0x3fd0cea886be2457,2
+np.float64,0xbfd01748fba02e92,0xbfd28875959e6901,2
+np.float64,0x7fb7ab01f22f5603,0x40861b369927bf53,2
+np.float64,0xbfe340274ce6804e,0xbfed72b39f0ebb24,2
+np.float64,0x7fc16c0c3422d817,0x40861e4eaf1a286c,2
+np.float64,0x3fc26944a324d288,0x3fc133a77b356ac4,2
+np.float64,0xa149d7134293b,0xa149d7134293b,2
+np.float64,0x800837382d106e71,0x800837382d106e71,2
+np.float64,0x797d1740f2fa4,0x797d1740f2fa4,2
+np.float64,0xc3f15b7787e2c,0xc3f15b7787e2c,2
+np.float64,0x80cad1b90195a,0x80cad1b90195a,2
+np.float64,0x3fdd8f1142bb1e23,0x3fd84d21490d1ce6,2
+np.float64,0xbfbde6c9123bcd90,0xbfbfcc030a86836a,2
+np.float64,0x8007f77e032feefd,0x8007f77e032feefd,2
+np.float64,0x3fe74fed1c6e9fda,0x3fe18322cf19cb61,2
+np.float64,0xbfd8a40bbcb14818,0xbfdf1d23520ba74b,2
+np.float64,0xbfeb7a0e6076f41d,0xbfff4ddfb926efa5,2
+np.float64,0xbfcb8c5f663718c0,0xbfcf0570f702bda9,2
+np.float64,0xf668cd97ecd1a,0xf668cd97ecd1a,2
+np.float64,0xbfe92accf572559a,0xbff8b4393878ffdb,2
+np.float64,0xbfeaa955567552ab,0xbffca70c7d73eee5,2
+np.float64,0xbfe083a14f610742,0xbfe739d84bc35077,2
+np.float64,0x78290568f0521,0x78290568f0521,2
+np.float64,0x3fe94bae2372975c,0x3fe2a3beac5c9858,2
+np.float64,0x3fca4fbab9349f78,0x3fc7edbca2492acb,2
+np.float64,0x8000000000000000,0x8000000000000000,2
+np.float64,0x7fb9eb505433d6a0,0x40861bf0adedb74d,2
+np.float64,0x7fdc66f72a38cded,0x408627c32aeecf0f,2
+np.float64,0x2e8e6f445d1cf,0x2e8e6f445d1cf,2
+np.float64,0xbfec43195af88633,0xc0012d7e3f91b7e8,2
+np.float64,0x7fcdb971e93b72e3,0x40862294c9e3a7bc,2
+np.float64,0x800cabc461195789,0x800cabc461195789,2
+np.float64,0x2c79709c58f2f,0x2c79709c58f2f,2
+np.float64,0x8005d772d3cbaee6,0x8005d772d3cbaee6,2
+np.float64,0x3fe84d8c03709b18,0x3fe21490ce3673dd,2
+np.float64,0x7fe5578adc2aaf15,0x40862b056e8437d4,2
+np.float64,0xbf91298c58225320,0xbf914ec86c32d11f,2
+np.float64,0xc7ed2b6d8fda6,0xc7ed2b6d8fda6,2
+np.float64,0x2761404c4ec29,0x2761404c4ec29,2
+np.float64,0x3fbad3c48835a789,0x3fb9833c02385305,2
+np.float64,0x3fa46fee5428dfe0,0x3fa40a357fb24c23,2
+np.float64,0xbfe3900c6fe72019,0xbfee3dba29dd9d43,2
+np.float64,0x3fe7a9e41a6f53c8,0x3fe1b704dfb9884b,2
+np.float64,0xbfe74a7a1eee94f4,0xbff4d269cacb1f29,2
+np.float64,0xbfee609c72fcc139,0xc007da8499d34123,2
+np.float64,0x3fef2d5fc23e5ac0,0x3fe5c44414e59cb4,2
+np.float64,0xbfd7bdc0402f7b80,0xbfddaae1e7bb78fb,2
+np.float64,0xd71ee01dae3dc,0xd71ee01dae3dc,2
+np.float64,0x3fe98cbcdef3197a,0x3fe2c7ffe33c4541,2
+np.float64,0x8000f8dbb3a1f1b8,0x8000f8dbb3a1f1b8,2
+np.float64,0x3fe3e98ad567d316,0x3fdef6e58058313f,2
+np.float64,0x41ad0bfc835a2,0x41ad0bfc835a2,2
+np.float64,0x7fdcc2dc0d3985b7,0x408627dce39f77af,2
+np.float64,0xbfe47b980de8f730,0xbff059acdccd6e2b,2
+np.float64,0xbfef49b6577e936d,0xc00e714f46b2ccc1,2
+np.float64,0x3fac31816c386300,0x3fab71cb92b0db8f,2
+np.float64,0x3fe59097e76b2130,0x3fe07c299fd1127c,2
+np.float64,0xbfecf0df5cf9e1bf,0xc002c7ebdd65039c,2
+np.float64,0x3fd2b7d0b6a56fa1,0x3fd06b638990ae02,2
+np.float64,0xbfeb68deecf6d1be,0xbfff1187e042d3e4,2
+np.float64,0x3fd44a9771a8952f,0x3fd1a01867c5e302,2
+np.float64,0xf79a9dedef354,0xf79a9dedef354,2
+np.float64,0x800c25a170d84b43,0x800c25a170d84b43,2
+np.float64,0x3ff0000000000000,0x3fe62e42fefa39ef,2
+np.float64,0x3fbff4f7623fe9f0,0x3fbe1d3878f4c417,2
+np.float64,0xd284c845a5099,0xd284c845a5099,2
+np.float64,0xbfe3c7815f678f02,0xbfeecdab5ca2e651,2
+np.float64,0x3fc19c934e233927,0x3fc08036104b1f23,2
+np.float64,0x800b6096de16c12e,0x800b6096de16c12e,2
+np.float64,0xbfe962a67e32c54d,0xbff9392313a112a1,2
+np.float64,0x2b9d0116573a1,0x2b9d0116573a1,2
+np.float64,0x3fcab269ed3564d4,0x3fc83f7e1c3095b7,2
+np.float64,0x3fc8c78d86318f1b,0x3fc6a6cde5696f99,2
+np.float64,0xd5b1e9b5ab63d,0xd5b1e9b5ab63d,2
+np.float64,0xbfed802a47fb0054,0xc00465cad3b5b0ef,2
+np.float64,0xbfd73aaf08ae755e,0xbfdcdbd62b8af271,2
+np.float64,0xbfd4f13c0229e278,0xbfd95dacff79e570,2
+np.float64,0xbfe9622808f2c450,0xbff937f13c397e8d,2
+np.float64,0xbfeddfa62efbbf4c,0xc005b0c835eed829,2
+np.float64,0x3fd65663d4acacc8,0x3fd3290cd0e675dc,2
+np.float64,0x8005e890f1abd123,0x8005e890f1abd123,2
+np.float64,0xbfe924919fb24923,0xbff8a5a827a28756,2
+np.float64,0x3fe8cdf490719be9,0x3fe25d39535e8366,2
+np.float64,0x7fc229e6ff2453cd,0x40861ea40ef87a5a,2
+np.float64,0x3fe5cf53ceeb9ea8,0x3fe0a18e0b65f27e,2
+np.float64,0xa79cf6fb4f39f,0xa79cf6fb4f39f,2
+np.float64,0x7fddbb3c0f3b7677,0x40862820d5edf310,2
+np.float64,0x3e1011de7c203,0x3e1011de7c203,2
+np.float64,0x3fc0b59a83216b38,0x3fbf6916510ff411,2
+np.float64,0x8647f98d0c8ff,0x8647f98d0c8ff,2
+np.float64,0x8005dad33ecbb5a7,0x8005dad33ecbb5a7,2
+np.float64,0x8a80d0631501a,0x8a80d0631501a,2
+np.float64,0xbfe18f7d6ee31efb,0xbfe976f06713afc1,2
+np.float64,0xbfe06eaed560dd5e,0xbfe70eac696933e6,2
+np.float64,0xbfed8ef93c7b1df2,0xc00495bfa3195b53,2
+np.float64,0x3febe9c24677d385,0x3fe411b10db16c42,2
+np.float64,0x7fd5d80c1fabb017,0x408625a97a7787ba,2
+np.float64,0x3fca79b59334f368,0x3fc8108a521341dc,2
+np.float64,0xbfccf8db4339f1b8,0xbfd06c9a5424aadb,2
+np.float64,0xbfea5ac5a574b58b,0xbffbc21d1405d840,2
+np.float64,0x800ce2bf4b19c57f,0x800ce2bf4b19c57f,2
+np.float64,0xbfe8df896d31bf13,0xbff807ab38ac41ab,2
+np.float64,0x3feab83da9f5707c,0x3fe36cdd827c0eff,2
+np.float64,0x3fee717683bce2ed,0x3fe564879171719b,2
+np.float64,0x80025e5577c4bcac,0x80025e5577c4bcac,2
+np.float64,0x3fe3e5378e67ca70,0x3fdef1902c5d1efd,2
+np.float64,0x3fa014bb7c202980,0x3f9faacf9238d499,2
+np.float64,0x3fddbf5e16bb7ebc,0x3fd86e2311cb0f6d,2
+np.float64,0x3fd24e50e6a49ca0,0x3fd0198f04f82186,2
+np.float64,0x656b5214cad6b,0x656b5214cad6b,2
+np.float64,0x8b0a4bfd1614a,0x8b0a4bfd1614a,2
+np.float64,0xbfeeb6bd9e7d6d7b,0xc009b669285e319e,2
+np.float64,0x8000000000000001,0x8000000000000001,2
+np.float64,0xbfe719feceee33fe,0xbff47a4c8cbf0cca,2
+np.float64,0xbfd14fa8c8a29f52,0xbfd42f27b1aced39,2
+np.float64,0x7fec9dcb80f93b96,0x40862d5e1e70bbb9,2
+np.float64,0x7fecacb826f9596f,0x40862d6249746915,2
+np.float64,0x973459f52e68b,0x973459f52e68b,2
+np.float64,0x7f40a59e00214b3b,0x4085f194f45f82b1,2
+np.float64,0x7fc5dbaec32bb75d,0x4086201f3e7065d9,2
+np.float64,0x82d0801305a10,0x82d0801305a10,2
+np.float64,0x7fec81c0f4790381,0x40862d5643c0fc85,2
+np.float64,0xbfe2d81e9ee5b03d,0xbfec71a8e864ea40,2
+np.float64,0x6c545c9ad8a8c,0x6c545c9ad8a8c,2
+np.float64,0x3f9be95a5037d2b5,0x3f9b89b48ac8f5d8,2
+np.float64,0x8000cae9702195d4,0x8000cae9702195d4,2
+np.float64,0xbfd375f45126ebe8,0xbfd733677e54a80d,2
+np.float64,0x3fd29a5b81a534b7,0x3fd05494bf200278,2
+np.float64,0xfff0000000000000,0xfff8000000000000,2
+np.float64,0x7fca8fc195351f82,0x408621ae61aa6c13,2
+np.float64,0x1b28e2ae3651d,0x1b28e2ae3651d,2
+np.float64,0x3fe7fdbd14effb7a,0x3fe1e714884b46a8,2
+np.float64,0x3fdf1ce068be39c0,0x3fd95b054e0fad3d,2
+np.float64,0x3fe79f9a636f3f34,0x3fe1b11a40c00b3e,2
+np.float64,0x3fe60eb7036c1d6e,0x3fe0c72a02176874,2
+np.float64,0x229da17e453b5,0x229da17e453b5,2
+np.float64,0x3fc1a921b5235240,0x3fc08b3f35e47fb1,2
+np.float64,0xbb92d2af7725b,0xbb92d2af7725b,2
+np.float64,0x3fe4110cb1e8221a,0x3fdf2787de6c73f7,2
+np.float64,0xbfbc87771a390ef0,0xbfbe3f6e95622363,2
+np.float64,0xbfe74025dfee804c,0xbff4bf7b1895e697,2
+np.float64,0x964eb6592c9d7,0x964eb6592c9d7,2
+np.float64,0x3f951689b82a2d00,0x3f94dfb38d746fdf,2
+np.float64,0x800356271be6ac4f,0x800356271be6ac4f,2
+np.float64,0x7fefffffffffffff,0x40862e42fefa39ef,2
+np.float64,0xbfed5ce250fab9c5,0xc003f7ddfeb94345,2
+np.float64,0x3fec3d5dc1387abc,0x3fe43e39c02d86f4,2
+np.float64,0x3999897e73332,0x3999897e73332,2
+np.float64,0xbfdcb57744b96aee,0xbfe30c4b98f3d088,2
+np.float64,0x7f961fb0b82c3f60,0x40860f9549c3a380,2
+np.float64,0x67d6efcacfadf,0x67d6efcacfadf,2
+np.float64,0x8002c9498f859294,0x8002c9498f859294,2
+np.float64,0xbfa3033800260670,0xbfa35fe3bf43e188,2
+np.float64,0xbfeab2fc157565f8,0xbffcc413c486b4eb,2
+np.float64,0x3fe25e62f364bcc6,0x3fdd0856e19e3430,2
+np.float64,0x7fb2f42dda25e85b,0x4086196fb34a65fd,2
+np.float64,0x3fe0f1a5af61e34c,0x3fdb3235a1786efb,2
+np.float64,0x800a340ca1f4681a,0x800a340ca1f4681a,2
+np.float64,0x7c20b9def8418,0x7c20b9def8418,2
+np.float64,0xdf0842a1be109,0xdf0842a1be109,2
+np.float64,0x3fe9f22cc2f3e45a,0x3fe300359b842bf0,2
+np.float64,0x3fe389ed73e713da,0x3fde809780fe4432,2
+np.float64,0x9500fb932a020,0x9500fb932a020,2
+np.float64,0x3fd8a21ffdb14440,0x3fd4d70862345d86,2
+np.float64,0x800d99c15cbb3383,0x800d99c15cbb3383,2
+np.float64,0x3fd96c98c932d932,0x3fd568959c9b028f,2
+np.float64,0x7fc228483a24508f,0x40861ea358420976,2
+np.float64,0x7fc6737bef2ce6f7,0x408620560ffc6a98,2
+np.float64,0xbfb2c27cee2584f8,0xbfb37b8cc7774b5f,2
+np.float64,0xbfd18409f9230814,0xbfd4771d1a9a24fb,2
+np.float64,0x3fb53cb3f42a7968,0x3fb466f06f88044b,2
+np.float64,0x3fef61d0187ec3a0,0x3fe5dec8a9d13dd9,2
+np.float64,0x3fe59a6ffd2b34e0,0x3fe0820a99c6143d,2
+np.float64,0x3fce18aff43c3160,0x3fcb07c7b523f0d1,2
+np.float64,0xbfb1319a62226338,0xbfb1cc62f31b2b40,2
+np.float64,0xa00cce6d4019a,0xa00cce6d4019a,2
+np.float64,0x80068ae8e0ed15d3,0x80068ae8e0ed15d3,2
+np.float64,0x3fecef353239de6a,0x3fe49c280adc607b,2
+np.float64,0x3fdf1a7fb0be34ff,0x3fd9596bafe2d766,2
+np.float64,0x3feb5e12eeb6bc26,0x3fe3c6be3ede8d07,2
+np.float64,0x3fdeff5cd43dfeba,0x3fd947262ec96b05,2
+np.float64,0x3f995e75e832bd00,0x3f990f511f4c7f1c,2
+np.float64,0xbfeb5b3ed0b6b67e,0xbffee24fc0fc2881,2
+np.float64,0x7fb82aad0a305559,0x40861b614d901182,2
+np.float64,0xbfe5c3a4926b8749,0xbff23cd0ad144fe6,2
+np.float64,0x3fef47da373e8fb4,0x3fe5d1aaa4031993,2
+np.float64,0x7fc6a8c3872d5186,0x40862068f5ca84be,2
+np.float64,0x7fc0c2276221844e,0x40861dff2566d001,2
+np.float64,0x7fc9ce7d28339cf9,0x40862173541f84d1,2
+np.float64,0x3fce2c34933c5869,0x3fcb179428ad241d,2
+np.float64,0xbfcf864c293f0c98,0xbfd21872c4821cfc,2
+np.float64,0x3fc51fd1f82a3fa4,0x3fc38d4f1685c166,2
+np.float64,0xbfe2707b70a4e0f7,0xbfeb795fbd5bb444,2
+np.float64,0x46629b568cc54,0x46629b568cc54,2
+np.float64,0x7fe5f821f32bf043,0x40862b40c2cdea3f,2
+np.float64,0x3fedd2c9457ba592,0x3fe512ce92394526,2
+np.float64,0x7fe6dcb8ceadb971,0x40862b925a7dc05d,2
+np.float64,0x3fd1b983b4a37307,0x3fcf4ae2545cf64e,2
+np.float64,0xbfe1c93104639262,0xbfe9f7d28e4c0c82,2
+np.float64,0x995ebc2932bd8,0x995ebc2932bd8,2
+np.float64,0x800a4c3ee614987e,0x800a4c3ee614987e,2
+np.float64,0x3fbb58766e36b0f0,0x3fb9fb3b9810ec16,2
+np.float64,0xbfe36d636666dac7,0xbfede5080f69053c,2
+np.float64,0x3f4feee1003fddc2,0x3f4feae5f05443d1,2
+np.float64,0x3fed0b772ffa16ee,0x3fe4aafb924903c6,2
+np.float64,0x800bb3faef3767f6,0x800bb3faef3767f6,2
+np.float64,0x3fe285cda5e50b9c,0x3fdd3a58df06c427,2
+np.float64,0x7feb9d560bb73aab,0x40862d152362bb94,2
+np.float64,0x3fecd1f447f9a3e9,0x3fe48cc78288cb3f,2
+np.float64,0x3fca927b0c3524f6,0x3fc8250f49ba28df,2
+np.float64,0x7fcc19944e383328,0x40862221b02fcf43,2
+np.float64,0xbfd8ddf41db1bbe8,0xbfdf7b92073ff2fd,2
+np.float64,0x80006fe736e0dfcf,0x80006fe736e0dfcf,2
+np.float64,0x800bbeb66d577d6d,0x800bbeb66d577d6d,2
+np.float64,0xbfe4329353e86526,0xbfefeaf19ab92b42,2
+np.float64,0x2fad72805f5af,0x2fad72805f5af,2
+np.float64,0x3fe1b827aa637050,0x3fdc33bf46012c0d,2
+np.float64,0x3fc3f3f8e227e7f2,0x3fc28aeb86d65278,2
+np.float64,0x3fec018933780312,0x3fe41e619aa4285c,2
+np.float64,0xbfd92428e0b24852,0xbfdfeecb08d154df,2
+np.float64,0x2d7046845ae0a,0x2d7046845ae0a,2
+np.float64,0x7fde7fd2233cffa3,0x408628550f8a948f,2
+np.float64,0x8000a32cd241465a,0x8000a32cd241465a,2
+np.float64,0x8004267a45084cf5,0x8004267a45084cf5,2
+np.float64,0xbfe6b422556d6844,0xbff3c71f67661e6e,2
+np.float64,0x3fe3a37d922746fb,0x3fdea04e04d6195c,2
+np.float64,0xbfddcc54b53b98aa,0xbfe40d2389cdb848,2
+np.float64,0x3fe18b4b92a31697,0x3fdbf9e68cbf5794,2
+np.float64,0x7fc9c5b2ee338b65,0x408621709a17a47a,2
+np.float64,0x1ebd1ce03d7b,0x1ebd1ce03d7b,2
+np.float64,0x8008a6fc39d14df9,0x8008a6fc39d14df9,2
+np.float64,0x3fec11384c782270,0x3fe426bdaedd2965,2
+np.float64,0x3fefc28344ff8507,0x3fe60f75d34fc3d2,2
+np.float64,0xc35f379786be7,0xc35f379786be7,2
+np.float64,0x3feef51f4a7dea3e,0x3fe5a7b95d7786b5,2
+np.float64,0x3fec9b9f0379373e,0x3fe4702477abbb63,2
+np.float64,0x3fde94f8cdbd29f0,0x3fd8ff50f7df0a6f,2
+np.float64,0xbfed32d1cdfa65a4,0xc0037c1470f6f979,2
+np.float64,0x800d3ba44f5a7749,0x800d3ba44f5a7749,2
+np.float64,0x3fe3c56c8fe78ad9,0x3fdeca4eb9bb8918,2
+np.float64,0xbfe7c97242ef92e4,0xbff5c2950dfd6f69,2
+np.float64,0xbd9440057b288,0xbd9440057b288,2
+np.float64,0x7feb2fc111f65f81,0x40862cf524bd2001,2
+np.float64,0x800a431e2df4863d,0x800a431e2df4863d,2
+np.float64,0x80038a3b79e71478,0x80038a3b79e71478,2
+np.float64,0x80000c93d4601928,0x80000c93d4601928,2
+np.float64,0x7fe9fec022f3fd7f,0x40862c995db8ada0,2
+np.float64,0x3fead0129c35a025,0x3fe379d7a92c8f79,2
+np.float64,0x3fdd8cbaf7bb1974,0x3fd84b87ff0c26c7,2
+np.float64,0x3fe8fb7c60b1f6f9,0x3fe276d5339e7135,2
+np.float64,0x85a255e10b44b,0x85a255e10b44b,2
+np.float64,0xbfe507c23fea0f84,0xbff1212d2260022a,2
+np.float64,0x3fc5487c7b2a90f9,0x3fc3b03222d3d148,2
+np.float64,0x7fec0bdcb8f817b8,0x40862d34e8fd11e7,2
+np.float64,0xbfc5f34b4f2be698,0xbfc8146a899c7a0c,2
+np.float64,0xbfa2a49c14254940,0xbfa2fdab2eae3826,2
+np.float64,0x800ec52f15dd8a5e,0x800ec52f15dd8a5e,2
+np.float64,0xbfe3ba4b12a77496,0xbfeeab256b3e9422,2
+np.float64,0x80034d6c7ba69ada,0x80034d6c7ba69ada,2
+np.float64,0x7fd394d4202729a7,0x408624c98a216742,2
+np.float64,0xbfd4493a38289274,0xbfd865d67af2de91,2
+np.float64,0xe47d6203c8fad,0xe47d6203c8fad,2
+np.float64,0x98eb4e4b31d6a,0x98eb4e4b31d6a,2
+np.float64,0x4507fb128a100,0x4507fb128a100,2
+np.float64,0xbfc77032e42ee064,0xbfc9e36ab747a14d,2
+np.float64,0xa1f8a03b43f14,0xa1f8a03b43f14,2
+np.float64,0xbfc3d4da8527a9b4,0xbfc58c27af2476b0,2
+np.float64,0x3fc0eb7d6921d6fb,0x3fbfc858a077ed61,2
+np.float64,0x7fddb2e9403b65d2,0x4086281e98443709,2
+np.float64,0xbfa7ea62942fd4c0,0xbfa87dfd06b05d2a,2
+np.float64,0xbfe7d5c5426fab8a,0xbff5daa969c6d9e5,2
+np.float64,0x3fbf7cba0c3ef974,0x3fbdb23cd8fe875b,2
+np.float64,0x7fe92021eb324043,0x40862c53aee8b154,2
+np.float64,0x7fefbaa1827f7542,0x40862e3194737072,2
+np.float64,0x3fc6f82c402df059,0x3fc520432cbc533f,2
+np.float64,0x7fb37679a826ecf2,0x408619a5f857e27f,2
+np.float64,0x79ec1528f3d83,0x79ec1528f3d83,2
+np.float64,0x3fbefe1d0c3dfc3a,0x3fbd41650ba2c893,2
+np.float64,0x3fc3e5e11827cbc2,0x3fc27eb9b47c9c42,2
+np.float64,0x16aed1922d5db,0x16aed1922d5db,2
+np.float64,0x800124f7e58249f1,0x800124f7e58249f1,2
+np.float64,0x8004f7d12489efa3,0x8004f7d12489efa3,2
+np.float64,0x3fef80b8e27f0172,0x3fe5ee5fd43322c6,2
+np.float64,0xbfe7740c88eee819,0xbff51f823c8da14d,2
+np.float64,0xbfe6e1f1f6edc3e4,0xbff416bcb1302e7c,2
+np.float64,0x8001a2c4a7e3458a,0x8001a2c4a7e3458a,2
+np.float64,0x3fe861e155f0c3c2,0x3fe2201d3000c329,2
+np.float64,0x3fd00a101a201420,0x3fcca01087dbd728,2
+np.float64,0x7fdf0eb1133e1d61,0x4086287a327839b8,2
+np.float64,0x95e3ffdb2bc80,0x95e3ffdb2bc80,2
+np.float64,0x3fd87a1e8230f43d,0x3fd4ba1eb9be1270,2
+np.float64,0x3fedc4792afb88f2,0x3fe50b6529080f73,2
+np.float64,0x7fc9e81fa833d03e,0x4086217b428cc6ff,2
+np.float64,0xbfd21f1ba5a43e38,0xbfd54e048b988e09,2
+np.float64,0xbfbf52af5a3ea560,0xbfc0b4ab3b81fafc,2
+np.float64,0x7fe475f8e268ebf1,0x40862aaf14fee029,2
+np.float64,0x3fcf56899f3ead10,0x3fcc081de28ae9cf,2
+np.float64,0x917d407122fa8,0x917d407122fa8,2
+np.float64,0x22e23e3245c49,0x22e23e3245c49,2
+np.float64,0xbfeec2814f3d8503,0xc00a00ecca27b426,2
+np.float64,0xbfd97fee1c32ffdc,0xbfe04351dfe306ec,2
diff --git a/numpy/core/tests/data/umath-validation-set-log2.csv b/numpy/core/tests/data/umath-validation-set-log2.csv
new file mode 100644
index 000000000..179c6519d
--- /dev/null
+++ b/numpy/core/tests/data/umath-validation-set-log2.csv
@@ -0,0 +1,1629 @@
+dtype,input,output,ulperrortol
+np.float32,0x80000000,0xff800000,3
+np.float32,0x7f12870a,0x42fe63db,3
+np.float32,0x3ef29cf5,0xbf89eb12,3
+np.float32,0x3d6ba8fb,0xc083d26c,3
+np.float32,0x3d9907e8,0xc06f8230,3
+np.float32,0x4ee592,0xc2fd656e,3
+np.float32,0x58d8b1,0xc2fd0db3,3
+np.float32,0x7ba103,0xc2fc19aa,3
+np.float32,0x7f52e90e,0x42ff70e4,3
+np.float32,0x7fcb15,0xc2fc0132,3
+np.float32,0x7cb7129f,0x42f50855,3
+np.float32,0x9faba,0xc301ae59,3
+np.float32,0x7f300a,0xc2fc04b4,3
+np.float32,0x3f0bf047,0xbf5f10cb,3
+np.float32,0x2fb1fb,0xc2fed934,3
+np.float32,0x3eedb0d1,0xbf8db417,3
+np.float32,0x3d7a0b40,0xc0811638,3
+np.float32,0x2e0bac,0xc2fef334,3
+np.float32,0x6278c1,0xc2fcc1b9,3
+np.float32,0x7f61ab2e,0x42ffa2d9,3
+np.float32,0x8fe7c,0xc301d4be,3
+np.float32,0x3f25e6ee,0xbf203536,3
+np.float32,0x7efc78f0,0x42fdf5c0,3
+np.float32,0x6d7304,0xc2fc73a7,3
+np.float32,0x7f1a472a,0x42fe89ed,3
+np.float32,0x7dd029a6,0x42f96734,3
+np.float32,0x3e9b9327,0xbfdbf8f7,3
+np.float32,0x3f4eefc1,0xbe9d2942,3
+np.float32,0x7f5b9b64,0x42ff8ebc,3
+np.float32,0x3e458ee1,0xc017ed6e,3
+np.float32,0x3f7b766b,0xbcd35acf,3
+np.float32,0x3e616070,0xc00bc378,3
+np.float32,0x7f20e633,0x42fea8f8,3
+np.float32,0x3ee3b461,0xbf95a126,3
+np.float32,0x7e7722ba,0x42fbe5f8,3
+np.float32,0x3f0873d7,0xbf6861fa,3
+np.float32,0x7b4cb2,0xc2fc1ba3,3
+np.float32,0x3f0b6b02,0xbf60712e,3
+np.float32,0x9bff4,0xc301b6f2,3
+np.float32,0x3f07be25,0xbf6a4f0c,3
+np.float32,0x3ef10e57,0xbf8b1b75,3
+np.float32,0x46ad75,0xc2fdb6b1,3
+np.float32,0x3f7bc542,0xbcc4e3a9,3
+np.float32,0x3f6673d4,0xbe1b509c,3
+np.float32,0x7f19fe59,0x42fe8890,3
+np.float32,0x7f800000,0x7f800000,3
+np.float32,0x7f2fe696,0x42feead0,3
+np.float32,0x3dc9432d,0xc0563655,3
+np.float32,0x3ee47623,0xbf950446,3
+np.float32,0x3f1f8817,0xbf2eab51,3
+np.float32,0x7f220ec5,0x42feae44,3
+np.float32,0x2325e3,0xc2ffbab1,3
+np.float32,0x29dfc8,0xc2ff395a,3
+np.float32,0x7f524950,0x42ff6eb3,3
+np.float32,0x3e2234e0,0xc02a21c8,3
+np.float32,0x7f1c6f5a,0x42fe942f,3
+np.float32,0x3b6a61,0xc2fe36e7,3
+np.float32,0x3f1df90e,0xbf324ba9,3
+np.float32,0xb57f0,0xc3017f07,3
+np.float32,0x7d0eba,0xc2fc112e,3
+np.float32,0x403aa9,0xc2fdfd5c,3
+np.float32,0x3e74ecc7,0xc004155f,3
+np.float32,0x17509c,0xc30074f2,3
+np.float32,0x7f62196b,0x42ffa442,3
+np.float32,0x3ecef9a9,0xbfa7417a,3
+np.float32,0x7f14b158,0x42fe6eb1,3
+np.float32,0x3ede12be,0xbf9a40fe,3
+np.float32,0x42cfaa,0xc2fde03f,3
+np.float32,0x3f407b0f,0xbed2a6f5,3
+np.float32,0x7f7fffff,0x43000000,3
+np.float32,0x5467c6,0xc2fd3394,3
+np.float32,0x7ea6b80f,0x42fcc336,3
+np.float32,0x3f21e7b2,0xbf293704,3
+np.float32,0x3dc7e9eb,0xc056d542,3
+np.float32,0x7f3e6e67,0x42ff2571,3
+np.float32,0x3e3e809d,0xc01b4911,3
+np.float32,0x3f800000,0x0,3
+np.float32,0x3d8fd238,0xc0753d52,3
+np.float32,0x3f74aa65,0xbd85cd0e,3
+np.float32,0x7ec30305,0x42fd36ff,3
+np.float32,0x3e97bb93,0xbfe0971d,3
+np.float32,0x3e109d9c,0xc034bb1b,3
+np.float32,0x3f4a0b67,0xbeaed537,3
+np.float32,0x3f25a7aa,0xbf20c228,3
+np.float32,0x3ebc05eb,0xbfb8fd6b,3
+np.float32,0x3eebe749,0xbf8f18e5,3
+np.float32,0x3e9dc479,0xbfd96356,3
+np.float32,0x7f245200,0x42feb882,3
+np.float32,0x1573a8,0xc30093b5,3
+np.float32,0x3e66c4b9,0xc00994a6,3
+np.float32,0x3e73bffc,0xc0048709,3
+np.float32,0x3dfef8e5,0xc0405f16,3
+np.float32,0x403750,0xc2fdfd83,3
+np.float32,0x3ebedf17,0xbfb636a4,3
+np.float32,0x15cae6,0xc3008de2,3
+np.float32,0x3edf4d4e,0xbf993c24,3
+np.float32,0x3f7cc41e,0xbc963fb3,3
+np.float32,0x3e9e12a4,0xbfd907ee,3
+np.float32,0x7ded7b59,0x42f9c889,3
+np.float32,0x7f034878,0x42fe12b5,3
+np.float32,0x7ddce43f,0x42f9930b,3
+np.float32,0x3d82b257,0xc07e1333,3
+np.float32,0x3dae89c1,0xc0635dd4,3
+np.float32,0x6b1d00,0xc2fc8396,3
+np.float32,0x449a5a,0xc2fdccb3,3
+np.float32,0x4e89d2,0xc2fd68cb,3
+np.float32,0x7e1ae83f,0x42fa8cef,3
+np.float32,0x7e4bb22c,0x42fb572e,3
+np.float32,0x3de308ea,0xc04b1634,3
+np.float32,0x7f238c7a,0x42feb508,3
+np.float32,0x3f6c62a3,0xbdeb86f3,3
+np.float32,0x3e58cba6,0xc00f5908,3
+np.float32,0x7f7dd91f,0x42fff9c4,3
+np.float32,0x3d989376,0xc06fc88d,3
+np.float32,0x3dd013c5,0xc0532339,3
+np.float32,0x4b17e6,0xc2fd89ed,3
+np.float32,0x7f67f287,0x42ffb71e,3
+np.float32,0x3f69365e,0xbe09ba3c,3
+np.float32,0x3e4b8b21,0xc0152bf1,3
+np.float32,0x3a75b,0xc3032171,3
+np.float32,0x7f303676,0x42feec1f,3
+np.float32,0x7f6570e5,0x42ffaf18,3
+np.float32,0x3f5ed61e,0xbe4cf676,3
+np.float32,0x3e9b22f9,0xbfdc7e4f,3
+np.float32,0x2c095e,0xc2ff1428,3
+np.float32,0x3f1b17c1,0xbf391754,3
+np.float32,0x422dc6,0xc2fde746,3
+np.float32,0x3f677c8d,0xbe14b365,3
+np.float32,0x3ef85d0c,0xbf8597a9,3
+np.float32,0x3ecaaa6b,0xbfab2430,3
+np.float32,0x3f0607d1,0xbf6eff3d,3
+np.float32,0x3f011fdb,0xbf7cc50d,3
+np.float32,0x6ed7c1,0xc2fc6a4e,3
+np.float32,0x7ec2d1a2,0x42fd3644,3
+np.float32,0x3f75b7fe,0xbd7238a2,3
+np.float32,0x3ef2d146,0xbf89c344,3
+np.float32,0x7ec2cd27,0x42fd3633,3
+np.float32,0x7ee1e55a,0x42fda397,3
+np.float32,0x7f464d6a,0x42ff435c,3
+np.float32,0x7f469a93,0x42ff447b,3
+np.float32,0x7ece752f,0x42fd6121,3
+np.float32,0x2ed878,0xc2fee67b,3
+np.float32,0x75b23,0xc3021eff,3
+np.float32,0x3e0f4be4,0xc03593b8,3
+np.float32,0x2778e1,0xc2ff64fc,3
+np.float32,0x5fe2b7,0xc2fcd561,3
+np.float32,0x19b8a9,0xc30050ab,3
+np.float32,0x7df303e5,0x42f9d98d,3
+np.float32,0x608b8d,0xc2fcd051,3
+np.float32,0x588f46,0xc2fd1017,3
+np.float32,0x3eec6a11,0xbf8eb2a1,3
+np.float32,0x3f714121,0xbdaf4906,3
+np.float32,0x7f4f7b9e,0x42ff64c9,3
+np.float32,0x3c271606,0xc0d3b29c,3
+np.float32,0x3f002fe0,0xbf7f75f6,3
+np.float32,0x7efa4798,0x42fdef4f,3
+np.float32,0x3f61a865,0xbe3a601a,3
+np.float32,0x7e8087aa,0x42fc030d,3
+np.float32,0x3f70f0c7,0xbdb321ba,3
+np.float32,0x5db898,0xc2fce63f,3
+np.float32,0x7a965f,0xc2fc1fea,3
+np.float32,0x7f68b112,0x42ffb97c,3
+np.float32,0x7ef0ed3d,0x42fdd32d,3
+np.float32,0x7f3156a1,0x42fef0d3,3
+np.float32,0x3f1d405f,0xbf33fc6e,3
+np.float32,0x3e3494cf,0xc0203945,3
+np.float32,0x6018de,0xc2fcd3c1,3
+np.float32,0x623e49,0xc2fcc370,3
+np.float32,0x3ea29f0f,0xbfd3cad4,3
+np.float32,0xa514,0xc305a20c,3
+np.float32,0x3e1b2ab1,0xc02e3a8f,3
+np.float32,0x3f450b6f,0xbec1578f,3
+np.float32,0x7eb12908,0x42fcf015,3
+np.float32,0x3f10b720,0xbf52ab48,3
+np.float32,0x3e0a93,0xc2fe16f6,3
+np.float32,0x93845,0xc301cb96,3
+np.float32,0x7f4e9ce3,0x42ff61af,3
+np.float32,0x3f6d4296,0xbde09ceb,3
+np.float32,0x6ddede,0xc2fc70d0,3
+np.float32,0x3f4fb6fd,0xbe9a636d,3
+np.float32,0x3f6d08de,0xbde36c0b,3
+np.float32,0x3f56f057,0xbe8122ad,3
+np.float32,0x334e95,0xc2fea349,3
+np.float32,0x7efadbcd,0x42fdf104,3
+np.float32,0x3db02e88,0xc0628046,3
+np.float32,0x3f3309d1,0xbf041066,3
+np.float32,0x2d8722,0xc2fefb8f,3
+np.float32,0x7e926cac,0x42fc6356,3
+np.float32,0x3e3674ab,0xc01f452e,3
+np.float32,0x1b46ce,0xc3003afc,3
+np.float32,0x3f06a338,0xbf6d53fc,3
+np.float32,0x1b1ba7,0xc3003d46,3
+np.float32,0x319dfb,0xc2febc06,3
+np.float32,0x3e2f126a,0xc02315a5,3
+np.float32,0x3f40fe65,0xbed0af9e,3
+np.float32,0x3f1d842f,0xbf335d4b,3
+np.float32,0x3d044e4f,0xc09e78f8,3
+np.float32,0x7f272674,0x42fec51f,3
+np.float32,0x3cda6d8f,0xc0a753db,3
+np.float32,0x3eb92f12,0xbfbbccbb,3
+np.float32,0x7e4318f4,0x42fb3752,3
+np.float32,0x3c5890,0xc2fe2b6d,3
+np.float32,0x3d1993c9,0xc09796f8,3
+np.float32,0x7f18ef24,0x42fe8377,3
+np.float32,0x3e30c3a0,0xc0223244,3
+np.float32,0x3f27cd27,0xbf1c00ef,3
+np.float32,0x3f150957,0xbf47cd6c,3
+np.float32,0x7e7178a3,0x42fbd4d8,3
+np.float32,0x3f298db8,0xbf182ac3,3
+np.float32,0x7cb3be,0xc2fc1348,3
+np.float32,0x3ef64266,0xbf8729de,3
+np.float32,0x3eeb06ce,0xbf8fc8f2,3
+np.float32,0x3f406e36,0xbed2d845,3
+np.float32,0x7f1e1bd3,0x42fe9c0b,3
+np.float32,0x478dcc,0xc2fdad97,3
+np.float32,0x7f7937b5,0x42ffec2b,3
+np.float32,0x3f20f350,0xbf2b6624,3
+np.float32,0x7f13661a,0x42fe683c,3
+np.float32,0x208177,0xc2fff46b,3
+np.float32,0x263cfb,0xc2ff7c72,3
+np.float32,0x7f0bd28c,0x42fe4141,3
+np.float32,0x7230d8,0xc2fc5453,3
+np.float32,0x3f261bbf,0xbf1fbfb4,3
+np.float32,0x737b56,0xc2fc4c05,3
+np.float32,0x3ef88f33,0xbf857263,3
+np.float32,0x7e036464,0x42fa1352,3
+np.float32,0x4b5c4f,0xc2fd874d,3
+np.float32,0x3f77984d,0xbd454596,3
+np.float32,0x3f674202,0xbe162932,3
+np.float32,0x3e7157d9,0xc0057197,3
+np.float32,0x3f3f21da,0xbed7d861,3
+np.float32,0x7f1fb40f,0x42fea375,3
+np.float32,0x7ef0157f,0x42fdd096,3
+np.float32,0x3f71e88d,0xbda74962,3
+np.float32,0x3f174855,0xbf424728,3
+np.float32,0x3f3fdd2c,0xbed505d5,3
+np.float32,0x7b95d1,0xc2fc19ed,3
+np.float32,0x7f23f4e5,0x42feb6df,3
+np.float32,0x7d741925,0x42f7dcd6,3
+np.float32,0x60f81d,0xc2fccd14,3
+np.float32,0x3f17d267,0xbf40f6ae,3
+np.float32,0x3f036fc8,0xbf7636f8,3
+np.float32,0x167653,0xc30082b5,3
+np.float32,0x256d05,0xc2ff8c4f,3
+np.float32,0x3eccc63d,0xbfa93adb,3
+np.float32,0x7f6c91ea,0x42ffc5b2,3
+np.float32,0x2ee52a,0xc2fee5b3,3
+np.float32,0x3dc3579e,0xc058f80d,3
+np.float32,0x4c7170,0xc2fd7cc4,3
+np.float32,0x7f737f20,0x42ffdb03,3
+np.float32,0x3f2f9dbf,0xbf0b3119,3
+np.float32,0x3f4d0c54,0xbea3eec5,3
+np.float32,0x7e380862,0x42fb0c32,3
+np.float32,0x5d637f,0xc2fce8df,3
+np.float32,0x3f0aa623,0xbf627c27,3
+np.float32,0x3e4d5896,0xc0145b88,3
+np.float32,0x3f6cacdc,0xbde7e7ca,3
+np.float32,0x63a2c3,0xc2fcb90a,3
+np.float32,0x6c138c,0xc2fc7cfa,3
+np.float32,0x2063c,0xc303fb88,3
+np.float32,0x7e9e5a3e,0x42fc9d2f,3
+np.float32,0x56ec64,0xc2fd1ddd,3
+np.float32,0x7f1d6a35,0x42fe98cc,3
+np.float32,0x73dc96,0xc2fc4998,3
+np.float32,0x3e5d74e5,0xc00d6238,3
+np.float32,0x7f033cbb,0x42fe1273,3
+np.float32,0x3f5143fc,0xbe94e4e7,3
+np.float32,0x1d56d9,0xc3002010,3
+np.float32,0x2bf3e4,0xc2ff1591,3
+np.float32,0x3f2a6ef1,0xbf164170,3
+np.float32,0x3f33238b,0xbf03db58,3
+np.float32,0x22780e,0xc2ffc91a,3
+np.float32,0x7f00b873,0x42fe0425,3
+np.float32,0x3f7f6145,0xbb654706,3
+np.float32,0x7fc00000,0x7fc00000,3
+np.float32,0x63895a,0xc2fcb9c7,3
+np.float32,0x18a1b2,0xc30060a8,3
+np.float32,0x7e43c6a6,0x42fb39e3,3
+np.float32,0x78676e,0xc2fc2d30,3
+np.float32,0x3f16d839,0xbf435940,3
+np.float32,0x7eff78ba,0x42fdfe79,3
+np.float32,0x3f2e152c,0xbf0e6e54,3
+np.float32,0x3db20ced,0xc06186e1,3
+np.float32,0x3f0cd1d8,0xbf5cbf57,3
+np.float32,0x3fd7a8,0xc2fe01d2,3
+np.float32,0x3ebb075e,0xbfb9f816,3
+np.float32,0x7f94ef,0xc2fc026b,3
+np.float32,0x3d80ba0e,0xc07f7a2b,3
+np.float32,0x7f227e15,0x42feb03f,3
+np.float32,0x792264bf,0x42e6afcc,3
+np.float32,0x7f501576,0x42ff66ec,3
+np.float32,0x223629,0xc2ffcea3,3
+np.float32,0x40a79e,0xc2fdf87b,3
+np.float32,0x449483,0xc2fdccf2,3
+np.float32,0x3f4fa978,0xbe9a9382,3
+np.float32,0x7f148c53,0x42fe6df9,3
+np.float32,0x3ec98b3c,0xbfac2a98,3
+np.float32,0x3e4da320,0xc0143a0a,3
+np.float32,0x3d1d94bb,0xc09666d0,3
+np.float32,0x3c8e624e,0xc0bb155b,3
+np.float32,0x66a9af,0xc2fca2ef,3
+np.float32,0x3ec76ed7,0xbfae1c57,3
+np.float32,0x3f4b52f3,0xbeaa2b81,3
+np.float32,0x7e99bbb5,0x42fc8750,3
+np.float32,0x3f69a46b,0xbe0701be,3
+np.float32,0x3f775400,0xbd4ba495,3
+np.float32,0x131e56,0xc300be3c,3
+np.float32,0x3f30abb4,0xbf08fb10,3
+np.float32,0x7f7e528c,0x42fffb25,3
+np.float32,0x3eb89515,0xbfbc668a,3
+np.float32,0x7e9191b6,0x42fc5f02,3
+np.float32,0x7e80c7e9,0x42fc047e,3
+np.float32,0x3f77ef58,0xbd3d2995,3
+np.float32,0x7ddb1f8a,0x42f98d1b,3
+np.float32,0x7ebc6c4f,0x42fd1d9c,3
+np.float32,0x3f6638e0,0xbe1ccab8,3
+np.float32,0x7f4c45,0xc2fc0410,3
+np.float32,0x3e7d8aad,0xc000e414,3
+np.float32,0x3f4d148b,0xbea3d12e,3
+np.float32,0x3e98c45c,0xbfdf55f4,3
+np.float32,0x3d754c78,0xc081f8a9,3
+np.float32,0x17e4cf,0xc3006be3,3
+np.float32,0x7eb65814,0x42fd0563,3
+np.float32,0x3f65e0d8,0xbe1f0008,3
+np.float32,0x3e99541f,0xbfdea87e,3
+np.float32,0x3f3cb80e,0xbee13b27,3
+np.float32,0x3e99f0c0,0xbfddec3b,3
+np.float32,0x3f43903e,0xbec6ea66,3
+np.float32,0x7e211cd4,0x42faa9f2,3
+np.float32,0x824af,0xc301f971,3
+np.float32,0x3e16a56e,0xc030f56c,3
+np.float32,0x542b3b,0xc2fd35a6,3
+np.float32,0x3eeea2d1,0xbf8cf873,3
+np.float32,0x232e93,0xc2ffb9fa,3
+np.float32,0x3e8c52b9,0xbfef06aa,3
+np.float32,0x7f69c7e3,0x42ffbcef,3
+np.float32,0x3f573e43,0xbe801714,3
+np.float32,0x43b009,0xc2fdd69f,3
+np.float32,0x3ee571ab,0xbf943966,3
+np.float32,0x3ee3d5d8,0xbf958604,3
+np.float32,0x338b12,0xc2fe9fe4,3
+np.float32,0x29cb1f,0xc2ff3ac6,3
+np.float32,0x3f0892b4,0xbf680e7a,3
+np.float32,0x3e8c4f7f,0xbfef0ae9,3
+np.float32,0x7c9d3963,0x42f497e6,3
+np.float32,0x3f26ba84,0xbf1e5f59,3
+np.float32,0x3dd0acc0,0xc052df6f,3
+np.float32,0x3e43fbda,0xc018aa8c,3
+np.float32,0x3ec4fd0f,0xbfb0635d,3
+np.float32,0x3f52c8c6,0xbe8f8d85,3
+np.float32,0x3f5fdc5d,0xbe462fdb,3
+np.float32,0x3f461920,0xbebd6743,3
+np.float32,0x6161ff,0xc2fcc9ef,3
+np.float32,0x7f7ed306,0x42fffc9a,3
+np.float32,0x3d212263,0xc0955f46,3
+np.float32,0x3eca5826,0xbfab6f36,3
+np.float32,0x7d6317ac,0x42f7a77e,3
+np.float32,0x3eb02063,0xbfc50f60,3
+np.float32,0x7f71a6f8,0x42ffd565,3
+np.float32,0x1a3efe,0xc3004935,3
+np.float32,0x3dc599c9,0xc057e856,3
+np.float32,0x3f3e1301,0xbedbf205,3
+np.float32,0xf17d4,0xc301158d,3
+np.float32,0x3f615f84,0xbe3c3d85,3
+np.float32,0x3de63be1,0xc049cb77,3
+np.float32,0x3e8d2f51,0xbfede541,3
+np.float32,0x3a5cdd,0xc2fe441c,3
+np.float32,0x3f443ec0,0xbec4586a,3
+np.float32,0x3eacbd00,0xbfc8a5ad,3
+np.float32,0x3f600f6a,0xbe44df1b,3
+np.float32,0x5f77a6,0xc2fcd89c,3
+np.float32,0x476706,0xc2fdaf28,3
+np.float32,0x2f469,0xc3036fde,3
+np.float32,0x7dc4ba24,0x42f93d77,3
+np.float32,0x3e2d6080,0xc023fb9b,3
+np.float32,0x7e8d7135,0x42fc49c3,3
+np.float32,0x3f589065,0xbe77247b,3
+np.float32,0x3f59e210,0xbe6e2c05,3
+np.float32,0x7f51d388,0x42ff6d15,3
+np.float32,0x7d9a5fda,0x42f88a63,3
+np.float32,0x3e67d5bc,0xc00927ab,3
+np.float32,0x61d72c,0xc2fcc679,3
+np.float32,0x3ef3351d,0xbf897766,3
+np.float32,0x1,0xc3150000,3
+np.float32,0x7f653429,0x42ffae54,3
+np.float32,0x7e1ad3e5,0x42fa8c8e,3
+np.float32,0x3f4ca01d,0xbea57500,3
+np.float32,0x3f7606db,0xbd6ad13e,3
+np.float32,0x7ec4a27d,0x42fd3d1f,3
+np.float32,0x3efe4fd5,0xbf8138c7,3
+np.float32,0x77c2f1,0xc2fc3124,3
+np.float32,0x7e4d3251,0x42fb5c9a,3
+np.float32,0x3f543ac7,0xbe8a8154,3
+np.float32,0x7c3dbe29,0x42f322c4,3
+np.float32,0x408e01,0xc2fdf9a0,3
+np.float32,0x45069b,0xc2fdc829,3
+np.float32,0x3d7ecab7,0xc08037e8,3
+np.float32,0xf8c22,0xc3010a99,3
+np.float32,0x7f69af63,0x42ffbca2,3
+np.float32,0x7ec7d228,0x42fd48fe,3
+np.float32,0xff800000,0xffc00000,3
+np.float32,0xdd7c5,0xc301357c,3
+np.float32,0x143f38,0xc300a90e,3
+np.float32,0x7e65c176,0x42fbb01b,3
+np.float32,0x2c1a9e,0xc2ff1307,3
+np.float32,0x7f6e9224,0x42ffcbeb,3
+np.float32,0x3d32ab39,0xc0909a77,3
+np.float32,0x3e150b42,0xc031f22b,3
+np.float32,0x1f84b4,0xc300059a,3
+np.float32,0x3f71ce21,0xbda88c2a,3
+np.float32,0x2625c4,0xc2ff7e33,3
+np.float32,0x3dd0b293,0xc052dcdc,3
+np.float32,0x625c11,0xc2fcc290,3
+np.float32,0x3f610297,0xbe3e9f24,3
+np.float32,0x7ebdd5e5,0x42fd2320,3
+np.float32,0x3e883458,0xbff486ff,3
+np.float32,0x782313,0xc2fc2ed4,3
+np.float32,0x7f39c843,0x42ff132f,3
+np.float32,0x7f326aa7,0x42fef54d,3
+np.float32,0x4d2c71,0xc2fd75be,3
+np.float32,0x3f55747c,0xbe86409e,3
+np.float32,0x7f7f0867,0x42fffd34,3
+np.float32,0x321316,0xc2feb53f,3
+np.float32,0x3e1b37ed,0xc02e32b0,3
+np.float32,0x80edf,0xc301fd54,3
+np.float32,0x3f0b08ad,0xbf617607,3
+np.float32,0x7f3f4174,0x42ff28a2,3
+np.float32,0x3d79306d,0xc0813eb0,3
+np.float32,0x3f5f657a,0xbe49413d,3
+np.float32,0x3f56c63a,0xbe81b376,3
+np.float32,0x7f667123,0x42ffb24f,3
+np.float32,0x3f71021b,0xbdb24d43,3
+np.float32,0x7f434ab1,0x42ff380f,3
+np.float32,0x3dcae496,0xc055779c,3
+np.float32,0x3f5a7d88,0xbe6a0f5b,3
+np.float32,0x3cdf5c32,0xc0a64bf5,3
+np.float32,0x3e56222c,0xc0107d11,3
+np.float32,0x561a3a,0xc2fd24df,3
+np.float32,0x7ddd953c,0x42f9955a,3
+np.float32,0x7e35d839,0x42fb035c,3
+np.float32,0x3ec1816c,0xbfb3aeb2,3
+np.float32,0x7c87cfcd,0x42f42bc2,3
+np.float32,0xd9cd,0xc3053baf,3
+np.float32,0x3f388234,0xbef1e5b7,3
+np.float32,0x3edfcaca,0xbf98d47b,3
+np.float32,0x3ef28852,0xbf89fac8,3
+np.float32,0x7f7525df,0x42ffe001,3
+np.float32,0x7f6c33ef,0x42ffc48c,3
+np.float32,0x3ea4a881,0xbfd17e61,3
+np.float32,0x3f3e379f,0xbedb63c6,3
+np.float32,0x3f0524c1,0xbf717301,3
+np.float32,0x3db3e7f0,0xc06091d3,3
+np.float32,0x800000,0xc2fc0000,3
+np.float32,0x3f2f2897,0xbf0c27ce,3
+np.float32,0x7eb1776d,0x42fcf15c,3
+np.float32,0x3f039018,0xbf75dc37,3
+np.float32,0x3c4055,0xc2fe2c96,3
+np.float32,0x3f603653,0xbe43dea5,3
+np.float32,0x7f700d24,0x42ffd07c,3
+np.float32,0x3f4741a3,0xbeb918dc,3
+np.float32,0x3f5fe959,0xbe45da2d,3
+np.float32,0x3f3e4401,0xbedb33b1,3
+np.float32,0x7f0705ff,0x42fe2775,3
+np.float32,0x3ea85662,0xbfcd69b0,3
+np.float32,0x3f15f49f,0xbf458829,3
+np.float32,0x3f17c50e,0xbf411728,3
+np.float32,0x3e483f60,0xc016add2,3
+np.float32,0x3f1ab9e5,0xbf39f71b,3
+np.float32,0x3de0b6fb,0xc04c08fe,3
+np.float32,0x7e671225,0x42fbb452,3
+np.float32,0x80800000,0xffc00000,3
+np.float32,0xe2df3,0xc3012c9d,3
+np.float32,0x3ede1e3c,0xbf9a3770,3
+np.float32,0x3df2ffde,0xc044cfec,3
+np.float32,0x3eed8da5,0xbf8dcf6c,3
+np.float32,0x3ead15c3,0xbfc846e1,3
+np.float32,0x7ef3750a,0x42fddae4,3
+np.float32,0x7e6ab7c0,0x42fbbfe4,3
+np.float32,0x7ea4bbe5,0x42fcba5d,3
+np.float32,0x3f227706,0xbf27f0a1,3
+np.float32,0x3ef39bfd,0xbf89295a,3
+np.float32,0x3f289a20,0xbf1a3edd,3
+np.float32,0x7f225f82,0x42feafb4,3
+np.float32,0x768963,0xc2fc38bc,3
+np.float32,0x3f493c00,0xbeb1ccfc,3
+np.float32,0x3f4e7249,0xbe9ee9a7,3
+np.float32,0x1d0c3a,0xc30023c0,3
+np.float32,0x7f3c5f78,0x42ff1d6a,3
+np.float32,0xff7fffff,0xffc00000,3
+np.float32,0x3ee7896a,0xbf928c2a,3
+np.float32,0x3e788479,0xc002bd2e,3
+np.float32,0x3ee4df17,0xbf94af84,3
+np.float32,0x5e06d7,0xc2fce3d7,3
+np.float32,0x3d7b2776,0xc080e1dc,3
+np.float32,0x3e3d39d3,0xc01be7fd,3
+np.float32,0x7c81dece,0x42f40ab7,3
+np.float32,0x3f7d2085,0xbc856255,3
+np.float32,0x7f7f6627,0x42fffe44,3
+np.float32,0x7f5f2e94,0x42ff9aaa,3
+np.float32,0x7f5835f2,0x42ff8339,3
+np.float32,0x3f6a0e32,0xbe046580,3
+np.float32,0x7e16f586,0x42fa79dd,3
+np.float32,0x3f04a2f2,0xbf72dbc5,3
+np.float32,0x3f35e334,0xbefc7740,3
+np.float32,0x3f0d056e,0xbf5c3824,3
+np.float32,0x7ebeb95e,0x42fd2693,3
+np.float32,0x3c6192,0xc2fe2aff,3
+np.float32,0x3e892b4f,0xbff33958,3
+np.float32,0x3f61d694,0xbe3931df,3
+np.float32,0x29d183,0xc2ff3a56,3
+np.float32,0x7f0b0598,0x42fe3d04,3
+np.float32,0x7f743b28,0x42ffdd3d,3
+np.float32,0x3a2ed6,0xc2fe4663,3
+np.float32,0x3e27403a,0xc0274de8,3
+np.float32,0x3f58ee78,0xbe74a349,3
+np.float32,0x3eaa4b,0xc2fe0f92,3
+np.float32,0x3ecb613b,0xbfaa7de8,3
+np.float32,0x7f637d81,0x42ffa8c9,3
+np.float32,0x3f026e96,0xbf790c73,3
+np.float32,0x386cdf,0xc2fe5d0c,3
+np.float32,0x35abd1,0xc2fe8202,3
+np.float32,0x3eac3cd1,0xbfc92ee8,3
+np.float32,0x3f567869,0xbe82bf47,3
+np.float32,0x3f65c643,0xbe1faae6,3
+np.float32,0x7f5422b9,0x42ff752b,3
+np.float32,0x7c26e9,0xc2fc168c,3
+np.float32,0x7eff5cfd,0x42fdfe29,3
+np.float32,0x3f728e7f,0xbd9f6142,3
+np.float32,0x3f10fd43,0xbf51f874,3
+np.float32,0x7e7ada08,0x42fbf0fe,3
+np.float32,0x3e82a611,0xbffc37be,3
+np.float32,0xbf800000,0xffc00000,3
+np.float32,0x3dbe2e12,0xc05b711c,3
+np.float32,0x7e768fa9,0x42fbe440,3
+np.float32,0x5e44e8,0xc2fce1f0,3
+np.float32,0x7f25071a,0x42febbae,3
+np.float32,0x3f54db5e,0xbe885339,3
+np.float32,0x3f0f2c26,0xbf56a0b8,3
+np.float32,0x22f9a7,0xc2ffbe55,3
+np.float32,0x7ed63dcb,0x42fd7c77,3
+np.float32,0x7ea4fae2,0x42fcbb78,3
+np.float32,0x3f1d7766,0xbf337b47,3
+np.float32,0x7f16d59f,0x42fe7941,3
+np.float32,0x3f3a1bb6,0xbeeb855c,3
+np.float32,0x3ef57128,0xbf87c709,3
+np.float32,0xb24ff,0xc3018591,3
+np.float32,0x3ef99e27,0xbf84a983,3
+np.float32,0x3eac2ccf,0xbfc94013,3
+np.float32,0x3e9d3e1e,0xbfda00dc,3
+np.float32,0x718213,0xc2fc58c1,3
+np.float32,0x7edbf509,0x42fd8fea,3
+np.float32,0x70c7f1,0xc2fc5d80,3
+np.float32,0x3f7012f5,0xbdbdc6cd,3
+np.float32,0x12cba,0xc304c487,3
+np.float32,0x7f5d445d,0x42ff944c,3
+np.float32,0x7f3e30bd,0x42ff2481,3
+np.float32,0x63b110,0xc2fcb8a0,3
+np.float32,0x3f39f728,0xbeec1680,3
+np.float32,0x3f5bea58,0xbe6074b1,3
+np.float32,0x3f350749,0xbefff679,3
+np.float32,0x3e91ab2c,0xbfe81f3e,3
+np.float32,0x7ec53fe0,0x42fd3f6d,3
+np.float32,0x3f6cbbdc,0xbde72c8e,3
+np.float32,0x3f4df49f,0xbea0abcf,3
+np.float32,0x3e9c9638,0xbfdac674,3
+np.float32,0x7f3b82ec,0x42ff1a07,3
+np.float32,0x7f612a09,0x42ffa132,3
+np.float32,0x7ea26650,0x42fcafd3,3
+np.float32,0x3a615138,0xc122f26d,3
+np.float32,0x3f1108bd,0xbf51db39,3
+np.float32,0x6f80f6,0xc2fc65ea,3
+np.float32,0x3f7cb578,0xbc98ecb1,3
+np.float32,0x7f54d31a,0x42ff7790,3
+np.float32,0x196868,0xc3005532,3
+np.float32,0x3f01ee0a,0xbf7a7925,3
+np.float32,0x3e184013,0xc02ffb11,3
+np.float32,0xadde3,0xc3018ee3,3
+np.float32,0x252a91,0xc2ff9173,3
+np.float32,0x3f0382c2,0xbf7601a9,3
+np.float32,0x6d818c,0xc2fc7345,3
+np.float32,0x3bfbfd,0xc2fe2fdd,3
+np.float32,0x7f3cad19,0x42ff1e9a,3
+np.float32,0x4169a7,0xc2fdefdf,3
+np.float32,0x3f615d96,0xbe3c4a2b,3
+np.float32,0x3f036480,0xbf7656ac,3
+np.float32,0x7f5fbda3,0x42ff9c83,3
+np.float32,0x3d202d,0xc2fe21f1,3
+np.float32,0x3d0f5e5d,0xc09ac3e9,3
+np.float32,0x3f0fff6e,0xbf548142,3
+np.float32,0x7f11ed32,0x42fe60d2,3
+np.float32,0x3e6f856b,0xc00624b6,3
+np.float32,0x7f7c4dd7,0x42fff542,3
+np.float32,0x3e76fb86,0xc0034fa0,3
+np.float32,0x3e8a0d6e,0xbff209e7,3
+np.float32,0x3eacad19,0xbfc8b6ad,3
+np.float32,0xa7776,0xc3019cbe,3
+np.float32,0x3dc84d74,0xc056a754,3
+np.float32,0x3efb8052,0xbf834626,3
+np.float32,0x3f0e55fc,0xbf58cacc,3
+np.float32,0x7e0e71e3,0x42fa4efb,3
+np.float32,0x3ed5a800,0xbfa1639c,3
+np.float32,0x3f33335b,0xbf03babf,3
+np.float32,0x38cad7,0xc2fe5842,3
+np.float32,0x3bc21256,0xc0ecc927,3
+np.float32,0x3f09522d,0xbf660a19,3
+np.float32,0xcbd5d,0xc3015428,3
+np.float32,0x492752,0xc2fd9d42,3
+np.float32,0x3f2b9b32,0xbf13b904,3
+np.float32,0x6544ac,0xc2fcad09,3
+np.float32,0x52eb12,0xc2fd40b5,3
+np.float32,0x3f66a7c0,0xbe1a03e8,3
+np.float32,0x7ab289,0xc2fc1f41,3
+np.float32,0x62af5e,0xc2fcc020,3
+np.float32,0x7f73e9cf,0x42ffdc46,3
+np.float32,0x3e5eca,0xc2fe130e,3
+np.float32,0x3e3a10f4,0xc01d7602,3
+np.float32,0x3f04db46,0xbf723f0d,3
+np.float32,0x18fc4a,0xc3005b63,3
+np.float32,0x525bcb,0xc2fd45b6,3
+np.float32,0x3f6b9108,0xbdf5c769,3
+np.float32,0x3e992e8c,0xbfded5c5,3
+np.float32,0x7efea647,0x42fdfc18,3
+np.float32,0x7e8371db,0x42fc139e,3
+np.float32,0x3f397cfb,0xbeedfc69,3
+np.float32,0x7e46d233,0x42fb454a,3
+np.float32,0x7d5281ad,0x42f76f79,3
+np.float32,0x7f4c1878,0x42ff58a1,3
+np.float32,0x3e96ca5e,0xbfe1bd97,3
+np.float32,0x6a2743,0xc2fc8a3d,3
+np.float32,0x7f688781,0x42ffb8f8,3
+np.float32,0x7814b7,0xc2fc2f2d,3
+np.float32,0x3f2ffdc9,0xbf0a6756,3
+np.float32,0x3f766fa8,0xbd60fe24,3
+np.float32,0x4dc64e,0xc2fd7003,3
+np.float32,0x3a296f,0xc2fe46a8,3
+np.float32,0x3f2af942,0xbf15162e,3
+np.float32,0x7f702c32,0x42ffd0dc,3
+np.float32,0x7e61e318,0x42fba390,3
+np.float32,0x7f7d3bdb,0x42fff7fa,3
+np.float32,0x3ee87f3f,0xbf91c881,3
+np.float32,0x2bbc28,0xc2ff193c,3
+np.float32,0x3e01f918,0xc03e966e,3
+np.float32,0x7f0b39f4,0x42fe3e1a,3
+np.float32,0x3eaa4d64,0xbfcb4516,3
+np.float32,0x3e53901e,0xc0119a88,3
+np.float32,0x603cb,0xc3026957,3
+np.float32,0x7e81f926,0x42fc0b4d,3
+np.float32,0x5dab7c,0xc2fce6a6,3
+np.float32,0x3f46fefd,0xbeba1018,3
+np.float32,0x648448,0xc2fcb28a,3
+np.float32,0x3ec49470,0xbfb0c58b,3
+np.float32,0x3e8a5393,0xbff1ac2b,3
+np.float32,0x3f27ccfc,0xbf1c014e,3
+np.float32,0x3ed886e6,0xbf9eeca8,3
+np.float32,0x7cfbe06e,0x42f5f401,3
+np.float32,0x3f5aa7ba,0xbe68f229,3
+np.float32,0x9500d,0xc301c7e3,3
+np.float32,0x3f4861,0xc2fe0853,3
+np.float32,0x3e5ae104,0xc00e76f5,3
+np.float32,0x71253a,0xc2fc5b1e,3
+np.float32,0xcf7b8,0xc3014d9c,3
+np.float32,0x7f7edd2d,0x42fffcb7,3
+np.float32,0x3e9039ee,0xbfe9f5ab,3
+np.float32,0x2fd54e,0xc2fed712,3
+np.float32,0x3f600752,0xbe45147a,3
+np.float32,0x3f4da8f6,0xbea1bb5c,3
+np.float32,0x3f2d34a9,0xbf104bd9,3
+np.float32,0x3e1e66dd,0xc02c52d2,3
+np.float32,0x798276,0xc2fc2670,3
+np.float32,0xd55e2,0xc3014347,3
+np.float32,0x80000001,0xffc00000,3
+np.float32,0x3e7a5ead,0xc0020da6,3
+np.float32,0x7ec4c744,0x42fd3da9,3
+np.float32,0x597e00,0xc2fd085a,3
+np.float32,0x3dff6bf4,0xc0403575,3
+np.float32,0x5d6f1a,0xc2fce883,3
+np.float32,0x7e21faff,0x42faadea,3
+np.float32,0x3e570fea,0xc01016c6,3
+np.float32,0x28e6b6,0xc2ff4ab7,3
+np.float32,0x7e77062d,0x42fbe5a3,3
+np.float32,0x74cac4,0xc2fc43b0,3
+np.float32,0x3f707273,0xbdb93078,3
+np.float32,0x228e96,0xc2ffc737,3
+np.float32,0x686ac1,0xc2fc966b,3
+np.float32,0x3d76400d,0xc081cae8,3
+np.float32,0x3e9f502f,0xbfd7966b,3
+np.float32,0x3f6bc656,0xbdf32b1f,3
+np.float32,0x3edb828b,0xbf9c65d4,3
+np.float32,0x6c6e56,0xc2fc7a8e,3
+np.float32,0x3f04552e,0xbf73b48f,3
+np.float32,0x3f39cb69,0xbeecc457,3
+np.float32,0x7f681c44,0x42ffb7a3,3
+np.float32,0x7f5b44ee,0x42ff8d99,3
+np.float32,0x3e71430a,0xc005798d,3
+np.float32,0x3edcfde3,0xbf9b27c6,3
+np.float32,0x3f616a5a,0xbe3bf67f,3
+np.float32,0x3f523936,0xbe918548,3
+np.float32,0x3f39ce3a,0xbeecb925,3
+np.float32,0x3eac589a,0xbfc91120,3
+np.float32,0x7efc8d3d,0x42fdf5fc,3
+np.float32,0x5704b0,0xc2fd1d0f,3
+np.float32,0x7e7972e9,0x42fbecda,3
+np.float32,0x3eb0811c,0xbfc4aa13,3
+np.float32,0x7f1efcbb,0x42fea023,3
+np.float32,0x3e0b9e32,0xc037fa6b,3
+np.float32,0x7eef6a48,0x42fdce87,3
+np.float32,0x3cc0a373,0xc0ad20c0,3
+np.float32,0x3f2a75bb,0xbf1632ba,3
+np.float32,0x0,0xff800000,3
+np.float32,0x7ecdb6f4,0x42fd5e77,3
+np.float32,0x7f2e2dfd,0x42fee38d,3
+np.float32,0x3ee17f6e,0xbf976d8c,3
+np.float32,0x3f51e7ee,0xbe92a319,3
+np.float32,0x3f06942f,0xbf6d7d3c,3
+np.float32,0x3f7ba528,0xbccac6f1,3
+np.float32,0x3f413787,0xbecfd513,3
+np.float32,0x3e085e48,0xc03a2716,3
+np.float32,0x7e4c5e0e,0x42fb599c,3
+np.float32,0x306f76,0xc2fecdd4,3
+np.float32,0x7f5c2203,0x42ff9081,3
+np.float32,0x3d5355b4,0xc088da05,3
+np.float32,0x9a2a,0xc305bb4f,3
+np.float32,0x3db93a1f,0xc05de0db,3
+np.float32,0x4e50c6,0xc2fd6ae4,3
+np.float32,0x7ec4afed,0x42fd3d51,3
+np.float32,0x3a8f27,0xc2fe41a0,3
+np.float32,0x7f213caf,0x42feaa84,3
+np.float32,0x7e7b5f00,0x42fbf286,3
+np.float32,0x7e367194,0x42fb05ca,3
+np.float32,0x7f56e6de,0x42ff7ebd,3
+np.float32,0x3ed7383e,0xbfa00aef,3
+np.float32,0x7e844752,0x42fc184a,3
+np.float32,0x15157,0xc3049a19,3
+np.float32,0x3f78cd92,0xbd28824a,3
+np.float32,0x7ecddb16,0x42fd5ef9,3
+np.float32,0x3e479f16,0xc016f7d8,3
+np.float32,0x3f5cb418,0xbe5b2bd3,3
+np.float32,0x7c0934cb,0x42f2334e,3
+np.float32,0x3ebe5505,0xbfb6bc69,3
+np.float32,0x3eb1335a,0xbfc3eff5,3
+np.float32,0x3f2488a3,0xbf234444,3
+np.float32,0x642906,0xc2fcb52a,3
+np.float32,0x3da635fa,0xc067e15a,3
+np.float32,0x7e0d80db,0x42fa4a15,3
+np.float32,0x4f0b9d,0xc2fd640a,3
+np.float32,0x7e083806,0x42fa2df8,3
+np.float32,0x7f77f8c6,0x42ffe877,3
+np.float32,0x3e7bb46a,0xc0018ff5,3
+np.float32,0x3f06eb2e,0xbf6c8eca,3
+np.float32,0x7eae8f7c,0x42fce52a,3
+np.float32,0x3de481a0,0xc04a7d7f,3
+np.float32,0x3eed4311,0xbf8e096f,3
+np.float32,0x3f7b0300,0xbce8903d,3
+np.float32,0x3811b,0xc30330dd,3
+np.float32,0x3eb6f8e1,0xbfbe04bc,3
+np.float32,0x3ec35210,0xbfb1f55a,3
+np.float32,0x3d386916,0xc08f24a5,3
+np.float32,0x3f1fa197,0xbf2e704d,3
+np.float32,0x7f2020a5,0x42fea56a,3
+np.float32,0x7e1ea53f,0x42fa9e8c,3
+np.float32,0x3f148903,0xbf490bf9,3
+np.float32,0x3f2f56a0,0xbf0bc6c9,3
+np.float32,0x7da9fc,0xc2fc0d9b,3
+np.float32,0x3d802134,0xc07fe810,3
+np.float32,0x3f6cb927,0xbde74e57,3
+np.float32,0x7e05b125,0x42fa2023,3
+np.float32,0x3f3307f9,0xbf041433,3
+np.float32,0x5666bf,0xc2fd2250,3
+np.float32,0x3f51c93b,0xbe930f28,3
+np.float32,0x3eb5dcfe,0xbfbf241e,3
+np.float32,0xb2773,0xc301853f,3
+np.float32,0x7f4dee96,0x42ff5f3f,3
+np.float32,0x3e3f5c33,0xc01adee1,3
+np.float32,0x3f2ed29a,0xbf0cdd4a,3
+np.float32,0x3e3c01ef,0xc01c80ab,3
+np.float32,0x3ec2236e,0xbfb31458,3
+np.float32,0x7e841dc4,0x42fc1761,3
+np.float32,0x3df2cd8e,0xc044e30c,3
+np.float32,0x3f010901,0xbf7d0670,3
+np.float32,0x3c05ceaa,0xc0ddf39b,3
+np.float32,0x3f517226,0xbe944206,3
+np.float32,0x3f23c83d,0xbf24f522,3
+np.float32,0x7fc9da,0xc2fc0139,3
+np.float32,0x7f1bde53,0x42fe9181,3
+np.float32,0x3ea3786c,0xbfd2d4a5,3
+np.float32,0x3e83a71b,0xbffacdd2,3
+np.float32,0x3f6f0d4f,0xbdca61d5,3
+np.float32,0x7f5ab613,0x42ff8bb7,3
+np.float32,0x3ab1ec,0xc2fe3fea,3
+np.float32,0x4fbf58,0xc2fd5d82,3
+np.float32,0x3dea141b,0xc0484403,3
+np.float32,0x7d86ad3b,0x42f8258f,3
+np.float32,0x7f345315,0x42fefd29,3
+np.float32,0x3f3752fe,0xbef6a780,3
+np.float32,0x64830d,0xc2fcb293,3
+np.float32,0x3d9dc1eb,0xc06cb32a,3
+np.float32,0x3f2f935a,0xbf0b46f6,3
+np.float32,0xb90a4,0xc30177e3,3
+np.float32,0x4111dd,0xc2fdf3c1,3
+np.float32,0x3d4cd078,0xc08a4c68,3
+np.float32,0x3e95c3f1,0xbfe30011,3
+np.float32,0x3ec9f356,0xbfabcb4e,3
+np.float32,0x1b90d5,0xc3003717,3
+np.float32,0xee70f,0xc3011a3e,3
+np.float32,0x7fa00000,0x7fe00000,3
+np.float32,0x3f74cdb6,0xbd8422af,3
+np.float32,0x3d9b56fe,0xc06e2037,3
+np.float32,0x3f1853df,0xbf3fbc40,3
+np.float32,0x7d86a011,0x42f82547,3
+np.float32,0x3dff9629,0xc0402634,3
+np.float32,0x46f8c9,0xc2fdb39f,3
+np.float32,0x3e9b410b,0xbfdc5a87,3
+np.float32,0x3f5aed42,0xbe671cac,3
+np.float32,0x3b739886,0xc101257f,3
+np.float64,0x3fe2f58d6565eb1b,0xbfe82a641138e19a,2
+np.float64,0x3fee7f0642fcfe0d,0xbfb1c702f6974932,2
+np.float64,0x25b71f244b6e5,0xc090030d3b3c5d2b,2
+np.float64,0x8c9cc8e1193b,0xc0900b752a678fa8,2
+np.float64,0x3fd329b5d326536c,0xbffbd607f6db945c,2
+np.float64,0x3fb5109b3a2a2136,0xc00cd36bd15dfb18,2
+np.float64,0x3fd5393ae12a7276,0xbff97a7e4a157154,2
+np.float64,0x3fd374d1b926e9a3,0xbffb7c3e1a3a7ed3,2
+np.float64,0x3fe2c7f4e2658fea,0xbfe899f15ca78fcb,2
+np.float64,0x7fe3d6b81ee7ad6f,0x408ffa7b63d407ee,2
+np.float64,0x3fe086d097e10da1,0xbfee81456ce8dd03,2
+np.float64,0x7fd374a64ca6e94c,0x408ff241c7306d39,2
+np.float64,0x3fc0709a5b20e135,0xc007afdede31b29c,2
+np.float64,0x3fd4218f4b28431f,0xbffab2c696966e2d,2
+np.float64,0x143134c828628,0xc09006a8372c4d8a,2
+np.float64,0x3f8bd0aa0037a154,0xc018cf0e8b9c3107,2
+np.float64,0x7fe0ce905ee19d20,0x408ff8915e71bd67,2
+np.float64,0x3fda0f5f32b41ebe,0xbff4bd5e0869e820,2
+np.float64,0x7fe9ae63d0b35cc7,0x408ffd760ca4f292,2
+np.float64,0x3fe75abd9eeeb57b,0xbfdd1476fc8b3089,2
+np.float64,0x786c3110f0d87,0xc08ff8b44cedbeea,2
+np.float64,0x22c5fe80458d,0xc09013853591c2f2,2
+np.float64,0x3fdc250797384a0f,0xbff2f6a02c961f0b,2
+np.float64,0x3fa2b367b02566cf,0xc013199238485054,2
+np.float64,0x3fd26a910ca4d522,0xbffcc0e2089b1c0c,2
+np.float64,0x8068d3b300d1b,0xc08ff7f690210aac,2
+np.float64,0x3fe663bfa9ecc77f,0xbfe07cd95a43a5ce,2
+np.float64,0x3fd0ddb07321bb61,0xbffec886665e895e,2
+np.float64,0x3f91c730b0238e61,0xc0176452badc8d22,2
+np.float64,0x4dd10d309ba22,0xc08ffdbe738b1d8d,2
+np.float64,0x7fe322afa4a6455e,0x408ffa10c038f9de,2
+np.float64,0x7fdf7f7c42befef8,0x408ff7d147ddaad5,2
+np.float64,0x7fd673f386ace7e6,0x408ff3e920d00eef,2
+np.float64,0x3feaebfcadb5d7f9,0xbfcfe8ec27083478,2
+np.float64,0x3fdc6dc23738db84,0xbff2bb46794f07b8,2
+np.float64,0xcd8819599b103,0xc08ff288c5b2cf0f,2
+np.float64,0xfda00e77fb402,0xc08ff01b895d2236,2
+np.float64,0x840b02ff08161,0xc08ff7a41e41114c,2
+np.float64,0x3fbdce3a383b9c74,0xc008d1e61903a289,2
+np.float64,0x3fd24ed3c4a49da8,0xbffce3c12136b6d3,2
+np.float64,0x3fe8d0834131a107,0xbfd77b194e7051d4,2
+np.float64,0x3fdd0cb11aba1962,0xbff23b9dbd554455,2
+np.float64,0x1a32d97e3465c,0xc090052781a37271,2
+np.float64,0x3fdb09d2b1b613a5,0xbff3e396b862bd83,2
+np.float64,0x3fe04c848aa09909,0xbfef2540dd90103a,2
+np.float64,0x3fce0c48613c1891,0xc000b9f76877d744,2
+np.float64,0x3fc37109a226e213,0xc005c05d8b2b9a2f,2
+np.float64,0x81cf3837039e7,0xc08ff7d686517dff,2
+np.float64,0xd9342c29b2686,0xc08ff1e591c9a895,2
+np.float64,0x7fec731b0638e635,0x408ffea4884550a9,2
+np.float64,0x3fba0fc138341f82,0xc00a5e839b085f64,2
+np.float64,0x7fdda893b03b5126,0x408ff71f7c5a2797,2
+np.float64,0xd2a4bb03a5498,0xc08ff2402f7a907c,2
+np.float64,0x3fea61fb0d34c3f6,0xbfd1d293fbe76183,2
+np.float64,0x3fed5cf486fab9e9,0xbfbfc2e01a7ffff1,2
+np.float64,0x3fcbabc2bf375785,0xc001ad7750c9dbdf,2
+np.float64,0x3fdb5fff53b6bfff,0xbff39a7973a0c6a5,2
+np.float64,0x7feef05a00bde0b3,0x408fff9c5cbc8651,2
+np.float64,0xb1cf24f1639e5,0xc08ff434de10fffb,2
+np.float64,0x3fa583989c2b0731,0xc0124a8a3bbf18ce,2
+np.float64,0x7feae90bf9f5d217,0x408ffe002e7bbbea,2
+np.float64,0x3fe9ef41c4b3de84,0xbfd367878ae4528e,2
+np.float64,0x9be24ce337c4a,0xc08ff5b9b1c31cf9,2
+np.float64,0x3fe916894cb22d13,0xbfd677f915d58503,2
+np.float64,0x3fec1bab20f83756,0xbfc7f2777aabe8ee,2
+np.float64,0x3feaabf2873557e5,0xbfd0d11f28341233,2
+np.float64,0x3fd4d3c3b529a787,0xbff9e9e47acc8ca9,2
+np.float64,0x3fe4cfe96c699fd3,0xbfe3dc53fa739169,2
+np.float64,0xccfdb97399fb7,0xc08ff2908d893400,2
+np.float64,0x3fec7598be78eb31,0xbfc5a750f8f3441a,2
+np.float64,0x355be5fc6ab7e,0xc090010ca315b50b,2
+np.float64,0x3fba9f9074353f21,0xc00a1f80eaf5e581,2
+np.float64,0x7fdcaff189395fe2,0x408ff6bd1c5b90d9,2
+np.float64,0x3fd94d3b64b29a77,0xbff56be1b43d25f3,2
+np.float64,0x4e5f29949cbe6,0xc08ffda972da1d73,2
+np.float64,0x3fe654e2d9aca9c6,0xbfe09b88dcd8f15d,2
+np.float64,0x7fdc130190b82602,0x408ff67d496c1a27,2
+np.float64,0x3fbcd4701e39a8e0,0xc009343e36627e80,2
+np.float64,0x7fdaa4d38f3549a6,0x408ff5e2c6d8678f,2
+np.float64,0x3febe95e5237d2bd,0xbfc93e16d453fe3a,2
+np.float64,0x9ef5ca553deba,0xc08ff57ff4f7883d,2
+np.float64,0x7fe878e91170f1d1,0x408ffce795868fc8,2
+np.float64,0x3fe63dff466c7bff,0xbfe0caf2b79c9e5f,2
+np.float64,0x6561446ccac29,0xc08ffab0e383834c,2
+np.float64,0x30c6c2ae618d9,0xc09001914b30381b,2
+np.float64,0x7ff0000000000000,0x7ff0000000000000,2
+np.float64,0x3fe5c9daf1ab93b6,0xbfe1be81baf4dbdb,2
+np.float64,0x3fe0a03e24a1407c,0xbfee3a73c4c0e8f8,2
+np.float64,0xff2a2cf3fe546,0xc08ff009a7e6e782,2
+np.float64,0x7fcf0332213e0663,0x408fefa36235e210,2
+np.float64,0x3fb612affc2c2560,0xc00c494be9c8c33b,2
+np.float64,0x3fd2b259702564b3,0xbffc67967f077e75,2
+np.float64,0x7fcb63685d36c6d0,0x408fee343343f913,2
+np.float64,0x3fe369f1d5a6d3e4,0xbfe71251139939ad,2
+np.float64,0x3fdd17c618ba2f8c,0xbff232d11c986251,2
+np.float64,0x3f92cc8040259901,0xc01711d8e06b52ee,2
+np.float64,0x69a81dc2d3504,0xc08ffa36cdaf1141,2
+np.float64,0x3fea0fad99b41f5b,0xbfd2f4625a652645,2
+np.float64,0xd1cd5799a39ab,0xc08ff24c02b90d26,2
+np.float64,0x324e59ce649cc,0xc0900163ad091c76,2
+np.float64,0x3fc3d460a227a8c1,0xc00585f903dc7a7f,2
+np.float64,0xa7185ec74e30c,0xc08ff4ec7d65ccd9,2
+np.float64,0x3fa254eaac24a9d5,0xc01337053963321a,2
+np.float64,0x3feaeb112435d622,0xbfcfef3be17f81f6,2
+np.float64,0x60144c3ac028a,0xc08ffb4f8eb94595,2
+np.float64,0x7fa4d2ec6829a5d8,0x408fdb0a9670ab83,2
+np.float64,0x3fed1372f97a26e6,0xbfc1b1fe50d48a55,2
+np.float64,0x3fd5ade5972b5bcb,0xbff8fcf28f525031,2
+np.float64,0x7fe72e335bee5c66,0x408ffc4759236437,2
+np.float64,0x7fdfafab143f5f55,0x408ff7e2e22a8129,2
+np.float64,0x3fe90d0db9321a1b,0xbfd69ae5fe10eb9e,2
+np.float64,0x7fe20a59072414b1,0x408ff962a2492484,2
+np.float64,0x3fed853690bb0a6d,0xbfbdc9dc5f199d2b,2
+np.float64,0x3fd709d469ae13a9,0xbff795a218deb700,2
+np.float64,0x3fe21c35f5e4386c,0xbfea47d71789329b,2
+np.float64,0x9ea5ec053d4be,0xc08ff585c2f6b7a3,2
+np.float64,0x3fc0580f9e20b01f,0xc007c1268f49d037,2
+np.float64,0xd99127abb3225,0xc08ff1e0a1ff339d,2
+np.float64,0x3fdc8c9bbfb91937,0xbff2a2478354effb,2
+np.float64,0x3fe15fc6b162bf8d,0xbfec323ac358e008,2
+np.float64,0xffefffffffffffff,0x7ff8000000000000,2
+np.float64,0x3fee341afb3c6836,0xbfb556b6faee9a84,2
+np.float64,0x3fe4b64c56296c99,0xbfe4154835ad2afe,2
+np.float64,0x85de22810bbc5,0xc08ff77b914fe5b5,2
+np.float64,0x3fd22c72e3a458e6,0xbffd0f4269d20bb9,2
+np.float64,0xc090e5218123,0xc09009a4a65a8a8f,2
+np.float64,0x7fd9641692b2c82c,0x408ff5547782bdfc,2
+np.float64,0x3fd9b9cb28b37396,0xbff509a8fb59a9f1,2
+np.float64,0x3fcd2726f93a4e4e,0xc001135059a22117,2
+np.float64,0x3fa4b493d4296928,0xc0128323c7a55f4a,2
+np.float64,0x47455e788e8ac,0xc08ffec2101c1e82,2
+np.float64,0x3fe0d7e2e261afc6,0xbfeda0f1e2d0f4bd,2
+np.float64,0x3fe860fc5b70c1f9,0xbfd91dc42eaf72c2,2
+np.float64,0xa5d7805b4baf0,0xc08ff502bc819ff6,2
+np.float64,0xd83395b1b0673,0xc08ff1f33c3f94c2,2
+np.float64,0x3f865972e02cb2e6,0xc01a1243651565c8,2
+np.float64,0x52fc6952a5f8e,0xc08ffd006b158179,2
+np.float64,0x7fecac6c793958d8,0x408ffebbb1c09a70,2
+np.float64,0x7fe621ff606c43fe,0x408ffbbeb2b1473a,2
+np.float64,0x3fdb9f3f9db73e7f,0xbff365610c52bda7,2
+np.float64,0x7feab92992757252,0x408ffdeb92a04813,2
+np.float64,0xcc46c79f988d9,0xc08ff29adf03fb7c,2
+np.float64,0x3fe3156a03262ad4,0xbfe7dd0f598781c7,2
+np.float64,0x3fc00e3a61201c75,0xc007f5c121a87302,2
+np.float64,0x3fdce8e9f739d1d4,0xbff2581d41ef50ef,2
+np.float64,0x0,0xfff0000000000000,2
+np.float64,0x7d373ac4fa6e8,0xc08ff840fa8beaec,2
+np.float64,0x3fee41e0653c83c1,0xbfb4ae786f2a0d54,2
+np.float64,0x3ff0000000000000,0x0,2
+np.float64,0x7feca6fff9794dff,0x408ffeb982a70556,2
+np.float64,0x7fc532716d2a64e2,0x408feb3f0f6c095b,2
+np.float64,0x3fe4ec2954a9d853,0xbfe39dd44aa5a040,2
+np.float64,0x7fd3321d52a6643a,0x408ff21a0ab9cd85,2
+np.float64,0x7fd8f1b2dfb1e365,0x408ff52001fa7922,2
+np.float64,0x3fee5e58cabcbcb2,0xbfb3539734a24d8b,2
+np.float64,0x3feebf6e7dfd7edd,0xbfad7c648f025102,2
+np.float64,0x6008026ec0101,0xc08ffb5108b54a93,2
+np.float64,0x3fea06f5e2340dec,0xbfd3134a48283360,2
+np.float64,0x41cad13c8395b,0xc08fffae654b2426,2
+np.float64,0x7fedb5c9353b6b91,0x408fff249f1f32b6,2
+np.float64,0xe00c5af9c018c,0xc08ff189e68c655f,2
+np.float64,0x7feac398ddf58731,0x408ffdf01374de9f,2
+np.float64,0x3fed21127c7a4225,0xbfc15b8cf55628fa,2
+np.float64,0x3fd3446711a688ce,0xbffbb5f7252a9fa3,2
+np.float64,0x7fe75fa07a6ebf40,0x408ffc5fdb096018,2
+np.float64,0x3feeb1618cbd62c3,0xbfaece3bd0863070,2
+np.float64,0x7f5226e180244dc2,0x408fb174d506e52f,2
+np.float64,0x3fcd67deca3acfbe,0xc000f9cd7a490749,2
+np.float64,0xdc6f30efb8de6,0xc08ff1b9f2a22d2e,2
+np.float64,0x9c14931338293,0xc08ff5b5f975ec5d,2
+np.float64,0x7fe93e802df27cff,0x408ffd4354eba0e0,2
+np.float64,0x3feb92ae5077255d,0xbfcb7f2084e44dbb,2
+np.float64,0xd78dbfddaf1b8,0xc08ff1fc19fa5a13,2
+np.float64,0x7fe14c301fa2985f,0x408ff8e666cb6592,2
+np.float64,0xbda3d8b77b47b,0xc08ff37689f4b2e5,2
+np.float64,0x8a42953b14853,0xc08ff71c2db3b8cf,2
+np.float64,0x7fe4ca7e186994fb,0x408ffb05e94254a7,2
+np.float64,0x7fe92ffc5e325ff8,0x408ffd3cb0265b12,2
+np.float64,0x91b262912364d,0xc08ff681619be214,2
+np.float64,0x33fe2b0667fc6,0xc0900132f3fab55e,2
+np.float64,0x3fde10e9183c21d2,0xbff17060fb4416c7,2
+np.float64,0xb6b811cb6d702,0xc08ff3e46303b541,2
+np.float64,0x3fe4a7bda0a94f7b,0xbfe435c6481cd0e3,2
+np.float64,0x7fd9fe6057b3fcc0,0x408ff599c79a822c,2
+np.float64,0x3fef44bf917e897f,0xbfa11484e351a6e9,2
+np.float64,0x3fe57d701daafae0,0xbfe2618ab40fc01b,2
+np.float64,0x7fe52d2adbaa5a55,0x408ffb3c2fb1c99d,2
+np.float64,0xb432f66d6865f,0xc08ff40d6b4084fe,2
+np.float64,0xbff0000000000000,0x7ff8000000000000,2
+np.float64,0x7fecd2292bf9a451,0x408ffecad860de6f,2
+np.float64,0x3fddd2ae153ba55c,0xbff1a059adaca33e,2
+np.float64,0x3fee55d6e5bcabae,0xbfb3bb1c6179d820,2
+np.float64,0x7fc1d0085623a010,0x408fe93d16ada7a7,2
+np.float64,0x829b000105360,0xc08ff7c47629a68f,2
+np.float64,0x7fe1e0257523c04a,0x408ff94782cf0717,2
+np.float64,0x7fd652f9ad2ca5f2,0x408ff3d820ec892e,2
+np.float64,0x3fef2246203e448c,0xbfa444ab6209d8cd,2
+np.float64,0x3fec6c0ae178d816,0xbfc5e559ebd4e790,2
+np.float64,0x3fe6ddfee92dbbfe,0xbfdf06dd7d3fa7a8,2
+np.float64,0x3fb7fbcbea2ff798,0xc00b5404d859d148,2
+np.float64,0x7feb9a154d37342a,0x408ffe4b26c29e55,2
+np.float64,0x3fe4db717aa9b6e3,0xbfe3c2c6b3ef13bc,2
+np.float64,0x3fbae17dda35c2fc,0xc00a030f7f4b37e7,2
+np.float64,0x7fd632b9082c6571,0x408ff3c76826ef19,2
+np.float64,0x7fc4184a15283093,0x408feaa14adf00be,2
+np.float64,0x3fe052d19920a5a3,0xbfef136b5df81a3e,2
+np.float64,0x7fe38b872b67170d,0x408ffa4f51aafc86,2
+np.float64,0x3fef9842d03f3086,0xbf92d3d2a21d4be2,2
+np.float64,0x9cea662139d4d,0xc08ff5a634810daa,2
+np.float64,0x3fe35f0855e6be11,0xbfe72c4b564e62aa,2
+np.float64,0x3fecee3d3779dc7a,0xbfc29ee942f8729e,2
+np.float64,0x3fe7903fd72f2080,0xbfdc41db9b5f4048,2
+np.float64,0xb958889572b11,0xc08ff3ba366cf84b,2
+np.float64,0x3fcb3a67c53674d0,0xc001dd21081ad1ea,2
+np.float64,0xe3b1b53fc7637,0xc08ff15a3505e1ce,2
+np.float64,0xe5954ae9cb2aa,0xc08ff141cbbf0ae4,2
+np.float64,0x3fe394af74e7295f,0xbfe6ad1d13f206e8,2
+np.float64,0x7fe21dd704643bad,0x408ff96f13f80c1a,2
+np.float64,0x3fd23a7cf02474fa,0xbffcfd7454117a05,2
+np.float64,0x7fe257515e24aea2,0x408ff99378764d52,2
+np.float64,0x7fe4c5d0a6e98ba0,0x408ffb03503cf939,2
+np.float64,0x3fadc2c1603b8583,0xc0106b2c17550e3a,2
+np.float64,0x3fc0f7f02421efe0,0xc007525ac446864c,2
+np.float64,0x3feaf0b27275e165,0xbfcfc8a03eaa32ad,2
+np.float64,0x5ce7503cb9ceb,0xc08ffbb2de365fa8,2
+np.float64,0x2a0014f654003,0xc090026e41761a0d,2
+np.float64,0x7fe2c848a8e59090,0x408ff9d9b723ee89,2
+np.float64,0x7f66f54bc02dea97,0x408fbc2ae0ec5623,2
+np.float64,0xa35a890146b6,0xc0900a97b358ddbd,2
+np.float64,0x7fee267ded7c4cfb,0x408fff501560c9f5,2
+np.float64,0x3fe07c328520f865,0xbfee9ef7c3435b58,2
+np.float64,0x3fe67122cf6ce246,0xbfe06147001932ba,2
+np.float64,0x3fdacc8925359912,0xbff41824cece219e,2
+np.float64,0xffa3047fff461,0xc08ff00431ec9be3,2
+np.float64,0x3e1af43e7c35f,0xc090002c6573d29b,2
+np.float64,0x86fa94590df53,0xc08ff7632525ed92,2
+np.float64,0x7fec4c76227898eb,0x408ffe94d032c657,2
+np.float64,0x7fe2274ce1e44e99,0x408ff975194cfdff,2
+np.float64,0x7fe670e1b4ace1c2,0x408ffbe78cc451de,2
+np.float64,0x7fe853871db0a70d,0x408ffcd5e6a6ff47,2
+np.float64,0x3fcbf265db37e4cc,0xc0019026336e1176,2
+np.float64,0x3fef033cef3e067a,0xbfa726712eaae7f0,2
+np.float64,0x5d74973abae94,0xc08ffba15e6bb992,2
+np.float64,0x7fdd9c99b6bb3932,0x408ff71ad24a7ae0,2
+np.float64,0xbdc8e09b7b91c,0xc08ff3744939e9a3,2
+np.float64,0xdbfcff71b7fa0,0xc08ff1bfeecc9dfb,2
+np.float64,0xf9b38cf5f3672,0xc08ff0499af34a43,2
+np.float64,0x3fea820aa6b50415,0xbfd162a38e1927b1,2
+np.float64,0x3fe67f59a12cfeb3,0xbfe04412adca49dc,2
+np.float64,0x3feb301d9c76603b,0xbfce17e6edeb92d5,2
+np.float64,0x828ce00b0519c,0xc08ff7c5b5c57cde,2
+np.float64,0x4f935e229f26c,0xc08ffd7c67c1c54f,2
+np.float64,0x7fcd139e023a273b,0x408feee4f12ff11e,2
+np.float64,0x666a9944ccd54,0xc08ffa92d5e5cd64,2
+np.float64,0x3fe792f0fa6f25e2,0xbfdc374fda28f470,2
+np.float64,0xe996029bd32c1,0xc08ff10eb9b47a11,2
+np.float64,0x3fe7b0dd1eef61ba,0xbfdbc2676dc77db0,2
+np.float64,0x7fd3ec0127a7d801,0x408ff287bf47e27d,2
+np.float64,0x3fe793a8ea6f2752,0xbfdc347f7717e48d,2
+np.float64,0x7fdb89d15e3713a2,0x408ff64457a13ea2,2
+np.float64,0x3fe35b3cbbe6b679,0xbfe73557c8321b70,2
+np.float64,0x66573c94ccae8,0xc08ffa9504af7eb5,2
+np.float64,0x3fc620a2302c4144,0xc00442036b944a67,2
+np.float64,0x49b2fe0693660,0xc08ffe5f131c3c7e,2
+np.float64,0x7fda936cdfb526d9,0x408ff5db3ab3f701,2
+np.float64,0xc774ceef8ee9a,0xc08ff2e16d082fa1,2
+np.float64,0x4da9f8a09b55,0xc0900ee2206d0c88,2
+np.float64,0x3fe2ca5d5ae594bb,0xbfe89406611a5f1a,2
+np.float64,0x7fe0832497e10648,0x408ff85d1de6056e,2
+np.float64,0x3fe6a9e3222d53c6,0xbfdfda35a9bc2de1,2
+np.float64,0x3fed3d92c8ba7b26,0xbfc0a73620db8b98,2
+np.float64,0x3fdd2ec093ba5d81,0xbff2209cf78ce3f1,2
+np.float64,0x62fcb968c5f98,0xc08ffaf775a593c7,2
+np.float64,0xfcfb019ff9f60,0xc08ff0230e95bd16,2
+np.float64,0x3fd7a63e8f2f4c7d,0xbff6faf4fff7dbe0,2
+np.float64,0x3fef23b0ec3e4762,0xbfa4230cb176f917,2
+np.float64,0x340d1e6a681a5,0xc09001314b68a0a2,2
+np.float64,0x7fc0b85ba02170b6,0x408fe8821487b802,2
+np.float64,0x7fe9976e84f32edc,0x408ffd6bb6aaf467,2
+np.float64,0x329a0e9e65343,0xc090015b044e3270,2
+np.float64,0x3fea4928d3f49252,0xbfd2299b05546eab,2
+np.float64,0x3f188c70003118e0,0xc02ac3ce23bc5d5a,2
+np.float64,0x3fecce5020b99ca0,0xbfc36b23153d5f50,2
+np.float64,0x3fe203873e24070e,0xbfea86edb3690830,2
+np.float64,0x3fe02d9eaa205b3d,0xbfef7d18c54a76d2,2
+np.float64,0xef7537ebdeea7,0xc08ff0c55e9d89e7,2
+np.float64,0x3fedf7572efbeeae,0xbfb840af357cf07c,2
+np.float64,0xd1a97a61a354,0xc0900926fdfb96cc,2
+np.float64,0x7fe6a0daeced41b5,0x408ffc001edf1407,2
+np.float64,0x3fe5063625aa0c6c,0xbfe3647cfb949d62,2
+np.float64,0x7fe9b28d31736519,0x408ffd77eb4a922b,2
+np.float64,0x7feea90d033d5219,0x408fff81a4bbff62,2
+np.float64,0x3fe9494d17f2929a,0xbfd5bde02eb5287a,2
+np.float64,0x7feee17a8cbdc2f4,0x408fff96cf0dc16a,2
+np.float64,0xb2ad18ef655a3,0xc08ff4267eda8af8,2
+np.float64,0x3fad3b52683a76a5,0xc01085ab75b797ce,2
+np.float64,0x2300a65846016,0xc090037b81ce9500,2
+np.float64,0x3feb1041f9b62084,0xbfcef0c87d8b3249,2
+np.float64,0x3fdd887d3e3b10fa,0xbff1da0e1ede6db2,2
+np.float64,0x3fd3e410eb27c822,0xbffaf9b5fc9cc8cc,2
+np.float64,0x3fe0aa53e3e154a8,0xbfee1e7b5c486578,2
+np.float64,0x7fe33e389aa67c70,0x408ffa214fe50961,2
+np.float64,0x3fd27e3a43a4fc75,0xbffca84a79e8adeb,2
+np.float64,0x3fb309e0082613c0,0xc00dfe407b77a508,2
+np.float64,0x7feaf2ed8cf5e5da,0x408ffe046a9d1ba9,2
+np.float64,0x1e76167a3cec4,0xc0900448cd35ec67,2
+np.float64,0x3fe0a18e1721431c,0xbfee36cf1165a0d4,2
+np.float64,0x3fa73b78c02e76f2,0xc011d9069823b172,2
+np.float64,0x3fef6d48287eda90,0xbf9ab2d08722c101,2
+np.float64,0x8fdf0da31fbe2,0xc08ff6a6a2accaa1,2
+np.float64,0x3fc3638db826c71b,0xc005c86191688826,2
+np.float64,0xaa9c09c555381,0xc08ff4aefe1d9473,2
+np.float64,0x7fccb0f4523961e8,0x408feebd84773f23,2
+np.float64,0xede75dcfdbcec,0xc08ff0d89ba887d1,2
+np.float64,0x7f8a051520340a29,0x408fcd9cc17f0d95,2
+np.float64,0x3fef5ca2babeb945,0xbf9dc221f3618e6a,2
+np.float64,0x7fea0ff4bcf41fe8,0x408ffda193359f22,2
+np.float64,0x7fe05c53fd20b8a7,0x408ff841dc7123e8,2
+np.float64,0x3fc625664b2c4acd,0xc0043f8749b9a1d8,2
+np.float64,0x7fed58f98f7ab1f2,0x408fff00585f48c2,2
+np.float64,0x3fb3e5e51427cbca,0xc00d7bcb6528cafe,2
+np.float64,0x3fe728bd3d6e517a,0xbfdddafa72bd0f60,2
+np.float64,0x3fe3f005dd27e00c,0xbfe5d7b3ec93bca0,2
+np.float64,0x3fd74fbd1a2e9f7a,0xbff750001b63ce81,2
+np.float64,0x3fd3af6d85a75edb,0xbffb371d678d11b4,2
+np.float64,0x7fa690ad8c2d215a,0x408fdbf7db9c7640,2
+np.float64,0x3fbdfd38e23bfa72,0xc008bfc1c5c9b89e,2
+np.float64,0x3fe2374684a46e8d,0xbfea030c4595dfba,2
+np.float64,0x7fc0806c372100d7,0x408fe85b36fee334,2
+np.float64,0x3fef3ac47b7e7589,0xbfa2007195c5213f,2
+np.float64,0x3fb55473922aa8e7,0xc00cae7af8230e0c,2
+np.float64,0x7fe018dc152031b7,0x408ff811e0d712fa,2
+np.float64,0x3fe3b3fca56767f9,0xbfe6638ae2c99c62,2
+np.float64,0x7fac79818c38f302,0x408fdea720b39c3c,2
+np.float64,0x7fefffffffffffff,0x4090000000000000,2
+np.float64,0xd2b290cba5652,0xc08ff23f6d7152a6,2
+np.float64,0x7fc5848eb52b091c,0x408feb6b6f8b77d0,2
+np.float64,0xf399f62de733f,0xc08ff092ae319ad8,2
+np.float64,0x7fdec56c12bd8ad7,0x408ff78c4ddbc667,2
+np.float64,0x3fca640f1e34c81e,0xc0023969c5cbfa4c,2
+np.float64,0x3fd55225db2aa44c,0xbff95f7442a2189e,2
+np.float64,0x7fefa009a97f4012,0x408fffdd2f42ef9f,2
+np.float64,0x4a3b70609478,0xc0900f24e449bc3d,2
+np.float64,0x7fe3738b1ba6e715,0x408ffa411f2cb5e7,2
+np.float64,0x7fe5e53f0b6bca7d,0x408ffb9ed8d95cea,2
+np.float64,0x3fe274dd24a4e9ba,0xbfe967fb114b2a83,2
+np.float64,0x3fcbc58b8c378b17,0xc001a2bb1e158bcc,2
+np.float64,0x3fefc2c0043f8580,0xbf862c9b464dcf38,2
+np.float64,0xc2c4fafd858a0,0xc08ff327aecc409b,2
+np.float64,0x3fd8bc39a9b17873,0xbff5f1ad46e5a51c,2
+np.float64,0x3fdf341656be682d,0xbff094f41e7cb4c4,2
+np.float64,0x3fef8495c13f092c,0xbf966cf6313bae4c,2
+np.float64,0x3fe14e0f05229c1e,0xbfec6166f26b7161,2
+np.float64,0x3fed42d3b2ba85a7,0xbfc0860b773d35d8,2
+np.float64,0x7fd92bbac5b25775,0x408ff53abcb3fe0c,2
+np.float64,0xb1635b6f62c6c,0xc08ff43bdf47accf,2
+np.float64,0x4a3a2dbc94746,0xc08ffe49fabddb36,2
+np.float64,0x87d831290fb06,0xc08ff750419dc6fb,2
+np.float64,0x3fec4713f7f88e28,0xbfc6d6217c9f5cf9,2
+np.float64,0x7fed43ba2d3a8773,0x408ffef7fa2fc303,2
+np.float64,0x7fd1ec5b56a3d8b6,0x408ff14f62615f1e,2
+np.float64,0x3fee534b6c7ca697,0xbfb3da1951aa3e68,2
+np.float64,0x3febb564c2b76aca,0xbfca9737062e55e7,2
+np.float64,0x943e6b0f287ce,0xc08ff64e2d09335c,2
+np.float64,0xf177d957e2efb,0xc08ff0acab2999fa,2
+np.float64,0x7fb5b881a82b7102,0x408fe3872b4fde5e,2
+np.float64,0x3fdb2b4a97b65695,0xbff3c715c91359bc,2
+np.float64,0x3fac0a17e4381430,0xc010c330967309fb,2
+np.float64,0x7fd8057990b00af2,0x408ff4b0a287a348,2
+np.float64,0x1f9026a23f206,0xc09004144f3a19dd,2
+np.float64,0x3fdb2977243652ee,0xbff3c8a2fd05803d,2
+np.float64,0x3fe0f6e74b21edcf,0xbfed4c3bb956bae0,2
+np.float64,0xde9cc3bbbd399,0xc08ff19ce5c1e762,2
+np.float64,0x3fe72ce106ae59c2,0xbfddca7ab14ceba2,2
+np.float64,0x3fa8ee14e031dc2a,0xc01170d54ca88e86,2
+np.float64,0x3fe0b09bbb216137,0xbfee0d189a95b877,2
+np.float64,0x7fdfdcb157bfb962,0x408ff7f33cf2afea,2
+np.float64,0x3fef84d5f53f09ac,0xbf966134e2a154f4,2
+np.float64,0x3fea0e0b1bb41c16,0xbfd2fa2d36637d19,2
+np.float64,0x1ab76fd6356ef,0xc090050a9616ffbd,2
+np.float64,0x7fd0ccf79a2199ee,0x408ff09045af2dee,2
+np.float64,0x7fea929345f52526,0x408ffddadc322b07,2
+np.float64,0x3fe9ef629cf3dec5,0xbfd367129c166838,2
+np.float64,0x3feedf0ea2fdbe1d,0xbfaa862afca44c00,2
+np.float64,0x7fce725f723ce4be,0x408fef6cfd2769a8,2
+np.float64,0x7fe4313b3ca86275,0x408ffaaf9557ef8c,2
+np.float64,0xe2d46463c5a8d,0xc08ff165725c6b08,2
+np.float64,0x7fbacb4ace359695,0x408fe5f3647bd0d5,2
+np.float64,0x3fbafd009635fa01,0xc009f745a7a5c5d5,2
+np.float64,0x3fe3cea66ce79d4d,0xbfe6253b895e2838,2
+np.float64,0x7feaa71484354e28,0x408ffde3c0bad2a6,2
+np.float64,0x3fd755b8b42eab71,0xbff74a1444c6e654,2
+np.float64,0x3fc313e2172627c4,0xc005f830e77940c3,2
+np.float64,0x12d699a225ad4,0xc090070ec00f2338,2
+np.float64,0x3fa975fe8432ebfd,0xc01151b3da48b3f9,2
+np.float64,0x7fdce3103b39c61f,0x408ff6d19b3326fa,2
+np.float64,0x7fd341cbba268396,0x408ff2237490fdca,2
+np.float64,0x3fd8405885b080b1,0xbff6666d8802a7d5,2
+np.float64,0x3fe0f0cca3a1e199,0xbfed5cdb3e600791,2
+np.float64,0x7fbd56680c3aaccf,0x408fe6ff55bf378d,2
+np.float64,0x3f939c4f3027389e,0xc016d364dd6313fb,2
+np.float64,0x3fe9e87fac73d0ff,0xbfd37f9a2be4fe38,2
+np.float64,0x7fc93c6a883278d4,0x408fed4260e614f1,2
+np.float64,0x7fa88c0ff031181f,0x408fdcf09a46bd3a,2
+np.float64,0xd5487f99aa910,0xc08ff21b6390ab3b,2
+np.float64,0x3fe34acc96e69599,0xbfe75c9d290428fb,2
+np.float64,0x3fd17f5964a2feb3,0xbffdef50b524137b,2
+np.float64,0xe23dec0dc47be,0xc08ff16d1ce61dcb,2
+np.float64,0x3fec8bd64fb917ad,0xbfc5173941614b8f,2
+np.float64,0x3fc81d97d7303b30,0xc00343ccb791401d,2
+np.float64,0x7fe79ad18e2f35a2,0x408ffc7cf0ab0f2a,2
+np.float64,0x3f96306b402c60d7,0xc0161ce54754cac1,2
+np.float64,0xfb09fc97f6140,0xc08ff039d1d30123,2
+np.float64,0x3fec9c4afa793896,0xbfc4ace43ee46079,2
+np.float64,0x3f9262dac824c5b6,0xc01732a3a7eeb598,2
+np.float64,0x3fa5cd33f42b9a68,0xc01236ed4d315a3a,2
+np.float64,0x3fe7bb336caf7667,0xbfdb9a268a82e267,2
+np.float64,0xc6c338f98d867,0xc08ff2ebb8475bbc,2
+np.float64,0x3fd50714482a0e29,0xbff9b14a9f84f2c2,2
+np.float64,0xfff0000000000000,0x7ff8000000000000,2
+np.float64,0x3fde2cd0f93c59a2,0xbff15afe35a43a37,2
+np.float64,0xf1719cb9e2e34,0xc08ff0acf77b06d3,2
+np.float64,0xfd3caaf9fa796,0xc08ff020101771bd,2
+np.float64,0x7f750d63a02a1ac6,0x408fc32ad0caa362,2
+np.float64,0x7fcc50f4e238a1e9,0x408fee96a5622f1a,2
+np.float64,0x421d1da0843a4,0xc08fff9ffe62d869,2
+np.float64,0x3fd9e17023b3c2e0,0xbff4e631d687ee8e,2
+np.float64,0x3fe4999a09693334,0xbfe4556b3734c215,2
+np.float64,0xd619ef03ac33e,0xc08ff21013c85529,2
+np.float64,0x3fc4da522229b4a4,0xc004f150b2c573aa,2
+np.float64,0x3feb04b053b60961,0xbfcf3fc9e00ebc40,2
+np.float64,0x3fbedec5ea3dbd8c,0xc0086a33dc22fab5,2
+np.float64,0x7fec3b217ab87642,0x408ffe8dbc8ca041,2
+np.float64,0xdb257d33b64b0,0xc08ff1cb42d3c182,2
+np.float64,0x7fa2d92ec025b25d,0x408fd9e414d11cb0,2
+np.float64,0x3fa425c550284b8b,0xc012ab7cbf83be12,2
+np.float64,0x10b4869021692,0xc09007c0487d648a,2
+np.float64,0x7f97918c902f2318,0x408fd47867806574,2
+np.float64,0x3fe4f91238e9f224,0xbfe38160b4e99919,2
+np.float64,0x3fc2b1af6125635f,0xc00634343bc58461,2
+np.float64,0x3fc2a98071255301,0xc0063942bc8301be,2
+np.float64,0x3fe4cfc585299f8b,0xbfe3dca39f114f34,2
+np.float64,0x3fd1ea75b3a3d4eb,0xbffd63acd02c5406,2
+np.float64,0x3fd6bf48492d7e91,0xbff7e0cd249f80f9,2
+np.float64,0x76643d36ecc88,0xc08ff8e68f13b38c,2
+np.float64,0x7feeabab3e7d5755,0x408fff82a0fd4501,2
+np.float64,0x46c0d4a68d81b,0xc08ffed79abaddc9,2
+np.float64,0x3fd088d57ca111ab,0xbfff3dd0ed7128ea,2
+np.float64,0x3fed25887cba4b11,0xbfc13f47639bd645,2
+np.float64,0x7fd90984b4b21308,0x408ff52b022c7fb4,2
+np.float64,0x3fe6ef31daadde64,0xbfdec185760cbf21,2
+np.float64,0x3fe48dbe83291b7d,0xbfe47005b99920bd,2
+np.float64,0x3fdce8422f39d084,0xbff258a33a96cc8e,2
+np.float64,0xb8ecdef771d9c,0xc08ff3c0eca61b10,2
+np.float64,0x3fe9bbf9a03377f3,0xbfd41ecfdcc336b9,2
+np.float64,0x7fe2565339a4aca5,0x408ff992d8851eaf,2
+np.float64,0x3fe1693e3822d27c,0xbfec1919da2ca697,2
+np.float64,0x3fd3680488a6d009,0xbffb8b7330275947,2
+np.float64,0x7fbe4f3d2c3c9e79,0x408fe75fa3f4e600,2
+np.float64,0x7fd4cfef3ca99fdd,0x408ff308ee3ab50f,2
+np.float64,0x3fd9c9a51cb3934a,0xbff4fb7440055ce6,2
+np.float64,0x3fe08a9640a1152d,0xbfee76bd1bfbf5c2,2
+np.float64,0x3fef012c41fe0259,0xbfa757a2da7f9707,2
+np.float64,0x3fee653fe2fcca80,0xbfb2ffae0c95025c,2
+np.float64,0x7fd0776933a0eed1,0x408ff054e7b43d41,2
+np.float64,0x4c94e5c09929d,0xc08ffdedb7f49e5e,2
+np.float64,0xca3e3d17947c8,0xc08ff2b86dce2f7a,2
+np.float64,0x3fb528e1342a51c2,0xc00cc626c8e2d9ba,2
+np.float64,0xd774df81aee9c,0xc08ff1fd6f0a7548,2
+np.float64,0x3fc47a9b6128f537,0xc00526c577b80849,2
+np.float64,0x3fe29a6f6a6534df,0xbfe90a5f83644911,2
+np.float64,0x3fecda4f59f9b49f,0xbfc31e4a80c4cbb6,2
+np.float64,0x7fe51d44f5aa3a89,0x408ffb3382437426,2
+np.float64,0x3fd677fc412ceff9,0xbff82999086977e7,2
+np.float64,0x3fe2a3c7e7254790,0xbfe8f33415cdba9d,2
+np.float64,0x3fe6d8d1dc6db1a4,0xbfdf1bc61bc24dff,2
+np.float64,0x7febb32d8ef7665a,0x408ffe55a043ded1,2
+np.float64,0x60677860c0d0,0xc0900da2caa7d571,2
+np.float64,0x7390c2e0e7219,0xc08ff92df18bb5d2,2
+np.float64,0x3fca53711b34a6e2,0xc00240b07a9b529b,2
+np.float64,0x7fe7ce6dd8ef9cdb,0x408ffc961164ead9,2
+np.float64,0x7fc0c9de0d2193bb,0x408fe88e245767f6,2
+np.float64,0xc0ee217981dc4,0xc08ff343b77ea770,2
+np.float64,0x72bd4668e57a9,0xc08ff94323fd74fc,2
+np.float64,0x7fd6970e252d2e1b,0x408ff3fb1e2fead2,2
+np.float64,0x7fdcb61040396c20,0x408ff6bf926bc98f,2
+np.float64,0xda4faa25b49f6,0xc08ff1d68b3877f0,2
+np.float64,0x3feb344749f6688f,0xbfcdfba2d66c72c5,2
+np.float64,0x3fe2aa4284e55485,0xbfe8e32ae0683f57,2
+np.float64,0x3f8e8fcfd03d1fa0,0xc01843efb2129908,2
+np.float64,0x8000000000000000,0xfff0000000000000,2
+np.float64,0x3fd8e01155b1c023,0xbff5d0529dae9515,2
+np.float64,0x3fe8033f3370067e,0xbfda837c80b87e7c,2
+np.float64,0x7fc5bf831e2b7f05,0x408feb8ae3b039a0,2
+np.float64,0x3fd8dcdf5331b9bf,0xbff5d349e1ed422a,2
+np.float64,0x3fe58b4e302b169c,0xbfe243c9cbccde44,2
+np.float64,0x3fea8a2e47b5145d,0xbfd1464e37221894,2
+np.float64,0x75cd1e88eb9a4,0xc08ff8f553ef0475,2
+np.float64,0x7fcfc876e23f90ed,0x408fefebe6cc95e6,2
+np.float64,0x7f51aceb002359d5,0x408fb1263f9003fb,2
+np.float64,0x7fc2a1b877254370,0x408fe9c1ec52f8b9,2
+np.float64,0x7fd495810e292b01,0x408ff2e859414d31,2
+np.float64,0x7fd72048632e4090,0x408ff440690cebdb,2
+np.float64,0x7fd7aafaffaf6,0xc08ff803a390779f,2
+np.float64,0x7fe18067d4a300cf,0x408ff9090a02693f,2
+np.float64,0x3fdc1080f8b82102,0xbff3077bf44a89bd,2
+np.float64,0x3fc34a462f26948c,0xc005d777b3cdf139,2
+np.float64,0x3fe21e4a1fe43c94,0xbfea428acfbc6ea9,2
+np.float64,0x1f0d79083e1b0,0xc090042c65a7abf2,2
+np.float64,0x3fe8d0d15931a1a3,0xbfd779f6bbd4db78,2
+np.float64,0x3fe74578022e8af0,0xbfdd68b6c15e9f5e,2
+np.float64,0x50995dd0a132c,0xc08ffd56a5c8accf,2
+np.float64,0x3f9a6342b034c685,0xc0151ce1973c62bd,2
+np.float64,0x3f30856a00210ad4,0xc027e852f4d1fcbc,2
+np.float64,0x3febcf7646b79eed,0xbfc9e9cc9d12425c,2
+np.float64,0x8010000000000000,0x7ff8000000000000,2
+np.float64,0x3fdf520c02bea418,0xbff07ed5013f3062,2
+np.float64,0x3fe5433ecbea867e,0xbfe2df38968b6d14,2
+np.float64,0x3fb933a84e326751,0xc00ac1a144ad26c5,2
+np.float64,0x7b6d72c2f6daf,0xc08ff86b7a67f962,2
+np.float64,0xaef5dae75debc,0xc08ff46496bb2932,2
+np.float64,0x522d869aa45b1,0xc08ffd1d55281e98,2
+np.float64,0xa2462b05448c6,0xc08ff542fe0ac5fd,2
+np.float64,0x3fe2b71dd6e56e3c,0xbfe8c3690cf15415,2
+np.float64,0x3fe5778231aaef04,0xbfe26e495d09b783,2
+np.float64,0x3fe9b8d564f371ab,0xbfd42a161132970d,2
+np.float64,0x3f89ebc34033d787,0xc019373f90bfc7f1,2
+np.float64,0x3fe438ddc6e871bc,0xbfe53039341b0a93,2
+np.float64,0x873c75250e78f,0xc08ff75d8478dccd,2
+np.float64,0x807134cb00e27,0xc08ff7f5cf59c57a,2
+np.float64,0x3fac459878388b31,0xc010b6fe803bcdc2,2
+np.float64,0xca9dc7eb953b9,0xc08ff2b2fb480784,2
+np.float64,0x7feb38587bb670b0,0x408ffe21ff6d521e,2
+np.float64,0x7fd70e9b782e1d36,0x408ff437936b393a,2
+np.float64,0x3fa4037bbc2806f7,0xc012b55744c65ab2,2
+np.float64,0x3fd3d4637427a8c7,0xbffb0beebf4311ef,2
+np.float64,0x7fdabbda5db577b4,0x408ff5ecbc0d4428,2
+np.float64,0x7fda9be0a2b537c0,0x408ff5dee5d03d5a,2
+np.float64,0x7fe9c74396338e86,0x408ffd813506a18a,2
+np.float64,0x3fd058243e20b048,0xbfff822ffd8a7f21,2
+np.float64,0x3fe6aa6ca9ed54d9,0xbfdfd805629ff49e,2
+np.float64,0x3fd91431d5322864,0xbff5a025eea8c78b,2
+np.float64,0x7fe4d7f02329afdf,0x408ffb0d5d9b7878,2
+np.float64,0x3fe2954a12252a94,0xbfe917266e3e22d5,2
+np.float64,0x3fb25f7c8224bef9,0xc00e6764c81b3718,2
+np.float64,0x3fda4bddeeb497bc,0xbff4880638908c81,2
+np.float64,0x55dfd12eabbfb,0xc08ffc9b54ff4002,2
+np.float64,0x3fe8f399e031e734,0xbfd6f8e5c4dcd93f,2
+np.float64,0x3fd954a24832a945,0xbff56521f4707a06,2
+np.float64,0x3fdea911f2bd5224,0xbff0fcb2d0c2b2e2,2
+np.float64,0x3fe6b4ff8a2d69ff,0xbfdfacfc85cafeab,2
+np.float64,0x3fc7fa02042ff404,0xc00354e13b0767ad,2
+np.float64,0x3fe955088c72aa11,0xbfd593130f29949e,2
+np.float64,0xd7e74ec1afcea,0xc08ff1f74f61721c,2
+np.float64,0x3fe9d69c1ab3ad38,0xbfd3bf710a337e06,2
+np.float64,0x3fd85669a2b0acd3,0xbff65176143ccc1e,2
+np.float64,0x3fea99b285353365,0xbfd11062744783f2,2
+np.float64,0x3fe2c79f80a58f3f,0xbfe89ac33f990289,2
+np.float64,0x3f8332ba30266574,0xc01af2cb7b635783,2
+np.float64,0x30d0150061a1,0xc090119030f74c5d,2
+np.float64,0x3fdbf4cb06b7e996,0xbff31e5207aaa754,2
+np.float64,0x3fe6b56c216d6ad8,0xbfdfab42fb2941c5,2
+np.float64,0x7fc4dc239829b846,0x408feb0fb0e13fbe,2
+np.float64,0x3fd0ab85ef21570c,0xbfff0d95d6c7a35c,2
+np.float64,0x7fe13d75e5e27aeb,0x408ff8dc8efa476b,2
+np.float64,0x3fece3b832f9c770,0xbfc2e21b165d583f,2
+np.float64,0x3fe3a279c4e744f4,0xbfe68ca4fbb55dbf,2
+np.float64,0x3feb64659ef6c8cb,0xbfccb6204b6bf724,2
+np.float64,0x2279a6bc44f36,0xc0900391eeeb3e7c,2
+np.float64,0xb88046d571009,0xc08ff3c7b5b45300,2
+np.float64,0x7ff4000000000000,0x7ffc000000000000,2
+np.float64,0x3fe49af059a935e1,0xbfe4526c294f248f,2
+np.float64,0xa3e5508147cc,0xc0900a92ce5924b1,2
+np.float64,0x7fc56def3d2adbdd,0x408feb5f46c360e8,2
+np.float64,0x7fd99f3574333e6a,0x408ff56f3807987c,2
+np.float64,0x3fdc38d56fb871ab,0xbff2e667cad8f36a,2
+np.float64,0xd0b03507a1607,0xc08ff25bbcf8aa9d,2
+np.float64,0xc493f9078927f,0xc08ff30c5fa4e759,2
+np.float64,0x3fc86ddbcb30dbb8,0xc0031da1fcb56d75,2
+np.float64,0x7fe75dc395aebb86,0x408ffc5eef841491,2
+np.float64,0x1647618a2c8ed,0xc0900616ef9479c1,2
+np.float64,0xdf144763be289,0xc08ff196b527f3c9,2
+np.float64,0x3fe0b29da6a1653b,0xbfee078b5f4d7744,2
+np.float64,0x3feb055852b60ab1,0xbfcf3b4db5779a7a,2
+np.float64,0x3fe8bc1625f1782c,0xbfd7c739ade904bc,2
+np.float64,0x7fd19bfb8ea337f6,0x408ff11b2b55699c,2
+np.float64,0x3fed1d80d1ba3b02,0xbfc1722e8d3ce094,2
+np.float64,0x2d9c65925b38e,0xc09001f46bcd3bc5,2
+np.float64,0x7fed6f4d857ade9a,0x408fff091cf6a3b4,2
+np.float64,0x3fd070cd6ba0e19b,0xbfff5f7609ca29e8,2
+np.float64,0x7fea3508b8f46a10,0x408ffdb1f30bd6be,2
+np.float64,0x508b897ca1172,0xc08ffd58a0eb3583,2
+np.float64,0x7feba367b07746ce,0x408ffe4f0bf4bd4e,2
+np.float64,0x3fefebd5c4bfd7ac,0xbf6d20b4fcf21b69,2
+np.float64,0x3fd8ef07b8b1de0f,0xbff5c2745c0795a5,2
+np.float64,0x3fd38ed518271daa,0xbffb5d75f00f6900,2
+np.float64,0x6de0fecedbc20,0xc08ff9c307bbc647,2
+np.float64,0xafc0ffc35f820,0xc08ff45737e5d6b4,2
+np.float64,0x7fd282097ca50412,0x408ff1ae3b27bf3b,2
+np.float64,0x3fe2f2d50b65e5aa,0xbfe831042e6a1e99,2
+np.float64,0x3faa437bac3486f7,0xc01123d8d962205a,2
+np.float64,0x3feea54434fd4a88,0xbfaff202cc456647,2
+np.float64,0x3fc9e65b8633ccb7,0xc00270e77ffd19da,2
+np.float64,0x7fee15af61fc2b5e,0x408fff49a49154a3,2
+np.float64,0x7fefe670a73fcce0,0x408ffff6c44c1005,2
+np.float64,0x3fc0832d0f21065a,0xc007a2dc2f25384a,2
+np.float64,0x3fecfc96bcb9f92d,0xbfc24367c3912620,2
+np.float64,0x3feb705682b6e0ad,0xbfcc65b1bb16f9c5,2
+np.float64,0x3fe185c4f9630b8a,0xbfebcdb401af67a4,2
+np.float64,0x3fb0a5a9f6214b54,0xc00f8ada2566a047,2
+np.float64,0x7fe2908cdda52119,0x408ff9b744861fb1,2
+np.float64,0x7fee776e183ceedb,0x408fff6ee7c2f86e,2
+np.float64,0x3fce1d608f3c3ac1,0xc000b3685d006474,2
+np.float64,0x7fecf92aa339f254,0x408ffeda6c998267,2
+np.float64,0xce13cb519c27a,0xc08ff280f02882a9,2
+np.float64,0x1,0xc090c80000000000,2
+np.float64,0x3fe485a8afa90b51,0xbfe4823265d5a50a,2
+np.float64,0x3feea60908bd4c12,0xbfafdf7ad7fe203f,2
+np.float64,0x3fd2253033a44a60,0xbffd187d0ec8d5b9,2
+np.float64,0x435338fc86a68,0xc08fff6a591059dd,2
+np.float64,0x7fce8763a73d0ec6,0x408fef74f1e715ff,2
+np.float64,0x3fbe5ddb783cbbb7,0xc0089acc5afa794b,2
+np.float64,0x7fe4cf19ada99e32,0x408ffb0877ca302b,2
+np.float64,0x3fe94c9ea1b2993d,0xbfd5b1c2e867b911,2
+np.float64,0x3fe75541c72eaa84,0xbfdd2a27aa117699,2
+np.float64,0x8000000000000001,0x7ff8000000000000,2
+np.float64,0x7fdbec7f2c37d8fd,0x408ff66d69a7f818,2
+np.float64,0x8ef10d091de22,0xc08ff6b9ca5094f8,2
+np.float64,0x3fea69025b74d205,0xbfd1b9fe2c252c70,2
+np.float64,0x562376d0ac46f,0xc08ffc924111cd31,2
+np.float64,0x8e8097ab1d013,0xc08ff6c2e2706f67,2
+np.float64,0x3fca6803ed34d008,0xc00237aef808825b,2
+np.float64,0x7fe8fe9067b1fd20,0x408ffd25f459a7d1,2
+np.float64,0x3f918e8c7f233,0xc0900009fe011d54,2
+np.float64,0x3fdfe773833fcee7,0xbff011bc1af87bb9,2
+np.float64,0xefffef6fdfffe,0xc08ff0beb0f09eb0,2
+np.float64,0x7fe64610282c8c1f,0x408ffbd17209db18,2
+np.float64,0xe66be8c1ccd7d,0xc08ff13706c056e1,2
+np.float64,0x2837e570506fd,0xc09002ae4dae0c1a,2
+np.float64,0x3febe3a081f7c741,0xbfc964171f2a5a47,2
+np.float64,0x3fe21ed09a243da1,0xbfea41342d29c3ff,2
+np.float64,0x3fe1596c8162b2d9,0xbfec431eee30823a,2
+np.float64,0x8f2b9a131e574,0xc08ff6b51104ed4e,2
+np.float64,0x3fe88ed179711da3,0xbfd870d08a4a4b0c,2
+np.float64,0x34159bc2682b4,0xc09001305a885f94,2
+np.float64,0x1ed31e543da65,0xc0900437481577f8,2
+np.float64,0x3feafbe9de75f7d4,0xbfcf7bcdbacf1c61,2
+np.float64,0xfb16fb27f62e0,0xc08ff03938e682a2,2
+np.float64,0x3fe5cd5ba7eb9ab7,0xbfe1b7165771af3c,2
+np.float64,0x7fe72905e76e520b,0x408ffc44c4e7e80c,2
+np.float64,0x7fb7136e2e2e26db,0x408fe439fd383fb7,2
+np.float64,0x8fa585e11f4c,0xc0900b55a08a486b,2
+np.float64,0x7fed985ce47b30b9,0x408fff192b596821,2
+np.float64,0x3feaaf0869755e11,0xbfd0c671571b3764,2
+np.float64,0x3fa40fd4ec281faa,0xc012b1c8dc0b9e5f,2
+np.float64,0x7fda2a70993454e0,0x408ff5ad47b0c68a,2
+np.float64,0x3fe5f7e931abefd2,0xbfe15d52b3605abf,2
+np.float64,0x3fe9fc6d3533f8da,0xbfd338b06a790994,2
+np.float64,0x3fe060649420c0c9,0xbfeeed1756111891,2
+np.float64,0x3fce8435e33d086c,0xc0008c41cea9ed40,2
+np.float64,0x7ff8000000000000,0x7ff8000000000000,2
+np.float64,0x617820aec2f05,0xc08ffb251e9af0f0,2
+np.float64,0x7fcc4ab6ee38956d,0x408fee9419c8f77d,2
+np.float64,0x7fdefda2fc3dfb45,0x408ff7a15063bc05,2
+np.float64,0x7fe5138ccaaa2719,0x408ffb2e30f3a46e,2
+np.float64,0x3fe3817a836702f5,0xbfe6da7c2b25e35a,2
+np.float64,0x3fb8a7dafa314fb6,0xc00b025bc0784ebe,2
+np.float64,0x349dc420693d,0xc09011215825d2c8,2
+np.float64,0x6b0e504ad61cb,0xc08ffa0fee9c5cd6,2
+np.float64,0x273987644e732,0xc09002d34294ed79,2
+np.float64,0x3fc0bd8a6e217b15,0xc0077a5828b4d2f5,2
+np.float64,0x758b48c4eb16a,0xc08ff8fbc8fbe46a,2
+np.float64,0x3fc8a9a52631534a,0xc00301854ec0ef81,2
+np.float64,0x7fe79d29a76f3a52,0x408ffc7e1607a4c1,2
+np.float64,0x3fd7d3ebce2fa7d8,0xbff6ce8a94aebcda,2
+np.float64,0x7fd1cb68a52396d0,0x408ff13a17533b2b,2
+np.float64,0x7fda514a5d34a294,0x408ff5be5e081578,2
+np.float64,0x3fc40b4382281687,0xc0056632c8067228,2
+np.float64,0x7feff1208c3fe240,0x408ffffaa180fa0d,2
+np.float64,0x8f58739f1eb0f,0xc08ff6b17402689d,2
+np.float64,0x1fdbe9a23fb7e,0xc090040685b2d24f,2
+np.float64,0xcb1d0e87963a2,0xc08ff2abbd903b82,2
+np.float64,0x3fc45a6a1a28b4d4,0xc00538f86c4aeaee,2
+np.float64,0x3fe61885b1ac310b,0xbfe118fd2251d2ec,2
+np.float64,0x3fedf584c8fbeb0a,0xbfb8572433ff67a9,2
+np.float64,0x7fb0bddd1a217bb9,0x408fe085e0d621db,2
+np.float64,0x72d8d3e0e5b3,0xc0900ca02f68c7a1,2
+np.float64,0x5cca6ff6b994f,0xc08ffbb6751fda01,2
+np.float64,0x7fe3197839a632ef,0x408ffa0b2fccfb68,2
+np.float64,0x3fcce4d9c139c9b4,0xc0012dae05baa91b,2
+np.float64,0x3fe76d00f62eda02,0xbfdccc5f12799be1,2
+np.float64,0x3fc53c22f72a7846,0xc004bbaa9cbc7958,2
+np.float64,0x7fdda02f1ebb405d,0x408ff71c37c71659,2
+np.float64,0x3fe0844eaba1089d,0xbfee884722762583,2
+np.float64,0x3febb438dc776872,0xbfca9f05e1c691f1,2
+np.float64,0x3fdf4170cdbe82e2,0xbff08b1561c8d848,2
+np.float64,0x3fce1b8d6f3c371b,0xc000b41b69507671,2
+np.float64,0x8370e60706e1d,0xc08ff7b19ea0b4ca,2
+np.float64,0x7fa5bf92382b7f23,0x408fdb8aebb3df87,2
+np.float64,0x7fe4a59979a94b32,0x408ffaf15c1358cd,2
+np.float64,0x3faa66086034cc11,0xc0111c466b7835d6,2
+np.float64,0x7fb7a958262f52af,0x408fe48408b1e093,2
+np.float64,0x3fdaacc5f635598c,0xbff43390d06b5614,2
+np.float64,0x3fd2825b9e2504b7,0xbffca3234264f109,2
+np.float64,0x3fcede160a3dbc2c,0xc0006a759e29060c,2
+np.float64,0x7fd3b19603a7632b,0x408ff265b528371c,2
+np.float64,0x7fcf8a86ea3f150d,0x408fefd552e7f3b2,2
+np.float64,0xedbcc0f7db798,0xc08ff0daad12096b,2
+np.float64,0xf1e1683de3c2d,0xc08ff0a7a0a37e00,2
+np.float64,0xb6ebd9bf6dd7b,0xc08ff3e11e28378d,2
+np.float64,0x3fec8090d6f90122,0xbfc56031b72194cc,2
+np.float64,0x3fd3e10e37a7c21c,0xbffafd34a3ebc933,2
+np.float64,0x7fbb1c96aa36392c,0x408fe616347b3342,2
+np.float64,0x3fe2f3996f25e733,0xbfe82f25bc5d1bbd,2
+np.float64,0x7fe8709da870e13a,0x408ffce3ab6ce59a,2
+np.float64,0x7fea3233d1b46467,0x408ffdb0b3bbc6de,2
+np.float64,0x65fa4112cbf49,0xc08ffa9f85eb72b9,2
+np.float64,0x3fca2cae9f34595d,0xc00251bb275afb87,2
+np.float64,0x8135fd9f026c0,0xc08ff7e42e14dce7,2
+np.float64,0x7fe0a6f057e14de0,0x408ff876081a4bfe,2
+np.float64,0x10000000000000,0xc08ff00000000000,2
+np.float64,0x3fe1fd506263faa1,0xbfea96dd8c543b72,2
+np.float64,0xa5532c554aa66,0xc08ff50bf5bfc66d,2
+np.float64,0xc239d00b8473a,0xc08ff32ff0ea3f92,2
+np.float64,0x7fdb5314e336a629,0x408ff62d4ff60d82,2
+np.float64,0x3fe5f506e2abea0e,0xbfe16362a4682120,2
+np.float64,0x3fa20c60202418c0,0xc0134e08d82608b6,2
+np.float64,0x7fe03864b22070c8,0x408ff82866d65e9a,2
+np.float64,0x3fe72cf5656e59eb,0xbfddca298969effa,2
+np.float64,0x5c295386b852b,0xc08ffbca90b136c9,2
+np.float64,0x7fd71e5020ae3c9f,0x408ff43f6d58eb7c,2
+np.float64,0x3fd1905a842320b5,0xbffdd8ecd288159c,2
+np.float64,0x3fe6bddb256d7bb6,0xbfdf88fee1a820bb,2
+np.float64,0xe061b967c0c37,0xc08ff18581951561,2
+np.float64,0x3fe534f65cea69ed,0xbfe2fe45fe7d3040,2
+np.float64,0xdc7dae07b8fb6,0xc08ff1b93074ea76,2
+np.float64,0x3fd0425082a084a1,0xbfffa11838b21633,2
+np.float64,0xba723fc974e48,0xc08ff3a8b8d01c58,2
+np.float64,0x3fce42ffc73c8600,0xc000a5062678406e,2
+np.float64,0x3f2e6d3c7e5ce,0xc090001304cfd1c7,2
+np.float64,0x3fd4b2e5f7a965cc,0xbffa0e6e6bae0a68,2
+np.float64,0x3fe6db1d18edb63a,0xbfdf128158ee92d9,2
+np.float64,0x7fe4e5792f29caf1,0x408ffb14d9dbf133,2
+np.float64,0x3fc11cdf992239bf,0xc00739569619cd77,2
+np.float64,0x3fc05ea11220bd42,0xc007bc841b48a890,2
+np.float64,0x4bd592d497ab3,0xc08ffe0ab1c962e2,2
+np.float64,0x280068fc5000e,0xc09002b64955e865,2
+np.float64,0x7fe2f2637065e4c6,0x408ff9f379c1253a,2
+np.float64,0x3fefc38467ff8709,0xbf85e53e64b9a424,2
+np.float64,0x2d78ec5a5af1e,0xc09001f8ea8601e0,2
+np.float64,0x7feeef2b957dde56,0x408fff9bebe995f7,2
+np.float64,0x2639baf44c738,0xc09002f9618d623b,2
+np.float64,0x3fc562964d2ac52d,0xc004a6d76959ef78,2
+np.float64,0x3fe21b071fe4360e,0xbfea4adb2cd96ade,2
+np.float64,0x7fe56aa6802ad54c,0x408ffb5d81d1a898,2
+np.float64,0x4296b452852d7,0xc08fff8ad7fbcbe1,2
+np.float64,0x7fe3fac4ff27f589,0x408ffa9049eec479,2
+np.float64,0x7fe7a83e6caf507c,0x408ffc837f436604,2
+np.float64,0x3fc4ac5b872958b7,0xc0050add72381ac3,2
+np.float64,0x3fd6d697c02dad30,0xbff7c931a3eefb01,2
+np.float64,0x3f61e391c023c724,0xc021ad91e754f94b,2
+np.float64,0x10817f9c21031,0xc09007d20434d7bc,2
+np.float64,0x3fdb9c4c4cb73899,0xbff367d8615c5ece,2
+np.float64,0x3fe26ead6b64dd5b,0xbfe977771def5989,2
+np.float64,0x3fc43ea5c3287d4c,0xc00548c2163ae631,2
+np.float64,0x3fe05bd8bba0b7b1,0xbfeef9ea0db91abc,2
+np.float64,0x3feac78369358f07,0xbfd071e2b0aeab39,2
+np.float64,0x7fe254922ca4a923,0x408ff991bdd4e5d3,2
+np.float64,0x3fe5a2f5842b45eb,0xbfe21135c9a71666,2
+np.float64,0x3fd5daf98c2bb5f3,0xbff8cd24f7c07003,2
+np.float64,0x3fcb2a1384365427,0xc001e40f0d04299a,2
+np.float64,0x3fe073974360e72f,0xbfeeb7183a9930b7,2
+np.float64,0xcf3440819e688,0xc08ff270d3a71001,2
+np.float64,0x3fd35656cda6acae,0xbffba083fba4939d,2
+np.float64,0x7fe6c59b4ded8b36,0x408ffc12ce725425,2
+np.float64,0x3fba896f943512df,0xc00a291cb6947701,2
+np.float64,0x7fe54917e86a922f,0x408ffb4b5e0fb848,2
+np.float64,0x7fed2a3f51ba547e,0x408ffeede945a948,2
+np.float64,0x3fdc72bd5038e57b,0xbff2b73b7e93e209,2
+np.float64,0x7fefdb3f9f3fb67e,0x408ffff2b702a768,2
+np.float64,0x3fb0184430203088,0xc00fee8c1351763c,2
+np.float64,0x7d6c3668fad87,0xc08ff83c195f2cca,2
+np.float64,0x3fd5aa254aab544b,0xbff900f16365991b,2
+np.float64,0x3f963daab02c7b55,0xc0161974495b1b71,2
+np.float64,0x3fa7a9c5982f538b,0xc011bde0f6052a89,2
+np.float64,0xb3a5a74b674b5,0xc08ff4167bc97c81,2
+np.float64,0x7fad0c14503a1828,0x408fdee1f2d56cd7,2
+np.float64,0x43e0e9d887c1e,0xc08fff522837b13b,2
+np.float64,0x3fe513b20aea2764,0xbfe346ea994100e6,2
+np.float64,0x7fe4e10393e9c206,0x408ffb12630f6a06,2
+np.float64,0x68b286e2d1651,0xc08ffa51c0d795d4,2
+np.float64,0x7fe8de453331bc89,0x408ffd17012b75ac,2
+np.float64,0x1b3d77d4367b0,0xc09004edea60aa36,2
+np.float64,0x3fd351cbc326a398,0xbffba5f0f4d5fdba,2
+np.float64,0x3fd264951b24c92a,0xbffcc8636788b9bf,2
+np.float64,0xd2465761a48cb,0xc08ff2455c9c53e5,2
+np.float64,0x7fe46a0ef028d41d,0x408ffacfe32c6f5d,2
+np.float64,0x3fafd8ac4c3fb159,0xc010071bf33195d0,2
+np.float64,0x902aec5d2055e,0xc08ff6a08e28aabc,2
+np.float64,0x3fcea61bb03d4c37,0xc0007f76e509b657,2
+np.float64,0x7fe8d90f9571b21e,0x408ffd1495f952e7,2
+np.float64,0x7fa650c9442ca192,0x408fdbd6ff22fdd8,2
+np.float64,0x3fe8ecfdf171d9fc,0xbfd7115df40e8580,2
+np.float64,0x7fd4e6fe7f29cdfc,0x408ff315b0dae183,2
+np.float64,0x77df4c52efbea,0xc08ff8c1d5c1df33,2
+np.float64,0xe200b0cfc4016,0xc08ff1703cfb8e79,2
+np.float64,0x3fe230ea7e2461d5,0xbfea132d2385160e,2
+np.float64,0x7fd1f7ced723ef9d,0x408ff156bfbf92a4,2
+np.float64,0x3fea762818f4ec50,0xbfd18c12a88e5f79,2
+np.float64,0x7feea4ba7c7d4974,0x408fff8004164054,2
+np.float64,0x833ec605067d9,0xc08ff7b606383841,2
+np.float64,0x7fd0c2d7fea185af,0x408ff0894f3a0cf4,2
+np.float64,0x3fe1d7d61d23afac,0xbfeaf76fee875d3e,2
+np.float64,0x65adecb0cb5be,0xc08ffaa82cb09d68,2
diff --git a/numpy/core/tests/data/umath-validation-set-sin b/numpy/core/tests/data/umath-validation-set-sin
deleted file mode 100644
index 64e78ae15..000000000
--- a/numpy/core/tests/data/umath-validation-set-sin
+++ /dev/null
@@ -1,660 +0,0 @@
-dtype,input,output,ulperrortol
-## +ve denormals ##
-np.float32,0x004b4716,0x004b4716,2
-np.float32,0x007b2490,0x007b2490,2
-np.float32,0x007c99fa,0x007c99fa,2
-np.float32,0x00734a0c,0x00734a0c,2
-np.float32,0x0070de24,0x0070de24,2
-np.float32,0x007fffff,0x007fffff,2
-np.float32,0x00000001,0x00000001,2
-## -ve denormals ##
-np.float32,0x80495d65,0x80495d65,2
-np.float32,0x806894f6,0x806894f6,2
-np.float32,0x80555a76,0x80555a76,2
-np.float32,0x804e1fb8,0x804e1fb8,2
-np.float32,0x80687de9,0x80687de9,2
-np.float32,0x807fffff,0x807fffff,2
-np.float32,0x80000001,0x80000001,2
-## +/-0.0f, +/-FLT_MIN +/-FLT_MAX ##
-np.float32,0x00000000,0x00000000,2
-np.float32,0x80000000,0x80000000,2
-np.float32,0x00800000,0x00800000,2
-np.float32,0x80800000,0x80800000,2
-## 1.00f ##
-np.float32,0x3f800000,0x3f576aa4,2
-np.float32,0x3f800001,0x3f576aa6,2
-np.float32,0x3f800002,0x3f576aa7,2
-np.float32,0xc090a8b0,0x3f7b4e48,2
-np.float32,0x41ce3184,0x3f192d43,2
-np.float32,0xc1d85848,0xbf7161cb,2
-np.float32,0x402b8820,0x3ee3f29f,2
-np.float32,0x42b4e454,0x3f1d0151,2
-np.float32,0x42a67a60,0x3f7ffa4c,2
-np.float32,0x41d92388,0x3f67beef,2
-np.float32,0x422dd66c,0xbeffb0c1,2
-np.float32,0xc28f5be6,0xbf0bae79,2
-np.float32,0x41ab2674,0x3f0ffe2b,2
-np.float32,0x3f490fdb,0x3f3504f3,2
-np.float32,0xbf490fdb,0xbf3504f3,2
-np.float32,0x3fc90fdb,0x3f800000,2
-np.float32,0xbfc90fdb,0xbf800000,2
-np.float32,0x40490fdb,0xb3bbbd2e,2
-np.float32,0xc0490fdb,0x33bbbd2e,2
-np.float32,0x3fc90fdb,0x3f800000,2
-np.float32,0xbfc90fdb,0xbf800000,2
-np.float32,0x40490fdb,0xb3bbbd2e,2
-np.float32,0xc0490fdb,0x33bbbd2e,2
-np.float32,0x40c90fdb,0x343bbd2e,2
-np.float32,0xc0c90fdb,0xb43bbd2e,2
-np.float32,0x4016cbe4,0x3f3504f3,2
-np.float32,0xc016cbe4,0xbf3504f3,2
-np.float32,0x4096cbe4,0xbf800000,2
-np.float32,0xc096cbe4,0x3f800000,2
-np.float32,0x4116cbe4,0xb2ccde2e,2
-np.float32,0xc116cbe4,0x32ccde2e,2
-np.float32,0x40490fdb,0xb3bbbd2e,2
-np.float32,0xc0490fdb,0x33bbbd2e,2
-np.float32,0x40c90fdb,0x343bbd2e,2
-np.float32,0xc0c90fdb,0xb43bbd2e,2
-np.float32,0x41490fdb,0x34bbbd2e,2
-np.float32,0xc1490fdb,0xb4bbbd2e,2
-np.float32,0x407b53d2,0xbf3504f5,2
-np.float32,0xc07b53d2,0x3f3504f5,2
-np.float32,0x40fb53d2,0x3f800000,2
-np.float32,0xc0fb53d2,0xbf800000,2
-np.float32,0x417b53d2,0xb535563d,2
-np.float32,0xc17b53d2,0x3535563d,2
-np.float32,0x4096cbe4,0xbf800000,2
-np.float32,0xc096cbe4,0x3f800000,2
-np.float32,0x4116cbe4,0xb2ccde2e,2
-np.float32,0xc116cbe4,0x32ccde2e,2
-np.float32,0x4196cbe4,0x334cde2e,2
-np.float32,0xc196cbe4,0xb34cde2e,2
-np.float32,0x40afede0,0xbf3504ef,2
-np.float32,0xc0afede0,0x3f3504ef,2
-np.float32,0x412fede0,0xbf800000,2
-np.float32,0xc12fede0,0x3f800000,2
-np.float32,0x41afede0,0xb5b222c4,2
-np.float32,0xc1afede0,0x35b222c4,2
-np.float32,0x40c90fdb,0x343bbd2e,2
-np.float32,0xc0c90fdb,0xb43bbd2e,2
-np.float32,0x41490fdb,0x34bbbd2e,2
-np.float32,0xc1490fdb,0xb4bbbd2e,2
-np.float32,0x41c90fdb,0x353bbd2e,2
-np.float32,0xc1c90fdb,0xb53bbd2e,2
-np.float32,0x40e231d6,0x3f3504f3,2
-np.float32,0xc0e231d6,0xbf3504f3,2
-np.float32,0x416231d6,0x3f800000,2
-np.float32,0xc16231d6,0xbf800000,2
-np.float32,0x41e231d6,0xb399a6a2,2
-np.float32,0xc1e231d6,0x3399a6a2,2
-np.float32,0x40fb53d2,0x3f800000,2
-np.float32,0xc0fb53d2,0xbf800000,2
-np.float32,0x417b53d2,0xb535563d,2
-np.float32,0xc17b53d2,0x3535563d,2
-np.float32,0x41fb53d2,0x35b5563d,2
-np.float32,0xc1fb53d2,0xb5b5563d,2
-np.float32,0x410a3ae7,0x3f3504eb,2
-np.float32,0xc10a3ae7,0xbf3504eb,2
-np.float32,0x418a3ae7,0xbf800000,2
-np.float32,0xc18a3ae7,0x3f800000,2
-np.float32,0x420a3ae7,0xb6308908,2
-np.float32,0xc20a3ae7,0x36308908,2
-np.float32,0x4116cbe4,0xb2ccde2e,2
-np.float32,0xc116cbe4,0x32ccde2e,2
-np.float32,0x4196cbe4,0x334cde2e,2
-np.float32,0xc196cbe4,0xb34cde2e,2
-np.float32,0x4216cbe4,0x33ccde2e,2
-np.float32,0xc216cbe4,0xb3ccde2e,2
-np.float32,0x41235ce2,0xbf3504f7,2
-np.float32,0xc1235ce2,0x3f3504f7,2
-np.float32,0x41a35ce2,0x3f800000,2
-np.float32,0xc1a35ce2,0xbf800000,2
-np.float32,0x42235ce2,0xb5b889b6,2
-np.float32,0xc2235ce2,0x35b889b6,2
-np.float32,0x412fede0,0xbf800000,2
-np.float32,0xc12fede0,0x3f800000,2
-np.float32,0x41afede0,0xb5b222c4,2
-np.float32,0xc1afede0,0x35b222c4,2
-np.float32,0x422fede0,0x363222c4,2
-np.float32,0xc22fede0,0xb63222c4,2
-np.float32,0x413c7edd,0xbf3504f3,2
-np.float32,0xc13c7edd,0x3f3504f3,2
-np.float32,0x41bc7edd,0xbf800000,2
-np.float32,0xc1bc7edd,0x3f800000,2
-np.float32,0x423c7edd,0xb4000add,2
-np.float32,0xc23c7edd,0x34000add,2
-np.float32,0x41490fdb,0x34bbbd2e,2
-np.float32,0xc1490fdb,0xb4bbbd2e,2
-np.float32,0x41c90fdb,0x353bbd2e,2
-np.float32,0xc1c90fdb,0xb53bbd2e,2
-np.float32,0x42490fdb,0x35bbbd2e,2
-np.float32,0xc2490fdb,0xb5bbbd2e,2
-np.float32,0x4155a0d9,0x3f3504fb,2
-np.float32,0xc155a0d9,0xbf3504fb,2
-np.float32,0x41d5a0d9,0x3f800000,2
-np.float32,0xc1d5a0d9,0xbf800000,2
-np.float32,0x4255a0d9,0xb633bc81,2
-np.float32,0xc255a0d9,0x3633bc81,2
-np.float32,0x416231d6,0x3f800000,2
-np.float32,0xc16231d6,0xbf800000,2
-np.float32,0x41e231d6,0xb399a6a2,2
-np.float32,0xc1e231d6,0x3399a6a2,2
-np.float32,0x426231d6,0x3419a6a2,2
-np.float32,0xc26231d6,0xb419a6a2,2
-np.float32,0x416ec2d4,0x3f3504ef,2
-np.float32,0xc16ec2d4,0xbf3504ef,2
-np.float32,0x41eec2d4,0xbf800000,2
-np.float32,0xc1eec2d4,0x3f800000,2
-np.float32,0x426ec2d4,0xb5bef0a7,2
-np.float32,0xc26ec2d4,0x35bef0a7,2
-np.float32,0x417b53d2,0xb535563d,2
-np.float32,0xc17b53d2,0x3535563d,2
-np.float32,0x41fb53d2,0x35b5563d,2
-np.float32,0xc1fb53d2,0xb5b5563d,2
-np.float32,0x427b53d2,0x3635563d,2
-np.float32,0xc27b53d2,0xb635563d,2
-np.float32,0x4183f268,0xbf3504ff,2
-np.float32,0xc183f268,0x3f3504ff,2
-np.float32,0x4203f268,0x3f800000,2
-np.float32,0xc203f268,0xbf800000,2
-np.float32,0x4283f268,0xb6859a13,2
-np.float32,0xc283f268,0x36859a13,2
-np.float32,0x418a3ae7,0xbf800000,2
-np.float32,0xc18a3ae7,0x3f800000,2
-np.float32,0x420a3ae7,0xb6308908,2
-np.float32,0xc20a3ae7,0x36308908,2
-np.float32,0x428a3ae7,0x36b08908,2
-np.float32,0xc28a3ae7,0xb6b08908,2
-np.float32,0x41908365,0xbf3504f6,2
-np.float32,0xc1908365,0x3f3504f6,2
-np.float32,0x42108365,0xbf800000,2
-np.float32,0xc2108365,0x3f800000,2
-np.float32,0x42908365,0x3592200d,2
-np.float32,0xc2908365,0xb592200d,2
-np.float32,0x4196cbe4,0x334cde2e,2
-np.float32,0xc196cbe4,0xb34cde2e,2
-np.float32,0x4216cbe4,0x33ccde2e,2
-np.float32,0xc216cbe4,0xb3ccde2e,2
-np.float32,0x4296cbe4,0x344cde2e,2
-np.float32,0xc296cbe4,0xb44cde2e,2
-np.float32,0x419d1463,0x3f3504f8,2
-np.float32,0xc19d1463,0xbf3504f8,2
-np.float32,0x421d1463,0x3f800000,2
-np.float32,0xc21d1463,0xbf800000,2
-np.float32,0x429d1463,0xb5c55799,2
-np.float32,0xc29d1463,0x35c55799,2
-np.float32,0x41a35ce2,0x3f800000,2
-np.float32,0xc1a35ce2,0xbf800000,2
-np.float32,0x42235ce2,0xb5b889b6,2
-np.float32,0xc2235ce2,0x35b889b6,2
-np.float32,0x42a35ce2,0x363889b6,2
-np.float32,0xc2a35ce2,0xb63889b6,2
-np.float32,0x41a9a561,0x3f3504e7,2
-np.float32,0xc1a9a561,0xbf3504e7,2
-np.float32,0x4229a561,0xbf800000,2
-np.float32,0xc229a561,0x3f800000,2
-np.float32,0x42a9a561,0xb68733d0,2
-np.float32,0xc2a9a561,0x368733d0,2
-np.float32,0x41afede0,0xb5b222c4,2
-np.float32,0xc1afede0,0x35b222c4,2
-np.float32,0x422fede0,0x363222c4,2
-np.float32,0xc22fede0,0xb63222c4,2
-np.float32,0x42afede0,0x36b222c4,2
-np.float32,0xc2afede0,0xb6b222c4,2
-np.float32,0x41b6365e,0xbf3504f0,2
-np.float32,0xc1b6365e,0x3f3504f0,2
-np.float32,0x4236365e,0x3f800000,2
-np.float32,0xc236365e,0xbf800000,2
-np.float32,0x42b6365e,0x358bb91c,2
-np.float32,0xc2b6365e,0xb58bb91c,2
-np.float32,0x41bc7edd,0xbf800000,2
-np.float32,0xc1bc7edd,0x3f800000,2
-np.float32,0x423c7edd,0xb4000add,2
-np.float32,0xc23c7edd,0x34000add,2
-np.float32,0x42bc7edd,0x34800add,2
-np.float32,0xc2bc7edd,0xb4800add,2
-np.float32,0x41c2c75c,0xbf3504ef,2
-np.float32,0xc1c2c75c,0x3f3504ef,2
-np.float32,0x4242c75c,0xbf800000,2
-np.float32,0xc242c75c,0x3f800000,2
-np.float32,0x42c2c75c,0xb5cbbe8a,2
-np.float32,0xc2c2c75c,0x35cbbe8a,2
-np.float32,0x41c90fdb,0x353bbd2e,2
-np.float32,0xc1c90fdb,0xb53bbd2e,2
-np.float32,0x42490fdb,0x35bbbd2e,2
-np.float32,0xc2490fdb,0xb5bbbd2e,2
-np.float32,0x42c90fdb,0x363bbd2e,2
-np.float32,0xc2c90fdb,0xb63bbd2e,2
-np.float32,0x41cf585a,0x3f3504ff,2
-np.float32,0xc1cf585a,0xbf3504ff,2
-np.float32,0x424f585a,0x3f800000,2
-np.float32,0xc24f585a,0xbf800000,2
-np.float32,0x42cf585a,0xb688cd8c,2
-np.float32,0xc2cf585a,0x3688cd8c,2
-np.float32,0x41d5a0d9,0x3f800000,2
-np.float32,0xc1d5a0d9,0xbf800000,2
-np.float32,0x4255a0d9,0xb633bc81,2
-np.float32,0xc255a0d9,0x3633bc81,2
-np.float32,0x42d5a0d9,0x36b3bc81,2
-np.float32,0xc2d5a0d9,0xb6b3bc81,2
-np.float32,0x41dbe958,0x3f3504e0,2
-np.float32,0xc1dbe958,0xbf3504e0,2
-np.float32,0x425be958,0xbf800000,2
-np.float32,0xc25be958,0x3f800000,2
-np.float32,0x42dbe958,0xb6deab75,2
-np.float32,0xc2dbe958,0x36deab75,2
-np.float32,0x41e231d6,0xb399a6a2,2
-np.float32,0xc1e231d6,0x3399a6a2,2
-np.float32,0x426231d6,0x3419a6a2,2
-np.float32,0xc26231d6,0xb419a6a2,2
-np.float32,0x42e231d6,0x3499a6a2,2
-np.float32,0xc2e231d6,0xb499a6a2,2
-np.float32,0x41e87a55,0xbf3504f8,2
-np.float32,0xc1e87a55,0x3f3504f8,2
-np.float32,0x42687a55,0x3f800000,2
-np.float32,0xc2687a55,0xbf800000,2
-np.float32,0x42e87a55,0xb5d2257b,2
-np.float32,0xc2e87a55,0x35d2257b,2
-np.float32,0x41eec2d4,0xbf800000,2
-np.float32,0xc1eec2d4,0x3f800000,2
-np.float32,0x426ec2d4,0xb5bef0a7,2
-np.float32,0xc26ec2d4,0x35bef0a7,2
-np.float32,0x42eec2d4,0x363ef0a7,2
-np.float32,0xc2eec2d4,0xb63ef0a7,2
-np.float32,0x41f50b53,0xbf3504e7,2
-np.float32,0xc1f50b53,0x3f3504e7,2
-np.float32,0x42750b53,0xbf800000,2
-np.float32,0xc2750b53,0x3f800000,2
-np.float32,0x42f50b53,0xb68a6748,2
-np.float32,0xc2f50b53,0x368a6748,2
-np.float32,0x41fb53d2,0x35b5563d,2
-np.float32,0xc1fb53d2,0xb5b5563d,2
-np.float32,0x427b53d2,0x3635563d,2
-np.float32,0xc27b53d2,0xb635563d,2
-np.float32,0x42fb53d2,0x36b5563d,2
-np.float32,0xc2fb53d2,0xb6b5563d,2
-np.float32,0x4200ce28,0x3f3504f0,2
-np.float32,0xc200ce28,0xbf3504f0,2
-np.float32,0x4280ce28,0x3f800000,2
-np.float32,0xc280ce28,0xbf800000,2
-np.float32,0x4300ce28,0x357dd672,2
-np.float32,0xc300ce28,0xb57dd672,2
-np.float32,0x4203f268,0x3f800000,2
-np.float32,0xc203f268,0xbf800000,2
-np.float32,0x4283f268,0xb6859a13,2
-np.float32,0xc283f268,0x36859a13,2
-np.float32,0x4303f268,0x37059a13,2
-np.float32,0xc303f268,0xb7059a13,2
-np.float32,0x420716a7,0x3f3504ee,2
-np.float32,0xc20716a7,0xbf3504ee,2
-np.float32,0x428716a7,0xbf800000,2
-np.float32,0xc28716a7,0x3f800000,2
-np.float32,0x430716a7,0xb5d88c6d,2
-np.float32,0xc30716a7,0x35d88c6d,2
-np.float32,0x420a3ae7,0xb6308908,2
-np.float32,0xc20a3ae7,0x36308908,2
-np.float32,0x428a3ae7,0x36b08908,2
-np.float32,0xc28a3ae7,0xb6b08908,2
-np.float32,0x430a3ae7,0x37308908,2
-np.float32,0xc30a3ae7,0xb7308908,2
-np.float32,0x420d5f26,0xbf350500,2
-np.float32,0xc20d5f26,0x3f350500,2
-np.float32,0x428d5f26,0x3f800000,2
-np.float32,0xc28d5f26,0xbf800000,2
-np.float32,0x430d5f26,0xb68c0105,2
-np.float32,0xc30d5f26,0x368c0105,2
-np.float32,0x42108365,0xbf800000,2
-np.float32,0xc2108365,0x3f800000,2
-np.float32,0x42908365,0x3592200d,2
-np.float32,0xc2908365,0xb592200d,2
-np.float32,0x43108365,0xb612200d,2
-np.float32,0xc3108365,0x3612200d,2
-np.float32,0x4213a7a5,0xbf3504df,2
-np.float32,0xc213a7a5,0x3f3504df,2
-np.float32,0x4293a7a5,0xbf800000,2
-np.float32,0xc293a7a5,0x3f800000,2
-np.float32,0x4313a7a5,0xb6e1deee,2
-np.float32,0xc313a7a5,0x36e1deee,2
-np.float32,0x4216cbe4,0x33ccde2e,2
-np.float32,0xc216cbe4,0xb3ccde2e,2
-np.float32,0x4296cbe4,0x344cde2e,2
-np.float32,0xc296cbe4,0xb44cde2e,2
-np.float32,0x4316cbe4,0x34ccde2e,2
-np.float32,0xc316cbe4,0xb4ccde2e,2
-np.float32,0x4219f024,0x3f35050f,2
-np.float32,0xc219f024,0xbf35050f,2
-np.float32,0x4299f024,0x3f800000,2
-np.float32,0xc299f024,0xbf800000,2
-np.float32,0x4319f024,0xb71bde6c,2
-np.float32,0xc319f024,0x371bde6c,2
-np.float32,0x421d1463,0x3f800000,2
-np.float32,0xc21d1463,0xbf800000,2
-np.float32,0x429d1463,0xb5c55799,2
-np.float32,0xc29d1463,0x35c55799,2
-np.float32,0x431d1463,0x36455799,2
-np.float32,0xc31d1463,0xb6455799,2
-np.float32,0x422038a3,0x3f3504d0,2
-np.float32,0xc22038a3,0xbf3504d0,2
-np.float32,0x42a038a3,0xbf800000,2
-np.float32,0xc2a038a3,0x3f800000,2
-np.float32,0x432038a3,0xb746cd61,2
-np.float32,0xc32038a3,0x3746cd61,2
-np.float32,0x42235ce2,0xb5b889b6,2
-np.float32,0xc2235ce2,0x35b889b6,2
-np.float32,0x42a35ce2,0x363889b6,2
-np.float32,0xc2a35ce2,0xb63889b6,2
-np.float32,0x43235ce2,0x36b889b6,2
-np.float32,0xc3235ce2,0xb6b889b6,2
-np.float32,0x42268121,0xbf3504f1,2
-np.float32,0xc2268121,0x3f3504f1,2
-np.float32,0x42a68121,0x3f800000,2
-np.float32,0xc2a68121,0xbf800000,2
-np.float32,0x43268121,0x35643aac,2
-np.float32,0xc3268121,0xb5643aac,2
-np.float32,0x4229a561,0xbf800000,2
-np.float32,0xc229a561,0x3f800000,2
-np.float32,0x42a9a561,0xb68733d0,2
-np.float32,0xc2a9a561,0x368733d0,2
-np.float32,0x4329a561,0x370733d0,2
-np.float32,0xc329a561,0xb70733d0,2
-np.float32,0x422cc9a0,0xbf3504ee,2
-np.float32,0xc22cc9a0,0x3f3504ee,2
-np.float32,0x42acc9a0,0xbf800000,2
-np.float32,0xc2acc9a0,0x3f800000,2
-np.float32,0x432cc9a0,0xb5e55a50,2
-np.float32,0xc32cc9a0,0x35e55a50,2
-np.float32,0x422fede0,0x363222c4,2
-np.float32,0xc22fede0,0xb63222c4,2
-np.float32,0x42afede0,0x36b222c4,2
-np.float32,0xc2afede0,0xb6b222c4,2
-np.float32,0x432fede0,0x373222c4,2
-np.float32,0xc32fede0,0xb73222c4,2
-np.float32,0x4233121f,0x3f350500,2
-np.float32,0xc233121f,0xbf350500,2
-np.float32,0x42b3121f,0x3f800000,2
-np.float32,0xc2b3121f,0xbf800000,2
-np.float32,0x4333121f,0xb68f347d,2
-np.float32,0xc333121f,0x368f347d,2
-np.float32,0x4236365e,0x3f800000,2
-np.float32,0xc236365e,0xbf800000,2
-np.float32,0x42b6365e,0x358bb91c,2
-np.float32,0xc2b6365e,0xb58bb91c,2
-np.float32,0x4336365e,0xb60bb91c,2
-np.float32,0xc336365e,0x360bb91c,2
-np.float32,0x42395a9e,0x3f3504df,2
-np.float32,0xc2395a9e,0xbf3504df,2
-np.float32,0x42b95a9e,0xbf800000,2
-np.float32,0xc2b95a9e,0x3f800000,2
-np.float32,0x43395a9e,0xb6e51267,2
-np.float32,0xc3395a9e,0x36e51267,2
-np.float32,0x423c7edd,0xb4000add,2
-np.float32,0xc23c7edd,0x34000add,2
-np.float32,0x42bc7edd,0x34800add,2
-np.float32,0xc2bc7edd,0xb4800add,2
-np.float32,0x433c7edd,0x35000add,2
-np.float32,0xc33c7edd,0xb5000add,2
-np.float32,0x423fa31d,0xbf35050f,2
-np.float32,0xc23fa31d,0x3f35050f,2
-np.float32,0x42bfa31d,0x3f800000,2
-np.float32,0xc2bfa31d,0xbf800000,2
-np.float32,0x433fa31d,0xb71d7828,2
-np.float32,0xc33fa31d,0x371d7828,2
-np.float32,0x4242c75c,0xbf800000,2
-np.float32,0xc242c75c,0x3f800000,2
-np.float32,0x42c2c75c,0xb5cbbe8a,2
-np.float32,0xc2c2c75c,0x35cbbe8a,2
-np.float32,0x4342c75c,0x364bbe8a,2
-np.float32,0xc342c75c,0xb64bbe8a,2
-np.float32,0x4245eb9c,0xbf3504d0,2
-np.float32,0xc245eb9c,0x3f3504d0,2
-np.float32,0x42c5eb9c,0xbf800000,2
-np.float32,0xc2c5eb9c,0x3f800000,2
-np.float32,0x4345eb9c,0xb748671d,2
-np.float32,0xc345eb9c,0x3748671d,2
-np.float32,0x42490fdb,0x35bbbd2e,2
-np.float32,0xc2490fdb,0xb5bbbd2e,2
-np.float32,0x42c90fdb,0x363bbd2e,2
-np.float32,0xc2c90fdb,0xb63bbd2e,2
-np.float32,0x43490fdb,0x36bbbd2e,2
-np.float32,0xc3490fdb,0xb6bbbd2e,2
-np.float32,0x424c341a,0x3f3504f1,2
-np.float32,0xc24c341a,0xbf3504f1,2
-np.float32,0x42cc341a,0x3f800000,2
-np.float32,0xc2cc341a,0xbf800000,2
-np.float32,0x434c341a,0x354a9ee6,2
-np.float32,0xc34c341a,0xb54a9ee6,2
-np.float32,0x424f585a,0x3f800000,2
-np.float32,0xc24f585a,0xbf800000,2
-np.float32,0x42cf585a,0xb688cd8c,2
-np.float32,0xc2cf585a,0x3688cd8c,2
-np.float32,0x434f585a,0x3708cd8c,2
-np.float32,0xc34f585a,0xb708cd8c,2
-np.float32,0x42527c99,0x3f3504ee,2
-np.float32,0xc2527c99,0xbf3504ee,2
-np.float32,0x42d27c99,0xbf800000,2
-np.float32,0xc2d27c99,0x3f800000,2
-np.float32,0x43527c99,0xb5f22833,2
-np.float32,0xc3527c99,0x35f22833,2
-np.float32,0x4255a0d9,0xb633bc81,2
-np.float32,0xc255a0d9,0x3633bc81,2
-np.float32,0x42d5a0d9,0x36b3bc81,2
-np.float32,0xc2d5a0d9,0xb6b3bc81,2
-np.float32,0x4355a0d9,0x3733bc81,2
-np.float32,0xc355a0d9,0xb733bc81,2
-np.float32,0x4258c518,0xbf350500,2
-np.float32,0xc258c518,0x3f350500,2
-np.float32,0x42d8c518,0x3f800000,2
-np.float32,0xc2d8c518,0xbf800000,2
-np.float32,0x4358c518,0xb69267f6,2
-np.float32,0xc358c518,0x369267f6,2
-np.float32,0x425be958,0xbf800000,2
-np.float32,0xc25be958,0x3f800000,2
-np.float32,0x42dbe958,0xb6deab75,2
-np.float32,0xc2dbe958,0x36deab75,2
-np.float32,0x435be958,0x375eab75,2
-np.float32,0xc35be958,0xb75eab75,2
-np.float32,0x425f0d97,0xbf3504df,2
-np.float32,0xc25f0d97,0x3f3504df,2
-np.float32,0x42df0d97,0xbf800000,2
-np.float32,0xc2df0d97,0x3f800000,2
-np.float32,0x435f0d97,0xb6e845e0,2
-np.float32,0xc35f0d97,0x36e845e0,2
-np.float32,0x426231d6,0x3419a6a2,2
-np.float32,0xc26231d6,0xb419a6a2,2
-np.float32,0x42e231d6,0x3499a6a2,2
-np.float32,0xc2e231d6,0xb499a6a2,2
-np.float32,0x436231d6,0x3519a6a2,2
-np.float32,0xc36231d6,0xb519a6a2,2
-np.float32,0x42655616,0x3f35050f,2
-np.float32,0xc2655616,0xbf35050f,2
-np.float32,0x42e55616,0x3f800000,2
-np.float32,0xc2e55616,0xbf800000,2
-np.float32,0x43655616,0xb71f11e5,2
-np.float32,0xc3655616,0x371f11e5,2
-np.float32,0x42687a55,0x3f800000,2
-np.float32,0xc2687a55,0xbf800000,2
-np.float32,0x42e87a55,0xb5d2257b,2
-np.float32,0xc2e87a55,0x35d2257b,2
-np.float32,0x43687a55,0x3652257b,2
-np.float32,0xc3687a55,0xb652257b,2
-np.float32,0x426b9e95,0x3f3504cf,2
-np.float32,0xc26b9e95,0xbf3504cf,2
-np.float32,0x42eb9e95,0xbf800000,2
-np.float32,0xc2eb9e95,0x3f800000,2
-np.float32,0x436b9e95,0xb74a00d9,2
-np.float32,0xc36b9e95,0x374a00d9,2
-np.float32,0x426ec2d4,0xb5bef0a7,2
-np.float32,0xc26ec2d4,0x35bef0a7,2
-np.float32,0x42eec2d4,0x363ef0a7,2
-np.float32,0xc2eec2d4,0xb63ef0a7,2
-np.float32,0x436ec2d4,0x36bef0a7,2
-np.float32,0xc36ec2d4,0xb6bef0a7,2
-np.float32,0x4271e713,0xbf3504f1,2
-np.float32,0xc271e713,0x3f3504f1,2
-np.float32,0x42f1e713,0x3f800000,2
-np.float32,0xc2f1e713,0xbf800000,2
-np.float32,0x4371e713,0x35310321,2
-np.float32,0xc371e713,0xb5310321,2
-np.float32,0x42750b53,0xbf800000,2
-np.float32,0xc2750b53,0x3f800000,2
-np.float32,0x42f50b53,0xb68a6748,2
-np.float32,0xc2f50b53,0x368a6748,2
-np.float32,0x43750b53,0x370a6748,2
-np.float32,0xc3750b53,0xb70a6748,2
-np.float32,0x42782f92,0xbf3504ee,2
-np.float32,0xc2782f92,0x3f3504ee,2
-np.float32,0x42f82f92,0xbf800000,2
-np.float32,0xc2f82f92,0x3f800000,2
-np.float32,0x43782f92,0xb5fef616,2
-np.float32,0xc3782f92,0x35fef616,2
-np.float32,0x427b53d2,0x3635563d,2
-np.float32,0xc27b53d2,0xb635563d,2
-np.float32,0x42fb53d2,0x36b5563d,2
-np.float32,0xc2fb53d2,0xb6b5563d,2
-np.float32,0x437b53d2,0x3735563d,2
-np.float32,0xc37b53d2,0xb735563d,2
-np.float32,0x427e7811,0x3f350500,2
-np.float32,0xc27e7811,0xbf350500,2
-np.float32,0x42fe7811,0x3f800000,2
-np.float32,0xc2fe7811,0xbf800000,2
-np.float32,0x437e7811,0xb6959b6f,2
-np.float32,0xc37e7811,0x36959b6f,2
-np.float32,0x4280ce28,0x3f800000,2
-np.float32,0xc280ce28,0xbf800000,2
-np.float32,0x4300ce28,0x357dd672,2
-np.float32,0xc300ce28,0xb57dd672,2
-np.float32,0x4380ce28,0xb5fdd672,2
-np.float32,0xc380ce28,0x35fdd672,2
-np.float32,0x42826048,0x3f3504de,2
-np.float32,0xc2826048,0xbf3504de,2
-np.float32,0x43026048,0xbf800000,2
-np.float32,0xc3026048,0x3f800000,2
-np.float32,0x43826048,0xb6eb7958,2
-np.float32,0xc3826048,0x36eb7958,2
-np.float32,0x4283f268,0xb6859a13,2
-np.float32,0xc283f268,0x36859a13,2
-np.float32,0x4303f268,0x37059a13,2
-np.float32,0xc303f268,0xb7059a13,2
-np.float32,0x4383f268,0x37859a13,2
-np.float32,0xc383f268,0xb7859a13,2
-np.float32,0x42858487,0xbf3504e2,2
-np.float32,0xc2858487,0x3f3504e2,2
-np.float32,0x43058487,0x3f800000,2
-np.float32,0xc3058487,0xbf800000,2
-np.float32,0x43858487,0x36bea8be,2
-np.float32,0xc3858487,0xb6bea8be,2
-np.float32,0x428716a7,0xbf800000,2
-np.float32,0xc28716a7,0x3f800000,2
-np.float32,0x430716a7,0xb5d88c6d,2
-np.float32,0xc30716a7,0x35d88c6d,2
-np.float32,0x438716a7,0x36588c6d,2
-np.float32,0xc38716a7,0xb6588c6d,2
-np.float32,0x4288a8c7,0xbf3504cf,2
-np.float32,0xc288a8c7,0x3f3504cf,2
-np.float32,0x4308a8c7,0xbf800000,2
-np.float32,0xc308a8c7,0x3f800000,2
-np.float32,0x4388a8c7,0xb74b9a96,2
-np.float32,0xc388a8c7,0x374b9a96,2
-np.float32,0x428a3ae7,0x36b08908,2
-np.float32,0xc28a3ae7,0xb6b08908,2
-np.float32,0x430a3ae7,0x37308908,2
-np.float32,0xc30a3ae7,0xb7308908,2
-np.float32,0x438a3ae7,0x37b08908,2
-np.float32,0xc38a3ae7,0xb7b08908,2
-np.float32,0x428bcd06,0x3f3504f2,2
-np.float32,0xc28bcd06,0xbf3504f2,2
-np.float32,0x430bcd06,0x3f800000,2
-np.float32,0xc30bcd06,0xbf800000,2
-np.float32,0x438bcd06,0x3517675b,2
-np.float32,0xc38bcd06,0xb517675b,2
-np.float32,0x428d5f26,0x3f800000,2
-np.float32,0xc28d5f26,0xbf800000,2
-np.float32,0x430d5f26,0xb68c0105,2
-np.float32,0xc30d5f26,0x368c0105,2
-np.float32,0x438d5f26,0x370c0105,2
-np.float32,0xc38d5f26,0xb70c0105,2
-np.float32,0x428ef146,0x3f3504c0,2
-np.float32,0xc28ef146,0xbf3504c0,2
-np.float32,0x430ef146,0xbf800000,2
-np.float32,0xc30ef146,0x3f800000,2
-np.float32,0x438ef146,0xb790bc40,2
-np.float32,0xc38ef146,0x3790bc40,2
-np.float32,0x42908365,0x3592200d,2
-np.float32,0xc2908365,0xb592200d,2
-np.float32,0x43108365,0xb612200d,2
-np.float32,0xc3108365,0x3612200d,2
-np.float32,0x43908365,0xb692200d,2
-np.float32,0xc3908365,0x3692200d,2
-np.float32,0x42921585,0xbf350501,2
-np.float32,0xc2921585,0x3f350501,2
-np.float32,0x43121585,0x3f800000,2
-np.float32,0xc3121585,0xbf800000,2
-np.float32,0x43921585,0xb698cee8,2
-np.float32,0xc3921585,0x3698cee8,2
-np.float32,0x4293a7a5,0xbf800000,2
-np.float32,0xc293a7a5,0x3f800000,2
-np.float32,0x4313a7a5,0xb6e1deee,2
-np.float32,0xc313a7a5,0x36e1deee,2
-np.float32,0x4393a7a5,0x3761deee,2
-np.float32,0xc393a7a5,0xb761deee,2
-np.float32,0x429539c5,0xbf3504b1,2
-np.float32,0xc29539c5,0x3f3504b1,2
-np.float32,0x431539c5,0xbf800000,2
-np.float32,0xc31539c5,0x3f800000,2
-np.float32,0x439539c5,0xb7bbab34,2
-np.float32,0xc39539c5,0x37bbab34,2
-np.float32,0x4296cbe4,0x344cde2e,2
-np.float32,0xc296cbe4,0xb44cde2e,2
-np.float32,0x4316cbe4,0x34ccde2e,2
-np.float32,0xc316cbe4,0xb4ccde2e,2
-np.float32,0x4396cbe4,0x354cde2e,2
-np.float32,0xc396cbe4,0xb54cde2e,2
-np.float32,0x42985e04,0x3f350510,2
-np.float32,0xc2985e04,0xbf350510,2
-np.float32,0x43185e04,0x3f800000,2
-np.float32,0xc3185e04,0xbf800000,2
-np.float32,0x43985e04,0xb722455d,2
-np.float32,0xc3985e04,0x3722455d,2
-np.float32,0x4299f024,0x3f800000,2
-np.float32,0xc299f024,0xbf800000,2
-np.float32,0x4319f024,0xb71bde6c,2
-np.float32,0xc319f024,0x371bde6c,2
-np.float32,0x4399f024,0x379bde6c,2
-np.float32,0xc399f024,0xb79bde6c,2
-np.float32,0x429b8243,0x3f3504fc,2
-np.float32,0xc29b8243,0xbf3504fc,2
-np.float32,0x431b8243,0xbf800000,2
-np.float32,0xc31b8243,0x3f800000,2
-np.float32,0x439b8243,0x364b2eb8,2
-np.float32,0xc39b8243,0xb64b2eb8,2
-np.float32,0x435b2047,0xbf350525,2
-np.float32,0x42a038a2,0xbf800000,2
-np.float32,0x432038a2,0x3664ca7e,2
-np.float32,0x4345eb9b,0x365e638c,2
-np.float32,0x42c5eb9b,0xbf800000,2
-np.float32,0x42eb9e94,0xbf800000,2
-np.float32,0x4350ea79,0x3f800000,2
-np.float32,0x42dbe957,0x3585522a,2
-np.float32,0x425be957,0xbf800000,2
-np.float32,0x435be957,0xb605522a,2
-np.float32,0x476362a2,0xbd7ff911,2
-np.float32,0x464c99a4,0x3e7f4d41,2
-np.float32,0x4471f73d,0x3e7fe1b0,2
-np.float32,0x445a6752,0x3e7ef367,2
-np.float32,0x474fa400,0x3e7f9fcd,2
-np.float32,0x45c1e72f,0xbe7fc7af,2
-np.float32,0x4558c91d,0x3e7e9f31,2
-np.float32,0x43784f94,0xbdff6654,2
-np.float32,0x466e8500,0xbe7ea0a3,2
-np.float32,0x468e1c25,0x3e7e22fb,2
-np.float32,0x44ea6cfc,0x3dff70c3,2
-np.float32,0x4605126c,0x3e7f89ef,2
-np.float32,0x4788b3c6,0xbb87d853,2
-np.float32,0x4531b042,0x3dffd163,2
-np.float32,0x43f1f71d,0x3dfff387,2
-np.float32,0x462c3fa5,0xbd7fe13d,2
-np.float32,0x441c5354,0xbdff76b4,2
-np.float32,0x44908b69,0x3e7dcf0d,2
-np.float32,0x478813ad,0xbe7e9d80,2
-np.float32,0x441c4351,0x3dff937b,2
diff --git a/numpy/core/tests/data/umath-validation-set-sin.csv b/numpy/core/tests/data/umath-validation-set-sin.csv
new file mode 100644
index 000000000..3b913ccd9
--- /dev/null
+++ b/numpy/core/tests/data/umath-validation-set-sin.csv
@@ -0,0 +1,1370 @@
+dtype,input,output,ulperrortol
+## +ve denormals ##
+np.float32,0x004b4716,0x004b4716,2
+np.float32,0x007b2490,0x007b2490,2
+np.float32,0x007c99fa,0x007c99fa,2
+np.float32,0x00734a0c,0x00734a0c,2
+np.float32,0x0070de24,0x0070de24,2
+np.float32,0x007fffff,0x007fffff,2
+np.float32,0x00000001,0x00000001,2
+## -ve denormals ##
+np.float32,0x80495d65,0x80495d65,2
+np.float32,0x806894f6,0x806894f6,2
+np.float32,0x80555a76,0x80555a76,2
+np.float32,0x804e1fb8,0x804e1fb8,2
+np.float32,0x80687de9,0x80687de9,2
+np.float32,0x807fffff,0x807fffff,2
+np.float32,0x80000001,0x80000001,2
+## +/-0.0f, +/-FLT_MIN +/-FLT_MAX ##
+np.float32,0x00000000,0x00000000,2
+np.float32,0x80000000,0x80000000,2
+np.float32,0x00800000,0x00800000,2
+np.float32,0x80800000,0x80800000,2
+## 1.00f ##
+np.float32,0x3f800000,0x3f576aa4,2
+np.float32,0x3f800001,0x3f576aa6,2
+np.float32,0x3f800002,0x3f576aa7,2
+np.float32,0xc090a8b0,0x3f7b4e48,2
+np.float32,0x41ce3184,0x3f192d43,2
+np.float32,0xc1d85848,0xbf7161cb,2
+np.float32,0x402b8820,0x3ee3f29f,2
+np.float32,0x42b4e454,0x3f1d0151,2
+np.float32,0x42a67a60,0x3f7ffa4c,2
+np.float32,0x41d92388,0x3f67beef,2
+np.float32,0x422dd66c,0xbeffb0c1,2
+np.float32,0xc28f5be6,0xbf0bae79,2
+np.float32,0x41ab2674,0x3f0ffe2b,2
+np.float32,0x3f490fdb,0x3f3504f3,2
+np.float32,0xbf490fdb,0xbf3504f3,2
+np.float32,0x3fc90fdb,0x3f800000,2
+np.float32,0xbfc90fdb,0xbf800000,2
+np.float32,0x40490fdb,0xb3bbbd2e,2
+np.float32,0xc0490fdb,0x33bbbd2e,2
+np.float32,0x3fc90fdb,0x3f800000,2
+np.float32,0xbfc90fdb,0xbf800000,2
+np.float32,0x40490fdb,0xb3bbbd2e,2
+np.float32,0xc0490fdb,0x33bbbd2e,2
+np.float32,0x40c90fdb,0x343bbd2e,2
+np.float32,0xc0c90fdb,0xb43bbd2e,2
+np.float32,0x4016cbe4,0x3f3504f3,2
+np.float32,0xc016cbe4,0xbf3504f3,2
+np.float32,0x4096cbe4,0xbf800000,2
+np.float32,0xc096cbe4,0x3f800000,2
+np.float32,0x4116cbe4,0xb2ccde2e,2
+np.float32,0xc116cbe4,0x32ccde2e,2
+np.float32,0x40490fdb,0xb3bbbd2e,2
+np.float32,0xc0490fdb,0x33bbbd2e,2
+np.float32,0x40c90fdb,0x343bbd2e,2
+np.float32,0xc0c90fdb,0xb43bbd2e,2
+np.float32,0x41490fdb,0x34bbbd2e,2
+np.float32,0xc1490fdb,0xb4bbbd2e,2
+np.float32,0x407b53d2,0xbf3504f5,2
+np.float32,0xc07b53d2,0x3f3504f5,2
+np.float32,0x40fb53d2,0x3f800000,2
+np.float32,0xc0fb53d2,0xbf800000,2
+np.float32,0x417b53d2,0xb535563d,2
+np.float32,0xc17b53d2,0x3535563d,2
+np.float32,0x4096cbe4,0xbf800000,2
+np.float32,0xc096cbe4,0x3f800000,2
+np.float32,0x4116cbe4,0xb2ccde2e,2
+np.float32,0xc116cbe4,0x32ccde2e,2
+np.float32,0x4196cbe4,0x334cde2e,2
+np.float32,0xc196cbe4,0xb34cde2e,2
+np.float32,0x40afede0,0xbf3504ef,2
+np.float32,0xc0afede0,0x3f3504ef,2
+np.float32,0x412fede0,0xbf800000,2
+np.float32,0xc12fede0,0x3f800000,2
+np.float32,0x41afede0,0xb5b222c4,2
+np.float32,0xc1afede0,0x35b222c4,2
+np.float32,0x40c90fdb,0x343bbd2e,2
+np.float32,0xc0c90fdb,0xb43bbd2e,2
+np.float32,0x41490fdb,0x34bbbd2e,2
+np.float32,0xc1490fdb,0xb4bbbd2e,2
+np.float32,0x41c90fdb,0x353bbd2e,2
+np.float32,0xc1c90fdb,0xb53bbd2e,2
+np.float32,0x40e231d6,0x3f3504f3,2
+np.float32,0xc0e231d6,0xbf3504f3,2
+np.float32,0x416231d6,0x3f800000,2
+np.float32,0xc16231d6,0xbf800000,2
+np.float32,0x41e231d6,0xb399a6a2,2
+np.float32,0xc1e231d6,0x3399a6a2,2
+np.float32,0x40fb53d2,0x3f800000,2
+np.float32,0xc0fb53d2,0xbf800000,2
+np.float32,0x417b53d2,0xb535563d,2
+np.float32,0xc17b53d2,0x3535563d,2
+np.float32,0x41fb53d2,0x35b5563d,2
+np.float32,0xc1fb53d2,0xb5b5563d,2
+np.float32,0x410a3ae7,0x3f3504eb,2
+np.float32,0xc10a3ae7,0xbf3504eb,2
+np.float32,0x418a3ae7,0xbf800000,2
+np.float32,0xc18a3ae7,0x3f800000,2
+np.float32,0x420a3ae7,0xb6308908,2
+np.float32,0xc20a3ae7,0x36308908,2
+np.float32,0x4116cbe4,0xb2ccde2e,2
+np.float32,0xc116cbe4,0x32ccde2e,2
+np.float32,0x4196cbe4,0x334cde2e,2
+np.float32,0xc196cbe4,0xb34cde2e,2
+np.float32,0x4216cbe4,0x33ccde2e,2
+np.float32,0xc216cbe4,0xb3ccde2e,2
+np.float32,0x41235ce2,0xbf3504f7,2
+np.float32,0xc1235ce2,0x3f3504f7,2
+np.float32,0x41a35ce2,0x3f800000,2
+np.float32,0xc1a35ce2,0xbf800000,2
+np.float32,0x42235ce2,0xb5b889b6,2
+np.float32,0xc2235ce2,0x35b889b6,2
+np.float32,0x412fede0,0xbf800000,2
+np.float32,0xc12fede0,0x3f800000,2
+np.float32,0x41afede0,0xb5b222c4,2
+np.float32,0xc1afede0,0x35b222c4,2
+np.float32,0x422fede0,0x363222c4,2
+np.float32,0xc22fede0,0xb63222c4,2
+np.float32,0x413c7edd,0xbf3504f3,2
+np.float32,0xc13c7edd,0x3f3504f3,2
+np.float32,0x41bc7edd,0xbf800000,2
+np.float32,0xc1bc7edd,0x3f800000,2
+np.float32,0x423c7edd,0xb4000add,2
+np.float32,0xc23c7edd,0x34000add,2
+np.float32,0x41490fdb,0x34bbbd2e,2
+np.float32,0xc1490fdb,0xb4bbbd2e,2
+np.float32,0x41c90fdb,0x353bbd2e,2
+np.float32,0xc1c90fdb,0xb53bbd2e,2
+np.float32,0x42490fdb,0x35bbbd2e,2
+np.float32,0xc2490fdb,0xb5bbbd2e,2
+np.float32,0x4155a0d9,0x3f3504fb,2
+np.float32,0xc155a0d9,0xbf3504fb,2
+np.float32,0x41d5a0d9,0x3f800000,2
+np.float32,0xc1d5a0d9,0xbf800000,2
+np.float32,0x4255a0d9,0xb633bc81,2
+np.float32,0xc255a0d9,0x3633bc81,2
+np.float32,0x416231d6,0x3f800000,2
+np.float32,0xc16231d6,0xbf800000,2
+np.float32,0x41e231d6,0xb399a6a2,2
+np.float32,0xc1e231d6,0x3399a6a2,2
+np.float32,0x426231d6,0x3419a6a2,2
+np.float32,0xc26231d6,0xb419a6a2,2
+np.float32,0x416ec2d4,0x3f3504ef,2
+np.float32,0xc16ec2d4,0xbf3504ef,2
+np.float32,0x41eec2d4,0xbf800000,2
+np.float32,0xc1eec2d4,0x3f800000,2
+np.float32,0x426ec2d4,0xb5bef0a7,2
+np.float32,0xc26ec2d4,0x35bef0a7,2
+np.float32,0x417b53d2,0xb535563d,2
+np.float32,0xc17b53d2,0x3535563d,2
+np.float32,0x41fb53d2,0x35b5563d,2
+np.float32,0xc1fb53d2,0xb5b5563d,2
+np.float32,0x427b53d2,0x3635563d,2
+np.float32,0xc27b53d2,0xb635563d,2
+np.float32,0x4183f268,0xbf3504ff,2
+np.float32,0xc183f268,0x3f3504ff,2
+np.float32,0x4203f268,0x3f800000,2
+np.float32,0xc203f268,0xbf800000,2
+np.float32,0x4283f268,0xb6859a13,2
+np.float32,0xc283f268,0x36859a13,2
+np.float32,0x418a3ae7,0xbf800000,2
+np.float32,0xc18a3ae7,0x3f800000,2
+np.float32,0x420a3ae7,0xb6308908,2
+np.float32,0xc20a3ae7,0x36308908,2
+np.float32,0x428a3ae7,0x36b08908,2
+np.float32,0xc28a3ae7,0xb6b08908,2
+np.float32,0x41908365,0xbf3504f6,2
+np.float32,0xc1908365,0x3f3504f6,2
+np.float32,0x42108365,0xbf800000,2
+np.float32,0xc2108365,0x3f800000,2
+np.float32,0x42908365,0x3592200d,2
+np.float32,0xc2908365,0xb592200d,2
+np.float32,0x4196cbe4,0x334cde2e,2
+np.float32,0xc196cbe4,0xb34cde2e,2
+np.float32,0x4216cbe4,0x33ccde2e,2
+np.float32,0xc216cbe4,0xb3ccde2e,2
+np.float32,0x4296cbe4,0x344cde2e,2
+np.float32,0xc296cbe4,0xb44cde2e,2
+np.float32,0x419d1463,0x3f3504f8,2
+np.float32,0xc19d1463,0xbf3504f8,2
+np.float32,0x421d1463,0x3f800000,2
+np.float32,0xc21d1463,0xbf800000,2
+np.float32,0x429d1463,0xb5c55799,2
+np.float32,0xc29d1463,0x35c55799,2
+np.float32,0x41a35ce2,0x3f800000,2
+np.float32,0xc1a35ce2,0xbf800000,2
+np.float32,0x42235ce2,0xb5b889b6,2
+np.float32,0xc2235ce2,0x35b889b6,2
+np.float32,0x42a35ce2,0x363889b6,2
+np.float32,0xc2a35ce2,0xb63889b6,2
+np.float32,0x41a9a561,0x3f3504e7,2
+np.float32,0xc1a9a561,0xbf3504e7,2
+np.float32,0x4229a561,0xbf800000,2
+np.float32,0xc229a561,0x3f800000,2
+np.float32,0x42a9a561,0xb68733d0,2
+np.float32,0xc2a9a561,0x368733d0,2
+np.float32,0x41afede0,0xb5b222c4,2
+np.float32,0xc1afede0,0x35b222c4,2
+np.float32,0x422fede0,0x363222c4,2
+np.float32,0xc22fede0,0xb63222c4,2
+np.float32,0x42afede0,0x36b222c4,2
+np.float32,0xc2afede0,0xb6b222c4,2
+np.float32,0x41b6365e,0xbf3504f0,2
+np.float32,0xc1b6365e,0x3f3504f0,2
+np.float32,0x4236365e,0x3f800000,2
+np.float32,0xc236365e,0xbf800000,2
+np.float32,0x42b6365e,0x358bb91c,2
+np.float32,0xc2b6365e,0xb58bb91c,2
+np.float32,0x41bc7edd,0xbf800000,2
+np.float32,0xc1bc7edd,0x3f800000,2
+np.float32,0x423c7edd,0xb4000add,2
+np.float32,0xc23c7edd,0x34000add,2
+np.float32,0x42bc7edd,0x34800add,2
+np.float32,0xc2bc7edd,0xb4800add,2
+np.float32,0x41c2c75c,0xbf3504ef,2
+np.float32,0xc1c2c75c,0x3f3504ef,2
+np.float32,0x4242c75c,0xbf800000,2
+np.float32,0xc242c75c,0x3f800000,2
+np.float32,0x42c2c75c,0xb5cbbe8a,2
+np.float32,0xc2c2c75c,0x35cbbe8a,2
+np.float32,0x41c90fdb,0x353bbd2e,2
+np.float32,0xc1c90fdb,0xb53bbd2e,2
+np.float32,0x42490fdb,0x35bbbd2e,2
+np.float32,0xc2490fdb,0xb5bbbd2e,2
+np.float32,0x42c90fdb,0x363bbd2e,2
+np.float32,0xc2c90fdb,0xb63bbd2e,2
+np.float32,0x41cf585a,0x3f3504ff,2
+np.float32,0xc1cf585a,0xbf3504ff,2
+np.float32,0x424f585a,0x3f800000,2
+np.float32,0xc24f585a,0xbf800000,2
+np.float32,0x42cf585a,0xb688cd8c,2
+np.float32,0xc2cf585a,0x3688cd8c,2
+np.float32,0x41d5a0d9,0x3f800000,2
+np.float32,0xc1d5a0d9,0xbf800000,2
+np.float32,0x4255a0d9,0xb633bc81,2
+np.float32,0xc255a0d9,0x3633bc81,2
+np.float32,0x42d5a0d9,0x36b3bc81,2
+np.float32,0xc2d5a0d9,0xb6b3bc81,2
+np.float32,0x41dbe958,0x3f3504e0,2
+np.float32,0xc1dbe958,0xbf3504e0,2
+np.float32,0x425be958,0xbf800000,2
+np.float32,0xc25be958,0x3f800000,2
+np.float32,0x42dbe958,0xb6deab75,2
+np.float32,0xc2dbe958,0x36deab75,2
+np.float32,0x41e231d6,0xb399a6a2,2
+np.float32,0xc1e231d6,0x3399a6a2,2
+np.float32,0x426231d6,0x3419a6a2,2
+np.float32,0xc26231d6,0xb419a6a2,2
+np.float32,0x42e231d6,0x3499a6a2,2
+np.float32,0xc2e231d6,0xb499a6a2,2
+np.float32,0x41e87a55,0xbf3504f8,2
+np.float32,0xc1e87a55,0x3f3504f8,2
+np.float32,0x42687a55,0x3f800000,2
+np.float32,0xc2687a55,0xbf800000,2
+np.float32,0x42e87a55,0xb5d2257b,2
+np.float32,0xc2e87a55,0x35d2257b,2
+np.float32,0x41eec2d4,0xbf800000,2
+np.float32,0xc1eec2d4,0x3f800000,2
+np.float32,0x426ec2d4,0xb5bef0a7,2
+np.float32,0xc26ec2d4,0x35bef0a7,2
+np.float32,0x42eec2d4,0x363ef0a7,2
+np.float32,0xc2eec2d4,0xb63ef0a7,2
+np.float32,0x41f50b53,0xbf3504e7,2
+np.float32,0xc1f50b53,0x3f3504e7,2
+np.float32,0x42750b53,0xbf800000,2
+np.float32,0xc2750b53,0x3f800000,2
+np.float32,0x42f50b53,0xb68a6748,2
+np.float32,0xc2f50b53,0x368a6748,2
+np.float32,0x41fb53d2,0x35b5563d,2
+np.float32,0xc1fb53d2,0xb5b5563d,2
+np.float32,0x427b53d2,0x3635563d,2
+np.float32,0xc27b53d2,0xb635563d,2
+np.float32,0x42fb53d2,0x36b5563d,2
+np.float32,0xc2fb53d2,0xb6b5563d,2
+np.float32,0x4200ce28,0x3f3504f0,2
+np.float32,0xc200ce28,0xbf3504f0,2
+np.float32,0x4280ce28,0x3f800000,2
+np.float32,0xc280ce28,0xbf800000,2
+np.float32,0x4300ce28,0x357dd672,2
+np.float32,0xc300ce28,0xb57dd672,2
+np.float32,0x4203f268,0x3f800000,2
+np.float32,0xc203f268,0xbf800000,2
+np.float32,0x4283f268,0xb6859a13,2
+np.float32,0xc283f268,0x36859a13,2
+np.float32,0x4303f268,0x37059a13,2
+np.float32,0xc303f268,0xb7059a13,2
+np.float32,0x420716a7,0x3f3504ee,2
+np.float32,0xc20716a7,0xbf3504ee,2
+np.float32,0x428716a7,0xbf800000,2
+np.float32,0xc28716a7,0x3f800000,2
+np.float32,0x430716a7,0xb5d88c6d,2
+np.float32,0xc30716a7,0x35d88c6d,2
+np.float32,0x420a3ae7,0xb6308908,2
+np.float32,0xc20a3ae7,0x36308908,2
+np.float32,0x428a3ae7,0x36b08908,2
+np.float32,0xc28a3ae7,0xb6b08908,2
+np.float32,0x430a3ae7,0x37308908,2
+np.float32,0xc30a3ae7,0xb7308908,2
+np.float32,0x420d5f26,0xbf350500,2
+np.float32,0xc20d5f26,0x3f350500,2
+np.float32,0x428d5f26,0x3f800000,2
+np.float32,0xc28d5f26,0xbf800000,2
+np.float32,0x430d5f26,0xb68c0105,2
+np.float32,0xc30d5f26,0x368c0105,2
+np.float32,0x42108365,0xbf800000,2
+np.float32,0xc2108365,0x3f800000,2
+np.float32,0x42908365,0x3592200d,2
+np.float32,0xc2908365,0xb592200d,2
+np.float32,0x43108365,0xb612200d,2
+np.float32,0xc3108365,0x3612200d,2
+np.float32,0x4213a7a5,0xbf3504df,2
+np.float32,0xc213a7a5,0x3f3504df,2
+np.float32,0x4293a7a5,0xbf800000,2
+np.float32,0xc293a7a5,0x3f800000,2
+np.float32,0x4313a7a5,0xb6e1deee,2
+np.float32,0xc313a7a5,0x36e1deee,2
+np.float32,0x4216cbe4,0x33ccde2e,2
+np.float32,0xc216cbe4,0xb3ccde2e,2
+np.float32,0x4296cbe4,0x344cde2e,2
+np.float32,0xc296cbe4,0xb44cde2e,2
+np.float32,0x4316cbe4,0x34ccde2e,2
+np.float32,0xc316cbe4,0xb4ccde2e,2
+np.float32,0x4219f024,0x3f35050f,2
+np.float32,0xc219f024,0xbf35050f,2
+np.float32,0x4299f024,0x3f800000,2
+np.float32,0xc299f024,0xbf800000,2
+np.float32,0x4319f024,0xb71bde6c,2
+np.float32,0xc319f024,0x371bde6c,2
+np.float32,0x421d1463,0x3f800000,2
+np.float32,0xc21d1463,0xbf800000,2
+np.float32,0x429d1463,0xb5c55799,2
+np.float32,0xc29d1463,0x35c55799,2
+np.float32,0x431d1463,0x36455799,2
+np.float32,0xc31d1463,0xb6455799,2
+np.float32,0x422038a3,0x3f3504d0,2
+np.float32,0xc22038a3,0xbf3504d0,2
+np.float32,0x42a038a3,0xbf800000,2
+np.float32,0xc2a038a3,0x3f800000,2
+np.float32,0x432038a3,0xb746cd61,2
+np.float32,0xc32038a3,0x3746cd61,2
+np.float32,0x42235ce2,0xb5b889b6,2
+np.float32,0xc2235ce2,0x35b889b6,2
+np.float32,0x42a35ce2,0x363889b6,2
+np.float32,0xc2a35ce2,0xb63889b6,2
+np.float32,0x43235ce2,0x36b889b6,2
+np.float32,0xc3235ce2,0xb6b889b6,2
+np.float32,0x42268121,0xbf3504f1,2
+np.float32,0xc2268121,0x3f3504f1,2
+np.float32,0x42a68121,0x3f800000,2
+np.float32,0xc2a68121,0xbf800000,2
+np.float32,0x43268121,0x35643aac,2
+np.float32,0xc3268121,0xb5643aac,2
+np.float32,0x4229a561,0xbf800000,2
+np.float32,0xc229a561,0x3f800000,2
+np.float32,0x42a9a561,0xb68733d0,2
+np.float32,0xc2a9a561,0x368733d0,2
+np.float32,0x4329a561,0x370733d0,2
+np.float32,0xc329a561,0xb70733d0,2
+np.float32,0x422cc9a0,0xbf3504ee,2
+np.float32,0xc22cc9a0,0x3f3504ee,2
+np.float32,0x42acc9a0,0xbf800000,2
+np.float32,0xc2acc9a0,0x3f800000,2
+np.float32,0x432cc9a0,0xb5e55a50,2
+np.float32,0xc32cc9a0,0x35e55a50,2
+np.float32,0x422fede0,0x363222c4,2
+np.float32,0xc22fede0,0xb63222c4,2
+np.float32,0x42afede0,0x36b222c4,2
+np.float32,0xc2afede0,0xb6b222c4,2
+np.float32,0x432fede0,0x373222c4,2
+np.float32,0xc32fede0,0xb73222c4,2
+np.float32,0x4233121f,0x3f350500,2
+np.float32,0xc233121f,0xbf350500,2
+np.float32,0x42b3121f,0x3f800000,2
+np.float32,0xc2b3121f,0xbf800000,2
+np.float32,0x4333121f,0xb68f347d,2
+np.float32,0xc333121f,0x368f347d,2
+np.float32,0x4236365e,0x3f800000,2
+np.float32,0xc236365e,0xbf800000,2
+np.float32,0x42b6365e,0x358bb91c,2
+np.float32,0xc2b6365e,0xb58bb91c,2
+np.float32,0x4336365e,0xb60bb91c,2
+np.float32,0xc336365e,0x360bb91c,2
+np.float32,0x42395a9e,0x3f3504df,2
+np.float32,0xc2395a9e,0xbf3504df,2
+np.float32,0x42b95a9e,0xbf800000,2
+np.float32,0xc2b95a9e,0x3f800000,2
+np.float32,0x43395a9e,0xb6e51267,2
+np.float32,0xc3395a9e,0x36e51267,2
+np.float32,0x423c7edd,0xb4000add,2
+np.float32,0xc23c7edd,0x34000add,2
+np.float32,0x42bc7edd,0x34800add,2
+np.float32,0xc2bc7edd,0xb4800add,2
+np.float32,0x433c7edd,0x35000add,2
+np.float32,0xc33c7edd,0xb5000add,2
+np.float32,0x423fa31d,0xbf35050f,2
+np.float32,0xc23fa31d,0x3f35050f,2
+np.float32,0x42bfa31d,0x3f800000,2
+np.float32,0xc2bfa31d,0xbf800000,2
+np.float32,0x433fa31d,0xb71d7828,2
+np.float32,0xc33fa31d,0x371d7828,2
+np.float32,0x4242c75c,0xbf800000,2
+np.float32,0xc242c75c,0x3f800000,2
+np.float32,0x42c2c75c,0xb5cbbe8a,2
+np.float32,0xc2c2c75c,0x35cbbe8a,2
+np.float32,0x4342c75c,0x364bbe8a,2
+np.float32,0xc342c75c,0xb64bbe8a,2
+np.float32,0x4245eb9c,0xbf3504d0,2
+np.float32,0xc245eb9c,0x3f3504d0,2
+np.float32,0x42c5eb9c,0xbf800000,2
+np.float32,0xc2c5eb9c,0x3f800000,2
+np.float32,0x4345eb9c,0xb748671d,2
+np.float32,0xc345eb9c,0x3748671d,2
+np.float32,0x42490fdb,0x35bbbd2e,2
+np.float32,0xc2490fdb,0xb5bbbd2e,2
+np.float32,0x42c90fdb,0x363bbd2e,2
+np.float32,0xc2c90fdb,0xb63bbd2e,2
+np.float32,0x43490fdb,0x36bbbd2e,2
+np.float32,0xc3490fdb,0xb6bbbd2e,2
+np.float32,0x424c341a,0x3f3504f1,2
+np.float32,0xc24c341a,0xbf3504f1,2
+np.float32,0x42cc341a,0x3f800000,2
+np.float32,0xc2cc341a,0xbf800000,2
+np.float32,0x434c341a,0x354a9ee6,2
+np.float32,0xc34c341a,0xb54a9ee6,2
+np.float32,0x424f585a,0x3f800000,2
+np.float32,0xc24f585a,0xbf800000,2
+np.float32,0x42cf585a,0xb688cd8c,2
+np.float32,0xc2cf585a,0x3688cd8c,2
+np.float32,0x434f585a,0x3708cd8c,2
+np.float32,0xc34f585a,0xb708cd8c,2
+np.float32,0x42527c99,0x3f3504ee,2
+np.float32,0xc2527c99,0xbf3504ee,2
+np.float32,0x42d27c99,0xbf800000,2
+np.float32,0xc2d27c99,0x3f800000,2
+np.float32,0x43527c99,0xb5f22833,2
+np.float32,0xc3527c99,0x35f22833,2
+np.float32,0x4255a0d9,0xb633bc81,2
+np.float32,0xc255a0d9,0x3633bc81,2
+np.float32,0x42d5a0d9,0x36b3bc81,2
+np.float32,0xc2d5a0d9,0xb6b3bc81,2
+np.float32,0x4355a0d9,0x3733bc81,2
+np.float32,0xc355a0d9,0xb733bc81,2
+np.float32,0x4258c518,0xbf350500,2
+np.float32,0xc258c518,0x3f350500,2
+np.float32,0x42d8c518,0x3f800000,2
+np.float32,0xc2d8c518,0xbf800000,2
+np.float32,0x4358c518,0xb69267f6,2
+np.float32,0xc358c518,0x369267f6,2
+np.float32,0x425be958,0xbf800000,2
+np.float32,0xc25be958,0x3f800000,2
+np.float32,0x42dbe958,0xb6deab75,2
+np.float32,0xc2dbe958,0x36deab75,2
+np.float32,0x435be958,0x375eab75,2
+np.float32,0xc35be958,0xb75eab75,2
+np.float32,0x425f0d97,0xbf3504df,2
+np.float32,0xc25f0d97,0x3f3504df,2
+np.float32,0x42df0d97,0xbf800000,2
+np.float32,0xc2df0d97,0x3f800000,2
+np.float32,0x435f0d97,0xb6e845e0,2
+np.float32,0xc35f0d97,0x36e845e0,2
+np.float32,0x426231d6,0x3419a6a2,2
+np.float32,0xc26231d6,0xb419a6a2,2
+np.float32,0x42e231d6,0x3499a6a2,2
+np.float32,0xc2e231d6,0xb499a6a2,2
+np.float32,0x436231d6,0x3519a6a2,2
+np.float32,0xc36231d6,0xb519a6a2,2
+np.float32,0x42655616,0x3f35050f,2
+np.float32,0xc2655616,0xbf35050f,2
+np.float32,0x42e55616,0x3f800000,2
+np.float32,0xc2e55616,0xbf800000,2
+np.float32,0x43655616,0xb71f11e5,2
+np.float32,0xc3655616,0x371f11e5,2
+np.float32,0x42687a55,0x3f800000,2
+np.float32,0xc2687a55,0xbf800000,2
+np.float32,0x42e87a55,0xb5d2257b,2
+np.float32,0xc2e87a55,0x35d2257b,2
+np.float32,0x43687a55,0x3652257b,2
+np.float32,0xc3687a55,0xb652257b,2
+np.float32,0x426b9e95,0x3f3504cf,2
+np.float32,0xc26b9e95,0xbf3504cf,2
+np.float32,0x42eb9e95,0xbf800000,2
+np.float32,0xc2eb9e95,0x3f800000,2
+np.float32,0x436b9e95,0xb74a00d9,2
+np.float32,0xc36b9e95,0x374a00d9,2
+np.float32,0x426ec2d4,0xb5bef0a7,2
+np.float32,0xc26ec2d4,0x35bef0a7,2
+np.float32,0x42eec2d4,0x363ef0a7,2
+np.float32,0xc2eec2d4,0xb63ef0a7,2
+np.float32,0x436ec2d4,0x36bef0a7,2
+np.float32,0xc36ec2d4,0xb6bef0a7,2
+np.float32,0x4271e713,0xbf3504f1,2
+np.float32,0xc271e713,0x3f3504f1,2
+np.float32,0x42f1e713,0x3f800000,2
+np.float32,0xc2f1e713,0xbf800000,2
+np.float32,0x4371e713,0x35310321,2
+np.float32,0xc371e713,0xb5310321,2
+np.float32,0x42750b53,0xbf800000,2
+np.float32,0xc2750b53,0x3f800000,2
+np.float32,0x42f50b53,0xb68a6748,2
+np.float32,0xc2f50b53,0x368a6748,2
+np.float32,0x43750b53,0x370a6748,2
+np.float32,0xc3750b53,0xb70a6748,2
+np.float32,0x42782f92,0xbf3504ee,2
+np.float32,0xc2782f92,0x3f3504ee,2
+np.float32,0x42f82f92,0xbf800000,2
+np.float32,0xc2f82f92,0x3f800000,2
+np.float32,0x43782f92,0xb5fef616,2
+np.float32,0xc3782f92,0x35fef616,2
+np.float32,0x427b53d2,0x3635563d,2
+np.float32,0xc27b53d2,0xb635563d,2
+np.float32,0x42fb53d2,0x36b5563d,2
+np.float32,0xc2fb53d2,0xb6b5563d,2
+np.float32,0x437b53d2,0x3735563d,2
+np.float32,0xc37b53d2,0xb735563d,2
+np.float32,0x427e7811,0x3f350500,2
+np.float32,0xc27e7811,0xbf350500,2
+np.float32,0x42fe7811,0x3f800000,2
+np.float32,0xc2fe7811,0xbf800000,2
+np.float32,0x437e7811,0xb6959b6f,2
+np.float32,0xc37e7811,0x36959b6f,2
+np.float32,0x4280ce28,0x3f800000,2
+np.float32,0xc280ce28,0xbf800000,2
+np.float32,0x4300ce28,0x357dd672,2
+np.float32,0xc300ce28,0xb57dd672,2
+np.float32,0x4380ce28,0xb5fdd672,2
+np.float32,0xc380ce28,0x35fdd672,2
+np.float32,0x42826048,0x3f3504de,2
+np.float32,0xc2826048,0xbf3504de,2
+np.float32,0x43026048,0xbf800000,2
+np.float32,0xc3026048,0x3f800000,2
+np.float32,0x43826048,0xb6eb7958,2
+np.float32,0xc3826048,0x36eb7958,2
+np.float32,0x4283f268,0xb6859a13,2
+np.float32,0xc283f268,0x36859a13,2
+np.float32,0x4303f268,0x37059a13,2
+np.float32,0xc303f268,0xb7059a13,2
+np.float32,0x4383f268,0x37859a13,2
+np.float32,0xc383f268,0xb7859a13,2
+np.float32,0x42858487,0xbf3504e2,2
+np.float32,0xc2858487,0x3f3504e2,2
+np.float32,0x43058487,0x3f800000,2
+np.float32,0xc3058487,0xbf800000,2
+np.float32,0x43858487,0x36bea8be,2
+np.float32,0xc3858487,0xb6bea8be,2
+np.float32,0x428716a7,0xbf800000,2
+np.float32,0xc28716a7,0x3f800000,2
+np.float32,0x430716a7,0xb5d88c6d,2
+np.float32,0xc30716a7,0x35d88c6d,2
+np.float32,0x438716a7,0x36588c6d,2
+np.float32,0xc38716a7,0xb6588c6d,2
+np.float32,0x4288a8c7,0xbf3504cf,2
+np.float32,0xc288a8c7,0x3f3504cf,2
+np.float32,0x4308a8c7,0xbf800000,2
+np.float32,0xc308a8c7,0x3f800000,2
+np.float32,0x4388a8c7,0xb74b9a96,2
+np.float32,0xc388a8c7,0x374b9a96,2
+np.float32,0x428a3ae7,0x36b08908,2
+np.float32,0xc28a3ae7,0xb6b08908,2
+np.float32,0x430a3ae7,0x37308908,2
+np.float32,0xc30a3ae7,0xb7308908,2
+np.float32,0x438a3ae7,0x37b08908,2
+np.float32,0xc38a3ae7,0xb7b08908,2
+np.float32,0x428bcd06,0x3f3504f2,2
+np.float32,0xc28bcd06,0xbf3504f2,2
+np.float32,0x430bcd06,0x3f800000,2
+np.float32,0xc30bcd06,0xbf800000,2
+np.float32,0x438bcd06,0x3517675b,2
+np.float32,0xc38bcd06,0xb517675b,2
+np.float32,0x428d5f26,0x3f800000,2
+np.float32,0xc28d5f26,0xbf800000,2
+np.float32,0x430d5f26,0xb68c0105,2
+np.float32,0xc30d5f26,0x368c0105,2
+np.float32,0x438d5f26,0x370c0105,2
+np.float32,0xc38d5f26,0xb70c0105,2
+np.float32,0x428ef146,0x3f3504c0,2
+np.float32,0xc28ef146,0xbf3504c0,2
+np.float32,0x430ef146,0xbf800000,2
+np.float32,0xc30ef146,0x3f800000,2
+np.float32,0x438ef146,0xb790bc40,2
+np.float32,0xc38ef146,0x3790bc40,2
+np.float32,0x42908365,0x3592200d,2
+np.float32,0xc2908365,0xb592200d,2
+np.float32,0x43108365,0xb612200d,2
+np.float32,0xc3108365,0x3612200d,2
+np.float32,0x43908365,0xb692200d,2
+np.float32,0xc3908365,0x3692200d,2
+np.float32,0x42921585,0xbf350501,2
+np.float32,0xc2921585,0x3f350501,2
+np.float32,0x43121585,0x3f800000,2
+np.float32,0xc3121585,0xbf800000,2
+np.float32,0x43921585,0xb698cee8,2
+np.float32,0xc3921585,0x3698cee8,2
+np.float32,0x4293a7a5,0xbf800000,2
+np.float32,0xc293a7a5,0x3f800000,2
+np.float32,0x4313a7a5,0xb6e1deee,2
+np.float32,0xc313a7a5,0x36e1deee,2
+np.float32,0x4393a7a5,0x3761deee,2
+np.float32,0xc393a7a5,0xb761deee,2
+np.float32,0x429539c5,0xbf3504b1,2
+np.float32,0xc29539c5,0x3f3504b1,2
+np.float32,0x431539c5,0xbf800000,2
+np.float32,0xc31539c5,0x3f800000,2
+np.float32,0x439539c5,0xb7bbab34,2
+np.float32,0xc39539c5,0x37bbab34,2
+np.float32,0x4296cbe4,0x344cde2e,2
+np.float32,0xc296cbe4,0xb44cde2e,2
+np.float32,0x4316cbe4,0x34ccde2e,2
+np.float32,0xc316cbe4,0xb4ccde2e,2
+np.float32,0x4396cbe4,0x354cde2e,2
+np.float32,0xc396cbe4,0xb54cde2e,2
+np.float32,0x42985e04,0x3f350510,2
+np.float32,0xc2985e04,0xbf350510,2
+np.float32,0x43185e04,0x3f800000,2
+np.float32,0xc3185e04,0xbf800000,2
+np.float32,0x43985e04,0xb722455d,2
+np.float32,0xc3985e04,0x3722455d,2
+np.float32,0x4299f024,0x3f800000,2
+np.float32,0xc299f024,0xbf800000,2
+np.float32,0x4319f024,0xb71bde6c,2
+np.float32,0xc319f024,0x371bde6c,2
+np.float32,0x4399f024,0x379bde6c,2
+np.float32,0xc399f024,0xb79bde6c,2
+np.float32,0x429b8243,0x3f3504fc,2
+np.float32,0xc29b8243,0xbf3504fc,2
+np.float32,0x431b8243,0xbf800000,2
+np.float32,0xc31b8243,0x3f800000,2
+np.float32,0x439b8243,0x364b2eb8,2
+np.float32,0xc39b8243,0xb64b2eb8,2
+np.float32,0x435b2047,0xbf350525,2
+np.float32,0x42a038a2,0xbf800000,2
+np.float32,0x432038a2,0x3664ca7e,2
+np.float32,0x4345eb9b,0x365e638c,2
+np.float32,0x42c5eb9b,0xbf800000,2
+np.float32,0x42eb9e94,0xbf800000,2
+np.float32,0x4350ea79,0x3f800000,2
+np.float32,0x42dbe957,0x3585522a,2
+np.float32,0x425be957,0xbf800000,2
+np.float32,0x435be957,0xb605522a,2
+np.float32,0x476362a2,0xbd7ff911,2
+np.float32,0x464c99a4,0x3e7f4d41,2
+np.float32,0x4471f73d,0x3e7fe1b0,2
+np.float32,0x445a6752,0x3e7ef367,2
+np.float32,0x474fa400,0x3e7f9fcd,2
+np.float32,0x45c1e72f,0xbe7fc7af,2
+np.float32,0x4558c91d,0x3e7e9f31,2
+np.float32,0x43784f94,0xbdff6654,2
+np.float32,0x466e8500,0xbe7ea0a3,2
+np.float32,0x468e1c25,0x3e7e22fb,2
+np.float32,0x44ea6cfc,0x3dff70c3,2
+np.float32,0x4605126c,0x3e7f89ef,2
+np.float32,0x4788b3c6,0xbb87d853,2
+np.float32,0x4531b042,0x3dffd163,2
+np.float32,0x43f1f71d,0x3dfff387,2
+np.float32,0x462c3fa5,0xbd7fe13d,2
+np.float32,0x441c5354,0xbdff76b4,2
+np.float32,0x44908b69,0x3e7dcf0d,2
+np.float32,0x478813ad,0xbe7e9d80,2
+np.float32,0x441c4351,0x3dff937b,2
+np.float64,0x1,0x1,4
+np.float64,0x8000000000000001,0x8000000000000001,4
+np.float64,0x10000000000000,0x10000000000000,4
+np.float64,0x8010000000000000,0x8010000000000000,4
+np.float64,0x7fefffffffffffff,0x3f7452fc98b34e97,4
+np.float64,0xffefffffffffffff,0xbf7452fc98b34e97,4
+np.float64,0x7ff0000000000000,0xfff8000000000000,4
+np.float64,0xfff0000000000000,0xfff8000000000000,4
+np.float64,0x7ff8000000000000,0x7ff8000000000000,4
+np.float64,0x7ff4000000000000,0x7ffc000000000000,4
+np.float64,0xbfda51b226b4a364,0xbfd9956328ff876c,4
+np.float64,0xbfb4a65aee294cb8,0xbfb4a09fd744f8a5,4
+np.float64,0xbfd73b914fae7722,0xbfd6b9cce55af379,4
+np.float64,0xbfd90c12b4b21826,0xbfd869a3867b51c2,4
+np.float64,0x3fe649bb3d6c9376,0x3fe48778d9b48a21,4
+np.float64,0xbfd5944532ab288a,0xbfd52c30e1951b42,4
+np.float64,0x3fb150c45222a190,0x3fb14d633eb8275d,4
+np.float64,0x3fe4a6ffa9e94e00,0x3fe33f8a95c33299,4
+np.float64,0x3fe8d2157171a42a,0x3fe667d904ac95a6,4
+np.float64,0xbfa889f52c3113f0,0xbfa8878d90a23fa5,4
+np.float64,0x3feb3234bef6646a,0x3fe809d541d9017a,4
+np.float64,0x3fc6de266f2dbc50,0x3fc6bf0ee80a0d86,4
+np.float64,0x3fe8455368f08aa6,0x3fe6028254338ed5,4
+np.float64,0xbfe5576079eaaec1,0xbfe3cb4a8f6bc3f5,4
+np.float64,0xbfe9f822ff73f046,0xbfe7360d7d5cb887,4
+np.float64,0xbfb1960e7e232c20,0xbfb1928438258602,4
+np.float64,0xbfca75938d34eb28,0xbfca4570979bf2fa,4
+np.float64,0x3fd767dd15aecfbc,0x3fd6e33039018bab,4
+np.float64,0xbfe987750ef30eea,0xbfe6e7ed30ce77f0,4
+np.float64,0xbfe87f95a1f0ff2b,0xbfe62ca7e928bb2a,4
+np.float64,0xbfd2465301a48ca6,0xbfd2070245775d76,4
+np.float64,0xbfb1306ed22260e0,0xbfb12d2088eaa4f9,4
+np.float64,0xbfd8089010b01120,0xbfd778f9db77f2f3,4
+np.float64,0x3fbf9cf4ee3f39f0,0x3fbf88674fde1ca2,4
+np.float64,0x3fe6d8468a6db08e,0x3fe4f403f38b7bec,4
+np.float64,0xbfd9e5deefb3cbbe,0xbfd932692c722351,4
+np.float64,0x3fd1584d55a2b09c,0x3fd122253eeecc2e,4
+np.float64,0x3fe857979cf0af30,0x3fe60fc12b5ba8db,4
+np.float64,0x3fe3644149e6c882,0x3fe239f47013cfe6,4
+np.float64,0xbfe22ea62be45d4c,0xbfe13834c17d56fe,4
+np.float64,0xbfe8d93e1df1b27c,0xbfe66cf4ee467fd2,4
+np.float64,0xbfe9c497c9f38930,0xbfe7127417da4204,4
+np.float64,0x3fd6791cecacf238,0x3fd6039ccb5a7fde,4
+np.float64,0xbfc1dc1b1523b838,0xbfc1cd48edd9ae19,4
+np.float64,0xbfc92a8491325508,0xbfc901176e0158a5,4
+np.float64,0x3fa8649b3430c940,0x3fa8623e82d9504f,4
+np.float64,0x3fe0bed6a1617dae,0x3fdffbb307fb1abe,4
+np.float64,0x3febdf7765f7beee,0x3fe87ad01a89b74a,4
+np.float64,0xbfd3a56d46a74ada,0xbfd356cf41bf83cd,4
+np.float64,0x3fd321d824a643b0,0x3fd2d93846a224b3,4
+np.float64,0xbfc6a49fb52d4940,0xbfc686704906e7d3,4
+np.float64,0xbfdd4103c9ba8208,0xbfdc3ef0c03615b4,4
+np.float64,0xbfe0b78a51e16f14,0xbfdfef0d9ffc38b5,4
+np.float64,0xbfdac7a908b58f52,0xbfda0158956ceecf,4
+np.float64,0xbfbfbf12f23f7e28,0xbfbfaa428989258c,4
+np.float64,0xbfd55f5aa2aabeb6,0xbfd4fa39de65f33a,4
+np.float64,0x3fe06969abe0d2d4,0x3fdf6744fafdd9cf,4
+np.float64,0x3fe56ab8be6ad572,0x3fe3da7a1986d543,4
+np.float64,0xbfeefbbec67df77e,0xbfea5d426132f4aa,4
+np.float64,0x3fe6e1f49cedc3ea,0x3fe4fb53f3d8e3d5,4
+np.float64,0x3feceb231c79d646,0x3fe923d3efa55414,4
+np.float64,0xbfd03dd08ea07ba2,0xbfd011549aa1998a,4
+np.float64,0xbfd688327aad1064,0xbfd611c61b56adbe,4
+np.float64,0xbfde3249d8bc6494,0xbfdd16a7237a39d5,4
+np.float64,0x3febd4b65677a96c,0x3fe873e1a401ef03,4
+np.float64,0xbfe46bd2b368d7a6,0xbfe31023c2467749,4
+np.float64,0x3fbf9f5cde3f3ec0,0x3fbf8aca8ec53c45,4
+np.float64,0x3fc20374032406e8,0x3fc1f43f1f2f4d5e,4
+np.float64,0xbfec143b16f82876,0xbfe89caa42582381,4
+np.float64,0xbfd14fa635a29f4c,0xbfd119ced11da669,4
+np.float64,0x3fe25236d4e4a46e,0x3fe156242d644b7a,4
+np.float64,0xbfe4ed793469daf2,0xbfe377a88928fd77,4
+np.float64,0xbfb363572626c6b0,0xbfb35e98d8fe87ae,4
+np.float64,0xbfb389d5aa2713a8,0xbfb384fae55565a7,4
+np.float64,0x3fca6e001934dc00,0x3fca3e0661eaca84,4
+np.float64,0x3fe748f3f76e91e8,0x3fe548ab2168aea6,4
+np.float64,0x3fef150efdfe2a1e,0x3fea6b92d74f60d3,4
+np.float64,0xbfd14b52b1a296a6,0xbfd115a387c0fa93,4
+np.float64,0x3fe3286b5ce650d6,0x3fe208a6469a7527,4
+np.float64,0xbfd57b4f4baaf69e,0xbfd514a12a9f7ab0,4
+np.float64,0xbfef14bd467e297b,0xbfea6b64bbfd42ce,4
+np.float64,0xbfe280bc90650179,0xbfe17d2c49955dba,4
+np.float64,0x3fca8759d7350eb0,0x3fca56d5c17bbc14,4
+np.float64,0xbfdf988f30bf311e,0xbfde53f96f69b05f,4
+np.float64,0x3f6b6eeb4036de00,0x3f6b6ee7e3f86f9a,4
+np.float64,0xbfed560be8faac18,0xbfe9656c5cf973d8,4
+np.float64,0x3fc6102c592c2058,0x3fc5f43efad5396d,4
+np.float64,0xbfdef64ed2bdec9e,0xbfddc4b7fbd45aea,4
+np.float64,0x3fe814acd570295a,0x3fe5df183d543bfe,4
+np.float64,0x3fca21313f344260,0x3fc9f2d47f64fbe2,4
+np.float64,0xbfe89932cc713266,0xbfe63f186a2f60ce,4
+np.float64,0x3fe4ffcff169ffa0,0x3fe386336115ee21,4
+np.float64,0x3fee6964087cd2c8,0x3fea093d31e2c2c5,4
+np.float64,0xbfbeea604e3dd4c0,0xbfbed72734852669,4
+np.float64,0xbfea1954fb7432aa,0xbfe74cdad8720032,4
+np.float64,0x3fea3e1a5ef47c34,0x3fe765ffba65a11d,4
+np.float64,0x3fcedb850b3db708,0x3fce8f39d92f00ba,4
+np.float64,0x3fd3b52d41a76a5c,0x3fd365d22b0003f9,4
+np.float64,0xbfa4108a0c282110,0xbfa40f397fcd844f,4
+np.float64,0x3fd7454c57ae8a98,0x3fd6c2e5542c6c83,4
+np.float64,0xbfeecd3c7a7d9a79,0xbfea42ca943a1695,4
+np.float64,0xbfdddda397bbbb48,0xbfdccb27283d4c4c,4
+np.float64,0x3fe6b52cf76d6a5a,0x3fe4d96ff32925ff,4
+np.float64,0xbfa39a75ec2734f0,0xbfa3993c0da84f87,4
+np.float64,0x3fdd3fe6fdba7fcc,0x3fdc3df12fe9e525,4
+np.float64,0xbfb57a98162af530,0xbfb5742525d5fbe2,4
+np.float64,0xbfd3e166cfa7c2ce,0xbfd38ff2891be9b0,4
+np.float64,0x3fdb6a04f9b6d408,0x3fda955e5018e9dc,4
+np.float64,0x3fe4ab03a4e95608,0x3fe342bfa76e1aa8,4
+np.float64,0xbfe6c8480b6d9090,0xbfe4e7eaa935b3f5,4
+np.float64,0xbdd6b5a17bae,0xbdd6b5a17bae,4
+np.float64,0xd6591979acb23,0xd6591979acb23,4
+np.float64,0x5adbed90b5b7e,0x5adbed90b5b7e,4
+np.float64,0xa664c5314cc99,0xa664c5314cc99,4
+np.float64,0x1727fb162e500,0x1727fb162e500,4
+np.float64,0xdb49a93db6935,0xdb49a93db6935,4
+np.float64,0xb10c958d62193,0xb10c958d62193,4
+np.float64,0xad38276f5a705,0xad38276f5a705,4
+np.float64,0x1d5d0b983aba2,0x1d5d0b983aba2,4
+np.float64,0x915f48e122be9,0x915f48e122be9,4
+np.float64,0x475958ae8eb2c,0x475958ae8eb2c,4
+np.float64,0x3af8406675f09,0x3af8406675f09,4
+np.float64,0x655e88a4cabd2,0x655e88a4cabd2,4
+np.float64,0x40fee8ce81fde,0x40fee8ce81fde,4
+np.float64,0xab83103f57062,0xab83103f57062,4
+np.float64,0x7cf934b8f9f27,0x7cf934b8f9f27,4
+np.float64,0x29f7524853eeb,0x29f7524853eeb,4
+np.float64,0x4a5e954894bd3,0x4a5e954894bd3,4
+np.float64,0x24638f3a48c73,0x24638f3a48c73,4
+np.float64,0xa4f32fc749e66,0xa4f32fc749e66,4
+np.float64,0xf8e92df7f1d26,0xf8e92df7f1d26,4
+np.float64,0x292e9d50525d4,0x292e9d50525d4,4
+np.float64,0xe937e897d26fd,0xe937e897d26fd,4
+np.float64,0xd3bde1d5a77bc,0xd3bde1d5a77bc,4
+np.float64,0xa447ffd548900,0xa447ffd548900,4
+np.float64,0xa3b7b691476f7,0xa3b7b691476f7,4
+np.float64,0x490095c892013,0x490095c892013,4
+np.float64,0xfc853235f90a7,0xfc853235f90a7,4
+np.float64,0x5a8bc082b5179,0x5a8bc082b5179,4
+np.float64,0x1baca45a37595,0x1baca45a37595,4
+np.float64,0x2164120842c83,0x2164120842c83,4
+np.float64,0x66692bdeccd26,0x66692bdeccd26,4
+np.float64,0xf205bdd3e40b8,0xf205bdd3e40b8,4
+np.float64,0x7c3fff98f8801,0x7c3fff98f8801,4
+np.float64,0xccdf10e199bf,0xccdf10e199bf,4
+np.float64,0x92db8e8125b8,0x92db8e8125b8,4
+np.float64,0x5789a8d6af136,0x5789a8d6af136,4
+np.float64,0xbdda869d7bb51,0xbdda869d7bb51,4
+np.float64,0xb665e0596ccbc,0xb665e0596ccbc,4
+np.float64,0x74e6b46ee9cd7,0x74e6b46ee9cd7,4
+np.float64,0x4f39cf7c9e73b,0x4f39cf7c9e73b,4
+np.float64,0xfdbf3907fb7e7,0xfdbf3907fb7e7,4
+np.float64,0xafdef4d55fbdf,0xafdef4d55fbdf,4
+np.float64,0xb49858236930b,0xb49858236930b,4
+np.float64,0x3ebe21d47d7c5,0x3ebe21d47d7c5,4
+np.float64,0x5b620512b6c41,0x5b620512b6c41,4
+np.float64,0x31918cda63232,0x31918cda63232,4
+np.float64,0x68b5741ed16af,0x68b5741ed16af,4
+np.float64,0xa5c09a5b4b814,0xa5c09a5b4b814,4
+np.float64,0x55f51c14abea4,0x55f51c14abea4,4
+np.float64,0xda8a3e41b515,0xda8a3e41b515,4
+np.float64,0x9ea9c8513d539,0x9ea9c8513d539,4
+np.float64,0x7f23b964fe478,0x7f23b964fe478,4
+np.float64,0xf6e08c7bedc12,0xf6e08c7bedc12,4
+np.float64,0x7267aa24e4cf6,0x7267aa24e4cf6,4
+np.float64,0x236bb93a46d78,0x236bb93a46d78,4
+np.float64,0x9a98430b35309,0x9a98430b35309,4
+np.float64,0xbb683fef76d08,0xbb683fef76d08,4
+np.float64,0x1ff0eb6e3fe1e,0x1ff0eb6e3fe1e,4
+np.float64,0xf524038fea481,0xf524038fea481,4
+np.float64,0xd714e449ae29d,0xd714e449ae29d,4
+np.float64,0x4154fd7682aa0,0x4154fd7682aa0,4
+np.float64,0x5b8d2f6cb71a7,0x5b8d2f6cb71a7,4
+np.float64,0xc91aa21d92355,0xc91aa21d92355,4
+np.float64,0xbd94fd117b2a0,0xbd94fd117b2a0,4
+np.float64,0x685b207ad0b65,0x685b207ad0b65,4
+np.float64,0xd2485b05a490c,0xd2485b05a490c,4
+np.float64,0x151ea5e62a3d6,0x151ea5e62a3d6,4
+np.float64,0x2635a7164c6b6,0x2635a7164c6b6,4
+np.float64,0x88ae3b5d115c8,0x88ae3b5d115c8,4
+np.float64,0x8a055a55140ac,0x8a055a55140ac,4
+np.float64,0x756f7694eadef,0x756f7694eadef,4
+np.float64,0x866d74630cdaf,0x866d74630cdaf,4
+np.float64,0x39e44f2873c8b,0x39e44f2873c8b,4
+np.float64,0x2a07ceb6540fb,0x2a07ceb6540fb,4
+np.float64,0xc52b96398a573,0xc52b96398a573,4
+np.float64,0x9546543b2a8cb,0x9546543b2a8cb,4
+np.float64,0x5b995b90b732c,0x5b995b90b732c,4
+np.float64,0x2de10a565bc22,0x2de10a565bc22,4
+np.float64,0x3b06ee94760df,0x3b06ee94760df,4
+np.float64,0xb18e77a5631cf,0xb18e77a5631cf,4
+np.float64,0x3b89ae3a77137,0x3b89ae3a77137,4
+np.float64,0xd9b0b6e5b3617,0xd9b0b6e5b3617,4
+np.float64,0x30b2310861647,0x30b2310861647,4
+np.float64,0x326a3ab464d48,0x326a3ab464d48,4
+np.float64,0x4c18610a9830d,0x4c18610a9830d,4
+np.float64,0x541dea42a83be,0x541dea42a83be,4
+np.float64,0xcd027dbf9a050,0xcd027dbf9a050,4
+np.float64,0x780a0f80f015,0x780a0f80f015,4
+np.float64,0x740ed5b2e81db,0x740ed5b2e81db,4
+np.float64,0xc226814d844d0,0xc226814d844d0,4
+np.float64,0xde958541bd2b1,0xde958541bd2b1,4
+np.float64,0xb563d3296ac7b,0xb563d3296ac7b,4
+np.float64,0x1db3b0b83b677,0x1db3b0b83b677,4
+np.float64,0xa7b0275d4f605,0xa7b0275d4f605,4
+np.float64,0x72f8d038e5f1b,0x72f8d038e5f1b,4
+np.float64,0x860ed1350c1da,0x860ed1350c1da,4
+np.float64,0x79f88262f3f11,0x79f88262f3f11,4
+np.float64,0x8817761f102ef,0x8817761f102ef,4
+np.float64,0xac44784b5888f,0xac44784b5888f,4
+np.float64,0x800fd594241fab28,0x800fd594241fab28,4
+np.float64,0x800ede32f8ddbc66,0x800ede32f8ddbc66,4
+np.float64,0x800de4c1121bc982,0x800de4c1121bc982,4
+np.float64,0x80076ebcddcedd7a,0x80076ebcddcedd7a,4
+np.float64,0x800b3fee06567fdc,0x800b3fee06567fdc,4
+np.float64,0x800b444426b68889,0x800b444426b68889,4
+np.float64,0x800b1c037a563807,0x800b1c037a563807,4
+np.float64,0x8001eb88c2a3d712,0x8001eb88c2a3d712,4
+np.float64,0x80058aae6dab155e,0x80058aae6dab155e,4
+np.float64,0x80083df2d4f07be6,0x80083df2d4f07be6,4
+np.float64,0x800e3b19d97c7634,0x800e3b19d97c7634,4
+np.float64,0x800a71c6f374e38e,0x800a71c6f374e38e,4
+np.float64,0x80048557f1490ab1,0x80048557f1490ab1,4
+np.float64,0x8000a00e6b01401e,0x8000a00e6b01401e,4
+np.float64,0x800766a3e2cecd49,0x800766a3e2cecd49,4
+np.float64,0x80015eb44602bd69,0x80015eb44602bd69,4
+np.float64,0x800bde885a77bd11,0x800bde885a77bd11,4
+np.float64,0x800224c53ea4498b,0x800224c53ea4498b,4
+np.float64,0x80048e8c6a291d1a,0x80048e8c6a291d1a,4
+np.float64,0x800b667e4af6ccfd,0x800b667e4af6ccfd,4
+np.float64,0x800ae3d7e395c7b0,0x800ae3d7e395c7b0,4
+np.float64,0x80086c245550d849,0x80086c245550d849,4
+np.float64,0x800d7d25f6fafa4c,0x800d7d25f6fafa4c,4
+np.float64,0x800f8d9ab0ff1b35,0x800f8d9ab0ff1b35,4
+np.float64,0x800690e949cd21d3,0x800690e949cd21d3,4
+np.float64,0x8003022381060448,0x8003022381060448,4
+np.float64,0x80085e0dad70bc1c,0x80085e0dad70bc1c,4
+np.float64,0x800e2ffc369c5ff9,0x800e2ffc369c5ff9,4
+np.float64,0x800b629b5af6c537,0x800b629b5af6c537,4
+np.float64,0x800fdc964b7fb92d,0x800fdc964b7fb92d,4
+np.float64,0x80036bb4b1c6d76a,0x80036bb4b1c6d76a,4
+np.float64,0x800b382f7f16705f,0x800b382f7f16705f,4
+np.float64,0x800ebac9445d7593,0x800ebac9445d7593,4
+np.float64,0x80015075c3e2a0ec,0x80015075c3e2a0ec,4
+np.float64,0x8002a6ec5ce54dd9,0x8002a6ec5ce54dd9,4
+np.float64,0x8009fab74a93f56f,0x8009fab74a93f56f,4
+np.float64,0x800c94b9ea992974,0x800c94b9ea992974,4
+np.float64,0x800dc2efd75b85e0,0x800dc2efd75b85e0,4
+np.float64,0x800be6400d57cc80,0x800be6400d57cc80,4
+np.float64,0x80021f6858443ed1,0x80021f6858443ed1,4
+np.float64,0x800600e2ac4c01c6,0x800600e2ac4c01c6,4
+np.float64,0x800a2159e6b442b4,0x800a2159e6b442b4,4
+np.float64,0x800c912f4bb9225f,0x800c912f4bb9225f,4
+np.float64,0x800a863a9db50c76,0x800a863a9db50c76,4
+np.float64,0x800ac16851d582d1,0x800ac16851d582d1,4
+np.float64,0x8003f7d32e87efa7,0x8003f7d32e87efa7,4
+np.float64,0x800be4eee3d7c9de,0x800be4eee3d7c9de,4
+np.float64,0x80069ff0ac4d3fe2,0x80069ff0ac4d3fe2,4
+np.float64,0x80061c986d4c3932,0x80061c986d4c3932,4
+np.float64,0x8000737b4de0e6f7,0x8000737b4de0e6f7,4
+np.float64,0x8002066ef7440cdf,0x8002066ef7440cdf,4
+np.float64,0x8001007050c200e1,0x8001007050c200e1,4
+np.float64,0x8008df9fa351bf40,0x8008df9fa351bf40,4
+np.float64,0x800f8394ee5f072a,0x800f8394ee5f072a,4
+np.float64,0x80008e0b01c11c17,0x80008e0b01c11c17,4
+np.float64,0x800f7088ed3ee112,0x800f7088ed3ee112,4
+np.float64,0x800285b86f650b72,0x800285b86f650b72,4
+np.float64,0x8008ec18af51d832,0x8008ec18af51d832,4
+np.float64,0x800da08523bb410a,0x800da08523bb410a,4
+np.float64,0x800de853ca7bd0a8,0x800de853ca7bd0a8,4
+np.float64,0x8008c8aefad1915e,0x8008c8aefad1915e,4
+np.float64,0x80010c39d5821874,0x80010c39d5821874,4
+np.float64,0x8009208349724107,0x8009208349724107,4
+np.float64,0x800783783f0f06f1,0x800783783f0f06f1,4
+np.float64,0x80025caf9984b960,0x80025caf9984b960,4
+np.float64,0x800bc76fa6778ee0,0x800bc76fa6778ee0,4
+np.float64,0x80017e2f89a2fc60,0x80017e2f89a2fc60,4
+np.float64,0x800ef169843de2d3,0x800ef169843de2d3,4
+np.float64,0x80098a5f7db314bf,0x80098a5f7db314bf,4
+np.float64,0x800d646f971ac8df,0x800d646f971ac8df,4
+np.float64,0x800110d1dc6221a4,0x800110d1dc6221a4,4
+np.float64,0x800f8b422a1f1684,0x800f8b422a1f1684,4
+np.float64,0x800785c97dcf0b94,0x800785c97dcf0b94,4
+np.float64,0x800da201283b4403,0x800da201283b4403,4
+np.float64,0x800a117cc7b422fa,0x800a117cc7b422fa,4
+np.float64,0x80024731cfa48e64,0x80024731cfa48e64,4
+np.float64,0x800199d456c333a9,0x800199d456c333a9,4
+np.float64,0x8005f66bab8becd8,0x8005f66bab8becd8,4
+np.float64,0x8008e7227c11ce45,0x8008e7227c11ce45,4
+np.float64,0x8007b66cc42f6cda,0x8007b66cc42f6cda,4
+np.float64,0x800669e6f98cd3cf,0x800669e6f98cd3cf,4
+np.float64,0x800aed917375db23,0x800aed917375db23,4
+np.float64,0x8008b6dd15116dbb,0x8008b6dd15116dbb,4
+np.float64,0x800f49869cfe930d,0x800f49869cfe930d,4
+np.float64,0x800a712661b4e24d,0x800a712661b4e24d,4
+np.float64,0x800944e816f289d1,0x800944e816f289d1,4
+np.float64,0x800eba0f8a1d741f,0x800eba0f8a1d741f,4
+np.float64,0x800cf6ded139edbe,0x800cf6ded139edbe,4
+np.float64,0x80023100c6246202,0x80023100c6246202,4
+np.float64,0x800c5a94add8b52a,0x800c5a94add8b52a,4
+np.float64,0x800adf329b95be66,0x800adf329b95be66,4
+np.float64,0x800af9afc115f360,0x800af9afc115f360,4
+np.float64,0x800d66ce837acd9d,0x800d66ce837acd9d,4
+np.float64,0x8003ffb5e507ff6d,0x8003ffb5e507ff6d,4
+np.float64,0x80027d280024fa51,0x80027d280024fa51,4
+np.float64,0x800fc37e1d1f86fc,0x800fc37e1d1f86fc,4
+np.float64,0x800fc7258b9f8e4b,0x800fc7258b9f8e4b,4
+np.float64,0x8003fb5789e7f6b0,0x8003fb5789e7f6b0,4
+np.float64,0x800eb4e7a13d69cf,0x800eb4e7a13d69cf,4
+np.float64,0x800951850952a30a,0x800951850952a30a,4
+np.float64,0x3fed4071be3a80e3,0x3fe95842074431df,4
+np.float64,0x3f8d2341203a4682,0x3f8d2300b453bd9f,4
+np.float64,0x3fdc8ce332b919c6,0x3fdb9cdf1440c28f,4
+np.float64,0x3fdc69bd84b8d37b,0x3fdb7d25c8166b7b,4
+np.float64,0x3fc4c22ad0298456,0x3fc4aae73e231b4f,4
+np.float64,0x3fea237809f446f0,0x3fe753cc6ca96193,4
+np.float64,0x3fd34cf6462699ed,0x3fd30268909bb47e,4
+np.float64,0x3fafce20643f9c41,0x3fafc8e41a240e35,4
+np.float64,0x3fdc6d416538da83,0x3fdb805262292863,4
+np.float64,0x3fe7d8362aefb06c,0x3fe5b2ce659db7fd,4
+np.float64,0x3fe290087de52011,0x3fe189f9a3eb123d,4
+np.float64,0x3fa62d2bf82c5a58,0x3fa62b65958ca2b8,4
+np.float64,0x3fafd134403fa269,0x3fafcbf670f8a6f3,4
+np.float64,0x3fa224e53c2449ca,0x3fa223ec5de1631b,4
+np.float64,0x3fb67e2c2c2cfc58,0x3fb676c445fb70a0,4
+np.float64,0x3fda358d01346b1a,0x3fd97b9441666eb2,4
+np.float64,0x3fdd30fc4bba61f9,0x3fdc308da423778d,4
+np.float64,0x3fc56e99c52add34,0x3fc5550004492621,4
+np.float64,0x3fe32d08de265a12,0x3fe20c761a73cec2,4
+np.float64,0x3fd46cf932a8d9f2,0x3fd414a7f3db03df,4
+np.float64,0x3fd94cfa2b3299f4,0x3fd8a5961b3e4bdd,4
+np.float64,0x3fed6ea3a6fadd47,0x3fe9745b2f6c9204,4
+np.float64,0x3fe4431d1768863a,0x3fe2ef61d0481de0,4
+np.float64,0x3fe1d8e00ea3b1c0,0x3fe0efab5050ee78,4
+np.float64,0x3fe56f37dcaade70,0x3fe3de00b0f392e0,4
+np.float64,0x3fde919a2dbd2334,0x3fdd6b6d2dcf2396,4
+np.float64,0x3fe251e3d4a4a3c8,0x3fe155de69605d60,4
+np.float64,0x3fe5e0ecc5abc1da,0x3fe436a5de5516cf,4
+np.float64,0x3fcd48780c3a90f0,0x3fcd073fa907ba9b,4
+np.float64,0x3fe4e8149229d029,0x3fe37360801d5b66,4
+np.float64,0x3fb9ef159633de2b,0x3fb9e3bc05a15d1d,4
+np.float64,0x3fc24a3f0424947e,0x3fc23a5432ca0e7c,4
+np.float64,0x3fe55ca196aab943,0x3fe3cf6b3143435a,4
+np.float64,0x3fe184544c2308a9,0x3fe0a7b49fa80aec,4
+np.float64,0x3fe2c76e83658edd,0x3fe1b8355c1ea771,4
+np.float64,0x3fea8d2c4ab51a59,0x3fe79ba85aabc099,4
+np.float64,0x3fd74f98abae9f31,0x3fd6cc85005d0593,4
+np.float64,0x3fec6de9a678dbd3,0x3fe8d59a1d23cdd1,4
+np.float64,0x3fec8a0e50f9141d,0x3fe8e7500f6f6a00,4
+np.float64,0x3fe9de6d08b3bcda,0x3fe7245319508767,4
+np.float64,0x3fe4461fd1688c40,0x3fe2f1cf0b93aba6,4
+np.float64,0x3fde342d9d3c685b,0x3fdd185609d5719d,4
+np.float64,0x3feb413fc8368280,0x3fe813c091d2519a,4
+np.float64,0x3fe64333156c8666,0x3fe48275b9a6a358,4
+np.float64,0x3fe03c65226078ca,0x3fdf18b26786be35,4
+np.float64,0x3fee11054dbc220b,0x3fe9d579a1cfa7ad,4
+np.float64,0x3fbaefccae35df99,0x3fbae314fef7c7ea,4
+np.float64,0x3feed4e3487da9c7,0x3fea4729241c8811,4
+np.float64,0x3fbb655df836cabc,0x3fbb57fcf9a097be,4
+np.float64,0x3fe68b0273ed1605,0x3fe4b96109afdf76,4
+np.float64,0x3fd216bfc3242d80,0x3fd1d957363f6a43,4
+np.float64,0x3fe01328d4a02652,0x3fded083bbf94aba,4
+np.float64,0x3fe3f9a61ae7f34c,0x3fe2b3f701b79028,4
+np.float64,0x3fed4e7cf8fa9cfa,0x3fe960d27084fb40,4
+np.float64,0x3faec08e343d811c,0x3faebbd2aa07ac1f,4
+np.float64,0x3fd2d1bbeea5a378,0x3fd28c9aefcf48ad,4
+np.float64,0x3fd92e941fb25d28,0x3fd889857f88410d,4
+np.float64,0x3fe43decb7e87bd9,0x3fe2eb32b4ee4667,4
+np.float64,0x3fef49cabcfe9395,0x3fea892f9a233f76,4
+np.float64,0x3fe3e96812e7d2d0,0x3fe2a6c6b45dd6ee,4
+np.float64,0x3fd24c0293a49805,0x3fd20c76d54473cb,4
+np.float64,0x3fb43d6b7e287ad7,0x3fb438060772795a,4
+np.float64,0x3fe87bf7d3f0f7f0,0x3fe62a0c47411c62,4
+np.float64,0x3fee82a2e07d0546,0x3fea17e27e752b7b,4
+np.float64,0x3fe40c01bbe81803,0x3fe2c2d9483f44d8,4
+np.float64,0x3fd686ccae2d0d99,0x3fd610763fb61097,4
+np.float64,0x3fe90fcf2af21f9e,0x3fe693c12df59ba9,4
+np.float64,0x3fefb3ce11ff679c,0x3feac3dd4787529d,4
+np.float64,0x3fcec53ff63d8a80,0x3fce79992af00c58,4
+np.float64,0x3fe599dd7bab33bb,0x3fe3ff5da7575d85,4
+np.float64,0x3fe9923b1a732476,0x3fe6ef71d13db456,4
+np.float64,0x3febf76fcef7eee0,0x3fe88a3952e11373,4
+np.float64,0x3fc2cfd128259fa2,0x3fc2be7fd47fd811,4
+np.float64,0x3fe4d37ae269a6f6,0x3fe36300d45e3745,4
+np.float64,0x3fe23aa2e4247546,0x3fe1424e172f756f,4
+np.float64,0x3fe4f0596ca9e0b3,0x3fe379f0c49de7ef,4
+np.float64,0x3fe2e4802fe5c900,0x3fe1d062a8812601,4
+np.float64,0x3fe5989c79eb3139,0x3fe3fe6308552dec,4
+np.float64,0x3fe3c53cb4e78a79,0x3fe28956e573aca4,4
+np.float64,0x3fe6512beeeca258,0x3fe48d2d5ece979f,4
+np.float64,0x3fd8473ddb308e7c,0x3fd7b33e38adc6ad,4
+np.float64,0x3fecd09c9679a139,0x3fe91361fa0c5bcb,4
+np.float64,0x3fc991530e3322a6,0x3fc965e2c514a9e9,4
+np.float64,0x3f6d4508403a8a11,0x3f6d45042b68acc5,4
+np.float64,0x3fea1f198f743e33,0x3fe750ce918d9330,4
+np.float64,0x3fd0a0bb4da14177,0x3fd07100f9c71e1c,4
+np.float64,0x3fd30c45ffa6188c,0x3fd2c499f9961f66,4
+np.float64,0x3fcad98e7c35b31d,0x3fcaa74293cbc52e,4
+np.float64,0x3fec8e4a5eb91c95,0x3fe8e9f898d118db,4
+np.float64,0x3fd19fdb79233fb7,0x3fd1670c00febd24,4
+np.float64,0x3fea9fcbb1f53f97,0x3fe7a836b29c4075,4
+np.float64,0x3fc6d12ea12da25d,0x3fc6b24bd2f89f59,4
+np.float64,0x3fd6af3658ad5e6d,0x3fd636613e08df3f,4
+np.float64,0x3fe31bc385a63787,0x3fe1fe3081621213,4
+np.float64,0x3fc0dbba2221b774,0x3fc0cf42c9313dba,4
+np.float64,0x3fef639ce87ec73a,0x3fea9795454f1036,4
+np.float64,0x3fee5f29dcbcbe54,0x3fea0349b288f355,4
+np.float64,0x3fed46bdb37a8d7b,0x3fe95c199f5aa569,4
+np.float64,0x3fef176afa3e2ed6,0x3fea6ce78b2aa3aa,4
+np.float64,0x3fc841e7683083cf,0x3fc81cccb84848cc,4
+np.float64,0xbfda3ec9a2347d94,0xbfd9840d180e9de3,4
+np.float64,0xbfcd5967ae3ab2d0,0xbfcd17be13142bb9,4
+np.float64,0xbfedf816573bf02d,0xbfe9c6bb06476c60,4
+np.float64,0xbfd0d6e10e21adc2,0xbfd0a54f99d2f3dc,4
+np.float64,0xbfe282df096505be,0xbfe17ef5e2e80760,4
+np.float64,0xbfd77ae6e62ef5ce,0xbfd6f4f6b603ad8a,4
+np.float64,0xbfe37b171aa6f62e,0xbfe24cb4b2d0ade4,4
+np.float64,0xbfef9e5ed9bf3cbe,0xbfeab817b41000bd,4
+np.float64,0xbfe624d6f96c49ae,0xbfe46b1e9c9aff86,4
+np.float64,0xbfefb5da65ff6bb5,0xbfeac4fc9c982772,4
+np.float64,0xbfd29a65d52534cc,0xbfd2579df8ff87b9,4
+np.float64,0xbfd40270172804e0,0xbfd3af6471104aef,4
+np.float64,0xbfb729ee7a2e53e0,0xbfb721d7dbd2705e,4
+np.float64,0xbfb746f1382e8de0,0xbfb73ebc1207f8e3,4
+np.float64,0xbfd3c7e606a78fcc,0xbfd377a8aa1b0dd9,4
+np.float64,0xbfd18c4880231892,0xbfd1543506584ad5,4
+np.float64,0xbfea988080753101,0xbfe7a34cba0d0fa1,4
+np.float64,0xbf877400e02ee800,0xbf8773df47fa7e35,4
+np.float64,0xbfb07e050820fc08,0xbfb07b198d4a52c9,4
+np.float64,0xbfee0a3621fc146c,0xbfe9d1745a05ba77,4
+np.float64,0xbfe78de246ef1bc4,0xbfe57bf2baab91c8,4
+np.float64,0xbfcdbfd3bd3b7fa8,0xbfcd7b728a955a06,4
+np.float64,0xbfe855ea79b0abd5,0xbfe60e8a4a17b921,4
+np.float64,0xbfd86c8e3530d91c,0xbfd7d5e36c918dc1,4
+np.float64,0xbfe4543169e8a863,0xbfe2fd23d42f552e,4
+np.float64,0xbfe41efbf1283df8,0xbfe2d235a2faed1a,4
+np.float64,0xbfd9a55464b34aa8,0xbfd8f7083f7281e5,4
+np.float64,0xbfe5f5078d6bea0f,0xbfe44637d910c270,4
+np.float64,0xbfe6d83e3dedb07c,0xbfe4f3fdadd10552,4
+np.float64,0xbfdb767e70b6ecfc,0xbfdaa0b6c17f3fb1,4
+np.float64,0xbfdfc91b663f9236,0xbfde7eb0dfbeaa26,4
+np.float64,0xbfbfbd18783f7a30,0xbfbfa84bf2fa1c8d,4
+np.float64,0xbfe51199242a2332,0xbfe39447dbe066ae,4
+np.float64,0xbfdbb94814b77290,0xbfdadd63bd796972,4
+np.float64,0xbfd8c6272cb18c4e,0xbfd828f2d9e8607e,4
+np.float64,0xbfce51e0b63ca3c0,0xbfce097ee908083a,4
+np.float64,0xbfe99a177d73342f,0xbfe6f4ec776a57ae,4
+np.float64,0xbfefde2ab0ffbc55,0xbfeadafdcbf54733,4
+np.float64,0xbfcccb5c1c3996b8,0xbfcc8d586a73d126,4
+np.float64,0xbfdf7ddcedbefbba,0xbfde3c749a906de7,4
+np.float64,0xbfef940516ff280a,0xbfeab26429e89f4b,4
+np.float64,0xbfe08009f1e10014,0xbfdf8eab352997eb,4
+np.float64,0xbfe9c02682b3804d,0xbfe70f5fd05f79ee,4
+np.float64,0xbfb3ca1732279430,0xbfb3c50bec5b453a,4
+np.float64,0xbfe368e81926d1d0,0xbfe23dc704d0887c,4
+np.float64,0xbfbd20cc2e3a4198,0xbfbd10b7e6d81c6c,4
+np.float64,0xbfd67ece4d2cfd9c,0xbfd608f527dcc5e7,4
+np.float64,0xbfdc02d1333805a2,0xbfdb20104454b79f,4
+np.float64,0xbfc007a626200f4c,0xbfbff9dc9dc70193,4
+np.float64,0xbfda9e4f8fb53ca0,0xbfd9db8af35dc630,4
+np.float64,0xbfd8173d77302e7a,0xbfd786a0cf3e2914,4
+np.float64,0xbfeb8fcbd0b71f98,0xbfe84734debc10fb,4
+np.float64,0xbfe4bf1cb7697e3a,0xbfe352c891113f29,4
+np.float64,0xbfc18624d5230c48,0xbfc178248e863b64,4
+np.float64,0xbfcf184bac3e3098,0xbfceca3b19be1ebe,4
+np.float64,0xbfd2269c42a44d38,0xbfd1e8920d72b694,4
+np.float64,0xbfe8808526b1010a,0xbfe62d5497292495,4
+np.float64,0xbfe498bd1da9317a,0xbfe334245eadea93,4
+np.float64,0xbfef0855aebe10ab,0xbfea6462f29aeaf9,4
+np.float64,0xbfdeb186c93d630e,0xbfdd87c37943c602,4
+np.float64,0xbfb29fe2ae253fc8,0xbfb29bae3c87efe4,4
+np.float64,0xbfddd9c6c3bbb38e,0xbfdcc7b400bf384b,4
+np.float64,0xbfe3506673e6a0cd,0xbfe2299f26295553,4
+np.float64,0xbfe765957a2ecb2b,0xbfe55e03cf22edab,4
+np.float64,0xbfecc9876c79930f,0xbfe90efaf15b6207,4
+np.float64,0xbfefb37a0a7f66f4,0xbfeac3af3898e7c2,4
+np.float64,0xbfeefa0da7bdf41b,0xbfea5c4cde53c1c3,4
+np.float64,0xbfe6639ee9ecc73e,0xbfe49b4e28a72482,4
+np.float64,0xbfef91a4bb7f2349,0xbfeab114ac9e25dd,4
+np.float64,0xbfc8b392bb316724,0xbfc88c657f4441a3,4
+np.float64,0xbfc88a358231146c,0xbfc863cb900970fe,4
+np.float64,0xbfef25a9d23e4b54,0xbfea74eda432aabe,4
+np.float64,0xbfe6aceea0ed59de,0xbfe4d32e54a3fd01,4
+np.float64,0xbfefe2b3e37fc568,0xbfeadd74f4605835,4
+np.float64,0xbfa9eecb8833dd90,0xbfa9ebf4f4cb2591,4
+np.float64,0xbfd42bad7428575a,0xbfd3d69de8e52d0a,4
+np.float64,0xbfbc366b4a386cd8,0xbfbc27ceee8f3019,4
+np.float64,0xbfd9bca7be337950,0xbfd90c80e6204e57,4
+np.float64,0xbfe8173f53f02e7f,0xbfe5e0f8d8ed329c,4
+np.float64,0xbfce22dbcb3c45b8,0xbfcddbc8159b63af,4
+np.float64,0xbfea2d7ba7345af7,0xbfe75aa62ad5b80a,4
+np.float64,0xbfc08b783e2116f0,0xbfc07faf8d501558,4
+np.float64,0xbfb8c4161c318830,0xbfb8ba33950748ec,4
+np.float64,0xbfddd930bcbbb262,0xbfdcc72dffdf51bb,4
+np.float64,0xbfd108ce8a22119e,0xbfd0d5801e7698bd,4
+np.float64,0xbfd5bd2b5dab7a56,0xbfd552c52c468c76,4
+np.float64,0xbfe7ffe67fefffcd,0xbfe5cfe96e35e6e5,4
+np.float64,0xbfa04ec6bc209d90,0xbfa04e120a2c25cc,4
+np.float64,0xbfef7752cc7eeea6,0xbfeaa28715addc4f,4
+np.float64,0xbfe7083c2eae1078,0xbfe5182bf8ddfc8e,4
+np.float64,0xbfe05dafd0a0bb60,0xbfdf52d397cfe5f6,4
+np.float64,0xbfacb4f2243969e0,0xbfacb118991ea235,4
+np.float64,0xbfc7d47e422fa8fc,0xbfc7b1504714a4fd,4
+np.float64,0xbfbd70b2243ae168,0xbfbd60182efb61de,4
+np.float64,0xbfe930e49cb261c9,0xbfe6ab272b3f9cfc,4
+np.float64,0xbfb5f537e62bea70,0xbfb5ee540dcdc635,4
+np.float64,0xbfbb0c8278361908,0xbfbaffa1f7642a87,4
+np.float64,0xbfe82af2447055e4,0xbfe5ef54ca8db9e8,4
+np.float64,0xbfe92245e6f2448c,0xbfe6a0d32168040b,4
+np.float64,0xbfb799a8522f3350,0xbfb7911a7ada3640,4
+np.float64,0x7faa8290c8350521,0x3fe5916f67209cd6,4
+np.float64,0x7f976597082ecb2d,0x3fcf94dce396bd37,4
+np.float64,0x7fede721237bce41,0x3fe3e7b1575b005f,4
+np.float64,0x7fd5f674d72bece9,0x3fe3210628eba199,4
+np.float64,0x7f9b0f1aa0361e34,0x3feffd34d15d1da7,4
+np.float64,0x7fec48346ab89068,0x3fe93dd84253d9a2,4
+np.float64,0x7f9cac76283958eb,0xbfec4cd999653868,4
+np.float64,0x7fed51ab6bbaa356,0x3fecc27fb5f37bca,4
+np.float64,0x7fded3c116bda781,0xbfda473efee47cf1,4
+np.float64,0x7fd19c48baa33890,0xbfe25700cbfc0326,4
+np.float64,0x7fe5c8f478ab91e8,0xbfee4ab6d84806be,4
+np.float64,0x7fe53c64e46a78c9,0x3fee19c3f227f4e1,4
+np.float64,0x7fc2ad1936255a31,0xbfe56db9b877f807,4
+np.float64,0x7fe2b071b52560e2,0xbfce3990a8d390a9,4
+np.float64,0x7fc93f3217327e63,0xbfd1f6d7ef838d2b,4
+np.float64,0x7fec26df08784dbd,0x3fd5397be41c93d9,4
+np.float64,0x7fcf4770183e8edf,0x3fe6354f5a785016,4
+np.float64,0x7fdc9fcc0bb93f97,0xbfeeeae952e8267d,4
+np.float64,0x7feb21f29c7643e4,0x3fec20122e33f1bf,4
+np.float64,0x7fd0b51273216a24,0x3fefb09f8daba00b,4
+np.float64,0x7fe747a9d76e8f53,0x3feb46a3232842a4,4
+np.float64,0x7fd58885972b110a,0xbfce5ea57c186221,4
+np.float64,0x7fca3ce85c3479d0,0x3fef93a24548e8ca,4
+np.float64,0x7fe1528a46a2a514,0xbfb54bb578d9da91,4
+np.float64,0x7fcc58b21b38b163,0x3feffb5b741ffc2d,4
+np.float64,0x7fdabcaaf5357955,0x3fecbf855db524d1,4
+np.float64,0x7fdd27c6933a4f8c,0xbfef2f41bb80144b,4
+np.float64,0x7fbda4e1be3b49c2,0x3fdb9b33f84f5381,4
+np.float64,0x7fe53363362a66c5,0x3fe4daff3a6a4ed0,4
+np.float64,0x7fe5719d62eae33a,0xbfef761d98f625d5,4
+np.float64,0x7f982ce5a83059ca,0x3fd0b27c3365f0a8,4
+np.float64,0x7fe6db8c42edb718,0x3fe786f4b1fe11a6,4
+np.float64,0x7fe62cca1b2c5993,0x3fd425b6c4c9714a,4
+np.float64,0x7feea88850bd5110,0xbfd7bbb432017175,4
+np.float64,0x7fad6c6ae43ad8d5,0x3fe82e49098bc6de,4
+np.float64,0x7fe70542f02e0a85,0x3fec3017960b4822,4
+np.float64,0x7feaf0bcbb35e178,0xbfc3aac74dd322d5,4
+np.float64,0x7fb5e152fe2bc2a5,0x3fd4b27a4720614c,4
+np.float64,0x7fe456ee5be8addc,0xbfe9e15ab5cff229,4
+np.float64,0x7fd4b53a8d296a74,0xbfefff450f503326,4
+np.float64,0x7fd7149d7a2e293a,0x3fef4ef0a9009096,4
+np.float64,0x7fd43fc5a8a87f8a,0x3fe0c929fee9dce7,4
+np.float64,0x7fef97022aff2e03,0x3fd4ea52a813da20,4
+np.float64,0x7fe035950ae06b29,0x3fef4e125394fb05,4
+np.float64,0x7fecd0548979a0a8,0x3fe89d226244037b,4
+np.float64,0x7fc79b3ac22f3675,0xbfee9c9cf78c8270,4
+np.float64,0x7fd8b8e8263171cf,0x3fe8e24437961db0,4
+np.float64,0x7fc288c23e251183,0xbfbaf8eca50986ca,4
+np.float64,0x7fe436b4b6686d68,0xbfecd661741931c4,4
+np.float64,0x7fcdf99abe3bf334,0x3feaa75c90830b92,4
+np.float64,0x7fd9f9739233f2e6,0xbfebbfcb301b0da5,4
+np.float64,0x7fd6fcbd1b2df979,0xbfccf2c77cb65f56,4
+np.float64,0x7fe242a97b248552,0xbfe5b0f13bcbabc8,4
+np.float64,0x7fe38bf3e06717e7,0x3fbc8fa9004d2668,4
+np.float64,0x7fecd0e8d479a1d1,0xbfe886a6b4f73a4a,4
+np.float64,0x7fe958d60232b1ab,0xbfeb7c4cf0cee2dd,4
+np.float64,0x7f9d492b583a9256,0xbfebe975d00221cb,4
+np.float64,0x7fd6c9983bad932f,0xbfefe817621a31f6,4
+np.float64,0x7fed0d7239fa1ae3,0x3feac7e1b6455b4b,4
+np.float64,0x7fe61dac90ec3b58,0x3fef845b9efe8421,4
+np.float64,0x7f9acd3010359a5f,0xbfe460d376200130,4
+np.float64,0x7fedced9673b9db2,0xbfeeaf23445e1944,4
+np.float64,0x7fd9f271a733e4e2,0xbfd41544535ecb78,4
+np.float64,0x7fe703339bee0666,0x3fef93334626b56c,4
+np.float64,0x7fec7761b7b8eec2,0xbfe6da9179e8e714,4
+np.float64,0x7fdd9fff043b3ffd,0xbfc0761dfb8d94f9,4
+np.float64,0x7fdc10ed17b821d9,0x3fe1481e2a26c77f,4
+np.float64,0x7fe7681e72aed03c,0x3fefff94a6d47c84,4
+np.float64,0x7fe18c29e1e31853,0x3fe86ebd2fd89456,4
+np.float64,0x7fb2fb273c25f64d,0xbfefc136f57e06de,4
+np.float64,0x7fac2bbb90385776,0x3fe25d8e3cdae7e3,4
+np.float64,0x7fed16789efa2cf0,0x3fe94555091fdfd9,4
+np.float64,0x7fd8fe8f7831fd1e,0xbfed58d520361902,4
+np.float64,0x7fa59bde3c2b37bb,0x3fef585391c077ff,4
+np.float64,0x7fda981b53353036,0x3fde02ca08737b5f,4
+np.float64,0x7fd29f388aa53e70,0xbfe04f5499246df2,4
+np.float64,0x7fcd0232513a0464,0xbfd9737f2f565829,4
+np.float64,0x7fe9a881bcf35102,0xbfe079cf285b35dd,4
+np.float64,0x7fdbe399a9b7c732,0x3fe965bc4220f340,4
+np.float64,0x7feb77414af6ee82,0xbfb7df2fcd491f55,4
+np.float64,0x7fa26e86c424dd0d,0xbfea474c3d65b9be,4
+np.float64,0x7feaee869e35dd0c,0xbfd7b333a888cd14,4
+np.float64,0x7fcbd67f6137acfe,0xbfe15a7a15dfcee6,4
+np.float64,0x7fe36991e766d323,0xbfeb288077c4ed9f,4
+np.float64,0x7fdcf4f4fcb9e9e9,0xbfea331ef7a75e7b,4
+np.float64,0x7fbe3445643c688a,0x3fedf21b94ae8e37,4
+np.float64,0x7fd984cfd2b3099f,0x3fc0d3ade71c395e,4
+np.float64,0x7fdec987b23d930e,0x3fe4af5e48f6c26e,4
+np.float64,0x7fde56a9953cad52,0x3fc8e7762cefb8b0,4
+np.float64,0x7fd39fb446273f68,0xbfe6c3443208f44d,4
+np.float64,0x7fc609c1a72c1382,0x3fe884e639571baa,4
+np.float64,0x7fe001be4b20037c,0xbfed0d90cbcb6010,4
+np.float64,0x7fce7ace283cf59b,0xbfd0303792e51f49,4
+np.float64,0x7fe27ba93da4f751,0x3fe548b5ce740d71,4
+np.float64,0x7fcc13c79b38278e,0xbfe2e14f5b64a1e9,4
+np.float64,0x7fc058550620b0a9,0x3fe44bb55ebd0590,4
+np.float64,0x7fa4ba8bf8297517,0x3fee59b39f9d08c4,4
+np.float64,0x7fe50d6872ea1ad0,0xbfea1eaa2d059e13,4
+np.float64,0x7feb7e33b476fc66,0xbfeff28a4424dd3e,4
+np.float64,0x7fe2d7d2a165afa4,0xbfdbaff0ba1ea460,4
+np.float64,0xffd126654b224cca,0xbfef0cd3031fb97c,4
+np.float64,0xffb5f884942bf108,0x3fe0de589bea2e4c,4
+np.float64,0xffe011b4bfe02369,0xbfe805a0edf1e1f2,4
+np.float64,0xffec13eae9b827d5,0x3fb5f30347d78447,4
+np.float64,0xffa6552ae82caa50,0x3fb1ecee60135f2f,4
+np.float64,0xffb62d38b02c5a70,0x3fbd35903148fd12,4
+np.float64,0xffe2c44ea425889d,0xbfd7616547f99a7d,4
+np.float64,0xffea24c61a74498c,0x3fef4a1b15ae9005,4
+np.float64,0xffd23a4ab2a47496,0x3fe933bfaa569ae9,4
+np.float64,0xffc34a073d269410,0xbfeec0f510bb7474,4
+np.float64,0xffeead84cfbd5b09,0x3feb2d635e5a78bd,4
+np.float64,0xffcfd8f3b43fb1e8,0xbfdd59625801771b,4
+np.float64,0xffd3c7f662a78fec,0x3f9cf3209edfbc4e,4
+np.float64,0xffe7b7e4f72f6fca,0xbfefdcff4925632c,4
+np.float64,0xffe48cab05e91956,0x3fe6b41217948423,4
+np.float64,0xffeb6980b336d301,0xbfca5de148f69324,4
+np.float64,0xffe3f15c4aa7e2b8,0xbfeb18efae892081,4
+np.float64,0xffcf290c713e5218,0x3fefe6f1a513ed26,4
+np.float64,0xffd80979b43012f4,0xbfde6c8df91af976,4
+np.float64,0xffc3181e0026303c,0x3fe7448f681def38,4
+np.float64,0xffedfa68f97bf4d1,0xbfeca6efb802d109,4
+np.float64,0xffca0931c0341264,0x3fe31b9f073b08cd,4
+np.float64,0xffe4c44934e98892,0x3feda393a2e8a0f7,4
+np.float64,0xffe65bb56f2cb76a,0xbfeffaf638a4b73e,4
+np.float64,0xffe406a332a80d46,0x3fe8151dadb853c1,4
+np.float64,0xffdb7eae9c36fd5e,0xbfeff89abf5ab16e,4
+np.float64,0xffe245a02da48b40,0x3fef1fb43e85f4b8,4
+np.float64,0xffe2bafa732575f4,0x3fcbab115c6fd86e,4
+np.float64,0xffe8b1eedb7163dd,0x3feff263df6f6b12,4
+np.float64,0xffe6c76c796d8ed8,0xbfe61a8668511293,4
+np.float64,0xffefe327d1ffc64f,0xbfd9b92887a84827,4
+np.float64,0xffa452180c28a430,0xbfa9b9e578a4e52f,4
+np.float64,0xffe9867d0bf30cf9,0xbfca577867588408,4
+np.float64,0xffdfe9b923bfd372,0x3fdab5c15f085c2d,4
+np.float64,0xffed590c6abab218,0xbfd7e7b6c5a120e6,4
+np.float64,0xffeaebcfbab5d79f,0x3fed58be8a9e2c3b,4
+np.float64,0xffe2ba83a8257507,0x3fe6c42a4ac1d4d9,4
+np.float64,0xffe01d5b0ee03ab6,0xbfe5dad6c9247db7,4
+np.float64,0xffe51095d52a212b,0x3fef822cebc32d8e,4
+np.float64,0xffebd7a901b7af51,0xbfe5e63f3e3b1185,4
+np.float64,0xffe4efdcde29dfb9,0xbfe811294dfa758f,4
+np.float64,0xffe3be1aa4a77c35,0x3fdd8dcfcd409bb1,4
+np.float64,0xffbe6f2f763cde60,0x3fd13766e43bd622,4
+np.float64,0xffeed3d80fbda7af,0x3fec10a23c1b7a4a,4
+np.float64,0xffd6ebff37add7fe,0xbfe6177411607c86,4
+np.float64,0xffe85a90f4b0b521,0x3fc09fdd66c8fde9,4
+np.float64,0xffea3d58c2b47ab1,0x3feb5bd4a04b3562,4
+np.float64,0xffef675be6beceb7,0x3fecd840683d1044,4
+np.float64,0xff726a088024d400,0x3feff2b4f47b5214,4
+np.float64,0xffc90856733210ac,0xbfe3c6ffbf6840a5,4
+np.float64,0xffc0b58d9a216b1c,0xbfe10314267d0611,4
+np.float64,0xffee1f3d0abc3e79,0xbfd12ea7efea9067,4
+np.float64,0xffd988c41a331188,0x3febe83802d8a32e,4
+np.float64,0xffe8f1ac9bb1e358,0xbfdbf5fa7e84f2f2,4
+np.float64,0xffe47af279e8f5e4,0x3fef11e339e5fa78,4
+np.float64,0xff9960a7f832c140,0xbfa150363f8ec5b2,4
+np.float64,0xffcac40fa7358820,0xbfec3d5847a3df1d,4
+np.float64,0xffcb024a9d360494,0xbfd060fa31fd6b6a,4
+np.float64,0xffe385ffb3270bff,0xbfee6859e8dcd9e8,4
+np.float64,0xffef62f2c53ec5e5,0x3fe0a71ffddfc718,4
+np.float64,0xffed87ff20fb0ffd,0xbfe661db7c4098e3,4
+np.float64,0xffe369278526d24e,0x3fd64d89a41822fc,4
+np.float64,0xff950288c02a0520,0x3fe1df91d1ad7d5c,4
+np.float64,0xffe70e7c2cee1cf8,0x3fc9fece08df2fd8,4
+np.float64,0xffbaf020b635e040,0xbfc68c43ff9911a7,4
+np.float64,0xffee0120b0fc0240,0x3f9f792e17b490b0,4
+np.float64,0xffe1fa4be7a3f498,0xbfef4b18ab4b319e,4
+np.float64,0xffe61887bf2c310f,0x3fe846714826cb32,4
+np.float64,0xffdc3cf77f3879ee,0x3fe033b948a36125,4
+np.float64,0xffcc2b86f238570c,0xbfefdcceac3f220f,4
+np.float64,0xffe1f030c0a3e061,0x3fef502a808c359a,4
+np.float64,0xffb872c4ee30e588,0x3fef66ed8d3e6175,4
+np.float64,0xffeac8fc617591f8,0xbfe5d8448602aac9,4
+np.float64,0xffe5be16afab7c2d,0x3fee75ccde3cd14d,4
+np.float64,0xffae230ad83c4610,0xbfe49bbe6074d459,4
+np.float64,0xffc8fbeff531f7e0,0x3f77201e0c927f97,4
+np.float64,0xffdc314f48b8629e,0x3fef810dfc5db118,4
+np.float64,0xffec1f8970783f12,0x3fe15567102e042a,4
+np.float64,0xffc6995f902d32c0,0xbfecd5d2eedf342c,4
+np.float64,0xffdc7af76b38f5ee,0xbfd6e754476ab320,4
+np.float64,0xffb30cf8682619f0,0x3fd5ac3dfc4048d0,4
+np.float64,0xffd3a77695a74eee,0xbfefb5d6889e36e9,4
+np.float64,0xffd8b971803172e4,0xbfeb7f62f0b6c70b,4
+np.float64,0xffde4c0234bc9804,0xbfed50ba9e16d5e0,4
+np.float64,0xffb62b3f342c5680,0xbfeabc0de4069b84,4
+np.float64,0xff9af5674035eac0,0xbfed6c198b6b1bd8,4
+np.float64,0xffdfe20cb43fc41a,0x3fb11f8238f66306,4
+np.float64,0xffd2ecd7a0a5d9b0,0xbfec17ef1a62b1e3,4
+np.float64,0xffce60f7863cc1f0,0x3fe6dbcad3e3a006,4
+np.float64,0xffbbb8306a377060,0xbfbfd0fbef485c4c,4
+np.float64,0xffd1b2bd2b23657a,0xbfda3e046d987b99,4
+np.float64,0xffc480f4092901e8,0xbfeeff0427f6897b,4
+np.float64,0xffe6e02d926dc05a,0xbfcd59552778890b,4
+np.float64,0xffd302e5b7a605cc,0xbfee7c08641366b0,4
+np.float64,0xffec2eb92f785d72,0xbfef5c9c7f771050,4
+np.float64,0xffea3e31a9747c62,0xbfc49cd54755faf0,4
+np.float64,0xffce0a4e333c149c,0x3feeb9a6d0db4aee,4
+np.float64,0xffdc520a2db8a414,0x3fefc7b72613dcd0,4
+np.float64,0xffe056b968a0ad72,0xbfe47a9fe1f827fb,4
+np.float64,0xffe5a10f4cab421e,0x3fec2b1f74b73dec,4
diff --git a/numpy/core/tests/data/umath-validation-set-sinh.csv b/numpy/core/tests/data/umath-validation-set-sinh.csv
new file mode 100644
index 000000000..5888c91c2
--- /dev/null
+++ b/numpy/core/tests/data/umath-validation-set-sinh.csv
@@ -0,0 +1,1429 @@
+dtype,input,output,ulperrortol
+np.float32,0xfee27582,0xff800000,2
+np.float32,0xff19f092,0xff800000,2
+np.float32,0xbf393576,0xbf49cb31,2
+np.float32,0x8020fdea,0x8020fdea,2
+np.float32,0x455f4e,0x455f4e,2
+np.float32,0xff718c35,0xff800000,2
+np.float32,0x3f3215e3,0x3f40cce5,2
+np.float32,0x19e833,0x19e833,2
+np.float32,0xff2dcd49,0xff800000,2
+np.float32,0x7e8f6c95,0x7f800000,2
+np.float32,0xbf159dac,0xbf1e47a5,2
+np.float32,0x100d3d,0x100d3d,2
+np.float32,0xff673441,0xff800000,2
+np.float32,0x80275355,0x80275355,2
+np.float32,0x4812d0,0x4812d0,2
+np.float32,0x8072b956,0x8072b956,2
+np.float32,0xff3bb918,0xff800000,2
+np.float32,0x0,0x0,2
+np.float32,0xfe327798,0xff800000,2
+np.float32,0x41d4e2,0x41d4e2,2
+np.float32,0xfe34b1b8,0xff800000,2
+np.float32,0x80199f72,0x80199f72,2
+np.float32,0x807242ce,0x807242ce,2
+np.float32,0x3ef4202d,0x3efd7b48,2
+np.float32,0x763529,0x763529,2
+np.float32,0x4f6662,0x4f6662,2
+np.float32,0x3f18efe9,0x3f2232b5,2
+np.float32,0x80701846,0x80701846,2
+np.float32,0x3f599948,0x3f74c393,2
+np.float32,0x5a3d69,0x5a3d69,2
+np.float32,0xbf4a7e65,0xbf6047a3,2
+np.float32,0xff0d4c82,0xff800000,2
+np.float32,0x7a74db,0x7a74db,2
+np.float32,0x803388e6,0x803388e6,2
+np.float32,0x7f4430bb,0x7f800000,2
+np.float32,0x14c5b1,0x14c5b1,2
+np.float32,0xfa113400,0xff800000,2
+np.float32,0x7f4b3209,0x7f800000,2
+np.float32,0x8038d88c,0x8038d88c,2
+np.float32,0xbef2f9de,0xbefc330b,2
+np.float32,0xbe147b38,0xbe15008f,2
+np.float32,0x2b61e6,0x2b61e6,2
+np.float32,0x80000001,0x80000001,2
+np.float32,0x8060456c,0x8060456c,2
+np.float32,0x3f30fa82,0x3f3f6a99,2
+np.float32,0xfd1f0220,0xff800000,2
+np.float32,0xbf2b7555,0xbf389151,2
+np.float32,0xff100b7a,0xff800000,2
+np.float32,0x70d3cd,0x70d3cd,2
+np.float32,0x2a8d4a,0x2a8d4a,2
+np.float32,0xbf7b733f,0xbf92f05f,2
+np.float32,0x3f7106dc,0x3f8b1fc6,2
+np.float32,0x3f39da7a,0x3f4a9d79,2
+np.float32,0x3f5dd73f,0x3f7aaab5,2
+np.float32,0xbe8c8754,0xbe8e4cba,2
+np.float32,0xbf6c74c9,0xbf87c556,2
+np.float32,0x800efbbb,0x800efbbb,2
+np.float32,0xff054ab5,0xff800000,2
+np.float32,0x800b4b46,0x800b4b46,2
+np.float32,0xff77fd74,0xff800000,2
+np.float32,0x257d0,0x257d0,2
+np.float32,0x7caa0c,0x7caa0c,2
+np.float32,0x8025d24d,0x8025d24d,2
+np.float32,0x3d9f1b60,0x3d9f445c,2
+np.float32,0xbe3bf6e8,0xbe3d0595,2
+np.float32,0x54bb93,0x54bb93,2
+np.float32,0xbf3e6a45,0xbf507716,2
+np.float32,0x3f4bb26e,0x3f61e1cd,2
+np.float32,0x3f698edc,0x3f85aac5,2
+np.float32,0xff7bd0ef,0xff800000,2
+np.float32,0xbed07b68,0xbed64a8e,2
+np.float32,0xbf237c72,0xbf2ed3d2,2
+np.float32,0x27b0fa,0x27b0fa,2
+np.float32,0x3f7606d1,0x3f8ed7d6,2
+np.float32,0x790dc0,0x790dc0,2
+np.float32,0x7f68f3ac,0x7f800000,2
+np.float32,0xbed39288,0xbed9a52f,2
+np.float32,0x3f6f8266,0x3f8a0187,2
+np.float32,0x3fbdca,0x3fbdca,2
+np.float32,0xbf7c3e5d,0xbf938b2c,2
+np.float32,0x802321a8,0x802321a8,2
+np.float32,0x3eecab66,0x3ef53031,2
+np.float32,0x62b324,0x62b324,2
+np.float32,0x3f13afac,0x3f1c03fe,2
+np.float32,0xff315ad7,0xff800000,2
+np.float32,0xbf1fac0d,0xbf2a3a63,2
+np.float32,0xbf543984,0xbf6d61d6,2
+np.float32,0x71a212,0x71a212,2
+np.float32,0x114fbe,0x114fbe,2
+np.float32,0x3f5b6ff2,0x3f77505f,2
+np.float32,0xff6ff89e,0xff800000,2
+np.float32,0xff4527a1,0xff800000,2
+np.float32,0x22cb3,0x22cb3,2
+np.float32,0x7f53bb6b,0x7f800000,2
+np.float32,0xff3d2dea,0xff800000,2
+np.float32,0xfd21dac0,0xff800000,2
+np.float32,0xfc486140,0xff800000,2
+np.float32,0x7e2b693a,0x7f800000,2
+np.float32,0x8022a9fb,0x8022a9fb,2
+np.float32,0x80765de0,0x80765de0,2
+np.float32,0x13d299,0x13d299,2
+np.float32,0x7ee53713,0x7f800000,2
+np.float32,0xbde1c770,0xbde23c96,2
+np.float32,0xbd473fc0,0xbd4753de,2
+np.float32,0x3f1cb455,0x3f26acf3,2
+np.float32,0x683e49,0x683e49,2
+np.float32,0x3ed5a9fc,0x3edbeb79,2
+np.float32,0x3f4fe3f6,0x3f67814f,2
+np.float32,0x802a2bce,0x802a2bce,2
+np.float32,0x7e951b4c,0x7f800000,2
+np.float32,0xbe6eb260,0xbe70dd44,2
+np.float32,0xbe3daca8,0xbe3ec2cb,2
+np.float32,0xbe9c38b2,0xbe9ea822,2
+np.float32,0xff2e29dc,0xff800000,2
+np.float32,0x7f62c7cc,0x7f800000,2
+np.float32,0xbf6799a4,0xbf84416c,2
+np.float32,0xbe30a7f0,0xbe318898,2
+np.float32,0xc83d9,0xc83d9,2
+np.float32,0x3f05abf4,0x3f0bd447,2
+np.float32,0x7e9b018a,0x7f800000,2
+np.float32,0xbf0ed72e,0xbf165e5b,2
+np.float32,0x8011ac8c,0x8011ac8c,2
+np.float32,0xbeb7c706,0xbebbbfcb,2
+np.float32,0x803637f9,0x803637f9,2
+np.float32,0xfe787cc8,0xff800000,2
+np.float32,0x3f533d4b,0x3f6c0a50,2
+np.float32,0x3f5c0f1c,0x3f782dde,2
+np.float32,0x3f301f36,0x3f3e590d,2
+np.float32,0x2dc929,0x2dc929,2
+np.float32,0xff15018a,0xff800000,2
+np.float32,0x3f4d0c56,0x3f63afeb,2
+np.float32,0xbf7a2ae3,0xbf91f6e4,2
+np.float32,0xbe771b84,0xbe798346,2
+np.float32,0x80800000,0x80800000,2
+np.float32,0x7f5689ba,0x7f800000,2
+np.float32,0x3f1c3177,0x3f2610df,2
+np.float32,0x3f1b9664,0x3f255825,2
+np.float32,0x3f7e5066,0x3f9520d4,2
+np.float32,0xbf1935f8,0xbf2285ab,2
+np.float32,0x3f096cc7,0x3f101ef9,2
+np.float32,0x8030c180,0x8030c180,2
+np.float32,0x6627ed,0x6627ed,2
+np.float32,0x454595,0x454595,2
+np.float32,0x7de66a33,0x7f800000,2
+np.float32,0xbf800000,0xbf966cfe,2
+np.float32,0xbf35c0a8,0xbf456939,2
+np.float32,0x3f6a6266,0x3f8643e0,2
+np.float32,0x3f0cbcee,0x3f13ef6a,2
+np.float32,0x7efd1e58,0x7f800000,2
+np.float32,0xfe9a74c6,0xff800000,2
+np.float32,0x807ebe6c,0x807ebe6c,2
+np.float32,0x80656736,0x80656736,2
+np.float32,0x800e0608,0x800e0608,2
+np.float32,0xbf30e39a,0xbf3f4e00,2
+np.float32,0x802015fd,0x802015fd,2
+np.float32,0x3e3ce26d,0x3e3df519,2
+np.float32,0x7ec142ac,0x7f800000,2
+np.float32,0xbf68c9ce,0xbf851c78,2
+np.float32,0xfede8356,0xff800000,2
+np.float32,0xbf1507ce,0xbf1d978d,2
+np.float32,0x3e53914c,0x3e551374,2
+np.float32,0x7f3e1c14,0x7f800000,2
+np.float32,0x8070d2ba,0x8070d2ba,2
+np.float32,0xbf4eb793,0xbf65ecee,2
+np.float32,0x7365a6,0x7365a6,2
+np.float32,0x8045cba2,0x8045cba2,2
+np.float32,0x7e4af521,0x7f800000,2
+np.float32,0xbf228625,0xbf2da9e1,2
+np.float32,0x7ee0536c,0x7f800000,2
+np.float32,0x3e126607,0x3e12e5d5,2
+np.float32,0x80311d92,0x80311d92,2
+np.float32,0xbf386b8b,0xbf48ca54,2
+np.float32,0x7f800000,0x7f800000,2
+np.float32,0x8049ec7a,0x8049ec7a,2
+np.float32,0xbf1dfde4,0xbf2836be,2
+np.float32,0x7e719a8c,0x7f800000,2
+np.float32,0x3eb9c856,0x3ebde2e6,2
+np.float32,0xfe3efda8,0xff800000,2
+np.float32,0xbe89d60c,0xbe8b81d1,2
+np.float32,0x3eaad338,0x3eae0317,2
+np.float32,0x7f4e5217,0x7f800000,2
+np.float32,0x3e9d0f40,0x3e9f88ce,2
+np.float32,0xbe026708,0xbe02c155,2
+np.float32,0x5fc22f,0x5fc22f,2
+np.float32,0x1c4572,0x1c4572,2
+np.float32,0xbed89d96,0xbedf22c5,2
+np.float32,0xbf3debee,0xbf4fd441,2
+np.float32,0xbf465520,0xbf5ac6e5,2
+np.float32,0x3f797081,0x3f9169b3,2
+np.float32,0xbf250734,0xbf30b2aa,2
+np.float32,0x7f5068e9,0x7f800000,2
+np.float32,0x3f1b814e,0x3f253f0c,2
+np.float32,0xbf27c5d3,0xbf340b05,2
+np.float32,0x3f1b78ae,0x3f2534c8,2
+np.float32,0x8059b51a,0x8059b51a,2
+np.float32,0x8059f182,0x8059f182,2
+np.float32,0xbf1bb36e,0xbf257ab8,2
+np.float32,0x41ac35,0x41ac35,2
+np.float32,0x68f41f,0x68f41f,2
+np.float32,0xbea504dc,0xbea7e40f,2
+np.float32,0x1,0x1,2
+np.float32,0x3e96b5b0,0x3e98e542,2
+np.float32,0x7f7fffff,0x7f800000,2
+np.float32,0x3c557a80,0x3c557c0c,2
+np.float32,0x800ca3ec,0x800ca3ec,2
+np.float32,0x8077d4aa,0x8077d4aa,2
+np.float32,0x3f000af0,0x3f0572d6,2
+np.float32,0x3e0434dd,0x3e0492f8,2
+np.float32,0x7d1a710a,0x7f800000,2
+np.float32,0x3f70f996,0x3f8b15f8,2
+np.float32,0x8033391d,0x8033391d,2
+np.float32,0x11927c,0x11927c,2
+np.float32,0x7f7784be,0x7f800000,2
+np.float32,0x7acb22af,0x7f800000,2
+np.float32,0x7e8b153c,0x7f800000,2
+np.float32,0x66d402,0x66d402,2
+np.float32,0xfed6e7b0,0xff800000,2
+np.float32,0x7f6872d3,0x7f800000,2
+np.float32,0x1bd49c,0x1bd49c,2
+np.float32,0xfdc4f1b8,0xff800000,2
+np.float32,0xbed8a466,0xbedf2a33,2
+np.float32,0x7ee789,0x7ee789,2
+np.float32,0xbece94b4,0xbed43b52,2
+np.float32,0x3cf3f734,0x3cf4006f,2
+np.float32,0x7e44aa00,0x7f800000,2
+np.float32,0x7f19e99c,0x7f800000,2
+np.float32,0x806ff1bc,0x806ff1bc,2
+np.float32,0x80296934,0x80296934,2
+np.float32,0x7f463363,0x7f800000,2
+np.float32,0xbf212ac3,0xbf2c06bb,2
+np.float32,0x3dc63778,0x3dc686ba,2
+np.float32,0x7f1b4328,0x7f800000,2
+np.float32,0x6311f6,0x6311f6,2
+np.float32,0xbf6b6fb6,0xbf870751,2
+np.float32,0xbf2c44cf,0xbf399155,2
+np.float32,0x3e7a67bc,0x3e7ce887,2
+np.float32,0x7f57c5f7,0x7f800000,2
+np.float32,0x7f2bb4ff,0x7f800000,2
+np.float32,0xbe9d448e,0xbe9fc0a4,2
+np.float32,0xbf4840f0,0xbf5d4f6b,2
+np.float32,0x7f1e1176,0x7f800000,2
+np.float32,0xff76638e,0xff800000,2
+np.float32,0xff055555,0xff800000,2
+np.float32,0x3f32b82b,0x3f419834,2
+np.float32,0xff363aa8,0xff800000,2
+np.float32,0x7f737fd0,0x7f800000,2
+np.float32,0x3da5d798,0x3da60602,2
+np.float32,0x3f1cc126,0x3f26bc3e,2
+np.float32,0x7eb07541,0x7f800000,2
+np.float32,0x3f7b2ff2,0x3f92bd2a,2
+np.float32,0x474f7,0x474f7,2
+np.float32,0x7fc00000,0x7fc00000,2
+np.float32,0xff2b0a4e,0xff800000,2
+np.float32,0xfeb24f16,0xff800000,2
+np.float32,0x2cb9fc,0x2cb9fc,2
+np.float32,0x67189d,0x67189d,2
+np.float32,0x8033d854,0x8033d854,2
+np.float32,0xbe85e94c,0xbe87717a,2
+np.float32,0x80767c6c,0x80767c6c,2
+np.float32,0x7ea84d65,0x7f800000,2
+np.float32,0x3f024bc7,0x3f07fead,2
+np.float32,0xbdcb0100,0xbdcb5625,2
+np.float32,0x3f160a9e,0x3f1ec7c9,2
+np.float32,0xff1734c8,0xff800000,2
+np.float32,0x7f424d5e,0x7f800000,2
+np.float32,0xbf75b215,0xbf8e9862,2
+np.float32,0x3f262a42,0x3f3214c4,2
+np.float32,0xbf4cfb53,0xbf639927,2
+np.float32,0x3f4ac8b8,0x3f60aa7c,2
+np.float32,0x3e90e593,0x3e92d6b3,2
+np.float32,0xbf66bccf,0xbf83a2d8,2
+np.float32,0x7d3d851a,0x7f800000,2
+np.float32,0x7bac783c,0x7f800000,2
+np.float32,0x8001c626,0x8001c626,2
+np.float32,0xbdffd480,0xbe003f7b,2
+np.float32,0x7f6680bf,0x7f800000,2
+np.float32,0xbecf448e,0xbed4f9bb,2
+np.float32,0x584c7,0x584c7,2
+np.float32,0x3f3e8ea0,0x3f50a5fb,2
+np.float32,0xbf5a5f04,0xbf75d56e,2
+np.float32,0x8065ae47,0x8065ae47,2
+np.float32,0xbf48dce3,0xbf5e1dba,2
+np.float32,0xbe8dae2e,0xbe8f7ed8,2
+np.float32,0x3f7ca6ab,0x3f93dace,2
+np.float32,0x4c3e81,0x4c3e81,2
+np.float32,0x80000000,0x80000000,2
+np.float32,0x3ee1f7d9,0x3ee96033,2
+np.float32,0x80588c6f,0x80588c6f,2
+np.float32,0x5ba34e,0x5ba34e,2
+np.float32,0x80095d28,0x80095d28,2
+np.float32,0xbe7ba198,0xbe7e2bdd,2
+np.float32,0xbe0bdcb4,0xbe0c4c22,2
+np.float32,0x1776f7,0x1776f7,2
+np.float32,0x80328b2a,0x80328b2a,2
+np.float32,0x3e978d37,0x3e99c63e,2
+np.float32,0x7ed50906,0x7f800000,2
+np.float32,0x3f776a54,0x3f8fe2bd,2
+np.float32,0xbed624c4,0xbedc7120,2
+np.float32,0x7f0b6a31,0x7f800000,2
+np.float32,0x7eb13913,0x7f800000,2
+np.float32,0xbe733684,0xbe758190,2
+np.float32,0x80016474,0x80016474,2
+np.float32,0x7a51ee,0x7a51ee,2
+np.float32,0x3f6cb91e,0x3f87f729,2
+np.float32,0xbd99b050,0xbd99d540,2
+np.float32,0x7c6e3cba,0x7f800000,2
+np.float32,0xbf00179a,0xbf05811e,2
+np.float32,0x3e609b29,0x3e626954,2
+np.float32,0xff3fd71a,0xff800000,2
+np.float32,0x5d8c2,0x5d8c2,2
+np.float32,0x7ee93662,0x7f800000,2
+np.float32,0x4b0b31,0x4b0b31,2
+np.float32,0x3ec243b7,0x3ec6f594,2
+np.float32,0x804d60f1,0x804d60f1,2
+np.float32,0xbf0cb784,0xbf13e929,2
+np.float32,0x3f13b74d,0x3f1c0cee,2
+np.float32,0xfe37cb64,0xff800000,2
+np.float32,0x1a88,0x1a88,2
+np.float32,0x3e22a472,0x3e2353ba,2
+np.float32,0x7f07d6a0,0x7f800000,2
+np.float32,0x3f78f435,0x3f910bb5,2
+np.float32,0x555a4a,0x555a4a,2
+np.float32,0x3e306c1f,0x3e314be3,2
+np.float32,0x8005877c,0x8005877c,2
+np.float32,0x4df389,0x4df389,2
+np.float32,0x8069ffc7,0x8069ffc7,2
+np.float32,0x3f328f24,0x3f4164c6,2
+np.float32,0x53a31b,0x53a31b,2
+np.float32,0xbe4d6768,0xbe4ec8be,2
+np.float32,0x7fa00000,0x7fe00000,2
+np.float32,0x3f484c1b,0x3f5d5e2f,2
+np.float32,0x8038be05,0x8038be05,2
+np.float32,0x58ac0f,0x58ac0f,2
+np.float32,0x7ed7fb72,0x7f800000,2
+np.float32,0x5a22e1,0x5a22e1,2
+np.float32,0xbebb7394,0xbebfaad6,2
+np.float32,0xbda98160,0xbda9b2ef,2
+np.float32,0x7f3e5c42,0x7f800000,2
+np.float32,0xfed204ae,0xff800000,2
+np.float32,0xbf5ef782,0xbf7c3ec5,2
+np.float32,0xbef7a0a8,0xbf00b292,2
+np.float32,0xfee6e176,0xff800000,2
+np.float32,0xfe121140,0xff800000,2
+np.float32,0xfe9e13be,0xff800000,2
+np.float32,0xbf3c98b1,0xbf4e2003,2
+np.float32,0x77520d,0x77520d,2
+np.float32,0xf17b2,0xf17b2,2
+np.float32,0x724d2f,0x724d2f,2
+np.float32,0x7eb326f5,0x7f800000,2
+np.float32,0x3edd6bf2,0x3ee4636e,2
+np.float32,0x350f57,0x350f57,2
+np.float32,0xff7d4435,0xff800000,2
+np.float32,0x802b2b9d,0x802b2b9d,2
+np.float32,0xbf7fbeee,0xbf963acf,2
+np.float32,0x804f3100,0x804f3100,2
+np.float32,0x7c594a71,0x7f800000,2
+np.float32,0x3ef49340,0x3efdfbb6,2
+np.float32,0x2e0659,0x2e0659,2
+np.float32,0x8006d5fe,0x8006d5fe,2
+np.float32,0xfd2a00b0,0xff800000,2
+np.float32,0xbee1c016,0xbee922ed,2
+np.float32,0x3e3b7de8,0x3e3c8a8b,2
+np.float32,0x805e6bba,0x805e6bba,2
+np.float32,0x1a7da2,0x1a7da2,2
+np.float32,0x6caba4,0x6caba4,2
+np.float32,0x802f7eab,0x802f7eab,2
+np.float32,0xff68b16b,0xff800000,2
+np.float32,0x8064f5e5,0x8064f5e5,2
+np.float32,0x2e39b4,0x2e39b4,2
+np.float32,0x800000,0x800000,2
+np.float32,0xfd0334c0,0xff800000,2
+np.float32,0x3e952fc4,0x3e974e7e,2
+np.float32,0x80057d33,0x80057d33,2
+np.float32,0x3ed3ddc4,0x3ed9f6f1,2
+np.float32,0x3f74ce18,0x3f8dedf4,2
+np.float32,0xff6bb7c0,0xff800000,2
+np.float32,0xff43bc21,0xff800000,2
+np.float32,0x80207570,0x80207570,2
+np.float32,0x7e1dda75,0x7f800000,2
+np.float32,0x3efe335c,0x3f0462ff,2
+np.float32,0xbf252c0c,0xbf30df70,2
+np.float32,0x3ef4b8e3,0x3efe25ba,2
+np.float32,0x7c33938d,0x7f800000,2
+np.float32,0x3eb1593c,0x3eb4ea95,2
+np.float32,0xfe1d0068,0xff800000,2
+np.float32,0xbf10da9b,0xbf18b551,2
+np.float32,0xfeb65748,0xff800000,2
+np.float32,0xfe8c6014,0xff800000,2
+np.float32,0x3f0503e2,0x3f0b14e3,2
+np.float32,0xfe5e5248,0xff800000,2
+np.float32,0xbd10afa0,0xbd10b754,2
+np.float32,0xff64b609,0xff800000,2
+np.float32,0xbf674a96,0xbf84089c,2
+np.float32,0x7f5d200d,0x7f800000,2
+np.float32,0x3cf44900,0x3cf45245,2
+np.float32,0x8044445a,0x8044445a,2
+np.float32,0xff35b676,0xff800000,2
+np.float32,0x806452cd,0x806452cd,2
+np.float32,0xbf2930fb,0xbf35c7b4,2
+np.float32,0x7e500617,0x7f800000,2
+np.float32,0x543719,0x543719,2
+np.float32,0x3ed11068,0x3ed6ec1d,2
+np.float32,0xbd8db068,0xbd8dcd59,2
+np.float32,0x3ede62c8,0x3ee571d0,2
+np.float32,0xbf00a410,0xbf061f9c,2
+np.float32,0xbf44fa39,0xbf58ff5b,2
+np.float32,0x3f1c3114,0x3f261069,2
+np.float32,0xbdea6210,0xbdeae521,2
+np.float32,0x80059f6d,0x80059f6d,2
+np.float32,0xbdba15f8,0xbdba578c,2
+np.float32,0x6d8a61,0x6d8a61,2
+np.float32,0x6f5428,0x6f5428,2
+np.float32,0x18d0e,0x18d0e,2
+np.float32,0x50e131,0x50e131,2
+np.float32,0x3f2f52be,0x3f3d5a7e,2
+np.float32,0x7399d8,0x7399d8,2
+np.float32,0x106524,0x106524,2
+np.float32,0x7ebf1c53,0x7f800000,2
+np.float32,0x80276458,0x80276458,2
+np.float32,0x3ebbde67,0x3ec01ceb,2
+np.float32,0x80144d9d,0x80144d9d,2
+np.float32,0x8017ea6b,0x8017ea6b,2
+np.float32,0xff38f201,0xff800000,2
+np.float32,0x7f2daa82,0x7f800000,2
+np.float32,0x3f3cb7c7,0x3f4e47ed,2
+np.float32,0x7f08c779,0x7f800000,2
+np.float32,0xbecc907a,0xbed20cec,2
+np.float32,0x7d440002,0x7f800000,2
+np.float32,0xbd410d80,0xbd411fcd,2
+np.float32,0x3d63ae07,0x3d63cc0c,2
+np.float32,0x805a9c13,0x805a9c13,2
+np.float32,0x803bdcdc,0x803bdcdc,2
+np.float32,0xbe88b354,0xbe8a5497,2
+np.float32,0x3f4eaf43,0x3f65e1c2,2
+np.float32,0x3f15e5b8,0x3f1e9c60,2
+np.float32,0x3e8a870c,0x3e8c394e,2
+np.float32,0x7e113de9,0x7f800000,2
+np.float32,0x7ee5ba41,0x7f800000,2
+np.float32,0xbe73d178,0xbe7620eb,2
+np.float32,0xfe972e6a,0xff800000,2
+np.float32,0xbf65567d,0xbf82a25a,2
+np.float32,0x3f38247e,0x3f487010,2
+np.float32,0xbece1c62,0xbed3b918,2
+np.float32,0x442c8d,0x442c8d,2
+np.float32,0x2dc52,0x2dc52,2
+np.float32,0x802ed923,0x802ed923,2
+np.float32,0x788cf8,0x788cf8,2
+np.float32,0x8024888e,0x8024888e,2
+np.float32,0x3f789bde,0x3f90c8fc,2
+np.float32,0x3f5de620,0x3f7abf88,2
+np.float32,0x3f0ffc45,0x3f17b2a7,2
+np.float32,0xbf709678,0xbf8accd4,2
+np.float32,0x12181f,0x12181f,2
+np.float32,0xfe54bbe4,0xff800000,2
+np.float32,0x7f1daba0,0x7f800000,2
+np.float32,0xbf6226df,0xbf805e3c,2
+np.float32,0xbd120610,0xbd120dfb,2
+np.float32,0x7f75e951,0x7f800000,2
+np.float32,0x80068048,0x80068048,2
+np.float32,0x45f04a,0x45f04a,2
+np.float32,0xff4c4f58,0xff800000,2
+np.float32,0x311604,0x311604,2
+np.float32,0x805e809c,0x805e809c,2
+np.float32,0x3d1d62c0,0x3d1d6caa,2
+np.float32,0x7f14ccf9,0x7f800000,2
+np.float32,0xff10017c,0xff800000,2
+np.float32,0xbf43ec48,0xbf579df4,2
+np.float32,0xff64da57,0xff800000,2
+np.float32,0x7f0622c5,0x7f800000,2
+np.float32,0x7f5460cd,0x7f800000,2
+np.float32,0xff0ef1c6,0xff800000,2
+np.float32,0xbece1146,0xbed3ad13,2
+np.float32,0x3f4d457f,0x3f63fc70,2
+np.float32,0xbdc1da28,0xbdc2244b,2
+np.float32,0xbe46d3f4,0xbe481463,2
+np.float32,0xff36b3d6,0xff800000,2
+np.float32,0xbec2e76c,0xbec7a540,2
+np.float32,0x8078fb81,0x8078fb81,2
+np.float32,0x7ec819cb,0x7f800000,2
+np.float32,0x39c4d,0x39c4d,2
+np.float32,0xbe8cddc2,0xbe8ea670,2
+np.float32,0xbf36dffb,0xbf46d48b,2
+np.float32,0xbf2302a3,0xbf2e4065,2
+np.float32,0x3e7b34a2,0x3e7dbb9a,2
+np.float32,0x3e3d87e1,0x3e3e9d62,2
+np.float32,0x7f3c94b1,0x7f800000,2
+np.float32,0x80455a85,0x80455a85,2
+np.float32,0xfd875568,0xff800000,2
+np.float32,0xbf618103,0xbf7fd1c8,2
+np.float32,0xbe332e3c,0xbe3418ac,2
+np.float32,0x80736b79,0x80736b79,2
+np.float32,0x3f705d9a,0x3f8aa2e6,2
+np.float32,0xbf3a36d2,0xbf4b134b,2
+np.float32,0xfddc55c0,0xff800000,2
+np.float32,0x805606fd,0x805606fd,2
+np.float32,0x3f4f0bc4,0x3f665e25,2
+np.float32,0xfebe7494,0xff800000,2
+np.float32,0xff0c541b,0xff800000,2
+np.float32,0xff0b8e7f,0xff800000,2
+np.float32,0xbcc51640,0xbcc51b1e,2
+np.float32,0x7ec1c4d0,0x7f800000,2
+np.float32,0xfc5c8e00,0xff800000,2
+np.float32,0x7f48d682,0x7f800000,2
+np.float32,0x7d5c7d8d,0x7f800000,2
+np.float32,0x8052ed03,0x8052ed03,2
+np.float32,0x7d4db058,0x7f800000,2
+np.float32,0xff3a65ee,0xff800000,2
+np.float32,0x806eeb93,0x806eeb93,2
+np.float32,0x803f9733,0x803f9733,2
+np.float32,0xbf2d1388,0xbf3a90e3,2
+np.float32,0x68e260,0x68e260,2
+np.float32,0x3e47a69f,0x3e48eb0e,2
+np.float32,0x3f0c4623,0x3f136646,2
+np.float32,0x3f37a831,0x3f47d249,2
+np.float32,0xff153a0c,0xff800000,2
+np.float32,0x2e8086,0x2e8086,2
+np.float32,0xc3f5e,0xc3f5e,2
+np.float32,0x7f31dc14,0x7f800000,2
+np.float32,0xfee37d68,0xff800000,2
+np.float32,0x711d4,0x711d4,2
+np.float32,0x7ede2ce4,0x7f800000,2
+np.float32,0xbf5d76d0,0xbf7a23d0,2
+np.float32,0xbe2b9eb4,0xbe2c6cac,2
+np.float32,0x2b14d7,0x2b14d7,2
+np.float32,0x3ea1db72,0x3ea4910e,2
+np.float32,0x7f3f03f7,0x7f800000,2
+np.float32,0x92de5,0x92de5,2
+np.float32,0x80322e1b,0x80322e1b,2
+np.float32,0xbf5eb214,0xbf7bdd55,2
+np.float32,0xbf21bf87,0xbf2cba14,2
+np.float32,0xbf5d4b78,0xbf79e73a,2
+np.float32,0xbc302840,0xbc30291e,2
+np.float32,0xfee567c6,0xff800000,2
+np.float32,0x7f70ee14,0x7f800000,2
+np.float32,0x7e5c4b33,0x7f800000,2
+np.float32,0x3f1e7b64,0x3f28ccfd,2
+np.float32,0xbf6309f7,0xbf80ff3e,2
+np.float32,0x1c2fe3,0x1c2fe3,2
+np.float32,0x8e78d,0x8e78d,2
+np.float32,0x7f2fce73,0x7f800000,2
+np.float32,0x7f25f690,0x7f800000,2
+np.float32,0x8074cba5,0x8074cba5,2
+np.float32,0x16975f,0x16975f,2
+np.float32,0x8012cf5c,0x8012cf5c,2
+np.float32,0x7da72138,0x7f800000,2
+np.float32,0xbf563f35,0xbf7025be,2
+np.float32,0x3f69d3f5,0x3f85dcbe,2
+np.float32,0xbf15c148,0xbf1e7184,2
+np.float32,0xbe7a077c,0xbe7c8564,2
+np.float32,0x3ebb6ef1,0x3ebfa5e3,2
+np.float32,0xbe41fde4,0xbe43277b,2
+np.float32,0x7f10b479,0x7f800000,2
+np.float32,0x3e021ace,0x3e02747d,2
+np.float32,0x3e93d984,0x3e95e9be,2
+np.float32,0xfe17e924,0xff800000,2
+np.float32,0xfe21a7cc,0xff800000,2
+np.float32,0x8019b660,0x8019b660,2
+np.float32,0x7e954631,0x7f800000,2
+np.float32,0x7e7330d1,0x7f800000,2
+np.float32,0xbe007d98,0xbe00d3fb,2
+np.float32,0x3ef3870e,0x3efcd077,2
+np.float32,0x7f5bbde8,0x7f800000,2
+np.float32,0x14a5b3,0x14a5b3,2
+np.float32,0x3e84d23f,0x3e8650e8,2
+np.float32,0x80763017,0x80763017,2
+np.float32,0xfe871f36,0xff800000,2
+np.float32,0x7ed43150,0x7f800000,2
+np.float32,0x3cc44547,0x3cc44a16,2
+np.float32,0x3ef0c0fa,0x3ef9b97d,2
+np.float32,0xbede9944,0xbee5ad86,2
+np.float32,0xbf10f0b2,0xbf18cf0a,2
+np.float32,0x3ecdaa78,0x3ed33dd9,2
+np.float32,0x3f7cc058,0x3f93ee6b,2
+np.float32,0x2d952f,0x2d952f,2
+np.float32,0x3f2cf2de,0x3f3a687a,2
+np.float32,0x8029b33c,0x8029b33c,2
+np.float32,0xbf22c737,0xbf2df888,2
+np.float32,0xff53c84a,0xff800000,2
+np.float32,0x40a509,0x40a509,2
+np.float32,0x56abce,0x56abce,2
+np.float32,0xff7fffff,0xff800000,2
+np.float32,0xbf3e67f6,0xbf50741c,2
+np.float32,0xfde67580,0xff800000,2
+np.float32,0x3f103e9b,0x3f17ffc7,2
+np.float32,0x3f3f7232,0x3f51cbe2,2
+np.float32,0x803e6d78,0x803e6d78,2
+np.float32,0x3a61da,0x3a61da,2
+np.float32,0xbc04de80,0xbc04dedf,2
+np.float32,0x7f1e7c52,0x7f800000,2
+np.float32,0x8058ee88,0x8058ee88,2
+np.float32,0x806dd660,0x806dd660,2
+np.float32,0x7e4af9,0x7e4af9,2
+np.float32,0x80702d27,0x80702d27,2
+np.float32,0x802cdad1,0x802cdad1,2
+np.float32,0x3e9b5c23,0x3e9dc149,2
+np.float32,0x7f076e89,0x7f800000,2
+np.float32,0x7f129d68,0x7f800000,2
+np.float32,0x7f6f0b0a,0x7f800000,2
+np.float32,0x7eafafb5,0x7f800000,2
+np.float32,0xbf2ef2ca,0xbf3ce332,2
+np.float32,0xff34c000,0xff800000,2
+np.float32,0x7f559274,0x7f800000,2
+np.float32,0xfed08556,0xff800000,2
+np.float32,0xbf014621,0xbf06d6ad,2
+np.float32,0xff23086a,0xff800000,2
+np.float32,0x6cb33f,0x6cb33f,2
+np.float32,0xfe6e3ffc,0xff800000,2
+np.float32,0x3e6bbec0,0x3e6dd546,2
+np.float32,0x8036afa6,0x8036afa6,2
+np.float32,0xff800000,0xff800000,2
+np.float32,0x3e0ed05c,0x3e0f46ff,2
+np.float32,0x3ec9215c,0x3ece57e6,2
+np.float32,0xbf449fa4,0xbf5888aa,2
+np.float32,0xff2c6640,0xff800000,2
+np.float32,0x7f08f4a7,0x7f800000,2
+np.float32,0xbf4f63e5,0xbf66d4c1,2
+np.float32,0x3f800000,0x3f966cfe,2
+np.float32,0xfe86c7d2,0xff800000,2
+np.float32,0x3f63f969,0x3f81a970,2
+np.float32,0xbd7022d0,0xbd704609,2
+np.float32,0xbead906c,0xbeb0e853,2
+np.float32,0x7ef149ee,0x7f800000,2
+np.float32,0xff0b9ff7,0xff800000,2
+np.float32,0x3f38380d,0x3f4888e7,2
+np.float32,0x3ef3a3e2,0x3efcf09e,2
+np.float32,0xff616477,0xff800000,2
+np.float32,0x3f3f83e4,0x3f51e2c3,2
+np.float32,0xbf79963c,0xbf918642,2
+np.float32,0x801416f4,0x801416f4,2
+np.float32,0xff75ce6d,0xff800000,2
+np.float32,0xbdbf3588,0xbdbf7cad,2
+np.float32,0xbe6ea938,0xbe70d3dc,2
+np.float32,0x8066f977,0x8066f977,2
+np.float32,0x3f5b5362,0x3f7728aa,2
+np.float32,0xbf72052c,0xbf8bdbd8,2
+np.float32,0xbe21ed74,0xbe229a6f,2
+np.float32,0x8062d19c,0x8062d19c,2
+np.float32,0x3ed8d01f,0x3edf59e6,2
+np.float32,0x803ed42b,0x803ed42b,2
+np.float32,0xbe099a64,0xbe0a0481,2
+np.float32,0xbe173eb4,0xbe17cba2,2
+np.float32,0xbebdcf02,0xbec22faf,2
+np.float32,0x7e3ff29e,0x7f800000,2
+np.float32,0x367c92,0x367c92,2
+np.float32,0xbf5c9db8,0xbf78f4a4,2
+np.float32,0xff0b49ea,0xff800000,2
+np.float32,0x3f4f9bc4,0x3f672001,2
+np.float32,0x85d4a,0x85d4a,2
+np.float32,0x80643e33,0x80643e33,2
+np.float32,0x8013aabd,0x8013aabd,2
+np.float32,0xff6997c3,0xff800000,2
+np.float32,0x3f4dd43c,0x3f64bbb6,2
+np.float32,0xff13bbb9,0xff800000,2
+np.float32,0x3f34efa2,0x3f446187,2
+np.float32,0x3e4b2f10,0x3e4c850d,2
+np.float32,0xfef695c6,0xff800000,2
+np.float32,0x7f7e0057,0x7f800000,2
+np.float32,0x3f6e1b9c,0x3f88fa40,2
+np.float32,0x806e46cf,0x806e46cf,2
+np.float32,0x3f15a88a,0x3f1e546c,2
+np.float32,0xbd2de7d0,0xbd2df530,2
+np.float32,0xbf63cae0,0xbf818854,2
+np.float32,0xbdc3e1a0,0xbdc42e1e,2
+np.float32,0xbf11a038,0xbf199b98,2
+np.float32,0xbec13706,0xbec5d56b,2
+np.float32,0x3f1c5f54,0x3f26478d,2
+np.float32,0x3e9ea97e,0x3ea136b4,2
+np.float32,0xfeb5a508,0xff800000,2
+np.float32,0x7f4698f4,0x7f800000,2
+np.float32,0xff51ee2c,0xff800000,2
+np.float32,0xff5994df,0xff800000,2
+np.float32,0x4b9fb9,0x4b9fb9,2
+np.float32,0xfda10d98,0xff800000,2
+np.float32,0x525555,0x525555,2
+np.float32,0x7ed571ef,0x7f800000,2
+np.float32,0xbf600d18,0xbf7dc50c,2
+np.float32,0x3ec674ca,0x3ecb768b,2
+np.float32,0x3cb69115,0x3cb694f3,2
+np.float32,0x7eac75f2,0x7f800000,2
+np.float32,0x804d4d75,0x804d4d75,2
+np.float32,0xfed5292e,0xff800000,2
+np.float32,0x800ed06a,0x800ed06a,2
+np.float32,0xfec37584,0xff800000,2
+np.float32,0x3ef96ac7,0x3f01b326,2
+np.float32,0x42f743,0x42f743,2
+np.float32,0x3f56f442,0x3f711e39,2
+np.float32,0xbf7ea726,0xbf956375,2
+np.float32,0x806c7202,0x806c7202,2
+np.float32,0xbd8ee980,0xbd8f0733,2
+np.float32,0xbdf2e930,0xbdf37b18,2
+np.float32,0x3f103910,0x3f17f955,2
+np.float32,0xff123e8f,0xff800000,2
+np.float32,0x806e4b5d,0x806e4b5d,2
+np.float32,0xbf4f3bfc,0xbf669f07,2
+np.float32,0xbf070c16,0xbf0d6609,2
+np.float32,0xff00e0ba,0xff800000,2
+np.float32,0xff49d828,0xff800000,2
+np.float32,0x7e47f04a,0x7f800000,2
+np.float32,0x7e984dac,0x7f800000,2
+np.float32,0x3f77473c,0x3f8fc858,2
+np.float32,0x3f017439,0x3f070ac8,2
+np.float32,0x118417,0x118417,2
+np.float32,0xbcf7a2c0,0xbcf7ac68,2
+np.float32,0xfee46fee,0xff800000,2
+np.float32,0x3e42a648,0x3e43d2e9,2
+np.float32,0x80131916,0x80131916,2
+np.float32,0x806209d3,0x806209d3,2
+np.float32,0x807c1f12,0x807c1f12,2
+np.float32,0x2f3696,0x2f3696,2
+np.float32,0xff28722b,0xff800000,2
+np.float32,0x7f1416a1,0x7f800000,2
+np.float32,0x8054e7a1,0x8054e7a1,2
+np.float32,0xbddc39a0,0xbddca656,2
+np.float32,0x7dc60175,0x7f800000,2
+np.float64,0x7fd0ae584da15cb0,0x7ff0000000000000,2
+np.float64,0x7fd41d68e5283ad1,0x7ff0000000000000,2
+np.float64,0x7fe93073bb7260e6,0x7ff0000000000000,2
+np.float64,0x3fb4fd19d229fa34,0x3fb5031f57dbac0f,2
+np.float64,0x85609ce10ac2,0x85609ce10ac2,2
+np.float64,0xbfd7aa12ccaf5426,0xbfd8351003a320e2,2
+np.float64,0x8004487c9b4890fa,0x8004487c9b4890fa,2
+np.float64,0x7fe7584cfd2eb099,0x7ff0000000000000,2
+np.float64,0x800ea8edc6dd51dc,0x800ea8edc6dd51dc,2
+np.float64,0x3fe0924aa5a12495,0x3fe15276e271c6dc,2
+np.float64,0x3feb1abf6d36357f,0x3fee76b4d3d06964,2
+np.float64,0x3fa8c14534318280,0x3fa8c3bd5ce5923c,2
+np.float64,0x800b9f5915d73eb3,0x800b9f5915d73eb3,2
+np.float64,0xffc05aaa7820b554,0xfff0000000000000,2
+np.float64,0x800157eda8c2afdc,0x800157eda8c2afdc,2
+np.float64,0xffe8d90042b1b200,0xfff0000000000000,2
+np.float64,0x3feda02ea93b405d,0x3ff1057e61d08d59,2
+np.float64,0xffd03b7361a076e6,0xfff0000000000000,2
+np.float64,0x3fe1a8ecd7e351da,0x3fe291eda9080847,2
+np.float64,0xffc5bfdff82b7fc0,0xfff0000000000000,2
+np.float64,0xbfe6fb3d386df67a,0xbfe9022c05df0565,2
+np.float64,0x7fefffffffffffff,0x7ff0000000000000,2
+np.float64,0x7fa10c340c221867,0x7ff0000000000000,2
+np.float64,0x3fe55cbf1daab97e,0x3fe6fc1648258b75,2
+np.float64,0xbfddeb5f60bbd6be,0xbfdf056d4fb5825f,2
+np.float64,0xffddb1a8213b6350,0xfff0000000000000,2
+np.float64,0xbfb20545e4240a88,0xbfb2091579375176,2
+np.float64,0x3f735ded2026bbda,0x3f735df1dad4ee3a,2
+np.float64,0xbfd1eb91efa3d724,0xbfd227c044dead61,2
+np.float64,0xffd737c588ae6f8c,0xfff0000000000000,2
+np.float64,0x3fc46818ec28d032,0x3fc47e416c4237a6,2
+np.float64,0x0,0x0,2
+np.float64,0xffb632097a2c6410,0xfff0000000000000,2
+np.float64,0xbfcb5ae84b36b5d0,0xbfcb905613af55b8,2
+np.float64,0xbfe7b926402f724c,0xbfe9f4f0be6aacc3,2
+np.float64,0x80081840b3f03082,0x80081840b3f03082,2
+np.float64,0x3fe767a656eecf4d,0x3fe98c53b4779de7,2
+np.float64,0x8005834c088b0699,0x8005834c088b0699,2
+np.float64,0x80074e92658e9d26,0x80074e92658e9d26,2
+np.float64,0x80045d60c268bac2,0x80045d60c268bac2,2
+np.float64,0xffb9aecfe8335da0,0xfff0000000000000,2
+np.float64,0x7fcad3e1cd35a7c3,0x7ff0000000000000,2
+np.float64,0xbf881853d03030c0,0xbf8818783e28fc87,2
+np.float64,0xe18c6d23c318e,0xe18c6d23c318e,2
+np.float64,0x7fcb367b8f366cf6,0x7ff0000000000000,2
+np.float64,0x5c13436cb8269,0x5c13436cb8269,2
+np.float64,0xffe5399938aa7332,0xfff0000000000000,2
+np.float64,0xbfdc45dbc3b88bb8,0xbfdd33958222c27e,2
+np.float64,0xbfd714691bae28d2,0xbfd7954edbef810b,2
+np.float64,0xbfdf18b02b3e3160,0xbfe02ad13634c651,2
+np.float64,0x8003e6f276e7cde6,0x8003e6f276e7cde6,2
+np.float64,0x3febb6b412776d68,0x3fef4f753def31f9,2
+np.float64,0x7fe016a3b4a02d46,0x7ff0000000000000,2
+np.float64,0x3fdc899ac7b91336,0x3fdd7e1cee1cdfc8,2
+np.float64,0x800219271e24324f,0x800219271e24324f,2
+np.float64,0x1529d93e2a53c,0x1529d93e2a53c,2
+np.float64,0x800d5bc827fab790,0x800d5bc827fab790,2
+np.float64,0x3e1495107c293,0x3e1495107c293,2
+np.float64,0x3fe89da0f2b13b42,0x3feb1dc1f3015ad7,2
+np.float64,0x800ba8c17b975183,0x800ba8c17b975183,2
+np.float64,0x8002dacf0265b59f,0x8002dacf0265b59f,2
+np.float64,0xffe6d0a4cc2da149,0xfff0000000000000,2
+np.float64,0x3fdf23fe82be47fc,0x3fe03126d8e2b309,2
+np.float64,0xffe41b1f1c28363e,0xfff0000000000000,2
+np.float64,0xbfd635c634ac6b8c,0xbfd6a8966da6adaa,2
+np.float64,0x800755bc08eeab79,0x800755bc08eeab79,2
+np.float64,0x800ba4c47c374989,0x800ba4c47c374989,2
+np.float64,0x7fec9f7649793eec,0x7ff0000000000000,2
+np.float64,0x7fdbf45738b7e8ad,0x7ff0000000000000,2
+np.float64,0x3f5597f07eab4,0x3f5597f07eab4,2
+np.float64,0xbfbf4599183e8b30,0xbfbf5985d8c65097,2
+np.float64,0xbf5b200580364000,0xbf5b2006501b21ae,2
+np.float64,0x7f91868370230d06,0x7ff0000000000000,2
+np.float64,0x3838e2a67071d,0x3838e2a67071d,2
+np.float64,0xffefe3ff5d3fc7fe,0xfff0000000000000,2
+np.float64,0xffe66b26d06cd64d,0xfff0000000000000,2
+np.float64,0xbfd830a571b0614a,0xbfd8c526927c742c,2
+np.float64,0x7fe8442122f08841,0x7ff0000000000000,2
+np.float64,0x800efa8c637df519,0x800efa8c637df519,2
+np.float64,0xf0026835e004d,0xf0026835e004d,2
+np.float64,0xffb11beefe2237e0,0xfff0000000000000,2
+np.float64,0x3fef9bbb327f3776,0x3ff2809f10641c32,2
+np.float64,0x350595306a0b3,0x350595306a0b3,2
+np.float64,0xf7f6538befecb,0xf7f6538befecb,2
+np.float64,0xffe36379c4a6c6f3,0xfff0000000000000,2
+np.float64,0x28b1d82e5163c,0x28b1d82e5163c,2
+np.float64,0x70a3d804e147c,0x70a3d804e147c,2
+np.float64,0xffd96c1bc9b2d838,0xfff0000000000000,2
+np.float64,0xffce8e00893d1c00,0xfff0000000000000,2
+np.float64,0x800f2bdcb25e57b9,0x800f2bdcb25e57b9,2
+np.float64,0xbfe0d9c63361b38c,0xbfe1a3eb02192b76,2
+np.float64,0xbfdc7b8711b8f70e,0xbfdd6e9db3a01e51,2
+np.float64,0x99e22ec133c46,0x99e22ec133c46,2
+np.float64,0xffeaef6ddab5dedb,0xfff0000000000000,2
+np.float64,0x7fe89c22c0f13845,0x7ff0000000000000,2
+np.float64,0x8002d5207de5aa42,0x8002d5207de5aa42,2
+np.float64,0x3fd1b13353236267,0x3fd1eb1b9345dfca,2
+np.float64,0x800ccae0a41995c1,0x800ccae0a41995c1,2
+np.float64,0x3fdbdaba38b7b574,0x3fdcbdfcbca37ce6,2
+np.float64,0x5b06d12cb60db,0x5b06d12cb60db,2
+np.float64,0xffd52262752a44c4,0xfff0000000000000,2
+np.float64,0x5a17f050b42ff,0x5a17f050b42ff,2
+np.float64,0x3d24205e7a485,0x3d24205e7a485,2
+np.float64,0x7fbed4dec63da9bd,0x7ff0000000000000,2
+np.float64,0xbfe56e9776aadd2f,0xbfe71212863c284f,2
+np.float64,0x7fea0bc952341792,0x7ff0000000000000,2
+np.float64,0x800f692d139ed25a,0x800f692d139ed25a,2
+np.float64,0xffdb63feab36c7fe,0xfff0000000000000,2
+np.float64,0x3fe1c2297fe38452,0x3fe2af21293c9571,2
+np.float64,0x7fede384747bc708,0x7ff0000000000000,2
+np.float64,0x800440169288802e,0x800440169288802e,2
+np.float64,0xffe3241eeb26483e,0xfff0000000000000,2
+np.float64,0xffe28f3879651e70,0xfff0000000000000,2
+np.float64,0xa435cbc1486d,0xa435cbc1486d,2
+np.float64,0x7fe55e08db6abc11,0x7ff0000000000000,2
+np.float64,0x1405e624280be,0x1405e624280be,2
+np.float64,0x3fd861bdf0b0c37c,0x3fd8f9d2e33e45e5,2
+np.float64,0x3feeb67cdc3d6cfa,0x3ff1d337d81d1c14,2
+np.float64,0x3fd159a10e22b342,0x3fd1903be7c2ea0c,2
+np.float64,0x3fd84626bc308c4d,0x3fd8dc373645e65b,2
+np.float64,0xffd3da81d9a7b504,0xfff0000000000000,2
+np.float64,0xbfd4a768b8294ed2,0xbfd503aa7c240051,2
+np.float64,0x3fe3059f2a660b3e,0x3fe42983e0c6bb2e,2
+np.float64,0x3fe3b8353827706a,0x3fe4fdd635c7269b,2
+np.float64,0xbfe4af0399695e07,0xbfe6277d9002b46c,2
+np.float64,0xbfd7e18a92afc316,0xbfd87066b54c4fe6,2
+np.float64,0x800432bcab48657a,0x800432bcab48657a,2
+np.float64,0x80033d609d267ac2,0x80033d609d267ac2,2
+np.float64,0x7fef5f758e7ebeea,0x7ff0000000000000,2
+np.float64,0xbfed7833dbfaf068,0xbff0e85bf45a5ebc,2
+np.float64,0x3fe2283985a45073,0x3fe325b0a9099c74,2
+np.float64,0xe820b4b3d0417,0xe820b4b3d0417,2
+np.float64,0x8003ecb72aa7d96f,0x8003ecb72aa7d96f,2
+np.float64,0xbfeab2c755b5658f,0xbfede7c83e92a625,2
+np.float64,0xbfc7b287f72f6510,0xbfc7d53ef2ffe9dc,2
+np.float64,0xffd9a41d0f33483a,0xfff0000000000000,2
+np.float64,0x3fd3a5b6e3a74b6c,0x3fd3f516f39a4725,2
+np.float64,0x800bc72091578e42,0x800bc72091578e42,2
+np.float64,0x800ff405ce9fe80c,0x800ff405ce9fe80c,2
+np.float64,0x57918600af24,0x57918600af24,2
+np.float64,0x2a5be7fa54b7e,0x2a5be7fa54b7e,2
+np.float64,0xbfdca7886bb94f10,0xbfdd9f142b5b43e4,2
+np.float64,0xbfe216993ee42d32,0xbfe3112936590995,2
+np.float64,0xbfe06bd9cf20d7b4,0xbfe126cd353ab42f,2
+np.float64,0x8003e6c31827cd87,0x8003e6c31827cd87,2
+np.float64,0x8005f37d810be6fc,0x8005f37d810be6fc,2
+np.float64,0x800715b081ae2b62,0x800715b081ae2b62,2
+np.float64,0x3fef94c35bff2986,0x3ff27b4bed2f4051,2
+np.float64,0x6f5798e0deb0,0x6f5798e0deb0,2
+np.float64,0x3fcef1f05c3de3e1,0x3fcf3f557550598f,2
+np.float64,0xbf9a91c400352380,0xbf9a92876273b85c,2
+np.float64,0x3fc9143f7f322880,0x3fc93d678c05d26b,2
+np.float64,0x78ad847af15b1,0x78ad847af15b1,2
+np.float64,0x8000fdc088c1fb82,0x8000fdc088c1fb82,2
+np.float64,0x800200fd304401fb,0x800200fd304401fb,2
+np.float64,0x7fb8ab09dc315613,0x7ff0000000000000,2
+np.float64,0x3fe949771b7292ee,0x3fec00891c3fc5a2,2
+np.float64,0xbfc54cae0e2a995c,0xbfc565e0f3d0e3af,2
+np.float64,0xffd546161e2a8c2c,0xfff0000000000000,2
+np.float64,0x800fe1d1279fc3a2,0x800fe1d1279fc3a2,2
+np.float64,0x3fd9c45301b388a8,0x3fda77fa1f4c79bf,2
+np.float64,0x7fe10ff238221fe3,0x7ff0000000000000,2
+np.float64,0xbfbc2181ae384300,0xbfbc3002229155c4,2
+np.float64,0xbfe7bbfae4ef77f6,0xbfe9f895e91f468d,2
+np.float64,0x800d3d994f7a7b33,0x800d3d994f7a7b33,2
+np.float64,0xffe6e15a896dc2b4,0xfff0000000000000,2
+np.float64,0x800e6b6c8abcd6d9,0x800e6b6c8abcd6d9,2
+np.float64,0xbfd862c938b0c592,0xbfd8faf1cdcb09db,2
+np.float64,0xffe2411f8464823e,0xfff0000000000000,2
+np.float64,0xffd0b32efaa1665e,0xfff0000000000000,2
+np.float64,0x3ac4ace475896,0x3ac4ace475896,2
+np.float64,0xf9c3a7ebf3875,0xf9c3a7ebf3875,2
+np.float64,0xdb998ba5b7332,0xdb998ba5b7332,2
+np.float64,0xbfe438a14fe87142,0xbfe5981751e4c5cd,2
+np.float64,0xbfbcf48cbc39e918,0xbfbd045d60e65d3a,2
+np.float64,0x7fde499615bc932b,0x7ff0000000000000,2
+np.float64,0x800bba269057744e,0x800bba269057744e,2
+np.float64,0x3fc9bb1ba3337638,0x3fc9e78fdb6799c1,2
+np.float64,0xffd9f974fbb3f2ea,0xfff0000000000000,2
+np.float64,0x7fcf1ad1693e35a2,0x7ff0000000000000,2
+np.float64,0x7fe5dcedd32bb9db,0x7ff0000000000000,2
+np.float64,0xeb06500bd60ca,0xeb06500bd60ca,2
+np.float64,0x7fd73e7b592e7cf6,0x7ff0000000000000,2
+np.float64,0xbfe9d91ae873b236,0xbfecc08482849bcd,2
+np.float64,0xffc85338b730a670,0xfff0000000000000,2
+np.float64,0x7fbba41eee37483d,0x7ff0000000000000,2
+np.float64,0x3fed5624fb7aac4a,0x3ff0cf9f0de1fd54,2
+np.float64,0xffe566d80d6acdb0,0xfff0000000000000,2
+np.float64,0x3fd4477884a88ef1,0x3fd49ec7acdd25a0,2
+np.float64,0x3fcb98c5fd37318c,0x3fcbcfa20e2c2712,2
+np.float64,0xffdeba71d5bd74e4,0xfff0000000000000,2
+np.float64,0x8001edc59dc3db8c,0x8001edc59dc3db8c,2
+np.float64,0x3fe6b09e896d613e,0x3fe8a3bb541ec0e3,2
+np.float64,0x3fe8694b4970d296,0x3fead94d271d05cf,2
+np.float64,0xb52c27bf6a585,0xb52c27bf6a585,2
+np.float64,0x7fcb0a21d9361443,0x7ff0000000000000,2
+np.float64,0xbfd9efc68cb3df8e,0xbfdaa7058c0ccbd1,2
+np.float64,0x8007cd170fef9a2f,0x8007cd170fef9a2f,2
+np.float64,0x3fe83325e770664c,0x3fea92c55c9d567e,2
+np.float64,0x800bd0085537a011,0x800bd0085537a011,2
+np.float64,0xffe05b9e7820b73c,0xfff0000000000000,2
+np.float64,0x3fea4ce4347499c8,0x3fed5cea9fdc541b,2
+np.float64,0x7fe08aae1921155b,0x7ff0000000000000,2
+np.float64,0x3fe7a5e7deef4bd0,0x3fe9dc2e20cfb61c,2
+np.float64,0xbfe0ccc8e6e19992,0xbfe195175f32ee3f,2
+np.float64,0xbfe8649717f0c92e,0xbfead3298974dcf0,2
+np.float64,0x7fed6c5308bad8a5,0x7ff0000000000000,2
+np.float64,0xffdbd8c7af37b190,0xfff0000000000000,2
+np.float64,0xbfb2bc4d06257898,0xbfb2c09569912839,2
+np.float64,0x3fc62eca512c5d95,0x3fc64b4251bce8f9,2
+np.float64,0xbfcae2ddbd35c5bc,0xbfcb15971fc61312,2
+np.float64,0x18d26ce831a4f,0x18d26ce831a4f,2
+np.float64,0x7fe38b279267164e,0x7ff0000000000000,2
+np.float64,0x97e1d9ab2fc3b,0x97e1d9ab2fc3b,2
+np.float64,0xbfee8e4785fd1c8f,0xbff1b52d16807627,2
+np.float64,0xbfb189b4a6231368,0xbfb18d37e83860ee,2
+np.float64,0xffd435761ea86aec,0xfff0000000000000,2
+np.float64,0x3fe6c48ebced891e,0x3fe8bcea189c3867,2
+np.float64,0x7fdadd3678b5ba6c,0x7ff0000000000000,2
+np.float64,0x7fea8f15b7b51e2a,0x7ff0000000000000,2
+np.float64,0xbff0000000000000,0xbff2cd9fc44eb982,2
+np.float64,0x80004c071120980f,0x80004c071120980f,2
+np.float64,0x8005367adfea6cf6,0x8005367adfea6cf6,2
+np.float64,0x3fbdc9139a3b9220,0x3fbdda4aba667ce5,2
+np.float64,0x7fed5ee3ad7abdc6,0x7ff0000000000000,2
+np.float64,0x51563fb2a2ac9,0x51563fb2a2ac9,2
+np.float64,0xbfba7d26ce34fa50,0xbfba894229c50ea1,2
+np.float64,0x6c10db36d821c,0x6c10db36d821c,2
+np.float64,0xbfbdaec0d03b5d80,0xbfbdbfca6ede64f4,2
+np.float64,0x800a1cbe7414397d,0x800a1cbe7414397d,2
+np.float64,0x800ae6e7f2d5cdd0,0x800ae6e7f2d5cdd0,2
+np.float64,0x3fea63d3fef4c7a8,0x3fed7c1356688ddc,2
+np.float64,0xbfde1e3a88bc3c76,0xbfdf3dfb09cc2260,2
+np.float64,0xbfd082d75a2105ae,0xbfd0b1e28c84877b,2
+np.float64,0x7fea1e5e85f43cbc,0x7ff0000000000000,2
+np.float64,0xffe2237a1a6446f4,0xfff0000000000000,2
+np.float64,0x3fd1e2be8523c57d,0x3fd21e93dfd1bbc4,2
+np.float64,0x3fd1acd428a359a8,0x3fd1e6916a42bc3a,2
+np.float64,0x61a152f0c342b,0x61a152f0c342b,2
+np.float64,0xbfc61a6b902c34d8,0xbfc6369557690ba0,2
+np.float64,0x7fd1a84b1f235095,0x7ff0000000000000,2
+np.float64,0x1c5cc7e638b9a,0x1c5cc7e638b9a,2
+np.float64,0x8008039755f0072f,0x8008039755f0072f,2
+np.float64,0x80097532d6f2ea66,0x80097532d6f2ea66,2
+np.float64,0xbfc6d979a12db2f4,0xbfc6f89777c53f8f,2
+np.float64,0x8004293ab1085276,0x8004293ab1085276,2
+np.float64,0x3fc2af5c21255eb8,0x3fc2c05dc0652554,2
+np.float64,0xbfd9a5ab87b34b58,0xbfda56d1076abc98,2
+np.float64,0xbfebd360ba77a6c2,0xbfef779fd6595f9b,2
+np.float64,0xffd5313c43aa6278,0xfff0000000000000,2
+np.float64,0xbfe994a262b32945,0xbfec64b969852ed5,2
+np.float64,0x3fce01a52e3c034a,0x3fce48324eb29c31,2
+np.float64,0x56bd74b2ad7af,0x56bd74b2ad7af,2
+np.float64,0xb84093ff70813,0xb84093ff70813,2
+np.float64,0x7fe776df946eedbe,0x7ff0000000000000,2
+np.float64,0xbfe294ac2e652958,0xbfe3a480938afa26,2
+np.float64,0x7fe741b4d0ee8369,0x7ff0000000000000,2
+np.float64,0x800b7e8a1056fd15,0x800b7e8a1056fd15,2
+np.float64,0x7fd28f1269251e24,0x7ff0000000000000,2
+np.float64,0x8009d4492e73a893,0x8009d4492e73a893,2
+np.float64,0x3fe3f27fca67e500,0x3fe543aff825e244,2
+np.float64,0x3fd12447e5a24890,0x3fd158efe43c0452,2
+np.float64,0xbfd58df0f2ab1be2,0xbfd5f6d908e3ebce,2
+np.float64,0xffc0a8e4642151c8,0xfff0000000000000,2
+np.float64,0xbfedb197787b632f,0xbff112367ec9d3e7,2
+np.float64,0xffdde07a7f3bc0f4,0xfff0000000000000,2
+np.float64,0x3fe91f3e5b723e7d,0x3febc886a1d48364,2
+np.float64,0x3fe50415236a082a,0x3fe68f43a5468d8c,2
+np.float64,0xd9a0c875b3419,0xd9a0c875b3419,2
+np.float64,0xbfee04ccf4bc099a,0xbff14f4740a114cf,2
+np.float64,0xbfd2bcc6a125798e,0xbfd30198b1e7d7ed,2
+np.float64,0xbfeb3c16f8f6782e,0xbfeea4ce47d09f58,2
+np.float64,0xffd3ba19e4a77434,0xfff0000000000000,2
+np.float64,0x8010000000000000,0x8010000000000000,2
+np.float64,0x3fdef0a642bde14d,0x3fe0146677b3a488,2
+np.float64,0x3fdc3dd0a2b87ba0,0x3fdd2abe65651487,2
+np.float64,0x3fdbb1fd47b763fb,0x3fdc915a2fd19f4b,2
+np.float64,0x7fbaa375e63546eb,0x7ff0000000000000,2
+np.float64,0x433ef8ee867e0,0x433ef8ee867e0,2
+np.float64,0xf5345475ea68b,0xf5345475ea68b,2
+np.float64,0xa126419b424c8,0xa126419b424c8,2
+np.float64,0x3fe0057248200ae5,0x3fe0b2f488339709,2
+np.float64,0xffc5e3b82f2bc770,0xfff0000000000000,2
+np.float64,0xffb215c910242b90,0xfff0000000000000,2
+np.float64,0xbfeba4ae0837495c,0xbfef3642e4b54aac,2
+np.float64,0xffbb187ebe363100,0xfff0000000000000,2
+np.float64,0x3fe4c6a496a98d49,0x3fe64440cdf06aab,2
+np.float64,0x800767a28f6ecf46,0x800767a28f6ecf46,2
+np.float64,0x3fdbed63b1b7dac8,0x3fdcd27318c0b683,2
+np.float64,0x80006d8339e0db07,0x80006d8339e0db07,2
+np.float64,0x8000b504f0416a0b,0x8000b504f0416a0b,2
+np.float64,0xbfe88055bfb100ac,0xbfeaf767bd2767b9,2
+np.float64,0x3fefe503317fca06,0x3ff2b8d4057240c8,2
+np.float64,0x7fe307538b660ea6,0x7ff0000000000000,2
+np.float64,0x944963c12892d,0x944963c12892d,2
+np.float64,0xbfd2c20b38a58416,0xbfd30717900f8233,2
+np.float64,0x7feed04e3e3da09b,0x7ff0000000000000,2
+np.float64,0x3fe639619cac72c3,0x3fe80de7b8560a8d,2
+np.float64,0x3fde066c66bc0cd9,0x3fdf237fb759a652,2
+np.float64,0xbfc56b22b52ad644,0xbfc584c267a47ebd,2
+np.float64,0x3fc710d5b12e21ab,0x3fc730d817ba0d0c,2
+np.float64,0x3fee1dfc347c3bf8,0x3ff161d9c3e15f68,2
+np.float64,0x3fde400954bc8013,0x3fdf639e5cc9e7a9,2
+np.float64,0x56e701f8adce1,0x56e701f8adce1,2
+np.float64,0xbfe33bbc89e67779,0xbfe46996b39381fe,2
+np.float64,0x7fec89e2f87913c5,0x7ff0000000000000,2
+np.float64,0xbfdad58b40b5ab16,0xbfdba098cc0ad5d3,2
+np.float64,0x3fe99c76a13338ed,0x3fec6f31bae613e7,2
+np.float64,0x3fe4242a29a84854,0x3fe57f6b45e5c0ef,2
+np.float64,0xbfe79d3199ef3a63,0xbfe9d0fb96c846ba,2
+np.float64,0x7ff8000000000000,0x7ff8000000000000,2
+np.float64,0xbfeb35a6cf766b4e,0xbfee9be4e7e943f7,2
+np.float64,0x3e047f267c091,0x3e047f267c091,2
+np.float64,0x4bf1376a97e28,0x4bf1376a97e28,2
+np.float64,0x800ef419685de833,0x800ef419685de833,2
+np.float64,0x3fe0efa61a21df4c,0x3fe1bce98baf2f0f,2
+np.float64,0x3fcc13c4d738278a,0x3fcc4d8c778bcaf7,2
+np.float64,0x800f1d291afe3a52,0x800f1d291afe3a52,2
+np.float64,0x3fd3f10e6da7e21d,0x3fd444106761ea1d,2
+np.float64,0x800706d6d76e0dae,0x800706d6d76e0dae,2
+np.float64,0xffa1ffbc9023ff80,0xfff0000000000000,2
+np.float64,0xbfe098f26d6131e5,0xbfe15a08a5f3eac0,2
+np.float64,0x3fe984f9cc7309f4,0x3fec4fcdbdb1cb9b,2
+np.float64,0x7fd7c2f1eaaf85e3,0x7ff0000000000000,2
+np.float64,0x800a8adb64f515b7,0x800a8adb64f515b7,2
+np.float64,0x80060d3ffc8c1a81,0x80060d3ffc8c1a81,2
+np.float64,0xbfec37e4aef86fc9,0xbff0029a6a1d61e2,2
+np.float64,0x800b21bcfcf6437a,0x800b21bcfcf6437a,2
+np.float64,0xbfc08facc1211f58,0xbfc09b8380ea8032,2
+np.float64,0xffebb4b52577696a,0xfff0000000000000,2
+np.float64,0x800b08096df61013,0x800b08096df61013,2
+np.float64,0x8000000000000000,0x8000000000000000,2
+np.float64,0xffd2f0c9c8a5e194,0xfff0000000000000,2
+np.float64,0xffe78b2299af1644,0xfff0000000000000,2
+np.float64,0x7fd0444794a0888e,0x7ff0000000000000,2
+np.float64,0x307c47b460f8a,0x307c47b460f8a,2
+np.float64,0xffe6b4c851ad6990,0xfff0000000000000,2
+np.float64,0xffe1877224a30ee4,0xfff0000000000000,2
+np.float64,0x48d7b5c091af7,0x48d7b5c091af7,2
+np.float64,0xbfa1dc6b1c23b8d0,0xbfa1dd5889e1b7da,2
+np.float64,0x3fe5004737ea008e,0x3fe68a9c310b08c1,2
+np.float64,0x7fec5f0742b8be0e,0x7ff0000000000000,2
+np.float64,0x3fd0a86285a150c5,0x3fd0d8b238d557fa,2
+np.float64,0x7fed60380efac06f,0x7ff0000000000000,2
+np.float64,0xeeca74dfdd94f,0xeeca74dfdd94f,2
+np.float64,0x3fda05aaa8b40b54,0x3fdabebdbf405e84,2
+np.float64,0x800e530ceb1ca61a,0x800e530ceb1ca61a,2
+np.float64,0x800b3866379670cd,0x800b3866379670cd,2
+np.float64,0xffedb3e7fa3b67cf,0xfff0000000000000,2
+np.float64,0xffdfa4c0713f4980,0xfff0000000000000,2
+np.float64,0x7fe4679e0728cf3b,0x7ff0000000000000,2
+np.float64,0xffe978611ef2f0c2,0xfff0000000000000,2
+np.float64,0x7fc9f4601f33e8bf,0x7ff0000000000000,2
+np.float64,0x3fd4942de6a9285c,0x3fd4ef6e089357dd,2
+np.float64,0x3faafe064435fc00,0x3fab0139cd6564dc,2
+np.float64,0x800d145a519a28b5,0x800d145a519a28b5,2
+np.float64,0xbfd82636f2304c6e,0xbfd8b9f75ddd2f02,2
+np.float64,0xbfdf2e975e3e5d2e,0xbfe037174280788c,2
+np.float64,0x7fd7051d7c2e0a3a,0x7ff0000000000000,2
+np.float64,0x8007933d452f267b,0x8007933d452f267b,2
+np.float64,0xb2043beb64088,0xb2043beb64088,2
+np.float64,0x3febfd9708f7fb2e,0x3fefb2ef090f18d2,2
+np.float64,0xffd9bc6bc83378d8,0xfff0000000000000,2
+np.float64,0xc10f9fd3821f4,0xc10f9fd3821f4,2
+np.float64,0x3fe3c83413a79068,0x3fe510fa1dd8edf7,2
+np.float64,0x3fbe26ccda3c4da0,0x3fbe38a892279975,2
+np.float64,0x3fcc1873103830e6,0x3fcc5257a6ae168d,2
+np.float64,0xe7e000e9cfc00,0xe7e000e9cfc00,2
+np.float64,0xffda73852bb4e70a,0xfff0000000000000,2
+np.float64,0xbfe831be19f0637c,0xbfea90f1b34da3e5,2
+np.float64,0xbfeb568f3076ad1e,0xbfeec97eebfde862,2
+np.float64,0x510a6ad0a214e,0x510a6ad0a214e,2
+np.float64,0x3fe6ba7e35ed74fc,0x3fe8b032a9a28c6a,2
+np.float64,0xffeb5cdcff76b9b9,0xfff0000000000000,2
+np.float64,0x4f0a23e89e145,0x4f0a23e89e145,2
+np.float64,0x446ec20288dd9,0x446ec20288dd9,2
+np.float64,0x7fe2521b02e4a435,0x7ff0000000000000,2
+np.float64,0x8001cd2969e39a54,0x8001cd2969e39a54,2
+np.float64,0x3fdfe90600bfd20c,0x3fe09fdcca10001c,2
+np.float64,0x7fd660c5762cc18a,0x7ff0000000000000,2
+np.float64,0xbfb11b23aa223648,0xbfb11e661949b377,2
+np.float64,0x800e025285fc04a5,0x800e025285fc04a5,2
+np.float64,0xffb180bb18230178,0xfff0000000000000,2
+np.float64,0xaaf590df55eb2,0xaaf590df55eb2,2
+np.float64,0xbfe8637d9df0c6fb,0xbfead1ba429462ec,2
+np.float64,0x7fd2577866a4aef0,0x7ff0000000000000,2
+np.float64,0xbfcfb2ab5a3f6558,0xbfd002ee87f272b9,2
+np.float64,0x7fdd64ae2f3ac95b,0x7ff0000000000000,2
+np.float64,0xffd1a502c9234a06,0xfff0000000000000,2
+np.float64,0x7fc4be4b60297c96,0x7ff0000000000000,2
+np.float64,0xbfb46b712a28d6e0,0xbfb470fca9919172,2
+np.float64,0xffdef913033df226,0xfff0000000000000,2
+np.float64,0x3fd94a3545b2946b,0x3fd9f40431ce9f9c,2
+np.float64,0x7fef88a0b6ff1140,0x7ff0000000000000,2
+np.float64,0xbfbcc81876399030,0xbfbcd7a0ab6cb388,2
+np.float64,0x800a4acfdd9495a0,0x800a4acfdd9495a0,2
+np.float64,0xffe270b3d5e4e167,0xfff0000000000000,2
+np.float64,0xbfd23f601e247ec0,0xbfd27eeca50a49eb,2
+np.float64,0x7fec6e796a78dcf2,0x7ff0000000000000,2
+np.float64,0x3fb85e0c9630bc19,0x3fb867791ccd6c72,2
+np.float64,0x7fe49fc424a93f87,0x7ff0000000000000,2
+np.float64,0xbfe75a99fbaeb534,0xbfe97ba37663de4c,2
+np.float64,0xffe85011b630a023,0xfff0000000000000,2
+np.float64,0xffe5962e492b2c5c,0xfff0000000000000,2
+np.float64,0x6f36ed4cde6de,0x6f36ed4cde6de,2
+np.float64,0x3feb72170af6e42e,0x3feeefbe6f1a2084,2
+np.float64,0x80014d8d60629b1c,0x80014d8d60629b1c,2
+np.float64,0xbfe0eb40d321d682,0xbfe1b7e31f252bf1,2
+np.float64,0x31fe305663fc7,0x31fe305663fc7,2
+np.float64,0x3fd2cd6381a59ac7,0x3fd312edc9868a4d,2
+np.float64,0xffcf0720793e0e40,0xfff0000000000000,2
+np.float64,0xbfeef1ef133de3de,0xbff1ffd5e1a3b648,2
+np.float64,0xbfd01c787aa038f0,0xbfd0482be3158a01,2
+np.float64,0x3fda3607c5b46c10,0x3fdaf3301e217301,2
+np.float64,0xffda9a9911b53532,0xfff0000000000000,2
+np.float64,0x3fc0b37c392166f8,0x3fc0bfa076f3c43e,2
+np.float64,0xbfe06591c760cb24,0xbfe11fad179ea12c,2
+np.float64,0x8006e369c20dc6d4,0x8006e369c20dc6d4,2
+np.float64,0x3fdf2912a8be5224,0x3fe033ff74b92f4d,2
+np.float64,0xffc0feb07821fd60,0xfff0000000000000,2
+np.float64,0xa4b938c949727,0xa4b938c949727,2
+np.float64,0x8008fe676571fccf,0x8008fe676571fccf,2
+np.float64,0xbfdda68459bb4d08,0xbfdeb8faab34fcbc,2
+np.float64,0xbfda18b419343168,0xbfdad360ca52ec7c,2
+np.float64,0x3febcbae35b7975c,0x3fef6cd51c9ebc15,2
+np.float64,0x3fbec615f63d8c30,0x3fbed912ba729926,2
+np.float64,0x7f99a831c8335063,0x7ff0000000000000,2
+np.float64,0x3fe663e8826cc7d1,0x3fe84330bd9aada8,2
+np.float64,0x70a9f9e6e1540,0x70a9f9e6e1540,2
+np.float64,0x8a13a5db14275,0x8a13a5db14275,2
+np.float64,0x7fc4330a3b286613,0x7ff0000000000000,2
+np.float64,0xbfe580c6136b018c,0xbfe728806cc7a99a,2
+np.float64,0x8000000000000001,0x8000000000000001,2
+np.float64,0xffec079d5df80f3a,0xfff0000000000000,2
+np.float64,0x8e1173c31c22f,0x8e1173c31c22f,2
+np.float64,0x3fe088456d21108b,0x3fe14712ca414103,2
+np.float64,0x3fe1b76f73636edf,0x3fe2a2b658557112,2
+np.float64,0xbfd4a1dd162943ba,0xbfd4fdd45cae8fb8,2
+np.float64,0x7fd60b46c8ac168d,0x7ff0000000000000,2
+np.float64,0xffe36cc3b166d987,0xfff0000000000000,2
+np.float64,0x3fdc2ae0cfb855c0,0x3fdd15f026773151,2
+np.float64,0xbfc41aa203283544,0xbfc42fd1b145fdd5,2
+np.float64,0xffed90c55fbb218a,0xfff0000000000000,2
+np.float64,0x3fe67e3a9aecfc75,0x3fe86440db65b4f6,2
+np.float64,0x7fd12dbeaba25b7c,0x7ff0000000000000,2
+np.float64,0xbfe1267c0de24cf8,0xbfe1fbb611bdf1e9,2
+np.float64,0x22e5619645cad,0x22e5619645cad,2
+np.float64,0x7fe327c72ea64f8d,0x7ff0000000000000,2
+np.float64,0x7fd2c3f545a587ea,0x7ff0000000000000,2
+np.float64,0x7fc7b689372f6d11,0x7ff0000000000000,2
+np.float64,0xc5e140bd8bc28,0xc5e140bd8bc28,2
+np.float64,0x3fccb3627a3966c5,0x3fccf11b44fa4102,2
+np.float64,0xbfd2cf725c259ee4,0xbfd315138d0e5dca,2
+np.float64,0x10000000000000,0x10000000000000,2
+np.float64,0xbfd3dfa8b627bf52,0xbfd431d17b235477,2
+np.float64,0xbfb82124e6304248,0xbfb82a4b6d9c2663,2
+np.float64,0x3fdcd590d9b9ab22,0x3fddd1d548806347,2
+np.float64,0x7fdee0cd1b3dc199,0x7ff0000000000000,2
+np.float64,0x8004ebfc60a9d7fa,0x8004ebfc60a9d7fa,2
+np.float64,0x3fe8eb818b71d704,0x3feb842679806108,2
+np.float64,0xffdd5e8fe63abd20,0xfff0000000000000,2
+np.float64,0xbfe3efcbd9e7df98,0xbfe54071436645ee,2
+np.float64,0x3fd5102557aa204b,0x3fd57203d31a05b8,2
+np.float64,0x3fe6318af7ec6316,0x3fe8041a177cbf96,2
+np.float64,0x3fdf3cecdabe79da,0x3fe03f2084ffbc78,2
+np.float64,0x7fe0ab6673a156cc,0x7ff0000000000000,2
+np.float64,0x800037d5c6c06fac,0x800037d5c6c06fac,2
+np.float64,0xffce58b86a3cb170,0xfff0000000000000,2
+np.float64,0xbfe3455d6ce68abb,0xbfe475034cecb2b8,2
+np.float64,0x991b663d3236d,0x991b663d3236d,2
+np.float64,0x3fda82d37c3505a7,0x3fdb46973da05c12,2
+np.float64,0x3f9b736fa036e6df,0x3f9b74471c234411,2
+np.float64,0x8001c96525e392cb,0x8001c96525e392cb,2
+np.float64,0x7ff0000000000000,0x7ff0000000000000,2
+np.float64,0xbfaf59122c3eb220,0xbfaf5e15f8b272b0,2
+np.float64,0xbf9aa7d288354fa0,0xbf9aa897d2a40cb5,2
+np.float64,0x8004a43428694869,0x8004a43428694869,2
+np.float64,0x7feead476dbd5a8e,0x7ff0000000000000,2
+np.float64,0xffca150f81342a20,0xfff0000000000000,2
+np.float64,0x80047ec3bc88fd88,0x80047ec3bc88fd88,2
+np.float64,0xbfee3e5b123c7cb6,0xbff179c8b8334278,2
+np.float64,0x3fd172359f22e46b,0x3fd1a9ba6b1420a1,2
+np.float64,0x3fe8e5e242f1cbc5,0x3feb7cbcaefc4d5c,2
+np.float64,0x8007fb059a6ff60c,0x8007fb059a6ff60c,2
+np.float64,0xe3899e71c7134,0xe3899e71c7134,2
+np.float64,0x7fe3b98326a77305,0x7ff0000000000000,2
+np.float64,0x7fec4e206cb89c40,0x7ff0000000000000,2
+np.float64,0xbfa3b012c4276020,0xbfa3b150c13b3cc5,2
+np.float64,0xffefffffffffffff,0xfff0000000000000,2
+np.float64,0xffe28a5b9aa514b6,0xfff0000000000000,2
+np.float64,0xbfd76a6cc2aed4da,0xbfd7f10f4d04e7f6,2
+np.float64,0xbc2b1c0178564,0xbc2b1c0178564,2
+np.float64,0x6d9d444adb3a9,0x6d9d444adb3a9,2
+np.float64,0xbfdcadd368395ba6,0xbfdda6037b5c429c,2
+np.float64,0x3fe11891fde23124,0x3fe1ebc1c204b14b,2
+np.float64,0x3fdd66c3eebacd88,0x3fde72526b5304c4,2
+np.float64,0xbfe79d85612f3b0b,0xbfe9d1673bd1f6d6,2
+np.float64,0x3fed60abdabac158,0x3ff0d7426b3800a2,2
+np.float64,0xbfb0ffa54021ff48,0xbfb102d81073a9f0,2
+np.float64,0xd2452af5a48a6,0xd2452af5a48a6,2
+np.float64,0xf4b835c1e971,0xf4b835c1e971,2
+np.float64,0x7e269cdafc4d4,0x7e269cdafc4d4,2
+np.float64,0x800097a21d812f45,0x800097a21d812f45,2
+np.float64,0x3fdfcc85e8bf990c,0x3fe08fcf770fd456,2
+np.float64,0xd8d53155b1aa6,0xd8d53155b1aa6,2
+np.float64,0x7fb8ed658831daca,0x7ff0000000000000,2
+np.float64,0xbfec865415b90ca8,0xbff03a4584d719f9,2
+np.float64,0xffd8cda62a319b4c,0xfff0000000000000,2
+np.float64,0x273598d84e6b4,0x273598d84e6b4,2
+np.float64,0x7fd566b5c32acd6b,0x7ff0000000000000,2
+np.float64,0xff61d9d48023b400,0xfff0000000000000,2
+np.float64,0xbfec5c3bf4f8b878,0xbff01c594243337c,2
+np.float64,0x7fd1be0561a37c0a,0x7ff0000000000000,2
+np.float64,0xffeaee3271b5dc64,0xfff0000000000000,2
+np.float64,0x800c0e1931b81c33,0x800c0e1931b81c33,2
+np.float64,0xbfad1171583a22e0,0xbfad1570e5c466d2,2
+np.float64,0x7fd783b0fe2f0761,0x7ff0000000000000,2
+np.float64,0x7fc39903e6273207,0x7ff0000000000000,2
+np.float64,0xffe00003c5600007,0xfff0000000000000,2
+np.float64,0x35a7b9c06b50,0x35a7b9c06b50,2
+np.float64,0x7fee441a22bc8833,0x7ff0000000000000,2
+np.float64,0xff6e47fbc03c9000,0xfff0000000000000,2
+np.float64,0xbfd3c3c9c8a78794,0xbfd41499b1912534,2
+np.float64,0x82c9c87f05939,0x82c9c87f05939,2
+np.float64,0xbfedeb0fe4fbd620,0xbff13c573ce9d3d0,2
+np.float64,0x2b79298656f26,0x2b79298656f26,2
+np.float64,0xbf5ee44f003dc800,0xbf5ee4503353c0ba,2
+np.float64,0xbfe1dd264e63ba4c,0xbfe2ce68116c7bf6,2
+np.float64,0x3fece10b7579c217,0x3ff07b21b11799c6,2
+np.float64,0x3fba47143a348e28,0x3fba52e601adf24c,2
+np.float64,0xffe9816e7a7302dc,0xfff0000000000000,2
+np.float64,0x8009a8047fd35009,0x8009a8047fd35009,2
+np.float64,0x800ac28e4e95851d,0x800ac28e4e95851d,2
+np.float64,0x80093facf4f27f5a,0x80093facf4f27f5a,2
+np.float64,0x3ff0000000000000,0x3ff2cd9fc44eb982,2
+np.float64,0x3fe76a9857eed530,0x3fe99018a5895a4f,2
+np.float64,0xbfd13c59a3a278b4,0xbfd171e133df0b16,2
+np.float64,0x7feb43bc83368778,0x7ff0000000000000,2
+np.float64,0xbfe2970c5fa52e18,0xbfe3a74a434c6efe,2
+np.float64,0xffd091c380212388,0xfff0000000000000,2
+np.float64,0x3febb3b9d2f76774,0x3fef4b4af2bd8580,2
+np.float64,0x7fec66787ef8ccf0,0x7ff0000000000000,2
+np.float64,0xbf935e185826bc40,0xbf935e640557a354,2
+np.float64,0x979df1552f3be,0x979df1552f3be,2
+np.float64,0x7fc096ee73212ddc,0x7ff0000000000000,2
+np.float64,0xbfe9de88faf3bd12,0xbfecc7d1ae691d1b,2
+np.float64,0x7fdc733f06b8e67d,0x7ff0000000000000,2
+np.float64,0xffd71be1a0ae37c4,0xfff0000000000000,2
+np.float64,0xb50dabd36a1b6,0xb50dabd36a1b6,2
+np.float64,0x7fce3d94d63c7b29,0x7ff0000000000000,2
+np.float64,0x7fbaf95e4435f2bc,0x7ff0000000000000,2
+np.float64,0x81a32a6f03466,0x81a32a6f03466,2
+np.float64,0xa99b5b4d5336c,0xa99b5b4d5336c,2
+np.float64,0x7f97c1eeb82f83dc,0x7ff0000000000000,2
+np.float64,0x3fe761636d6ec2c6,0x3fe98451160d2ffb,2
+np.float64,0xbfe3224ef5e6449e,0xbfe44b73eeadac52,2
+np.float64,0x7fde6feb0dbcdfd5,0x7ff0000000000000,2
+np.float64,0xbfee87f9ca7d0ff4,0xbff1b079e9d7f706,2
+np.float64,0x3fe46f4c9828de99,0x3fe5da2ab9609ea5,2
+np.float64,0xffb92fe882325fd0,0xfff0000000000000,2
+np.float64,0x80054bc63cea978d,0x80054bc63cea978d,2
+np.float64,0x3d988bea7b312,0x3d988bea7b312,2
+np.float64,0x3fe6468e1d6c8d1c,0x3fe81e64d37d39a8,2
+np.float64,0x3fd68eefc22d1de0,0x3fd7074264faeead,2
+np.float64,0xffb218a074243140,0xfff0000000000000,2
+np.float64,0x3fdbcb3b6cb79678,0x3fdcad011de40b7d,2
+np.float64,0x7fe3c161772782c2,0x7ff0000000000000,2
+np.float64,0x25575c904aaec,0x25575c904aaec,2
+np.float64,0x800fa43a8f5f4875,0x800fa43a8f5f4875,2
+np.float64,0x3fe41fc9e1e83f94,0x3fe57a25dd1a37f1,2
+np.float64,0x3fd895f4a7b12be9,0x3fd931e7b721a08a,2
+np.float64,0xce31469f9c629,0xce31469f9c629,2
+np.float64,0xffea0f55ca341eab,0xfff0000000000000,2
+np.float64,0xffe831c9ba306393,0xfff0000000000000,2
+np.float64,0x7fe2056f03a40add,0x7ff0000000000000,2
+np.float64,0x7fd6b075e02d60eb,0x7ff0000000000000,2
+np.float64,0x3fdfbef4273f7de8,0x3fe0882c1f59efc0,2
+np.float64,0x8005b9e094ab73c2,0x8005b9e094ab73c2,2
+np.float64,0x3fea881ac6351036,0x3fedad7a319b887c,2
+np.float64,0xbfe2c61c7ee58c39,0xbfe3de9a99d8a9c6,2
+np.float64,0x30b0d3786161b,0x30b0d3786161b,2
+np.float64,0x3fa51d56a02a3aad,0x3fa51edee2d2ecef,2
+np.float64,0x79745732f2e8c,0x79745732f2e8c,2
+np.float64,0x800d55b4907aab69,0x800d55b4907aab69,2
+np.float64,0xbfbe8fcf0a3d1fa0,0xbfbea267fbb5bfdf,2
+np.float64,0xbfd04e2756a09c4e,0xbfd07b74d079f9a2,2
+np.float64,0x3fc65170552ca2e1,0x3fc66e6eb00c82ed,2
+np.float64,0xbfb0674b8020ce98,0xbfb06a2b4771b64c,2
+np.float64,0x2059975840b34,0x2059975840b34,2
+np.float64,0x33d1385467a28,0x33d1385467a28,2
+np.float64,0x3fea41b74ff4836f,0x3fed4dc1a09e53cc,2
+np.float64,0xbfe8e08c9d71c119,0xbfeb75b4c59a6bec,2
+np.float64,0x7fdbbf14d6377e29,0x7ff0000000000000,2
+np.float64,0x3fcd8b71513b16e0,0x3fcdcec80174f9ad,2
+np.float64,0x5c50bc94b8a18,0x5c50bc94b8a18,2
+np.float64,0x969a18f52d343,0x969a18f52d343,2
+np.float64,0x3fd7ae44462f5c89,0x3fd8398bc34e395c,2
+np.float64,0xffdd0f8617ba1f0c,0xfff0000000000000,2
+np.float64,0xfff0000000000000,0xfff0000000000000,2
+np.float64,0xbfe2f9badb65f376,0xbfe41b771320ece8,2
+np.float64,0x3fd140bc7fa29,0x3fd140bc7fa29,2
+np.float64,0xbfe14523b5628a48,0xbfe21ee850972043,2
+np.float64,0x3feedd0336bdba06,0x3ff1f01afc1f3a06,2
+np.float64,0x800de423ad7bc848,0x800de423ad7bc848,2
+np.float64,0x4cef857c99df1,0x4cef857c99df1,2
+np.float64,0xbfea55e0e374abc2,0xbfed691e41d648dd,2
+np.float64,0x3fe70d7a18ae1af4,0x3fe91955a34d8094,2
+np.float64,0xbfc62fc3032c5f88,0xbfc64c3ec25decb8,2
+np.float64,0x3fc915abb5322b58,0x3fc93edac5cc73fe,2
+np.float64,0x69aaff66d3561,0x69aaff66d3561,2
+np.float64,0x5c6a90f2b8d53,0x5c6a90f2b8d53,2
+np.float64,0x3fefe30dc1bfc61c,0x3ff2b752257bdacd,2
+np.float64,0x3fef15db15fe2bb6,0x3ff21aea05601396,2
+np.float64,0xbfe353e5ac66a7cc,0xbfe48644e6553d1a,2
+np.float64,0x3fe6d30cffada61a,0x3fe8cf3e4c61ddac,2
+np.float64,0x7fb7857eb62f0afc,0x7ff0000000000000,2
+np.float64,0xbfdd9b53d23b36a8,0xbfdeac91a7af1340,2
+np.float64,0x3fd1456357228ac7,0x3fd17b3f7d39b27a,2
+np.float64,0x3fb57d10ae2afa21,0x3fb5838702b806f4,2
+np.float64,0x800c59c96c98b393,0x800c59c96c98b393,2
+np.float64,0x7fc1f2413823e481,0x7ff0000000000000,2
+np.float64,0xbfa3983624273070,0xbfa3996fa26c419a,2
+np.float64,0x7fb28874ae2510e8,0x7ff0000000000000,2
+np.float64,0x3fe826d02a304da0,0x3fea82bec50bc0b6,2
+np.float64,0x8008d6f0d3d1ade2,0x8008d6f0d3d1ade2,2
+np.float64,0xffe7c970ca2f92e1,0xfff0000000000000,2
+np.float64,0x7fcf42bcaa3e8578,0x7ff0000000000000,2
+np.float64,0x7fda1ab517343569,0x7ff0000000000000,2
+np.float64,0xbfe7926a65ef24d5,0xbfe9c323dd890d5b,2
+np.float64,0xbfcaf6282d35ec50,0xbfcb294f36a0a33d,2
+np.float64,0x800ca49df8d9493c,0x800ca49df8d9493c,2
+np.float64,0xffea18d26af431a4,0xfff0000000000000,2
+np.float64,0x3fb72f276e2e5e50,0x3fb7374539fd1221,2
+np.float64,0xffa6b613842d6c20,0xfff0000000000000,2
+np.float64,0xbfeb3c7263f678e5,0xbfeea54cdb60b54c,2
+np.float64,0x3fc976d2ba32eda5,0x3fc9a1e83a058de4,2
+np.float64,0xbfe4acd4b0e959aa,0xbfe624d5d4f9b9a6,2
+np.float64,0x7fca410a0f348213,0x7ff0000000000000,2
+np.float64,0xbfde368f77bc6d1e,0xbfdf5910c8c8bcb0,2
+np.float64,0xbfed7412937ae825,0xbff0e55afc428453,2
+np.float64,0xffef6b7b607ed6f6,0xfff0000000000000,2
+np.float64,0xbfb936f17e326de0,0xbfb941629a53c694,2
+np.float64,0x800dbb0c469b7619,0x800dbb0c469b7619,2
+np.float64,0x800f68b0581ed161,0x800f68b0581ed161,2
+np.float64,0x3fe25b2aad64b656,0x3fe361266fa9c5eb,2
+np.float64,0xbfb87e445a30fc88,0xbfb887d676910c3f,2
+np.float64,0x6e6ba9b6dcd76,0x6e6ba9b6dcd76,2
+np.float64,0x3fad27ce583a4f9d,0x3fad2bd72782ffdb,2
+np.float64,0xbfec0bc5d638178c,0xbfefc6e8c8f9095f,2
+np.float64,0x7fcba4a296374944,0x7ff0000000000000,2
+np.float64,0x8004ca237cc99448,0x8004ca237cc99448,2
+np.float64,0xffe85b8c3270b718,0xfff0000000000000,2
+np.float64,0x7fe7ee3eddafdc7d,0x7ff0000000000000,2
+np.float64,0xffd275967ca4eb2c,0xfff0000000000000,2
+np.float64,0xbfa95bc3a032b780,0xbfa95e6b288ecf43,2
+np.float64,0x3fc9e3214b33c643,0x3fca10667e7e7ff4,2
+np.float64,0x8001b89c5d837139,0x8001b89c5d837139,2
+np.float64,0xbf8807dfc0300fc0,0xbf880803e3badfbd,2
+np.float64,0x800aca94b895952a,0x800aca94b895952a,2
+np.float64,0x7fd79534a02f2a68,0x7ff0000000000000,2
+np.float64,0x3fe1b81179e37023,0x3fe2a371d8cc26f0,2
+np.float64,0x800699539d6d32a8,0x800699539d6d32a8,2
+np.float64,0xffe51dfbb3aa3bf7,0xfff0000000000000,2
+np.float64,0xbfdfb775abbf6eec,0xbfe083f48be2f98f,2
+np.float64,0x3fe87979d7b0f2f4,0x3feaee701d959079,2
+np.float64,0x3fd8e4e6a731c9cd,0x3fd986d29f25f982,2
+np.float64,0x3fe3dadaaf67b5b6,0x3fe527520fb02920,2
+np.float64,0x8003c2262bc7844d,0x8003c2262bc7844d,2
+np.float64,0x800c930add392616,0x800c930add392616,2
+np.float64,0xffb7a152a22f42a8,0xfff0000000000000,2
+np.float64,0x80028fe03dc51fc1,0x80028fe03dc51fc1,2
+np.float64,0xffe32ae60c6655cc,0xfff0000000000000,2
+np.float64,0x3fea3527e4746a50,0x3fed3cbbf47f18eb,2
+np.float64,0x800a53059e14a60c,0x800a53059e14a60c,2
+np.float64,0xbfd79e3b202f3c76,0xbfd828672381207b,2
+np.float64,0xffeed7e2eb7dafc5,0xfff0000000000000,2
+np.float64,0x3fec51ed6778a3db,0x3ff01509e34df61d,2
+np.float64,0xbfd84bc577b0978a,0xbfd8e23ec55e42e8,2
+np.float64,0x2483aff849077,0x2483aff849077,2
+np.float64,0x6f57883adeaf2,0x6f57883adeaf2,2
+np.float64,0xffd3fd74d927faea,0xfff0000000000000,2
+np.float64,0x7fca49ec773493d8,0x7ff0000000000000,2
+np.float64,0x7fd08fe2e8211fc5,0x7ff0000000000000,2
+np.float64,0x800852086db0a411,0x800852086db0a411,2
+np.float64,0x3fe5b1f2c9eb63e6,0x3fe7654f511bafc6,2
+np.float64,0xbfe01e2a58e03c54,0xbfe0cedb68f021e6,2
+np.float64,0x800988421d331085,0x800988421d331085,2
+np.float64,0xffd5038b18aa0716,0xfff0000000000000,2
+np.float64,0x8002c9264c85924d,0x8002c9264c85924d,2
+np.float64,0x3fd21ca302243946,0x3fd25ac653a71aab,2
+np.float64,0xbfea60d6e6f4c1ae,0xbfed78031d9dfa2b,2
+np.float64,0xffef97b6263f2f6b,0xfff0000000000000,2
+np.float64,0xbfd524732faa48e6,0xbfd5876ecc415dcc,2
+np.float64,0x660387e8cc072,0x660387e8cc072,2
+np.float64,0x7fcfc108a33f8210,0x7ff0000000000000,2
+np.float64,0x7febe5b0f877cb61,0x7ff0000000000000,2
+np.float64,0xbfa55fdfac2abfc0,0xbfa56176991851a8,2
+np.float64,0x25250f4c4a4a3,0x25250f4c4a4a3,2
+np.float64,0xffe2f6a2f2a5ed46,0xfff0000000000000,2
+np.float64,0x7fa754fcc02ea9f9,0x7ff0000000000000,2
+np.float64,0x3febd19dea37a33c,0x3fef75279f75d3b8,2
+np.float64,0xc5ed55218bdab,0xc5ed55218bdab,2
+np.float64,0x3fe72ff6b3ee5fed,0x3fe945388b979882,2
+np.float64,0xbfe16b854e22d70a,0xbfe24b10fc0dff14,2
+np.float64,0xffb22cbe10245980,0xfff0000000000000,2
+np.float64,0xa54246b54a849,0xa54246b54a849,2
+np.float64,0x3fe7f4cda76fe99c,0x3fea41edc74888b6,2
+np.float64,0x1,0x1,2
+np.float64,0x800d84acce9b095a,0x800d84acce9b095a,2
+np.float64,0xb0eef04761dde,0xb0eef04761dde,2
+np.float64,0x7ff4000000000000,0x7ffc000000000000,2
+np.float64,0xffecaf1dbb795e3b,0xfff0000000000000,2
+np.float64,0x90dbab8d21b76,0x90dbab8d21b76,2
+np.float64,0x3fe79584a9ef2b09,0x3fe9c71fa9e40eb5,2
diff --git a/numpy/core/tests/data/umath-validation-set-tan.csv b/numpy/core/tests/data/umath-validation-set-tan.csv
new file mode 100644
index 000000000..083cdb2fb
--- /dev/null
+++ b/numpy/core/tests/data/umath-validation-set-tan.csv
@@ -0,0 +1,1429 @@
+dtype,input,output,ulperrortol
+np.float32,0xfd97ece0,0xc11186e9,4
+np.float32,0x8013bb34,0x8013bb34,4
+np.float32,0x316389,0x316389,4
+np.float32,0x7f7fffff,0xbf1c9eca,4
+np.float32,0x3f7674bb,0x3fb7e450,4
+np.float32,0x80800000,0x80800000,4
+np.float32,0x7f5995e8,0xbf94106c,4
+np.float32,0x74527,0x74527,4
+np.float32,0x7f08caea,0xbeceddb6,4
+np.float32,0x2d49b2,0x2d49b2,4
+np.float32,0x3f74e5e4,0x3fb58695,4
+np.float32,0x3f3fcd51,0x3f6e1e81,4
+np.float32,0xbf4f3608,0xbf864d3d,4
+np.float32,0xbed974a0,0xbee78c70,4
+np.float32,0xff5f483c,0x3ecf3cb2,4
+np.float32,0x7f4532f4,0xc0b96f7b,4
+np.float32,0x3f0a4f7c,0x3f198cc0,4
+np.float32,0x210193,0x210193,4
+np.float32,0xfeebad7a,0xbf92eba8,4
+np.float32,0xfed29f74,0xc134cab6,4
+np.float32,0x803433a0,0x803433a0,4
+np.float32,0x64eb46,0x64eb46,4
+np.float32,0xbf54ef22,0xbf8c757b,4
+np.float32,0x3f3d5fdd,0x3f69a17b,4
+np.float32,0x80000001,0x80000001,4
+np.float32,0x800a837a,0x800a837a,4
+np.float32,0x6ff0be,0x6ff0be,4
+np.float32,0xfe8f1186,0x3f518820,4
+np.float32,0x804963e5,0x804963e5,4
+np.float32,0xfebaa59a,0x3fa1dbb0,4
+np.float32,0x637970,0x637970,4
+np.float32,0x3e722a6b,0x3e76c89a,4
+np.float32,0xff2b0478,0xbddccb5f,4
+np.float32,0xbf7bd85b,0xbfc06821,4
+np.float32,0x3ec33600,0x3ecd4126,4
+np.float32,0x3e0a43b9,0x3e0b1c69,4
+np.float32,0x7f7511b6,0xbe427083,4
+np.float32,0x3f28c114,0x3f465a73,4
+np.float32,0x3f179e1c,0x3f2c3e7c,4
+np.float32,0x7b2963,0x7b2963,4
+np.float32,0x3f423d06,0x3f72b442,4
+np.float32,0x3f5a24c6,0x3f925508,4
+np.float32,0xff18c834,0xbf79b5c8,4
+np.float32,0x3f401ece,0x3f6eb6ac,4
+np.float32,0x7b8a3013,0xbffab968,4
+np.float32,0x80091ff0,0x80091ff0,4
+np.float32,0x3f389c51,0x3f610b47,4
+np.float32,0x5ea174,0x5ea174,4
+np.float32,0x807a9eb2,0x807a9eb2,4
+np.float32,0x806ce61e,0x806ce61e,4
+np.float32,0xbe956acc,0xbe99cefc,4
+np.float32,0x7e60e247,0xbf5e64a5,4
+np.float32,0x7f398e24,0x404d12ed,4
+np.float32,0x3d9049f8,0x3d908735,4
+np.float32,0x7db17ffc,0xbf5b3d87,4
+np.float32,0xff453f78,0xc0239c9f,4
+np.float32,0x3f024aac,0x3f0ed802,4
+np.float32,0xbe781c30,0xbe7d1508,4
+np.float32,0x3f77962a,0x3fb9a28e,4
+np.float32,0xff7fffff,0x3f1c9eca,4
+np.float32,0x3f7152e3,0x3fb03f9d,4
+np.float32,0xff7cb167,0x3f9ce831,4
+np.float32,0x3e763e30,0x3e7b1a10,4
+np.float32,0xbf126527,0xbf24c253,4
+np.float32,0x803f6660,0x803f6660,4
+np.float32,0xbf79de38,0xbfbd38b1,4
+np.float32,0x8046c2f0,0x8046c2f0,4
+np.float32,0x6dc74e,0x6dc74e,4
+np.float32,0xbec9c45e,0xbed4e768,4
+np.float32,0x3f0eedb6,0x3f1fe610,4
+np.float32,0x7e031999,0xbcc13026,4
+np.float32,0x7efc2fd7,0x41e4b284,4
+np.float32,0xbeab7454,0xbeb22a1b,4
+np.float32,0x805ee67b,0x805ee67b,4
+np.float32,0x7f76e58e,0xc2436659,4
+np.float32,0xbe62b024,0xbe667718,4
+np.float32,0x3eea0808,0x3efbd182,4
+np.float32,0xbf7fd00c,0xbfc70719,4
+np.float32,0x7f27b640,0xbf0d97e0,4
+np.float32,0x3f1b58a4,0x3f31b6f4,4
+np.float32,0x252a9f,0x252a9f,4
+np.float32,0x7f65f95a,0xbead5de3,4
+np.float32,0xfc6ea780,0x42d15801,4
+np.float32,0x7eac4c52,0xc0682424,4
+np.float32,0xbe8a3f5a,0xbe8db54d,4
+np.float32,0xbf1644e2,0xbf2a4abd,4
+np.float32,0x3fc96a,0x3fc96a,4
+np.float32,0x7f38c0e4,0x3cc04af8,4
+np.float32,0x3f623d75,0x3f9c065d,4
+np.float32,0x3ee6a51a,0x3ef7a058,4
+np.float32,0x3dd11020,0x3dd1cacf,4
+np.float32,0xb6918,0xb6918,4
+np.float32,0xfdd7a540,0x3f22f081,4
+np.float32,0x80798563,0x80798563,4
+np.float32,0x3e9a8b7a,0x3e9f6a7e,4
+np.float32,0xbea515d4,0xbeab0df5,4
+np.float32,0xbea9b9f4,0xbeb03abe,4
+np.float32,0xbf11a5fa,0xbf23b478,4
+np.float32,0xfd6cadf0,0xbfa2a878,4
+np.float32,0xbf6edd07,0xbfacbb78,4
+np.float32,0xff5c5328,0x3e2d1552,4
+np.float32,0xbea2f788,0xbea8b3f5,4
+np.float32,0x802efaeb,0x802efaeb,4
+np.float32,0xff1c85e5,0x41f8560e,4
+np.float32,0x3f53b123,0x3f8b18e1,4
+np.float32,0xff798c4a,0x4092e66f,4
+np.float32,0x7f2e6fe7,0xbdcbd58f,4
+np.float32,0xfe8a8196,0x3fd7fc56,4
+np.float32,0x5e7ad4,0x5e7ad4,4
+np.float32,0xbf23a02d,0xbf3e4533,4
+np.float32,0x3f31c55c,0x3f5531bf,4
+np.float32,0x80331be3,0x80331be3,4
+np.float32,0x8056960a,0x8056960a,4
+np.float32,0xff1c06ae,0xbfd26992,4
+np.float32,0xbe0cc4b0,0xbe0da96c,4
+np.float32,0x7e925ad5,0xbf8dba54,4
+np.float32,0x2c8cec,0x2c8cec,4
+np.float32,0x8011951e,0x8011951e,4
+np.float32,0x3f2caf84,0x3f4cb89f,4
+np.float32,0xbd32c220,0xbd32df33,4
+np.float32,0xbec358d6,0xbecd6996,4
+np.float32,0x3f6e4930,0x3fabeb92,4
+np.float32,0xbf6a3afd,0xbfa65a3a,4
+np.float32,0x80067764,0x80067764,4
+np.float32,0x3d8df1,0x3d8df1,4
+np.float32,0x7ee51cf2,0x409e4061,4
+np.float32,0x435f5d,0x435f5d,4
+np.float32,0xbf5b17f7,0xbf936ebe,4
+np.float32,0x3ecaacb5,0x3ed5f81f,4
+np.float32,0x807b0aa5,0x807b0aa5,4
+np.float32,0x52b40b,0x52b40b,4
+np.float32,0x146a97,0x146a97,4
+np.float32,0x7f42b952,0xbfdcb413,4
+np.float32,0xbf1a1af2,0xbf2fe1bb,4
+np.float32,0x3f312034,0x3f541aa2,4
+np.float32,0x3f281d60,0x3f4554f9,4
+np.float32,0x50e451,0x50e451,4
+np.float32,0xbe45838c,0xbe480016,4
+np.float32,0xff7d0aeb,0x3eb0746e,4
+np.float32,0x7f32a489,0xbf96af6d,4
+np.float32,0xbf1b4e27,0xbf31a769,4
+np.float32,0x3f242936,0x3f3f1a44,4
+np.float32,0xbf7482ff,0xbfb4f201,4
+np.float32,0x4bda38,0x4bda38,4
+np.float32,0xbf022208,0xbf0ea2bb,4
+np.float32,0x7d08ca95,0xbe904602,4
+np.float32,0x7ed2f356,0xc02b55ad,4
+np.float32,0xbf131204,0xbf25b734,4
+np.float32,0xff3464b4,0x3fb23706,4
+np.float32,0x5a97cf,0x5a97cf,4
+np.float32,0xbe52db70,0xbe55e388,4
+np.float32,0x3f52934f,0x3f89e2aa,4
+np.float32,0xfeea866a,0x40a2b33f,4
+np.float32,0x80333925,0x80333925,4
+np.float32,0xfef5d13e,0xc00139ec,4
+np.float32,0x3f4750ab,0x3f7c87ad,4
+np.float32,0x3e41bfdd,0x3e44185a,4
+np.float32,0xbf5b0572,0xbf935935,4
+np.float32,0xbe93c9da,0xbe9808d8,4
+np.float32,0x7f501f33,0xc0f9973c,4
+np.float32,0x800af035,0x800af035,4
+np.float32,0x3f29faf8,0x3f4852a8,4
+np.float32,0xbe1e4c20,0xbe1f920c,4
+np.float32,0xbf7e8616,0xbfc4d79d,4
+np.float32,0x43ffbf,0x43ffbf,4
+np.float32,0x7f28e8a9,0xbfa1ac24,4
+np.float32,0xbf1f9f92,0xbf3820bc,4
+np.float32,0x3f07e004,0x3f1641c4,4
+np.float32,0x3ef7ea7f,0x3f06a64a,4
+np.float32,0x7e013101,0x3f6080e6,4
+np.float32,0x7f122a4f,0xbf0a796f,4
+np.float32,0xfe096960,0x3ed7273a,4
+np.float32,0x3f06abf1,0x3f14a4b2,4
+np.float32,0x3e50ded3,0x3e53d0f1,4
+np.float32,0x7f50b346,0x3eabb536,4
+np.float32,0xff5adb0f,0xbd441972,4
+np.float32,0xbecefe46,0xbedb0f66,4
+np.float32,0x7da70bd4,0xbec66273,4
+np.float32,0x169811,0x169811,4
+np.float32,0xbee4dfee,0xbef5721a,4
+np.float32,0x3efbeae3,0x3f0936e6,4
+np.float32,0x8031bd61,0x8031bd61,4
+np.float32,0x8048e443,0x8048e443,4
+np.float32,0xff209aa6,0xbeb364cb,4
+np.float32,0xff477499,0x3c1b0041,4
+np.float32,0x803fe929,0x803fe929,4
+np.float32,0x3f70158b,0x3fae7725,4
+np.float32,0x7f795723,0x3e8e850a,4
+np.float32,0x3cba99,0x3cba99,4
+np.float32,0x80588d2a,0x80588d2a,4
+np.float32,0x805d1f05,0x805d1f05,4
+np.float32,0xff4ac09a,0xbefe614d,4
+np.float32,0x804af084,0x804af084,4
+np.float32,0x7c64ae63,0xc1a8b563,4
+np.float32,0x8078d793,0x8078d793,4
+np.float32,0x7f3e2436,0xbf8bf9d3,4
+np.float32,0x7ccec1,0x7ccec1,4
+np.float32,0xbf6462c7,0xbf9eb830,4
+np.float32,0x3f1002ca,0x3f216843,4
+np.float32,0xfe878ca6,0x409e73a5,4
+np.float32,0x3bd841d9,0x3bd842a7,4
+np.float32,0x7d406f41,0xbd9dcfa3,4
+np.float32,0x7c6d6,0x7c6d6,4
+np.float32,0x3f4ef360,0x3f86074b,4
+np.float32,0x805f534a,0x805f534a,4
+np.float32,0x1,0x1,4
+np.float32,0x3f739ee2,0x3fb39db2,4
+np.float32,0x3d0c2352,0x3d0c3153,4
+np.float32,0xfe8a4f2c,0x3edd8add,4
+np.float32,0x3e52eaa0,0x3e55f362,4
+np.float32,0x7bde9758,0xbf5ba5cf,4
+np.float32,0xff422654,0xbf41e487,4
+np.float32,0x385e5b,0x385e5b,4
+np.float32,0x5751dd,0x5751dd,4
+np.float32,0xff6c671c,0xc03e2d6d,4
+np.float32,0x1458be,0x1458be,4
+np.float32,0x80153d4d,0x80153d4d,4
+np.float32,0x7efd2adb,0x3e25458f,4
+np.float32,0xbe161880,0xbe172e12,4
+np.float32,0x7ecea1aa,0x40a66d79,4
+np.float32,0xbf5b02a2,0xbf9355f0,4
+np.float32,0x15d9ab,0x15d9ab,4
+np.float32,0x2dc7c7,0x2dc7c7,4
+np.float32,0xfebbf81a,0x4193f6e6,4
+np.float32,0xfe8e3594,0xc00a6695,4
+np.float32,0x185aa8,0x185aa8,4
+np.float32,0x3daea156,0x3daf0e00,4
+np.float32,0x3e071688,0x3e07e08e,4
+np.float32,0x802db9e6,0x802db9e6,4
+np.float32,0x7f7be2c4,0x3f1363dd,4
+np.float32,0x7eba3f5e,0xc13eb497,4
+np.float32,0x3de04a00,0x3de130a9,4
+np.float32,0xbf1022bc,0xbf2194eb,4
+np.float32,0xbf5b547e,0xbf93b53b,4
+np.float32,0x3e867bd6,0x3e89aa10,4
+np.float32,0xbea5eb5c,0xbeabfb73,4
+np.float32,0x7f1efae9,0x3ffca038,4
+np.float32,0xff5d0344,0xbe55dbbb,4
+np.float32,0x805167e7,0x805167e7,4
+np.float32,0xbdb3a020,0xbdb41667,4
+np.float32,0xbedea6b4,0xbeedd5fd,4
+np.float32,0x8053b45c,0x8053b45c,4
+np.float32,0x7ed370e9,0x3d90eba5,4
+np.float32,0xbefcd7da,0xbf09cf91,4
+np.float32,0x78b9ac,0x78b9ac,4
+np.float32,0xbf2f6dc0,0xbf5141ef,4
+np.float32,0x802d3a7b,0x802d3a7b,4
+np.float32,0xfd45d120,0x3fec31cc,4
+np.float32,0xbf7e7020,0xbfc4b2af,4
+np.float32,0xf04da,0xf04da,4
+np.float32,0xbe9819d4,0xbe9cbd35,4
+np.float32,0x8075ab35,0x8075ab35,4
+np.float32,0xbf052fdc,0xbf12aa2c,4
+np.float32,0x3f1530d0,0x3f28bd9f,4
+np.float32,0x80791881,0x80791881,4
+np.float32,0x67f309,0x67f309,4
+np.float32,0x3f12f16a,0x3f2588f5,4
+np.float32,0x3ecdac47,0x3ed97ff8,4
+np.float32,0xbf297fb7,0xbf478c39,4
+np.float32,0x8069fa80,0x8069fa80,4
+np.float32,0x807f940e,0x807f940e,4
+np.float32,0xbf648dc8,0xbf9eeecb,4
+np.float32,0x3de873b0,0x3de9748d,4
+np.float32,0x3f1aa645,0x3f30af1f,4
+np.float32,0xff227a62,0x3d8283cc,4
+np.float32,0xbf37187d,0xbf5e5f4c,4
+np.float32,0x803b1b1f,0x803b1b1f,4
+np.float32,0x3f58142a,0x3f8ff8da,4
+np.float32,0x8004339e,0x8004339e,4
+np.float32,0xbf0f5654,0xbf2077a4,4
+np.float32,0x3f17e509,0x3f2ca598,4
+np.float32,0x3f800000,0x3fc75923,4
+np.float32,0xfdf79980,0x42f13047,4
+np.float32,0x7f111381,0x3f13c4c9,4
+np.float32,0xbea40c70,0xbea9e724,4
+np.float32,0x110520,0x110520,4
+np.float32,0x60490d,0x60490d,4
+np.float32,0x3f6703ec,0x3fa21951,4
+np.float32,0xbf098256,0xbf187652,4
+np.float32,0x658951,0x658951,4
+np.float32,0x3f53bf16,0x3f8b2818,4
+np.float32,0xff451811,0xc0026068,4
+np.float32,0x80777ee0,0x80777ee0,4
+np.float32,0x3e4fcc19,0x3e52b286,4
+np.float32,0x7f387ee0,0x3ce93eb6,4
+np.float32,0xff51181f,0xbfca3ee4,4
+np.float32,0xbf5655ae,0xbf8e0304,4
+np.float32,0xff2f1dcd,0x40025471,4
+np.float32,0x7f6e58e5,0xbe9930d5,4
+np.float32,0x7adf11,0x7adf11,4
+np.float32,0xbe9a2bc2,0xbe9f0185,4
+np.float32,0x8065d3a0,0x8065d3a0,4
+np.float32,0x3ed6e826,0x3ee47c45,4
+np.float32,0x80598ea0,0x80598ea0,4
+np.float32,0x7f10b90a,0x40437bd0,4
+np.float32,0x27b447,0x27b447,4
+np.float32,0x7ecd861c,0x3fce250f,4
+np.float32,0x0,0x0,4
+np.float32,0xbeba82d6,0xbec3394c,4
+np.float32,0xbf4958b0,0xbf8048ea,4
+np.float32,0x7c643e,0x7c643e,4
+np.float32,0x580770,0x580770,4
+np.float32,0x805bf54a,0x805bf54a,4
+np.float32,0x7f1f3cee,0xbe1a54d6,4
+np.float32,0xfefefdea,0x3fa84576,4
+np.float32,0x7f007b7a,0x3e8a6d25,4
+np.float32,0xbf177959,0xbf2c0919,4
+np.float32,0xbf30fda0,0xbf53e058,4
+np.float32,0x3f0576be,0x3f130861,4
+np.float32,0x3f49380e,0x3f80283a,4
+np.float32,0xebc56,0xebc56,4
+np.float32,0x654e3b,0x654e3b,4
+np.float32,0x14a4d8,0x14a4d8,4
+np.float32,0xff69b3cb,0xbf822a88,4
+np.float32,0xbe9b6c1c,0xbea06109,4
+np.float32,0xbefddd7e,0xbf0a787b,4
+np.float32,0x4c4ebb,0x4c4ebb,4
+np.float32,0x7d0a74,0x7d0a74,4
+np.float32,0xbebb5f80,0xbec43635,4
+np.float32,0x7ee79723,0xc1c7f3f3,4
+np.float32,0x7f2be4c7,0xbfa6c693,4
+np.float32,0x805bc7d5,0x805bc7d5,4
+np.float32,0x8042f12c,0x8042f12c,4
+np.float32,0x3ef91be8,0x3f07697b,4
+np.float32,0x3cf37ac0,0x3cf38d1c,4
+np.float32,0x800000,0x800000,4
+np.float32,0xbe1ebf4c,0xbe200806,4
+np.float32,0x7f380862,0xbeb512e8,4
+np.float32,0xbe320064,0xbe33d0fc,4
+np.float32,0xff300b0c,0xbfadb805,4
+np.float32,0x308a06,0x308a06,4
+np.float32,0xbf084f6e,0xbf16d7b6,4
+np.float32,0xff47cab6,0x3f892b65,4
+np.float32,0xbed99f4a,0xbee7bfd5,4
+np.float32,0xff7d74c0,0x3ee88c9a,4
+np.float32,0x3c3d23,0x3c3d23,4
+np.float32,0x8074bde8,0x8074bde8,4
+np.float32,0x80042164,0x80042164,4
+np.float32,0x3e97c92a,0x3e9c6500,4
+np.float32,0x3b80e0,0x3b80e0,4
+np.float32,0xbf16646a,0xbf2a783d,4
+np.float32,0x7f3b4cb1,0xc01339be,4
+np.float32,0xbf31f36e,0xbf557fd0,4
+np.float32,0x7f540618,0xbe5f6fc1,4
+np.float32,0x7eee47d0,0x40a27e94,4
+np.float32,0x7f12f389,0xbebed654,4
+np.float32,0x56cff5,0x56cff5,4
+np.float32,0x8056032b,0x8056032b,4
+np.float32,0x3ed34e40,0x3ee02e38,4
+np.float32,0x7d51a908,0xbf19a90e,4
+np.float32,0x80000000,0x80000000,4
+np.float32,0xfdf73fd0,0xbf0f8cad,4
+np.float32,0x7ee4fe6d,0xbf1ea7e4,4
+np.float32,0x1f15ba,0x1f15ba,4
+np.float32,0xd18c3,0xd18c3,4
+np.float32,0x80797705,0x80797705,4
+np.float32,0x7ef07091,0x3f2f3b9a,4
+np.float32,0x7f552f41,0x3faf608c,4
+np.float32,0x3f779977,0x3fb9a7ad,4
+np.float32,0xfe1a7a50,0xbdadc4d1,4
+np.float32,0xbf449cf0,0xbf7740db,4
+np.float32,0xbe44e620,0xbe475cad,4
+np.float32,0x3f63a098,0x3f9dc2b5,4
+np.float32,0xfed40a12,0x4164533a,4
+np.float32,0x7a2bbb,0x7a2bbb,4
+np.float32,0xff7f7b9e,0xbeee8740,4
+np.float32,0x7ee27f8b,0x4233f53b,4
+np.float32,0xbf044c06,0xbf117c28,4
+np.float32,0xbeffde54,0xbf0bc49f,4
+np.float32,0xfeaef2e8,0x3ff258fe,4
+np.float32,0x527451,0x527451,4
+np.float32,0xbcef8d00,0xbcef9e7c,4
+np.float32,0xbf0e20c0,0xbf1ec9b2,4
+np.float32,0x8024afda,0x8024afda,4
+np.float32,0x7ef6cb3e,0x422cad0b,4
+np.float32,0x3c120,0x3c120,4
+np.float32,0xbf125c8f,0xbf24b62c,4
+np.float32,0x7e770a93,0x402c9d86,4
+np.float32,0xbd30a4e0,0xbd30c0ee,4
+np.float32,0xbf4d3388,0xbf843530,4
+np.float32,0x3f529072,0x3f89df92,4
+np.float32,0xff0270b1,0xbf81be9a,4
+np.float32,0x5e07e7,0x5e07e7,4
+np.float32,0x7bec32,0x7bec32,4
+np.float32,0x7fc00000,0x7fc00000,4
+np.float32,0x3e3ba5e0,0x3e3dc6e9,4
+np.float32,0x3ecb62d4,0x3ed6ce2c,4
+np.float32,0x3eb3dde8,0x3ebba68f,4
+np.float32,0x8063f952,0x8063f952,4
+np.float32,0x7f204aeb,0x3e88614e,4
+np.float32,0xbeae1ddc,0xbeb5278e,4
+np.float32,0x6829e9,0x6829e9,4
+np.float32,0xbf361a99,0xbf5ca354,4
+np.float32,0xbf24fbe6,0xbf406326,4
+np.float32,0x3f329d41,0x3f56a061,4
+np.float32,0xfed6d666,0x3e8f71a5,4
+np.float32,0x337f92,0x337f92,4
+np.float32,0xbe1c4970,0xbe1d8305,4
+np.float32,0xbe6b7e18,0xbe6fbbde,4
+np.float32,0x3f2267b9,0x3f3c61da,4
+np.float32,0xbee1ee94,0xbef1d628,4
+np.float32,0x7ecffc1a,0x3f02987e,4
+np.float32,0xbe9b1306,0xbe9fff3b,4
+np.float32,0xbeffacae,0xbf0ba468,4
+np.float32,0x7f800000,0xffc00000,4
+np.float32,0xfefc9aa8,0xc19de2a3,4
+np.float32,0x7d7185bb,0xbf9090ec,4
+np.float32,0x7edfbafd,0x3fe9352f,4
+np.float32,0x4ef2ec,0x4ef2ec,4
+np.float32,0x7f4cab2e,0xbff4e5dd,4
+np.float32,0xff3b1788,0x3e3c22e9,4
+np.float32,0x4e15ee,0x4e15ee,4
+np.float32,0xbf5451e6,0xbf8bc8a7,4
+np.float32,0x3f7f6d2e,0x3fc65e8b,4
+np.float32,0xbf1d9184,0xbf35071b,4
+np.float32,0xbf3a81cf,0xbf646d9b,4
+np.float32,0xbe71acc4,0xbe7643ab,4
+np.float32,0x528b7d,0x528b7d,4
+np.float32,0x2cb1d0,0x2cb1d0,4
+np.float32,0x3f324bf8,0x3f56161a,4
+np.float32,0x80709a21,0x80709a21,4
+np.float32,0x4bc448,0x4bc448,4
+np.float32,0x3e8bd600,0x3e8f6b7a,4
+np.float32,0xbeb97d30,0xbec20dd6,4
+np.float32,0x2a5669,0x2a5669,4
+np.float32,0x805f2689,0x805f2689,4
+np.float32,0xfe569f50,0x3fc51952,4
+np.float32,0x1de44c,0x1de44c,4
+np.float32,0x3ec7036c,0x3ed1ae67,4
+np.float32,0x8052b8e5,0x8052b8e5,4
+np.float32,0xff740a6b,0x3f4981a8,4
+np.float32,0xfee9bb70,0xc05e23be,4
+np.float32,0xff4e12c9,0x4002b4ad,4
+np.float32,0x803de0c2,0x803de0c2,4
+np.float32,0xbf433a07,0xbf74966f,4
+np.float32,0x803e60ca,0x803e60ca,4
+np.float32,0xbf19ee98,0xbf2fa07a,4
+np.float32,0x92929,0x92929,4
+np.float32,0x7f709c27,0x4257ba2d,4
+np.float32,0x803167c6,0x803167c6,4
+np.float32,0xbf095ead,0xbf184607,4
+np.float32,0x617060,0x617060,4
+np.float32,0x2d85b3,0x2d85b3,4
+np.float32,0x53d20b,0x53d20b,4
+np.float32,0x3e046838,0x3e052666,4
+np.float32,0xbe7c5fdc,0xbe80ce4b,4
+np.float32,0x3d18d060,0x3d18e289,4
+np.float32,0x804dc031,0x804dc031,4
+np.float32,0x3f224166,0x3f3c26cd,4
+np.float32,0x7d683e3c,0xbea24f25,4
+np.float32,0xbf3a92aa,0xbf648be4,4
+np.float32,0x8072670b,0x8072670b,4
+np.float32,0xbe281aec,0xbe29a1bc,4
+np.float32,0x7f09d918,0xc0942490,4
+np.float32,0x7ca9fd07,0x4018b990,4
+np.float32,0x7d36ac5d,0x3cf57184,4
+np.float32,0x8039b62f,0x8039b62f,4
+np.float32,0x6cad7b,0x6cad7b,4
+np.float32,0x3c0fd9ab,0x3c0fda9d,4
+np.float32,0x80299883,0x80299883,4
+np.float32,0x3c2d0e3e,0x3c2d0fe4,4
+np.float32,0x8002cf62,0x8002cf62,4
+np.float32,0x801dde97,0x801dde97,4
+np.float32,0x80411856,0x80411856,4
+np.float32,0x6ebce8,0x6ebce8,4
+np.float32,0x7b7d1a,0x7b7d1a,4
+np.float32,0x8031d3de,0x8031d3de,4
+np.float32,0x8005c4ab,0x8005c4ab,4
+np.float32,0xbf7dd803,0xbfc3b3ef,4
+np.float32,0x8017ae60,0x8017ae60,4
+np.float32,0xfe9316ce,0xbfe0544a,4
+np.float32,0x3f136bfe,0x3f2636ff,4
+np.float32,0x3df87b80,0x3df9b57d,4
+np.float32,0xff44c356,0xbf11c7ad,4
+np.float32,0x4914ae,0x4914ae,4
+np.float32,0x80524c21,0x80524c21,4
+np.float32,0x805c7dc8,0x805c7dc8,4
+np.float32,0xfed3c0aa,0xbff0c0ab,4
+np.float32,0x7eb2bfbb,0xbf4600bc,4
+np.float32,0xfec8df84,0x3f5bd350,4
+np.float32,0x3e5431a4,0x3e5748c3,4
+np.float32,0xbee6a3a0,0xbef79e86,4
+np.float32,0xbf6cc9b2,0xbfa9d61a,4
+np.float32,0x3f132bd5,0x3f25dbd9,4
+np.float32,0x7e6d2e48,0x3f9d025b,4
+np.float32,0x3edf430c,0x3eee942d,4
+np.float32,0x3f0d1b8a,0x3f1d60e1,4
+np.float32,0xbdf2f688,0xbdf41bfb,4
+np.float32,0xbe47a284,0xbe4a33ff,4
+np.float32,0x3eaa9fbc,0x3eb13be7,4
+np.float32,0xfe98d45e,0x3eb84517,4
+np.float32,0x7efc23b3,0x3dcc1c99,4
+np.float32,0x3ca36242,0x3ca367ce,4
+np.float32,0x3f76a944,0x3fb834e3,4
+np.float32,0xbf45207c,0xbf783f9b,4
+np.float32,0x3e7c1220,0x3e80a4f8,4
+np.float32,0x3f018200,0x3f0dd14e,4
+np.float32,0x3f53cdde,0x3f8b3839,4
+np.float32,0xbdbacb58,0xbdbb5063,4
+np.float32,0x804af68d,0x804af68d,4
+np.float32,0x3e2c12fc,0x3e2db65b,4
+np.float32,0x3f039433,0x3f10895a,4
+np.float32,0x7ef5193d,0x3f4115f7,4
+np.float32,0x8030afbe,0x8030afbe,4
+np.float32,0x3f06fa2a,0x3f150d5d,4
+np.float32,0x3f124442,0x3f2493d2,4
+np.float32,0xbeb5b792,0xbebdc090,4
+np.float32,0xbedc90a4,0xbeeb4de9,4
+np.float32,0x3f3ff8,0x3f3ff8,4
+np.float32,0x3ee75bc5,0x3ef881e4,4
+np.float32,0xfe80e3de,0xbf5cd535,4
+np.float32,0xf52eb,0xf52eb,4
+np.float32,0x80660ee8,0x80660ee8,4
+np.float32,0x3e173a58,0x3e185648,4
+np.float32,0xfe49520c,0xbf728d7c,4
+np.float32,0xbecbb8ec,0xbed73373,4
+np.float32,0xbf027ae0,0xbf0f173e,4
+np.float32,0xbcab6740,0xbcab6da8,4
+np.float32,0xbf2a15e2,0xbf487e11,4
+np.float32,0x3b781b,0x3b781b,4
+np.float32,0x44f559,0x44f559,4
+np.float32,0xff6a0ca6,0xc174d7c3,4
+np.float32,0x6460ef,0x6460ef,4
+np.float32,0xfe58009c,0x3ee2bb30,4
+np.float32,0xfec3c038,0x3e30d617,4
+np.float32,0x7f0687c0,0xbf62c820,4
+np.float32,0xbf44655e,0xbf76d589,4
+np.float32,0xbf42968c,0xbf735e78,4
+np.float32,0x80385503,0x80385503,4
+np.float32,0xbea7e3a2,0xbeae2d59,4
+np.float32,0x3dd0b770,0x3dd17131,4
+np.float32,0xbf4bc185,0xbf82b907,4
+np.float32,0xfefd7d64,0xbee05650,4
+np.float32,0xfaac3c00,0xbff23bc9,4
+np.float32,0xbf562f0d,0xbf8dd7f4,4
+np.float32,0x7fa00000,0x7fe00000,4
+np.float32,0x3e01bdb8,0x3e027098,4
+np.float32,0x3e2868ab,0x3e29f19e,4
+np.float32,0xfec55f2e,0x3f39f304,4
+np.float32,0xed4e,0xed4e,4
+np.float32,0x3e2b7330,0x3e2d11fa,4
+np.float32,0x7f738542,0x40cbbe16,4
+np.float32,0x3f123521,0x3f247e71,4
+np.float32,0x73572c,0x73572c,4
+np.float32,0x804936c8,0x804936c8,4
+np.float32,0x803b80d8,0x803b80d8,4
+np.float32,0x7f566c57,0xbee2855a,4
+np.float32,0xff0e3bd8,0xbff0543f,4
+np.float32,0x7d2b2fe7,0xbf94ba4c,4
+np.float32,0xbf0da470,0xbf1e1dc2,4
+np.float32,0xbd276500,0xbd277ce0,4
+np.float32,0xfcd15dc0,0x403ccc2a,4
+np.float32,0x80071e59,0x80071e59,4
+np.float32,0xbe9b0c34,0xbe9ff7be,4
+np.float32,0x3f4f9069,0x3f86ac50,4
+np.float32,0x80042a95,0x80042a95,4
+np.float32,0x7de28e39,0x3bc9b7f4,4
+np.float32,0xbf641935,0xbf9e5af8,4
+np.float32,0x8034f068,0x8034f068,4
+np.float32,0xff33a3d2,0xbf408e75,4
+np.float32,0xbcc51540,0xbcc51efc,4
+np.float32,0xff6d1ddf,0x3ef58f0e,4
+np.float32,0xbf64dfc4,0xbf9f5725,4
+np.float32,0xff068a06,0x3eea8987,4
+np.float32,0xff01c0af,0x3f24cdfe,4
+np.float32,0x3f4def7e,0x3f84f802,4
+np.float32,0xbf1b4ae7,0xbf31a299,4
+np.float32,0x8077df2d,0x8077df2d,4
+np.float32,0x3f0155c5,0x3f0d9785,4
+np.float32,0x5a54b2,0x5a54b2,4
+np.float32,0x7f271f9e,0x3efb2ef3,4
+np.float32,0xbf0ff2ec,0xbf215217,4
+np.float32,0x7f500130,0xbf8a7fdd,4
+np.float32,0xfed9891c,0xbf65c872,4
+np.float32,0xfecbfaae,0x403bdbc2,4
+np.float32,0x3f3a5aba,0x3f642772,4
+np.float32,0x7ebc681e,0xbd8df059,4
+np.float32,0xfe05e400,0xbfe35d74,4
+np.float32,0xbf295ace,0xbf4750ea,4
+np.float32,0x7ea055b2,0x3f62d6be,4
+np.float32,0xbd00b520,0xbd00bff9,4
+np.float32,0xbf7677aa,0xbfb7e8cf,4
+np.float32,0x3e83f788,0x3e86f816,4
+np.float32,0x801f6710,0x801f6710,4
+np.float32,0x801133cc,0x801133cc,4
+np.float32,0x41da2a,0x41da2a,4
+np.float32,0xff1622fd,0x3f023650,4
+np.float32,0x806c7a72,0x806c7a72,4
+np.float32,0x3f10779c,0x3f220bb4,4
+np.float32,0xbf08cf94,0xbf17848d,4
+np.float32,0xbecb55b4,0xbed6bebd,4
+np.float32,0xbf0a1528,0xbf193d7b,4
+np.float32,0x806a16bd,0x806a16bd,4
+np.float32,0xc222a,0xc222a,4
+np.float32,0x3930de,0x3930de,4
+np.float32,0x3f5c3588,0x3f94bca2,4
+np.float32,0x1215ad,0x1215ad,4
+np.float32,0x3ed15030,0x3eddcf67,4
+np.float32,0x7da83b2e,0x3fce0d39,4
+np.float32,0x32b0a8,0x32b0a8,4
+np.float32,0x805aed6b,0x805aed6b,4
+np.float32,0x3ef8e02f,0x3f074346,4
+np.float32,0xbdeb6780,0xbdec7250,4
+np.float32,0x3f6e3cec,0x3fabda61,4
+np.float32,0xfefd467a,0x3ef7821a,4
+np.float32,0xfef090fe,0x3bb752a2,4
+np.float32,0x8019c538,0x8019c538,4
+np.float32,0x3e8cf284,0x3e909e81,4
+np.float32,0xbe6c6618,0xbe70b0a2,4
+np.float32,0x7f50a539,0x3f367be1,4
+np.float32,0x8019fe2f,0x8019fe2f,4
+np.float32,0x800c3f48,0x800c3f48,4
+np.float32,0xfd054cc0,0xc0f52802,4
+np.float32,0x3d0cca20,0x3d0cd853,4
+np.float32,0xbf4a7c44,0xbf816e74,4
+np.float32,0x3f46fc40,0x3f7be153,4
+np.float32,0x807c5849,0x807c5849,4
+np.float32,0xd7e41,0xd7e41,4
+np.float32,0x70589b,0x70589b,4
+np.float32,0x80357b95,0x80357b95,4
+np.float32,0x3de239f0,0x3de326a5,4
+np.float32,0x800b08e3,0x800b08e3,4
+np.float32,0x807ec946,0x807ec946,4
+np.float32,0x3e2e4b83,0x3e2fff76,4
+np.float32,0x3f198e0f,0x3f2f12a6,4
+np.float32,0xbecb1aca,0xbed67979,4
+np.float32,0x80134082,0x80134082,4
+np.float32,0x3f3a269f,0x3f63ca05,4
+np.float32,0x3f1381e4,0x3f265622,4
+np.float32,0xff293080,0xbf10be6f,4
+np.float32,0xff800000,0xffc00000,4
+np.float32,0x37d196,0x37d196,4
+np.float32,0x7e57eea7,0x3e7d8138,4
+np.float32,0x804b1dae,0x804b1dae,4
+np.float32,0x7d9508f9,0xc1075b35,4
+np.float32,0x3f7bf468,0x3fc095e0,4
+np.float32,0x55472c,0x55472c,4
+np.float32,0x3ecdcd86,0x3ed9a738,4
+np.float32,0x3ed9be0f,0x3ee7e4e9,4
+np.float32,0x3e7e0ddb,0x3e81b2fe,4
+np.float32,0x7ee6c1d3,0x3f850634,4
+np.float32,0x800f6fad,0x800f6fad,4
+np.float32,0xfefb3bd6,0xbff68ecc,4
+np.float32,0x8013d6e2,0x8013d6e2,4
+np.float32,0x3f3a2cb6,0x3f63d4ee,4
+np.float32,0xff383c84,0x3e7854bb,4
+np.float32,0x3f21946e,0x3f3b1cea,4
+np.float32,0xff322ea2,0x3fb22f31,4
+np.float32,0x8065a024,0x8065a024,4
+np.float32,0x7f395e30,0xbefe0de1,4
+np.float32,0x5b52db,0x5b52db,4
+np.float32,0x7f7caea7,0x3dac8ded,4
+np.float32,0xbf0431f8,0xbf1159b2,4
+np.float32,0x7f15b25b,0xc02a3833,4
+np.float32,0x80131abc,0x80131abc,4
+np.float32,0x7e829d81,0xbeb2e93d,4
+np.float32,0x3f2c64d7,0x3f4c3e4d,4
+np.float32,0x7f228d48,0xc1518c74,4
+np.float32,0xfc3c6f40,0xbf00d585,4
+np.float32,0x7f754f0f,0x3e2152f5,4
+np.float32,0xff65d32b,0xbe8bd56c,4
+np.float32,0xfea6b8c0,0x41608655,4
+np.float32,0x3f7d4b05,0x3fc2c96a,4
+np.float32,0x3f463230,0x3f7a54da,4
+np.float32,0x805117bb,0x805117bb,4
+np.float32,0xbf2ad4f7,0xbf49b30e,4
+np.float32,0x3eaa01ff,0x3eb08b56,4
+np.float32,0xff7a02bb,0x3f095f73,4
+np.float32,0x759176,0x759176,4
+np.float32,0x803c18d5,0x803c18d5,4
+np.float32,0xbe0722d8,0xbe07ed16,4
+np.float32,0x3f4b4a99,0x3f823fc6,4
+np.float32,0x3f7d0451,0x3fc25463,4
+np.float32,0xfee31e40,0xbfb41091,4
+np.float32,0xbf733d2c,0xbfb30cf1,4
+np.float32,0x7ed81015,0x417c380c,4
+np.float32,0x7daafc3e,0xbe2a37ed,4
+np.float32,0x3e44f82b,0x3e476f67,4
+np.float32,0x7c8d99,0x7c8d99,4
+np.float32,0x3f7aec5a,0x3fbee991,4
+np.float32,0xff09fd55,0x3e0709d3,4
+np.float32,0xff4ba4df,0x4173c01f,4
+np.float32,0x3f43d944,0x3f75c7bd,4
+np.float32,0xff6a9106,0x40a10eff,4
+np.float32,0x3bc8341c,0x3bc834bf,4
+np.float32,0x3eea82,0x3eea82,4
+np.float32,0xfea36a3c,0x435729b2,4
+np.float32,0x7dcc1fb0,0x3e330053,4
+np.float32,0x3f616ae6,0x3f9b01ae,4
+np.float32,0x8030963f,0x8030963f,4
+np.float32,0x10d1e2,0x10d1e2,4
+np.float32,0xfeb9a8a6,0x40e6daac,4
+np.float32,0xbe1aba00,0xbe1bea3a,4
+np.float32,0x3cb6b4ea,0x3cb6bcac,4
+np.float32,0x3d8b0b64,0x3d8b422f,4
+np.float32,0x7b6894,0x7b6894,4
+np.float32,0x3e89dcde,0x3e8d4b4b,4
+np.float32,0x3f12b952,0x3f253974,4
+np.float32,0x1c316c,0x1c316c,4
+np.float32,0x7e2da535,0x3f95fe6b,4
+np.float32,0x3ae9a494,0x3ae9a4a4,4
+np.float32,0xbc5f5500,0xbc5f588b,4
+np.float32,0x3e7850fc,0x3e7d4d0e,4
+np.float32,0xbf800000,0xbfc75923,4
+np.float32,0x3e652d69,0x3e691502,4
+np.float32,0xbf6bdd26,0xbfa89129,4
+np.float32,0x3f441cfc,0x3f764a02,4
+np.float32,0x7f5445ff,0xc0906191,4
+np.float32,0x807b2ee3,0x807b2ee3,4
+np.float32,0xbeb6cab8,0xbebef9c0,4
+np.float32,0xff737277,0xbf327011,4
+np.float32,0xfc832aa0,0x402fd52e,4
+np.float32,0xbf0c7538,0xbf1c7c0f,4
+np.float32,0x7e1301c7,0xbf0ee63e,4
+np.float64,0xbfe0ef7df7a1defc,0xbfe2b76a8d8aeb35,4
+np.float64,0x7fdd9c2eae3b385c,0xbfc00d6885485039,4
+np.float64,0xbfb484c710290990,0xbfb4900e0a527555,4
+np.float64,0x7fe73e5d6cee7cba,0x3fefbf70a56b60d3,4
+np.float64,0x800a110aa8d42216,0x800a110aa8d42216,4
+np.float64,0xffedd4f3f3bba9e7,0xbff076f8c4124919,4
+np.float64,0x800093407f812682,0x800093407f812682,4
+np.float64,0x800a23150e54462a,0x800a23150e54462a,4
+np.float64,0xbfb1076864220ed0,0xbfb10dd95a74b733,4
+np.float64,0x3fed1f8b37fa3f16,0x3ff496100985211f,4
+np.float64,0x3fdf762f84beec5f,0x3fe1223eb04a17e0,4
+np.float64,0x53fd4e0aa7faa,0x53fd4e0aa7faa,4
+np.float64,0x3fdbd283bdb7a507,0x3fddb7ec9856a546,4
+np.float64,0xbfe43f449d687e89,0xbfe77724a0d3072b,4
+np.float64,0x618b73bcc316f,0x618b73bcc316f,4
+np.float64,0x67759424ceeb3,0x67759424ceeb3,4
+np.float64,0xbfe4b6f7d9a96df0,0xbfe831371f3bd7a8,4
+np.float64,0x800a531b8b74a637,0x800a531b8b74a637,4
+np.float64,0xffeeffd5c37dffab,0x3fea140cbc2c3726,4
+np.float64,0x3fe648e2002c91c4,0x3feac1b8816f972a,4
+np.float64,0x800f16242a1e2c48,0x800f16242a1e2c48,4
+np.float64,0xffeeff8e1dbdff1b,0xc000b555f117dce7,4
+np.float64,0x3fdf1cf73fbe39f0,0x3fe0e9032401135b,4
+np.float64,0x7fe19c388b633870,0x3fd5271b69317d5b,4
+np.float64,0x918f226d231e5,0x918f226d231e5,4
+np.float64,0x4cc19ab499834,0x4cc19ab499834,4
+np.float64,0xbd3121d57a624,0xbd3121d57a624,4
+np.float64,0xbfd145d334a28ba6,0xbfd1b468866124d6,4
+np.float64,0x8bdbf41517b7f,0x8bdbf41517b7f,4
+np.float64,0x3fd1b8cb3ea37198,0x3fd2306b13396cae,4
+np.float64,0xbfd632a959ac6552,0xbfd7220fcfb5ef78,4
+np.float64,0x1cdaafc639b57,0x1cdaafc639b57,4
+np.float64,0x3febdcce1577b99c,0x3ff2fe076195a2bc,4
+np.float64,0x7fca6e945934dd28,0x3ff43040df7024e8,4
+np.float64,0x3fbe08e78e3c11cf,0x3fbe2c60e6b48f75,4
+np.float64,0x7fc1ed0d0523da19,0x3ff55f8dcad9440f,4
+np.float64,0xbfdc729b8cb8e538,0xbfde7b6e15dd60c4,4
+np.float64,0x3fd219404f243281,0x3fd298d7b3546531,4
+np.float64,0x3fe715c3f56e2b88,0x3fec255b5a59456e,4
+np.float64,0x7fe8b88e74b1711c,0x3ff60efd2c81d13d,4
+np.float64,0xa1d2b9fd43a57,0xa1d2b9fd43a57,4
+np.float64,0xffc1818223230304,0xbfb85c6c1e8018e7,4
+np.float64,0x3fde38ac8b3c7159,0x3fe0580c7e228576,4
+np.float64,0x8008faf7b491f5f0,0x8008faf7b491f5f0,4
+np.float64,0xffe7a1d751af43ae,0xbf7114cd7bbcd981,4
+np.float64,0xffec2db1b4b85b62,0xbff5cae759667f83,4
+np.float64,0x7fefce1ae27f9c35,0x3ff4b8b88f4876cf,4
+np.float64,0x7fd1ff56a523feac,0xbff342ce192f14dd,4
+np.float64,0x80026b3e3f84d67d,0x80026b3e3f84d67d,4
+np.float64,0xffedee5879bbdcb0,0xc02fae11508b2be0,4
+np.float64,0x8003c0dc822781ba,0x8003c0dc822781ba,4
+np.float64,0xffe38a79eca714f4,0xc008aa23b7a63980,4
+np.float64,0xbfda70411eb4e082,0xbfdc0d7e29c89010,4
+np.float64,0x800a5e34f574bc6a,0x800a5e34f574bc6a,4
+np.float64,0x3fc19fac6e233f59,0x3fc1bc66ac0d73d4,4
+np.float64,0x3a8a61ea7514d,0x3a8a61ea7514d,4
+np.float64,0x3fb57b536e2af6a0,0x3fb588451f72f44c,4
+np.float64,0x7fd68c6d082d18d9,0xc032ac926b665c9a,4
+np.float64,0xd5b87cfdab710,0xd5b87cfdab710,4
+np.float64,0xfe80b20bfd017,0xfe80b20bfd017,4
+np.float64,0x3fef8781e37f0f04,0x3ff8215fe2c1315a,4
+np.float64,0xffedddbb9c3bbb76,0x3fd959b82258a32a,4
+np.float64,0x3fc7d41f382fa83e,0x3fc81b94c3a091ba,4
+np.float64,0xffc3275dcf264ebc,0x3fb2b3d4985c6078,4
+np.float64,0x7fe34d2b7ba69a56,0x40001f3618e3c7c9,4
+np.float64,0x3fd64ae35fac95c7,0x3fd73d77e0b730f8,4
+np.float64,0x800e53bf6b3ca77f,0x800e53bf6b3ca77f,4
+np.float64,0xbfddf7c9083bef92,0xbfe02f392744d2d1,4
+np.float64,0x1c237cc038471,0x1c237cc038471,4
+np.float64,0x3fe4172beea82e58,0x3fe739b4bf16bc7e,4
+np.float64,0xfa950523f52a1,0xfa950523f52a1,4
+np.float64,0xffc839a2c5307344,0xbff70ff8a3c9247f,4
+np.float64,0x264f828c4c9f1,0x264f828c4c9f1,4
+np.float64,0x148a650a2914e,0x148a650a2914e,4
+np.float64,0x3fe8d255c0b1a4ac,0x3fef623c3ea8d6e3,4
+np.float64,0x800f4fbb28be9f76,0x800f4fbb28be9f76,4
+np.float64,0x7fdca57bcfb94af7,0x3ff51207563fb6cb,4
+np.float64,0x3fe4944107692882,0x3fe7fad593235364,4
+np.float64,0x800119b4f1a2336b,0x800119b4f1a2336b,4
+np.float64,0xbfe734075e6e680e,0xbfec5b35381069f2,4
+np.float64,0xffeb3c00db767801,0xbfbbd7d22df7b4b3,4
+np.float64,0xbfe95c658cb2b8cb,0xbff03ad5e0bc888a,4
+np.float64,0xffeefeb58fbdfd6a,0xbfd5c9264deb0e11,4
+np.float64,0x7fccc80fde39901f,0xc012c60f914f3ca2,4
+np.float64,0x3fe5da289c2bb451,0x3fea07ad00a0ca63,4
+np.float64,0x800e364b0a5c6c96,0x800e364b0a5c6c96,4
+np.float64,0x3fcf9ea7d23f3d50,0x3fd023b72e8c9dcf,4
+np.float64,0x800a475cfc948eba,0x800a475cfc948eba,4
+np.float64,0xffd4e0d757a9c1ae,0xbfa89d573352e011,4
+np.float64,0xbfd4dbec8229b7da,0xbfd5a165f12c7c40,4
+np.float64,0xffe307ab51260f56,0x3fe6b1639da58c3f,4
+np.float64,0xbfe6955a546d2ab4,0xbfeb44ae2183fee9,4
+np.float64,0xbfca1f18f5343e30,0xbfca7d804ccccdf4,4
+np.float64,0xe9f4dfebd3e9c,0xe9f4dfebd3e9c,4
+np.float64,0xfff0000000000000,0xfff8000000000000,4
+np.float64,0x8008e69c0fb1cd38,0x8008e69c0fb1cd38,4
+np.float64,0xbfead1ccf975a39a,0xbff1c84b3db8ca93,4
+np.float64,0x25a982424b531,0x25a982424b531,4
+np.float64,0x8010000000000000,0x8010000000000000,4
+np.float64,0x80056204ea0ac40b,0x80056204ea0ac40b,4
+np.float64,0x800d1442d07a2886,0x800d1442d07a2886,4
+np.float64,0xbfaef3dadc3de7b0,0xbfaefd85ae6205f0,4
+np.float64,0x7fe969ce4b32d39c,0xbff3c4364fc6778f,4
+np.float64,0x7fe418bac0a83175,0x402167d16b1efe0b,4
+np.float64,0x3fd7c82a25af9054,0x3fd8f0c701315672,4
+np.float64,0x80013782a7826f06,0x80013782a7826f06,4
+np.float64,0x7fc031c7ee20638f,0x400747ab705e6904,4
+np.float64,0x3fe8cf327ff19e65,0x3fef5c14f8aafa89,4
+np.float64,0xbfe331a416a66348,0xbfe5e2290a098dd4,4
+np.float64,0x800607b2116c0f65,0x800607b2116c0f65,4
+np.float64,0x7fb40448f0280891,0xbfd43d4f0ffa1d64,4
+np.float64,0x7fefffffffffffff,0xbf74530cfe729484,4
+np.float64,0x3fe39b5444a736a9,0x3fe67eaa0b6acf27,4
+np.float64,0x3fee4733c4fc8e68,0x3ff631eabeef9696,4
+np.float64,0xbfec840f3b79081e,0xbff3cc8563ab2e74,4
+np.float64,0xbfc8f6854c31ed0c,0xbfc948caacb3bba0,4
+np.float64,0xffbcf754a639eea8,0xbfc88d17cad3992b,4
+np.float64,0x8000bd3163417a64,0x8000bd3163417a64,4
+np.float64,0x3fe766d0eaeecda2,0x3fecb660882f7024,4
+np.float64,0xb6cc30156d986,0xb6cc30156d986,4
+np.float64,0xffc0161f9f202c40,0x3fe19bdefe5cf8b1,4
+np.float64,0xffe1e462caa3c8c5,0x3fe392c47feea17b,4
+np.float64,0x30a36a566146e,0x30a36a566146e,4
+np.float64,0x3fa996f580332deb,0x3fa99c6b4f2abebe,4
+np.float64,0x3fba71716e34e2e0,0x3fba899f35edba1d,4
+np.float64,0xbfe8f7e5e971efcc,0xbfefac431a0e3d55,4
+np.float64,0xf48f1803e91e3,0xf48f1803e91e3,4
+np.float64,0x7fe3edc0a127db80,0xc03d1a579a5d74a8,4
+np.float64,0xffeba82056375040,0x3fdfd701308700db,4
+np.float64,0xbfeb5a924cf6b524,0xbff2640de7cd107f,4
+np.float64,0xfa4cd1a9f499a,0xfa4cd1a9f499a,4
+np.float64,0x800de1be7b9bc37d,0x800de1be7b9bc37d,4
+np.float64,0xffd44e56ad289cae,0x3fdf4b8085db9b67,4
+np.float64,0xbfe4fb3aea69f676,0xbfe89d2cc46fcc50,4
+np.float64,0xbfe596495d6b2c92,0xbfe997a589a1f632,4
+np.float64,0x6f55a2b8deab5,0x6f55a2b8deab5,4
+np.float64,0x7fe72dc4712e5b88,0x4039c4586b28c2bc,4
+np.float64,0x89348bd712692,0x89348bd712692,4
+np.float64,0xffe062156120c42a,0x4005f0580973bc77,4
+np.float64,0xbfeabc714d7578e2,0xbff1b07e2fa57dc0,4
+np.float64,0x8003a56b3e874ad7,0x8003a56b3e874ad7,4
+np.float64,0x800eeadfb85dd5c0,0x800eeadfb85dd5c0,4
+np.float64,0x46d77a4c8daf0,0x46d77a4c8daf0,4
+np.float64,0x8000c06e7dc180de,0x8000c06e7dc180de,4
+np.float64,0x3fe428d211e851a4,0x3fe754b1c00a89bc,4
+np.float64,0xc5be11818b7c2,0xc5be11818b7c2,4
+np.float64,0x7fefc244893f8488,0x401133dc54f52de5,4
+np.float64,0x3fde30eee93c61de,0x3fe0532b827543a6,4
+np.float64,0xbfd447f48b288fea,0xbfd4fd0654f90718,4
+np.float64,0xbfde98dc7b3d31b8,0xbfe094df12f84a06,4
+np.float64,0x3fed2c1a1dfa5834,0x3ff4a6c4f3470a65,4
+np.float64,0xbfe992165073242d,0xbff071ab039c9177,4
+np.float64,0x3fd0145d1b2028ba,0x3fd06d3867b703dc,4
+np.float64,0x3fe179457362f28b,0x3fe3722f1d045fda,4
+np.float64,0x800e28964fbc512d,0x800e28964fbc512d,4
+np.float64,0x8004a5d785294bb0,0x8004a5d785294bb0,4
+np.float64,0xbfd652f2272ca5e4,0xbfd7469713125120,4
+np.float64,0x7fe61f49036c3e91,0xbf9b6ccdf2d87e70,4
+np.float64,0xffb7d47dd02fa8f8,0xc004449a82320b13,4
+np.float64,0x3feb82f996b705f3,0x3ff29336c738a4c5,4
+np.float64,0x3fbb7fceea36ffa0,0x3fbb9b02c8ad7f93,4
+np.float64,0x80004519fb208a35,0x80004519fb208a35,4
+np.float64,0xbfe0539114e0a722,0xbfe1e86dc5aa039c,4
+np.float64,0x0,0x0,4
+np.float64,0xbfe99d1125f33a22,0xbff07cf8ec04300f,4
+np.float64,0xffd4fbeecc29f7de,0x3ffab76775a8455f,4
+np.float64,0xbfbf1c618e3e38c0,0xbfbf43d2764a8333,4
+np.float64,0x800cae02a9d95c06,0x800cae02a9d95c06,4
+np.float64,0x3febc47d3bf788fa,0x3ff2e0d7cf8ef509,4
+np.float64,0x3fef838f767f071f,0x3ff81aeac309bca0,4
+np.float64,0xbfd5e70716abce0e,0xbfd6ccb033ef7a35,4
+np.float64,0x3f9116fa60222df5,0x3f9117625f008e0b,4
+np.float64,0xffe02b1e5f20563c,0xbfe6b2ec293520b7,4
+np.float64,0xbf9b5aec3036b5e0,0xbf9b5c96c4c7f951,4
+np.float64,0xfdb0169bfb603,0xfdb0169bfb603,4
+np.float64,0x7fcdd1d51c3ba3a9,0x401f0e12fa0b7570,4
+np.float64,0xbfd088103fa11020,0xbfd0e8c4a333ffb2,4
+np.float64,0x3fe22df82ee45bf0,0x3fe46d03a7c14de2,4
+np.float64,0xbfd57b0c28aaf618,0xbfd65349a6191de5,4
+np.float64,0x3fe0a42f50a1485f,0x3fe252e26775d9a4,4
+np.float64,0x800fab4e363f569c,0x800fab4e363f569c,4
+np.float64,0xffe9f0ed63f3e1da,0xbfe278c341b171d5,4
+np.float64,0x7fe26c244664d848,0xbfb325269dad1996,4
+np.float64,0xffe830410bf06081,0xc00181a39f606e96,4
+np.float64,0x800c548a0c78a914,0x800c548a0c78a914,4
+np.float64,0x800f94761ebf28ec,0x800f94761ebf28ec,4
+np.float64,0x3fe5984845eb3091,0x3fe99aeb653c666d,4
+np.float64,0x7fe93e5bf8f27cb7,0xc010d159fa27396a,4
+np.float64,0xffefffffffffffff,0x3f74530cfe729484,4
+np.float64,0x4c83f1269907f,0x4c83f1269907f,4
+np.float64,0x3fde0065a8bc00cc,0x3fe034a1cdf026d4,4
+np.float64,0x800743810d6e8703,0x800743810d6e8703,4
+np.float64,0x80040662d5280cc6,0x80040662d5280cc6,4
+np.float64,0x3fed20b2c5ba4166,0x3ff497988519d7aa,4
+np.float64,0xffe8fa15e5f1f42b,0x3fff82ca76d797b4,4
+np.float64,0xbb72e22f76e5d,0xbb72e22f76e5d,4
+np.float64,0x7fc18ffa7c231ff4,0xbff4b8b4c3315026,4
+np.float64,0xbfe8d1ac44f1a358,0xbfef60efc4f821e3,4
+np.float64,0x3fd38c1fe8271840,0x3fd42dc37ff7262b,4
+np.float64,0xe577bee5caef8,0xe577bee5caef8,4
+np.float64,0xbff0000000000000,0xbff8eb245cbee3a6,4
+np.float64,0xffcb3a9dd436753c,0x3fcd1a3aff1c3fc7,4
+np.float64,0x7fe44bf2172897e3,0x3ff60bfe82a379f4,4
+np.float64,0x8009203823924071,0x8009203823924071,4
+np.float64,0x7fef8e0abc7f1c14,0x3fe90e4962d47ce5,4
+np.float64,0xffda50004434a000,0x3fb50dee03e1418b,4
+np.float64,0x7fe2ff276ea5fe4e,0xc0355b7d2a0a8d9d,4
+np.float64,0x3fd0711ba5a0e238,0x3fd0d03823d2d259,4
+np.float64,0xe7625b03cec4c,0xe7625b03cec4c,4
+np.float64,0xbfd492c8d7a92592,0xbfd55006cde8d300,4
+np.float64,0x8001fee99f23fdd4,0x8001fee99f23fdd4,4
+np.float64,0x7ff4000000000000,0x7ffc000000000000,4
+np.float64,0xfa15df97f42bc,0xfa15df97f42bc,4
+np.float64,0xbfec3fdca9787fb9,0xbff377164b13c7a9,4
+np.float64,0xbcec10e579d82,0xbcec10e579d82,4
+np.float64,0xbfc3b4e2132769c4,0xbfc3dd1fcc7150a6,4
+np.float64,0x80045b149ee8b62a,0x80045b149ee8b62a,4
+np.float64,0xffe044554c2088aa,0xbff741436d558785,4
+np.float64,0xffcc65f09f38cbe0,0xc0172b4adc2d317d,4
+np.float64,0xf68b2d3bed166,0xf68b2d3bed166,4
+np.float64,0x7fc7f44c572fe898,0x3fec69f3b1eca790,4
+np.float64,0x3fac51f61438a3ec,0x3fac595d34156002,4
+np.float64,0xbfeaa9f256f553e5,0xbff19bfdf5984326,4
+np.float64,0x800e4742149c8e84,0x800e4742149c8e84,4
+np.float64,0xbfc493df132927c0,0xbfc4c1ba4268ead9,4
+np.float64,0xbfbf0c56383e18b0,0xbfbf3389fcf50c72,4
+np.float64,0xbf978a0e082f1420,0xbf978b1dd1da3d3c,4
+np.float64,0xbfe04375356086ea,0xbfe1d34c57314dd1,4
+np.float64,0x3feaeeb29b75dd65,0x3ff1e8b772374979,4
+np.float64,0xbfe15e42c3a2bc86,0xbfe34d45d56c5c15,4
+np.float64,0x3fe507429a6a0e85,0x3fe8b058176b3225,4
+np.float64,0x3feee2b26c3dc565,0x3ff71b73203de921,4
+np.float64,0xbfd496577aa92cae,0xbfd553fa7fe15a5f,4
+np.float64,0x7fe2c10953e58212,0x3fc8ead6a0d14bbf,4
+np.float64,0x800035b77aa06b70,0x800035b77aa06b70,4
+np.float64,0x2329201e46525,0x2329201e46525,4
+np.float64,0xbfe6225c9a6c44b9,0xbfea80861590fa02,4
+np.float64,0xbfd6925030ad24a0,0xbfd78e70b1c2215d,4
+np.float64,0xbfd82225c4b0444c,0xbfd958a60f845b39,4
+np.float64,0xbb03d8a17609,0xbb03d8a17609,4
+np.float64,0x7fc33967b12672ce,0x40001e00c9af4002,4
+np.float64,0xff9373c6d026e780,0xbff308654a459d3d,4
+np.float64,0x3feab1f9c5f563f4,0x3ff1a4e0fd2f093d,4
+np.float64,0xbf993ef768327de0,0xbf994046b64e308b,4
+np.float64,0xffb87382fc30e708,0xbfde0accb83c891b,4
+np.float64,0x800bb3a118176743,0x800bb3a118176743,4
+np.float64,0x800c810250d90205,0x800c810250d90205,4
+np.float64,0xbfd2c4eb9ba589d8,0xbfd3539508b4a4a8,4
+np.float64,0xbee1f5437dc3f,0xbee1f5437dc3f,4
+np.float64,0x3fc07aeab520f5d8,0x3fc0926272f9d8e2,4
+np.float64,0xbfe23747a3246e90,0xbfe47a20a6e98687,4
+np.float64,0x3fde1296debc252c,0x3fe0401143ff6b5c,4
+np.float64,0xbfcec8c2f73d9184,0xbfcf644e25ed3b74,4
+np.float64,0xff9314f2c82629e0,0x40559a0f9099dfd1,4
+np.float64,0xbfe27487afa4e910,0xbfe4d0e01200bde6,4
+np.float64,0xffb3d6637627acc8,0x3fe326d4b1e1834f,4
+np.float64,0xffe6f84d642df09a,0x3fc73fa9f57c3acb,4
+np.float64,0xffe67cf76fecf9ee,0xc01cf48c97937ef9,4
+np.float64,0x7fdc73fc12b8e7f7,0xbfcfcecde9331104,4
+np.float64,0xffdcf8789239f0f2,0x3fe345e3b8e28776,4
+np.float64,0x800a70af5314e15f,0x800a70af5314e15f,4
+np.float64,0xffc862300730c460,0x3fc4e9ea813beca7,4
+np.float64,0xbfcc6961bd38d2c4,0xbfcce33bfa6c6bd1,4
+np.float64,0xbfc9b76bbf336ed8,0xbfca117456ac37e5,4
+np.float64,0x7fb86e829430dd04,0x400a5bd7a18e302d,4
+np.float64,0x7fb9813ef833027d,0xbfe5a6494f143625,4
+np.float64,0x8005085e2c2a10bd,0x8005085e2c2a10bd,4
+np.float64,0xffe5af099d6b5e12,0x40369bbe31e03e06,4
+np.float64,0xffde03b1fd3c0764,0x3ff061120aa1f52a,4
+np.float64,0x7fa4eb6cdc29d6d9,0x3fe9defbe9010322,4
+np.float64,0x800803f4b11007ea,0x800803f4b11007ea,4
+np.float64,0x7febd50f6df7aa1e,0xbffcf540ccf220dd,4
+np.float64,0x7fed454f08fa8a9d,0xbffc2a8b81079403,4
+np.float64,0xbfed7e8c69bafd19,0xbff5161e51ba6634,4
+np.float64,0xffef92e78eff25ce,0xbffefeecddae0ad3,4
+np.float64,0x7fe5b9b413ab7367,0xbfc681ba29704176,4
+np.float64,0x29284e805252,0x29284e805252,4
+np.float64,0xffed3955bcfa72ab,0xbfc695acb5f468de,4
+np.float64,0x3fe464ee1ca8c9dc,0x3fe7b140ce50fdca,4
+np.float64,0xffe522ae4bea455c,0x3feb957c146e66ef,4
+np.float64,0x8000000000000000,0x8000000000000000,4
+np.float64,0x3fd0c353a2a186a8,0x3fd1283aaa43a411,4
+np.float64,0x3fdb30a749b6614f,0x3fdcf40df006ed10,4
+np.float64,0x800109213cc21243,0x800109213cc21243,4
+np.float64,0xbfe72aa0c5ee5542,0xbfec4a713f513bc5,4
+np.float64,0x800865344ad0ca69,0x800865344ad0ca69,4
+np.float64,0x7feb7df60eb6fbeb,0x3fb1df06a67aa22f,4
+np.float64,0x3fe83a5dd93074bc,0x3fee3d63cda72636,4
+np.float64,0xbfde70e548bce1ca,0xbfe07b8e19c9dac6,4
+np.float64,0xbfeea38d537d471b,0xbff6bb18c230c0be,4
+np.float64,0x3fefeebbc47fdd78,0x3ff8cdaa53b7c7b4,4
+np.float64,0x7fe6512e20eca25b,0xbff623cee44a22b5,4
+np.float64,0xf8fa5ca3f1f4c,0xf8fa5ca3f1f4c,4
+np.float64,0x7fd12d00ed225a01,0xbfe90d518ea61faf,4
+np.float64,0x80027db43504fb69,0x80027db43504fb69,4
+np.float64,0xffc10a01aa221404,0x3fcc2065b3d0157b,4
+np.float64,0xbfef8286e87f050e,0xbff8193a54449b59,4
+np.float64,0xbfc73178092e62f0,0xbfc7735072ba4593,4
+np.float64,0x3fc859d70630b3ae,0x3fc8a626522af1c0,4
+np.float64,0x3fe4654c4268ca99,0x3fe7b1d2913eda1a,4
+np.float64,0xbfce93cd843d279c,0xbfcf2c2ef16a0957,4
+np.float64,0xffbcaa16d4395430,0xbfd511ced032d784,4
+np.float64,0xbfe91f980e723f30,0xbfeffb39cf8c7746,4
+np.float64,0x800556fb6f0aadf8,0x800556fb6f0aadf8,4
+np.float64,0xffd009cde520139c,0x3fe4fa83b1e93d28,4
+np.float64,0x7febc0675e3780ce,0x3feb53930c004dae,4
+np.float64,0xbfe7f975bdeff2ec,0xbfedc36e6729b010,4
+np.float64,0x45aff57c8b5ff,0x45aff57c8b5ff,4
+np.float64,0xbfec7ebd0138fd7a,0xbff3c5cab680aae0,4
+np.float64,0x8009448003b28900,0x8009448003b28900,4
+np.float64,0x3fca4b992d349732,0x3fcaabebcc86aa9c,4
+np.float64,0x3fca069161340d20,0x3fca63ecc742ff3a,4
+np.float64,0x80063bc80bec7791,0x80063bc80bec7791,4
+np.float64,0xbfe1764bffe2ec98,0xbfe36e1cb30cec94,4
+np.float64,0xffd0dba72f21b74e,0x3fb1834964d57ef6,4
+np.float64,0xbfe31848fc263092,0xbfe5bd066445cbc3,4
+np.float64,0xbfd1fb227323f644,0xbfd278334e27f02d,4
+np.float64,0xffdc59069fb8b20e,0xbfdfc363f559ea2c,4
+np.float64,0x3fdea52a52bd4a55,0x3fe09cada4e5344c,4
+np.float64,0x3f715e55a022bd00,0x3f715e5c72a2809e,4
+np.float64,0x1d1ac6023a35a,0x1d1ac6023a35a,4
+np.float64,0x7feacc71627598e2,0x400486b82121da19,4
+np.float64,0xa0287fa340510,0xa0287fa340510,4
+np.float64,0xffe352c5abe6a58b,0xc002623346060543,4
+np.float64,0x7fed577a23baaef3,0x3fda19bc8fa3b21f,4
+np.float64,0x3fde8dd5263d1baa,0x3fe08de0fedf7029,4
+np.float64,0x3feddd3be2bbba78,0x3ff599b2f3e018cc,4
+np.float64,0xc7a009f58f401,0xc7a009f58f401,4
+np.float64,0xbfef03d5a4fe07ab,0xbff74ee08681f47b,4
+np.float64,0x7fe2cf60eea59ec1,0x3fe905fb44f8cc60,4
+np.float64,0xbfe498fcab6931fa,0xbfe8023a6ff8becf,4
+np.float64,0xbfef7142acfee285,0xbff7fd196133a595,4
+np.float64,0xd214ffdba42a0,0xd214ffdba42a0,4
+np.float64,0x8006de7d78cdbcfc,0x8006de7d78cdbcfc,4
+np.float64,0xb247d34f648fb,0xb247d34f648fb,4
+np.float64,0xbfdd5bece6bab7da,0xbfdf9ba63ca2c5b2,4
+np.float64,0x7fe874650af0e8c9,0x3fe74204e122c10f,4
+np.float64,0x800768c49baed18a,0x800768c49baed18a,4
+np.float64,0x3fb4c0a192298140,0x3fb4cc4c8aa43300,4
+np.float64,0xbfa740531c2e80a0,0xbfa7446b7c74ae8e,4
+np.float64,0x7fe10d6edf221add,0x3fedbcd2eae26657,4
+np.float64,0xbfe9175d0f722eba,0xbfefeaca7f32c6e3,4
+np.float64,0x953e11d32a7c2,0x953e11d32a7c2,4
+np.float64,0x80032df90c465bf3,0x80032df90c465bf3,4
+np.float64,0xffec5b799638b6f2,0xbfe95cd2c69be12c,4
+np.float64,0xffe0c3cfa9a1879f,0x3fe20b99b0c108ce,4
+np.float64,0x3fb610d8e22c21b2,0x3fb61ee0d6c16df8,4
+np.float64,0xffe16bb39962d766,0xc016d370381b6b42,4
+np.float64,0xbfdc72edb238e5dc,0xbfde7bd2de10717a,4
+np.float64,0xffed52dee3baa5bd,0xc01994c08899129a,4
+np.float64,0xffa92aab08325550,0xbff2b881ce363cbd,4
+np.float64,0x7fe028282de0504f,0xc0157ff96c69a9c7,4
+np.float64,0xbfdb2151bf3642a4,0xbfdce196fcc35857,4
+np.float64,0x3fcffbd13c3ff7a2,0x3fd0554b5f0371ac,4
+np.float64,0x800d206bff1a40d8,0x800d206bff1a40d8,4
+np.float64,0x458f818c8b1f1,0x458f818c8b1f1,4
+np.float64,0x800a7b56a234f6ae,0x800a7b56a234f6ae,4
+np.float64,0xffe3d86161e7b0c2,0xbff58d0dbde9f188,4
+np.float64,0xe8ed82e3d1db1,0xe8ed82e3d1db1,4
+np.float64,0x3fe234e0176469c0,0x3fe476bd36b96a75,4
+np.float64,0xbfc7cb9c132f9738,0xbfc812c46e185e0b,4
+np.float64,0xbfeba116c1f7422e,0xbff2b6b7563ad854,4
+np.float64,0x7fe7041de62e083b,0x3f5d2b42aca47274,4
+np.float64,0xbfcf60f4ff3ec1e8,0xbfd002eb83406436,4
+np.float64,0xbfc06067a520c0d0,0xbfc0776e5839ecda,4
+np.float64,0x4384965a87093,0x4384965a87093,4
+np.float64,0xd2ed9d01a5db4,0xd2ed9d01a5db4,4
+np.float64,0x3fbea88cb63d5119,0x3fbece49cc34a379,4
+np.float64,0x3fe7e982ebefd306,0x3feda5bd4c435d43,4
+np.float64,0xffdb60a3e036c148,0xbfcb7ed21e7a8f49,4
+np.float64,0x7fdba9231eb75245,0xbfd750cab1536398,4
+np.float64,0x800d593534dab26b,0x800d593534dab26b,4
+np.float64,0xffdf15fb683e2bf6,0x3fb3aaea23357f06,4
+np.float64,0xbfd6f8a2e5adf146,0xbfd802e509d67c67,4
+np.float64,0x3feeaa31513d5463,0x3ff6c52147dc053c,4
+np.float64,0xf2f6dfd3e5edc,0xf2f6dfd3e5edc,4
+np.float64,0x7fd58d8279ab1b04,0x403243f23d02af2a,4
+np.float64,0x8000000000000001,0x8000000000000001,4
+np.float64,0x3fdffb8e0ebff71c,0x3fe1786cb0a6b0f3,4
+np.float64,0xc999826b93331,0xc999826b93331,4
+np.float64,0xffc4966f19292ce0,0x3ff0836c75c56cc7,4
+np.float64,0x7fef95a4b2ff2b48,0xbfbbe2c27c78154f,4
+np.float64,0xb8f1307f71e26,0xb8f1307f71e26,4
+np.float64,0x3fe807bc7eb00f79,0x3fedde19f2d3c42d,4
+np.float64,0x5e4b6580bc98,0x5e4b6580bc98,4
+np.float64,0xffe19353576326a6,0xc0278c51fee07d36,4
+np.float64,0xbfb0ca6f3e2194e0,0xbfb0d09be673fa72,4
+np.float64,0x3fea724211b4e484,0x3ff15ee06f0a0a13,4
+np.float64,0xbfda21e1c4b443c4,0xbfdbb041f3c86832,4
+np.float64,0x8008082b24901057,0x8008082b24901057,4
+np.float64,0xbfd031aa4ea06354,0xbfd08c77729634bb,4
+np.float64,0xbfc407e153280fc4,0xbfc432275711df5f,4
+np.float64,0xbb4fa4b5769f5,0xbb4fa4b5769f5,4
+np.float64,0x7fed6d1daffada3a,0xc037a14bc7b41fab,4
+np.float64,0xffeee589943dcb12,0x3ff2abfe47037778,4
+np.float64,0x301379d260270,0x301379d260270,4
+np.float64,0xbfec2fefc2b85fe0,0xbff36362c0363e06,4
+np.float64,0xbfe0b1c82e216390,0xbfe264f503f7c22c,4
+np.float64,0xbfea2bce78f4579d,0xbff112d6f07935ea,4
+np.float64,0x18508ef230a13,0x18508ef230a13,4
+np.float64,0x800667a74d6ccf4f,0x800667a74d6ccf4f,4
+np.float64,0x79ce5c8cf39cc,0x79ce5c8cf39cc,4
+np.float64,0x3feda61c8efb4c39,0x3ff54c9ade076f54,4
+np.float64,0x3fe27e06b0e4fc0d,0x3fe4de665c1dc3ca,4
+np.float64,0xbfd15fea2722bfd4,0xbfd1d081c55813b0,4
+np.float64,0xbfe5222c4cea4458,0xbfe8db62deb7d2ad,4
+np.float64,0xbfe8a16c33b142d8,0xbfef02d5831592a8,4
+np.float64,0x3fdb60e7c4b6c1d0,0x3fdd2e4265c4c3b6,4
+np.float64,0x800076d62b60edad,0x800076d62b60edad,4
+np.float64,0xbfec8f1527791e2a,0xbff3da7ed3641e8d,4
+np.float64,0x2af03bfe55e08,0x2af03bfe55e08,4
+np.float64,0xa862ee0950c5e,0xa862ee0950c5e,4
+np.float64,0x7fea5a7c1eb4b4f7,0xbffa6f07d28ef211,4
+np.float64,0x90e118fb21c23,0x90e118fb21c23,4
+np.float64,0xbfead0721bf5a0e4,0xbff1c6c7a771a128,4
+np.float64,0x3f63f4a4c027e94a,0x3f63f4a75665da67,4
+np.float64,0x3fece0efa579c1e0,0x3ff443bec52f021e,4
+np.float64,0xbfdbe743b737ce88,0xbfddd129bff89c15,4
+np.float64,0x3fd48c9b8fa91938,0x3fd5492a630a8cb5,4
+np.float64,0x3ff0000000000000,0x3ff8eb245cbee3a6,4
+np.float64,0xbfd51ea33baa3d46,0xbfd5ebd5dc710204,4
+np.float64,0x3fcfbab0183f7560,0x3fd032a054580b00,4
+np.float64,0x8007abce13cf579d,0x8007abce13cf579d,4
+np.float64,0xbfef0f4723be1e8e,0xbff760c7008e8913,4
+np.float64,0x8006340f524c681f,0x8006340f524c681f,4
+np.float64,0x87b7d7010f71,0x87b7d7010f71,4
+np.float64,0x3fe9422da9b2845b,0x3ff02052e6148c45,4
+np.float64,0x7fddd259b93ba4b2,0xc000731aa33d84b6,4
+np.float64,0x3fe0156d12202ada,0x3fe1972ba309cb29,4
+np.float64,0x8004f1264b89e24d,0x8004f1264b89e24d,4
+np.float64,0x3fececdcacb9d9b9,0x3ff4534d5861f731,4
+np.float64,0x3fd1790ab822f215,0x3fd1eb97b1bb6fb4,4
+np.float64,0xffce5d11863cba24,0xbfcb4f38c17210da,4
+np.float64,0x800a30c32a546187,0x800a30c32a546187,4
+np.float64,0x3fa58cc61c2b198c,0x3fa59008add7233e,4
+np.float64,0xbfe0ac77d62158f0,0xbfe25de3dba0bc4a,4
+np.float64,0xeb8c5753d718b,0xeb8c5753d718b,4
+np.float64,0x3fee5438dafca872,0x3ff644fef7e7adb5,4
+np.float64,0x3faad1eb2c35a3e0,0x3faad83499f94057,4
+np.float64,0x3fe39152c46722a6,0x3fe66fba0b96ab6e,4
+np.float64,0xffd6fd17712dfa2e,0xc010d697d1ab8731,4
+np.float64,0x5214a888a4296,0x5214a888a4296,4
+np.float64,0x8000127a5da024f5,0x8000127a5da024f5,4
+np.float64,0x7feb3a366cb6746c,0x3fbe49bd8d5f213a,4
+np.float64,0xca479501948f3,0xca479501948f3,4
+np.float64,0x7fe7c799ce6f8f33,0xbfd796cd98dc620c,4
+np.float64,0xffe20bcf30a4179e,0xbff8ca5453fa088f,4
+np.float64,0x3fe624638a6c48c7,0x3fea83f123832c3c,4
+np.float64,0xbfe5f1377c6be26f,0xbfea2e143a2d522c,4
+np.float64,0x7fd193f9f8a327f3,0xbfb04ee2602574d4,4
+np.float64,0xbfe7419d2fee833a,0xbfec737f140d363d,4
+np.float64,0x1,0x1,4
+np.float64,0x7fe2ac246c655848,0x3fd14fee3237727a,4
+np.float64,0xa459b42948b37,0xa459b42948b37,4
+np.float64,0x3fb26155ae24c2ab,0x3fb2696fc446d4c6,4
+np.float64,0xbfdd7b332e3af666,0xbfdfc296c21f1aa8,4
+np.float64,0xbfe00dbda4a01b7c,0xbfe18d2b060f0506,4
+np.float64,0x8003bb22d3e77646,0x8003bb22d3e77646,4
+np.float64,0x3fee21b0a57c4361,0x3ff5fb6a21dc911c,4
+np.float64,0x80ca69270194d,0x80ca69270194d,4
+np.float64,0xbfd6d80350adb006,0xbfd7ddb501edbde0,4
+np.float64,0xd2f8b801a5f2,0xd2f8b801a5f2,4
+np.float64,0xbfe856b3f170ad68,0xbfee7334fdc49296,4
+np.float64,0x3fed5c1b20bab836,0x3ff4e73ee5d5c7f3,4
+np.float64,0xbfd58085a5ab010c,0xbfd6596ddc381ffa,4
+np.float64,0x3fe4f0134b29e027,0x3fe88b70602fbd21,4
+np.float64,0xffc9098fdc321320,0x4011c334a74a92cf,4
+np.float64,0x794749bef28ea,0x794749bef28ea,4
+np.float64,0xbfc86b547f30d6a8,0xbfc8b84a4fafe0af,4
+np.float64,0x7fe1356b9da26ad6,0x3fd270bca208d899,4
+np.float64,0x7fca0ef1aa341de2,0xbff851044c0734fa,4
+np.float64,0x80064cb8b62c9972,0x80064cb8b62c9972,4
+np.float64,0xffd3a09a83a74136,0x3ffb66dae0accdf5,4
+np.float64,0x800e301aa15c6035,0x800e301aa15c6035,4
+np.float64,0x800e51f323bca3e6,0x800e51f323bca3e6,4
+np.float64,0x7ff0000000000000,0xfff8000000000000,4
+np.float64,0x800c4278c87884f2,0x800c4278c87884f2,4
+np.float64,0xbfe8481649f0902c,0xbfee576772695096,4
+np.float64,0xffe2344e3fa4689c,0x3fb10442ec0888de,4
+np.float64,0xbfeada313d75b462,0xbff1d1aee3fab3a9,4
+np.float64,0x8009ddfb1333bbf7,0x8009ddfb1333bbf7,4
+np.float64,0x7fed3314c93a6629,0x3ff7a9b12dc1cd37,4
+np.float64,0x3fd55c26da2ab84e,0x3fd630a7b8aac78a,4
+np.float64,0x800cdb5203f9b6a4,0x800cdb5203f9b6a4,4
+np.float64,0xffd04a875da0950e,0x4009a13810ab121d,4
+np.float64,0x800f1acb527e3597,0x800f1acb527e3597,4
+np.float64,0xbf9519bf282a3380,0xbf951a82e9b955ff,4
+np.float64,0x3fcd7a42fa3af486,0x3fce028f3c51072d,4
+np.float64,0xbfdd3e21b73a7c44,0xbfdf769f2ff2480b,4
+np.float64,0xffd4361e2aa86c3c,0xbfc211ce8e9f792c,4
+np.float64,0x7fccf97f6939f2fe,0xbff8464bad830f06,4
+np.float64,0x800ce47fb939c900,0x800ce47fb939c900,4
+np.float64,0xffe9e51df173ca3b,0xbfceaf990d652c4e,4
+np.float64,0x3fe05bba5b20b775,0x3fe1f326e4455442,4
+np.float64,0x800a29b4b134536a,0x800a29b4b134536a,4
+np.float64,0xe6f794b7cdef3,0xe6f794b7cdef3,4
+np.float64,0xffb5b688ce2b6d10,0x3ff924bb97ae2f6d,4
+np.float64,0x7fa74105d82e820b,0x3fd49643aaa9eee4,4
+np.float64,0x80020d15f7a41a2d,0x80020d15f7a41a2d,4
+np.float64,0x3fd6a983d5ad5308,0x3fd7a8cc8835b5b8,4
+np.float64,0x7fcd9798f03b2f31,0x3fc534c2f7bf4721,4
+np.float64,0xffdd31873a3a630e,0xbfe3171fcdffb3f7,4
+np.float64,0x80075183234ea307,0x80075183234ea307,4
+np.float64,0x82f3132505e63,0x82f3132505e63,4
+np.float64,0x3febfd9cb837fb39,0x3ff325bbf812515d,4
+np.float64,0xbfb4630fda28c620,0xbfb46e1f802ec278,4
+np.float64,0x3feeed7c89fddafa,0x3ff72c20ce5a9ee4,4
+np.float64,0x7fd3dcb3c127b967,0x40123d27ec9ec31d,4
+np.float64,0xbfe923450c72468a,0xbff00149c5742725,4
+np.float64,0x7fdef7f91abdeff1,0xbfe02ceb21f7923d,4
+np.float64,0x7fdd70d28fbae1a4,0xbfefcc5c9d10cdfd,4
+np.float64,0x800ca445a8d9488c,0x800ca445a8d9488c,4
+np.float64,0x7fec2754e1f84ea9,0x40173f6c1c97f825,4
+np.float64,0x7fcbca31f7379463,0x401e26bd2667075b,4
+np.float64,0x8003fa1d0847f43b,0x8003fa1d0847f43b,4
+np.float64,0xffe95cf85932b9f0,0xc01308e60278aa11,4
+np.float64,0x8009c53948f38a73,0x8009c53948f38a73,4
+np.float64,0x3fdcca9226b99524,0x3fdee7a008f75d41,4
+np.float64,0xbfe9ee241f33dc48,0xbff0d16bfff6c8e9,4
+np.float64,0xbfb3365058266ca0,0xbfb33f9176ebb51d,4
+np.float64,0x7fa98e10f4331c21,0x3fdee04ffd31314e,4
+np.float64,0xbfe1a11aea634236,0xbfe3a8e3d84fda38,4
+np.float64,0xbfd8df051131be0a,0xbfda342805d1948b,4
+np.float64,0x3d49a2407a935,0x3d49a2407a935,4
+np.float64,0xfc51eefff8a3e,0xfc51eefff8a3e,4
+np.float64,0xda63950bb4c73,0xda63950bb4c73,4
+np.float64,0x80050f3d4fea1e7b,0x80050f3d4fea1e7b,4
+np.float64,0x3fcdbd6e453b7ae0,0x3fce497478c28e77,4
+np.float64,0x7ebd4932fd7aa,0x7ebd4932fd7aa,4
+np.float64,0x7fa3904eac27209c,0xc0015f3125efc151,4
+np.float64,0x7fc59f956b2b3f2a,0xc00c012e7a2c281f,4
+np.float64,0xbfd436d716a86dae,0xbfd4ea13533a942b,4
+np.float64,0x9347ae3d268f6,0x9347ae3d268f6,4
+np.float64,0xffd001764d2002ec,0xbffab3462e515623,4
+np.float64,0x3fe6f406662de80d,0x3febe9bac3954999,4
+np.float64,0x3f943ecaf8287d96,0x3f943f77dee5e77f,4
+np.float64,0x3fd6250efcac4a1c,0x3fd712afa947d56f,4
+np.float64,0xbfe849ff777093ff,0xbfee5b089d03391f,4
+np.float64,0xffd3b8ef8f2771e0,0x4000463ff7f29214,4
+np.float64,0xbfc3bae9252775d4,0xbfc3e34c133f1933,4
+np.float64,0xbfea93943df52728,0xbff18355e4fc341d,4
+np.float64,0x3fc4d922ad29b245,0x3fc508d66869ef29,4
+np.float64,0x4329694a8652e,0x4329694a8652e,4
+np.float64,0x8834f1a71069e,0x8834f1a71069e,4
+np.float64,0xe0e5be8dc1cb8,0xe0e5be8dc1cb8,4
+np.float64,0x7fef4d103afe9a1f,0xc0047b88b94554fe,4
+np.float64,0x3fe9b57af4f36af6,0x3ff0963831d51c3f,4
+np.float64,0x3fe081e2fa6103c6,0x3fe22572e41be655,4
+np.float64,0x3fd78cf7b42f19ef,0x3fd8acafa1ad776a,4
+np.float64,0x7fbffd58d43ffab1,0x3fb16092c7de6036,4
+np.float64,0xbfe1e8bfae23d180,0xbfe40c1c6277dd52,4
+np.float64,0x800a9f59fb153eb4,0x800a9f59fb153eb4,4
+np.float64,0xffebe14e33b7c29c,0x3fe0ec532f4deedd,4
+np.float64,0xffc36ca00426d940,0xc000806a712d6e83,4
+np.float64,0xbfcc2be82d3857d0,0xbfcca2a7d372ec64,4
+np.float64,0x800c03b908780772,0x800c03b908780772,4
+np.float64,0xf315a64be62b5,0xf315a64be62b5,4
+np.float64,0xbfe644043cec8808,0xbfeab974d3dc6d80,4
+np.float64,0x3fedb7de3cbb6fbc,0x3ff56549a5acd324,4
+np.float64,0xbfb1a875522350e8,0xbfb1afa41dee338d,4
+np.float64,0xffee8d4a407d1a94,0x3fead1749a636ff6,4
+np.float64,0x8004061c13080c39,0x8004061c13080c39,4
+np.float64,0x3fe650ae7feca15c,0x3feacefb8bc25f64,4
+np.float64,0x3fda8340e6b50682,0x3fdc24275cab1df8,4
+np.float64,0x8009084344321087,0x8009084344321087,4
+np.float64,0x7fdd19cb823a3396,0xbfd1d8fb35d89e3f,4
+np.float64,0xbfe893172571262e,0xbfeee716b592b93c,4
+np.float64,0x8ff5acc11fec,0x8ff5acc11fec,4
+np.float64,0xbfdca0c57cb9418a,0xbfdeb42465a1b59e,4
+np.float64,0xffd77bd2a3aef7a6,0x4012cd69e85b82d8,4
+np.float64,0xbfe6ea78982dd4f1,0xbfebd8ec61fb9e1f,4
+np.float64,0x7fe14b1d80a2963a,0xc02241642102cf71,4
+np.float64,0x3fe712bf286e257e,0x3fec20012329a7fb,4
+np.float64,0x7fcb6fa4d636df49,0x400b899d14a886b3,4
+np.float64,0x3fb82cb39a305960,0x3fb83f29c5f0822e,4
+np.float64,0x7fed694c8b3ad298,0xbfe2724373c69808,4
+np.float64,0xbfcd21229f3a4244,0xbfcda497fc3e1245,4
+np.float64,0x564d3770ac9a8,0x564d3770ac9a8,4
+np.float64,0xf4409e13e8814,0xf4409e13e8814,4
+np.float64,0x80068dca9a8d1b96,0x80068dca9a8d1b96,4
+np.float64,0xbfe13f82afe27f06,0xbfe3236ddded353f,4
+np.float64,0x80023f8114647f03,0x80023f8114647f03,4
+np.float64,0xeafba7dfd5f75,0xeafba7dfd5f75,4
+np.float64,0x3feca74ddeb94e9c,0x3ff3f95dcce5a227,4
+np.float64,0x10000000000000,0x10000000000000,4
+np.float64,0xbfebdb4141f7b682,0xbff2fc29823ac64a,4
+np.float64,0xbfcd75ee2f3aebdc,0xbfcdfdfd87cc6a29,4
+np.float64,0x7fc010cda420219a,0x3fae4ca2cf1f2657,4
+np.float64,0x1a90209e35205,0x1a90209e35205,4
+np.float64,0x8008057d01900afa,0x8008057d01900afa,4
+np.float64,0x3f9cb5f280396be5,0x3f9cb7dfb4e4be4e,4
+np.float64,0xffe1bbb60b63776c,0xc00011b1ffcb2561,4
+np.float64,0xffda883f6fb5107e,0x4044238ef4e2a198,4
+np.float64,0x3fc07c0b4a20f817,0x3fc09387de9eebcf,4
+np.float64,0x8003a9ebc0c753d8,0x8003a9ebc0c753d8,4
+np.float64,0x1d7fd5923affc,0x1d7fd5923affc,4
+np.float64,0xbfe9cd8cf9b39b1a,0xbff0af43e567ba4a,4
+np.float64,0x11285cb42250c,0x11285cb42250c,4
+np.float64,0xffe81ae1ccb035c3,0xbfe038be7eb563a6,4
+np.float64,0xbfe56473b1eac8e8,0xbfe94654d8ab9e75,4
+np.float64,0x3fee904619fd208c,0x3ff69e198152fe17,4
+np.float64,0xbfeeb9a2cbfd7346,0xbff6dc8d96da78cd,4
+np.float64,0x8006cdfa59ed9bf5,0x8006cdfa59ed9bf5,4
+np.float64,0x8008f2366d31e46d,0x8008f2366d31e46d,4
+np.float64,0x8008d5f91e31abf3,0x8008d5f91e31abf3,4
+np.float64,0x3fe85886f8b0b10e,0x3fee76af16f5a126,4
+np.float64,0x3fefb9b2b73f7365,0x3ff8745128fa3e3b,4
+np.float64,0x7fdf3e721f3e7ce3,0xbfb19381541ca2a8,4
+np.float64,0x3fd2768c41a4ed18,0x3fd2fe2f85a3f3a6,4
+np.float64,0xbfcabe3c6a357c78,0xbfcb239fb88bc260,4
+np.float64,0xffdffb6a3dbff6d4,0xbff7af4759fd557c,4
+np.float64,0x800817f75f302fef,0x800817f75f302fef,4
+np.float64,0xbfe6a1d1762d43a3,0xbfeb5a399a095ef3,4
+np.float64,0x7fd6f32f912de65e,0x40016dedc51aabd0,4
+np.float64,0x3fc6cb26652d964d,0x3fc7099f047d924a,4
+np.float64,0x3fe8b975d67172ec,0x3fef31946123c0e7,4
+np.float64,0xffe44a09d1e89413,0x3fdee9e5eac6e540,4
+np.float64,0xbfece76d4cb9cedb,0xbff44c34849d07ba,4
+np.float64,0x7feb76027036ec04,0x3fe08595a5e263ac,4
+np.float64,0xffe194f591a329ea,0x3fbe5bd626400a70,4
+np.float64,0xbfc170698122e0d4,0xbfc18c3de8b63565,4
+np.float64,0x3fc82b2c0f305658,0x3fc875c3b5fbcd08,4
+np.float64,0x3fd5015634aa02ac,0x3fd5cb1df07213c3,4
+np.float64,0x7fe640884b6c8110,0xbff66255a420abb5,4
+np.float64,0x5a245206b448b,0x5a245206b448b,4
+np.float64,0xffe9d9fa2f73b3f4,0xc0272b0dd34ab9bf,4
+np.float64,0x3fd990e8aab321d0,0x3fdb04cd3a29bcc3,4
+np.float64,0xde9dda8bbd3bc,0xde9dda8bbd3bc,4
+np.float64,0xbfe81b32b4703666,0xbfee029937fa9f5a,4
+np.float64,0xbfe68116886d022d,0xbfeb21c62081cb73,4
+np.float64,0x3fb8da191231b432,0x3fb8ee28c71507d3,4
+np.float64,0x3fb111395a222273,0x3fb117b57de3dea4,4
+np.float64,0xffbafadc6a35f5b8,0x3ffcc6d2370297b9,4
+np.float64,0x8002ca475b05948f,0x8002ca475b05948f,4
+np.float64,0xbfeafef57875fdeb,0xbff1fb1315676f24,4
+np.float64,0x7fcda427d73b484f,0xbff9f70212694d17,4
+np.float64,0xffe2517b3ba4a2f6,0xc029ca6707305bf4,4
+np.float64,0x7fc5ee156b2bdc2a,0xbff8384b59e9056e,4
+np.float64,0xbfec22af3278455e,0xbff3530fe25816b4,4
+np.float64,0x6b5a8c2cd6b52,0x6b5a8c2cd6b52,4
+np.float64,0xffdaf6c4b935ed8a,0x4002f00ce58affcf,4
+np.float64,0x800a41813c748303,0x800a41813c748303,4
+np.float64,0xbfd09a1269213424,0xbfd0fc0a0c5de8eb,4
+np.float64,0x7fa2cb74d42596e9,0x3fc3d40e000fa69d,4
+np.float64,0x7ff8000000000000,0x7ff8000000000000,4
+np.float64,0x3fbfbf8ed63f7f1e,0x3fbfe97bcad9f53a,4
+np.float64,0x7fe0ebba65a1d774,0x401b0f17b28618df,4
+np.float64,0x3fd02c3a25a05874,0x3fd086aa55b19c9c,4
+np.float64,0xec628f95d8c52,0xec628f95d8c52,4
+np.float64,0x3fd319329fa63264,0x3fd3afb04e0dec63,4
+np.float64,0x180e0ade301c2,0x180e0ade301c2,4
+np.float64,0xbfe8d78324f1af06,0xbfef6c66153064ee,4
+np.float64,0xffb89fa200313f48,0xbfeb96ff2d9358dc,4
+np.float64,0x7fe6abcf86ed579e,0xc0269f4de86365ec,4
+np.float64,0x7fdff8cd65bff19a,0xbfd0f7c6b9052c9a,4
+np.float64,0xbfd2e3a53d25c74a,0xbfd37520cda5f6b2,4
+np.float64,0x7fe844b096708960,0x3ff696a6182e5a7a,4
+np.float64,0x7fdce0c7a3b9c18e,0x3fd42875d69ed379,4
+np.float64,0xffba5a91cc34b520,0x4001b571e8991951,4
+np.float64,0xffe78fe4a6ef1fc9,0x3ff4507b31f5b3bc,4
+np.float64,0xbfd7047493ae08ea,0xbfd810618a53fffb,4
+np.float64,0xc6559def8cab4,0xc6559def8cab4,4
+np.float64,0x3fe75d67a76ebacf,0x3feca56817de65e4,4
+np.float64,0xffd24adbd6a495b8,0xc012c491addf2df5,4
+np.float64,0x7fed35e28dba6bc4,0x403a0fa555ff7ec6,4
+np.float64,0x80078c4afa0f1897,0x80078c4afa0f1897,4
+np.float64,0xa6ec39114dd87,0xa6ec39114dd87,4
+np.float64,0x7fb1bd33ba237a66,0x4010092bb6810fd4,4
+np.float64,0x800ecf215edd9e43,0x800ecf215edd9e43,4
+np.float64,0x3fb7c169242f82d2,0x3fb7d2ed30c462e6,4
+np.float64,0xbf71b46d60236900,0xbf71b4749a10c112,4
+np.float64,0x800d7851787af0a3,0x800d7851787af0a3,4
+np.float64,0x3fcb4a45e7369488,0x3fcbb61701a1bcec,4
+np.float64,0x3fd4e3682429c6d0,0x3fd5a9bcb916eb94,4
+np.float64,0x800497564c292ead,0x800497564c292ead,4
+np.float64,0xbfca3737a1346e70,0xbfca96a86ae5d687,4
+np.float64,0x19aa87e03356,0x19aa87e03356,4
+np.float64,0xffb2593fe624b280,0xc05fedb99b467ced,4
+np.float64,0xbfdd8748fbbb0e92,0xbfdfd1a7df17252c,4
+np.float64,0x8004c7afc7098f60,0x8004c7afc7098f60,4
+np.float64,0x7fde48b2bf3c9164,0xbfe36ef1158ed420,4
+np.float64,0xbfec8e0eb0f91c1d,0xbff3d9319705a602,4
+np.float64,0xffea1be204f437c3,0xc0144f67298c3e6f,4
+np.float64,0x7fdb906b593720d6,0xbfce99233396eda7,4
+np.float64,0x3fef0f114ffe1e22,0x3ff76072a258a51b,4
+np.float64,0x3fe3e284c8e7c50a,0x3fe6e9b05e17c999,4
+np.float64,0xbfbda9eef23b53e0,0xbfbdcc1abb443597,4
+np.float64,0x3feb6454d4f6c8aa,0x3ff26f65a85baba4,4
+np.float64,0x3fea317439f462e8,0x3ff118e2187ef33f,4
+np.float64,0x376ad0646ed5b,0x376ad0646ed5b,4
+np.float64,0x7fdd461a1c3a8c33,0x3f7ba20fb79e785f,4
+np.float64,0xebc520a3d78a4,0xebc520a3d78a4,4
+np.float64,0x3fca90fe53352200,0x3fcaf45c7fae234d,4
+np.float64,0xbfe80dd1de701ba4,0xbfede97e12cde9de,4
+np.float64,0x3fd242b00ea48560,0x3fd2c5cf9bf69a31,4
+np.float64,0x7fe46c057828d80a,0xbfe2f76837488f94,4
+np.float64,0x3fc162bea322c580,0x3fc17e517c958867,4
+np.float64,0xffebf0452ff7e08a,0x3ffc3fd95c257b54,4
+np.float64,0xffd88043c6310088,0x4008b05598d0d95f,4
+np.float64,0x800d8c49da5b1894,0x800d8c49da5b1894,4
+np.float64,0xbfed33b487ba6769,0xbff4b0ea941f8a6a,4
+np.float64,0x16b881e22d711,0x16b881e22d711,4
+np.float64,0x288bae0051177,0x288bae0051177,4
+np.float64,0xffc83a0fe8307420,0x4006eff03da17f86,4
+np.float64,0x3fc7868b252f0d18,0x3fc7cb4954290324,4
+np.float64,0xbfe195514b232aa2,0xbfe398aae6c8ed76,4
+np.float64,0x800c001ae7f80036,0x800c001ae7f80036,4
+np.float64,0x7feb82abe7370557,0xbff1e13fe6fad23c,4
+np.float64,0xffecf609cdf9ec13,0xc0112aa1805ae59e,4
+np.float64,0xffddd654f63bacaa,0x3fe46cce899f710d,4
+np.float64,0x3fe2163138642c62,0x3fe44b9c760acd4c,4
+np.float64,0x4e570dc09cae2,0x4e570dc09cae2,4
+np.float64,0x7fe9e8d091f3d1a0,0xc000fe20f8e9a4b5,4
+np.float64,0x7fe60042952c0084,0x3fd0aa740f394c2a,4
diff --git a/numpy/core/tests/data/umath-validation-set-tanh.csv b/numpy/core/tests/data/umath-validation-set-tanh.csv
new file mode 100644
index 000000000..9e3ddc60f
--- /dev/null
+++ b/numpy/core/tests/data/umath-validation-set-tanh.csv
@@ -0,0 +1,1429 @@
+dtype,input,output,ulperrortol
+np.float32,0xbe26ebb0,0xbe25752f,2
+np.float32,0xbe22ecc0,0xbe219054,2
+np.float32,0x8010a6b3,0x8010a6b3,2
+np.float32,0x3135da,0x3135da,2
+np.float32,0xbe982afc,0xbe93d727,2
+np.float32,0x16a51f,0x16a51f,2
+np.float32,0x491e56,0x491e56,2
+np.float32,0x4bf7ca,0x4bf7ca,2
+np.float32,0x3eebc21c,0x3edc65b2,2
+np.float32,0x80155c94,0x80155c94,2
+np.float32,0x3e14f626,0x3e13eb6a,2
+np.float32,0x801a238f,0x801a238f,2
+np.float32,0xbde33a80,0xbde24cf9,2
+np.float32,0xbef8439c,0xbee67a51,2
+np.float32,0x7f60d0a5,0x3f800000,2
+np.float32,0x190ee3,0x190ee3,2
+np.float32,0x80759113,0x80759113,2
+np.float32,0x800afa9f,0x800afa9f,2
+np.float32,0x7110cf,0x7110cf,2
+np.float32,0x3cf709f0,0x3cf6f6c6,2
+np.float32,0x3ef58da4,0x3ee44fa7,2
+np.float32,0xbf220ff2,0xbf0f662c,2
+np.float32,0xfd888078,0xbf800000,2
+np.float32,0xbe324734,0xbe307f9b,2
+np.float32,0x3eb5cb4f,0x3eae8560,2
+np.float32,0xbf7e7d02,0xbf425493,2
+np.float32,0x3ddcdcf0,0x3ddc02c2,2
+np.float32,0x8026d27a,0x8026d27a,2
+np.float32,0x3d4c0fb1,0x3d4be484,2
+np.float32,0xbf27d2c9,0xbf134d7c,2
+np.float32,0x8029ff80,0x8029ff80,2
+np.float32,0x7f046d2c,0x3f800000,2
+np.float32,0x13f94b,0x13f94b,2
+np.float32,0x7f4ff922,0x3f800000,2
+np.float32,0x3f4ea2ed,0x3f2b03e4,2
+np.float32,0x3e7211f0,0x3e6da8cf,2
+np.float32,0x7f39d0cf,0x3f800000,2
+np.float32,0xfee57fc6,0xbf800000,2
+np.float32,0xff6fb326,0xbf800000,2
+np.float32,0xff800000,0xbf800000,2
+np.float32,0x3f0437a4,0x3ef32fcd,2
+np.float32,0xff546d1e,0xbf800000,2
+np.float32,0x3eb5645b,0x3eae2a5c,2
+np.float32,0x3f08a6e5,0x3ef9ff8f,2
+np.float32,0x80800000,0x80800000,2
+np.float32,0x7f3413da,0x3f800000,2
+np.float32,0xfd760140,0xbf800000,2
+np.float32,0x7f3ad24a,0x3f800000,2
+np.float32,0xbf56e812,0xbf2f7f14,2
+np.float32,0xbece0338,0xbec3920a,2
+np.float32,0xbeede54a,0xbede22ae,2
+np.float32,0x7eaeb215,0x3f800000,2
+np.float32,0x3c213c00,0x3c213aab,2
+np.float32,0x7eaac217,0x3f800000,2
+np.float32,0xbf2f740e,0xbf1851a6,2
+np.float32,0x7f6ca5b8,0x3f800000,2
+np.float32,0xff42ce95,0xbf800000,2
+np.float32,0x802e4189,0x802e4189,2
+np.float32,0x80000001,0x80000001,2
+np.float32,0xbf31f298,0xbf19ebbe,2
+np.float32,0x3dcb0e6c,0x3dca64c1,2
+np.float32,0xbf29599c,0xbf145204,2
+np.float32,0x2e33f2,0x2e33f2,2
+np.float32,0x1c11e7,0x1c11e7,2
+np.float32,0x3f3b188d,0x3f1fa302,2
+np.float32,0x113300,0x113300,2
+np.float32,0x8054589e,0x8054589e,2
+np.float32,0x2a9e69,0x2a9e69,2
+np.float32,0xff513af7,0xbf800000,2
+np.float32,0x7f2e987a,0x3f800000,2
+np.float32,0x807cd426,0x807cd426,2
+np.float32,0x7f0dc4e4,0x3f800000,2
+np.float32,0x7e7c0d56,0x3f800000,2
+np.float32,0x5cb076,0x5cb076,2
+np.float32,0x80576426,0x80576426,2
+np.float32,0xff616222,0xbf800000,2
+np.float32,0xbf7accb5,0xbf40c005,2
+np.float32,0xfe4118c8,0xbf800000,2
+np.float32,0x804b9327,0x804b9327,2
+np.float32,0x3ed2b428,0x3ec79026,2
+np.float32,0x3f4a048f,0x3f286d41,2
+np.float32,0x800000,0x800000,2
+np.float32,0x7efceb9f,0x3f800000,2
+np.float32,0xbf5fe2d3,0xbf34246f,2
+np.float32,0x807e086a,0x807e086a,2
+np.float32,0x7ef5e856,0x3f800000,2
+np.float32,0xfc546f00,0xbf800000,2
+np.float32,0x3a65b890,0x3a65b88c,2
+np.float32,0x800cfa70,0x800cfa70,2
+np.float32,0x80672ea7,0x80672ea7,2
+np.float32,0x3f2bf3f2,0x3f160a12,2
+np.float32,0xbf0ab67e,0xbefd2004,2
+np.float32,0x3f2a0bb4,0x3f14c824,2
+np.float32,0xbeff5374,0xbeec12d7,2
+np.float32,0xbf221b58,0xbf0f6dff,2
+np.float32,0x7cc1f3,0x7cc1f3,2
+np.float32,0x7f234e3c,0x3f800000,2
+np.float32,0x3f60ff10,0x3f34b37d,2
+np.float32,0xbdd957f0,0xbdd887fe,2
+np.float32,0x801ce048,0x801ce048,2
+np.float32,0x7f3a8f76,0x3f800000,2
+np.float32,0xfdd13d08,0xbf800000,2
+np.float32,0x3e9af4a4,0x3e966445,2
+np.float32,0x1e55f3,0x1e55f3,2
+np.float32,0x327905,0x327905,2
+np.float32,0xbf03cf0b,0xbef28dad,2
+np.float32,0x3f0223d3,0x3eeff4f4,2
+np.float32,0xfdd96ff8,0xbf800000,2
+np.float32,0x428db8,0x428db8,2
+np.float32,0xbd74a200,0xbd7457a5,2
+np.float32,0x2a63a3,0x2a63a3,2
+np.float32,0x7e8aa9d7,0x3f800000,2
+np.float32,0x7f50b810,0x3f800000,2
+np.float32,0xbce5ec80,0xbce5dd0d,2
+np.float32,0x54711,0x54711,2
+np.float32,0x8074212a,0x8074212a,2
+np.float32,0xbf13d0ec,0xbf0551b5,2
+np.float32,0x80217f89,0x80217f89,2
+np.float32,0x3f300824,0x3f18b12f,2
+np.float32,0x7d252462,0x3f800000,2
+np.float32,0x807a154c,0x807a154c,2
+np.float32,0x8064d4b9,0x8064d4b9,2
+np.float32,0x804543b4,0x804543b4,2
+np.float32,0x4c269e,0x4c269e,2
+np.float32,0xff39823b,0xbf800000,2
+np.float32,0x3f5040b1,0x3f2be80b,2
+np.float32,0xbf7028c1,0xbf3bfee5,2
+np.float32,0x3e94eb78,0x3e90db93,2
+np.float32,0x3ccc1b40,0x3ccc1071,2
+np.float32,0xbe8796f0,0xbe8481a1,2
+np.float32,0xfc767bc0,0xbf800000,2
+np.float32,0xbdd81ed0,0xbdd75259,2
+np.float32,0xbed31bfc,0xbec7e82d,2
+np.float32,0xbf350a9e,0xbf1be1c6,2
+np.float32,0x33d41f,0x33d41f,2
+np.float32,0x3f73e076,0x3f3db0b5,2
+np.float32,0x3f800000,0x3f42f7d6,2
+np.float32,0xfee27c14,0xbf800000,2
+np.float32,0x7f6e4388,0x3f800000,2
+np.float32,0x4ea19b,0x4ea19b,2
+np.float32,0xff2d75f2,0xbf800000,2
+np.float32,0x7ee225ca,0x3f800000,2
+np.float32,0x3f31cb4b,0x3f19d2a4,2
+np.float32,0x80554a9d,0x80554a9d,2
+np.float32,0x3f4d57fa,0x3f2a4c03,2
+np.float32,0x3eac6a88,0x3ea62e72,2
+np.float32,0x773520,0x773520,2
+np.float32,0x8079c20a,0x8079c20a,2
+np.float32,0xfeb1eb94,0xbf800000,2
+np.float32,0xfe8d81c0,0xbf800000,2
+np.float32,0xfeed6902,0xbf800000,2
+np.float32,0x8066bb65,0x8066bb65,2
+np.float32,0x7f800000,0x3f800000,2
+np.float32,0x1,0x1,2
+np.float32,0x3f2c66a4,0x3f16554a,2
+np.float32,0x3cd231,0x3cd231,2
+np.float32,0x3e932a64,0x3e8f3e0c,2
+np.float32,0xbf3ab1c3,0xbf1f6420,2
+np.float32,0xbc902b20,0xbc902751,2
+np.float32,0x7dac0a5b,0x3f800000,2
+np.float32,0x3f2b7e06,0x3f15bc93,2
+np.float32,0x75de0,0x75de0,2
+np.float32,0x8020b7bc,0x8020b7bc,2
+np.float32,0x3f257cda,0x3f11bb6b,2
+np.float32,0x807480e5,0x807480e5,2
+np.float32,0xfe00d758,0xbf800000,2
+np.float32,0xbd9b54e0,0xbd9b08cd,2
+np.float32,0x4dfbe3,0x4dfbe3,2
+np.float32,0xff645788,0xbf800000,2
+np.float32,0xbe92c80a,0xbe8ee360,2
+np.float32,0x3eb9b400,0x3eb1f77c,2
+np.float32,0xff20b69c,0xbf800000,2
+np.float32,0x623c28,0x623c28,2
+np.float32,0xff235748,0xbf800000,2
+np.float32,0xbf3bbc56,0xbf2006f3,2
+np.float32,0x7e6f78b1,0x3f800000,2
+np.float32,0x7e1584e9,0x3f800000,2
+np.float32,0xff463423,0xbf800000,2
+np.float32,0x8002861e,0x8002861e,2
+np.float32,0xbf0491d8,0xbef3bb6a,2
+np.float32,0x7ea3bc17,0x3f800000,2
+np.float32,0xbedde7ea,0xbed0fb49,2
+np.float32,0xbf4bac48,0xbf295c8b,2
+np.float32,0xff28e276,0xbf800000,2
+np.float32,0x7e8f3bf5,0x3f800000,2
+np.float32,0xbf0a4a73,0xbefc7c9d,2
+np.float32,0x7ec5bd96,0x3f800000,2
+np.float32,0xbf4c22e8,0xbf299f2c,2
+np.float32,0x3e3970a0,0x3e377064,2
+np.float32,0x3ecb1118,0x3ec10c88,2
+np.float32,0xff548a7a,0xbf800000,2
+np.float32,0xfe8ec550,0xbf800000,2
+np.float32,0x3e158985,0x3e147bb2,2
+np.float32,0x7eb79ad7,0x3f800000,2
+np.float32,0xbe811384,0xbe7cd1ab,2
+np.float32,0xbdc4b9e8,0xbdc41f94,2
+np.float32,0xe0fd5,0xe0fd5,2
+np.float32,0x3f2485f2,0x3f11142b,2
+np.float32,0xfdd3c3d8,0xbf800000,2
+np.float32,0xfe8458e6,0xbf800000,2
+np.float32,0x3f06e398,0x3ef74dd8,2
+np.float32,0xff4752cf,0xbf800000,2
+np.float32,0x6998e3,0x6998e3,2
+np.float32,0x626751,0x626751,2
+np.float32,0x806631d6,0x806631d6,2
+np.float32,0xbf0c3cf4,0xbeff6c54,2
+np.float32,0x802860f8,0x802860f8,2
+np.float32,0xff2952cb,0xbf800000,2
+np.float32,0xff31d40b,0xbf800000,2
+np.float32,0x7c389473,0x3f800000,2
+np.float32,0x3dcd2f1b,0x3dcc8010,2
+np.float32,0x3d70c29f,0x3d707bbc,2
+np.float32,0x3f6bd386,0x3f39f979,2
+np.float32,0x1efec9,0x1efec9,2
+np.float32,0x3f675518,0x3f37d338,2
+np.float32,0x5fdbe3,0x5fdbe3,2
+np.float32,0x5d684e,0x5d684e,2
+np.float32,0xbedfe748,0xbed2a4c7,2
+np.float32,0x3f0cb07a,0x3f000cdc,2
+np.float32,0xbf77151e,0xbf3f1f5d,2
+np.float32,0x7f038ea0,0x3f800000,2
+np.float32,0x3ea91be9,0x3ea3376f,2
+np.float32,0xbdf20738,0xbdf0e861,2
+np.float32,0x807ea380,0x807ea380,2
+np.float32,0x2760ca,0x2760ca,2
+np.float32,0x7f20a544,0x3f800000,2
+np.float32,0x76ed83,0x76ed83,2
+np.float32,0x15a441,0x15a441,2
+np.float32,0x74c76d,0x74c76d,2
+np.float32,0xff3d5c2a,0xbf800000,2
+np.float32,0x7f6a76a6,0x3f800000,2
+np.float32,0x3eb87067,0x3eb0dabe,2
+np.float32,0xbf515cfa,0xbf2c83af,2
+np.float32,0xbdececc0,0xbdebdf9d,2
+np.float32,0x7f51b7c2,0x3f800000,2
+np.float32,0x3eb867ac,0x3eb0d30d,2
+np.float32,0xff50fd84,0xbf800000,2
+np.float32,0x806945e9,0x806945e9,2
+np.float32,0x298eed,0x298eed,2
+np.float32,0x441f53,0x441f53,2
+np.float32,0x8066d4b0,0x8066d4b0,2
+np.float32,0x3f6a479c,0x3f393dae,2
+np.float32,0xbf6ce2a7,0xbf3a7921,2
+np.float32,0x8064c3cf,0x8064c3cf,2
+np.float32,0xbf2d8146,0xbf170dfd,2
+np.float32,0x3b0e82,0x3b0e82,2
+np.float32,0xbea97574,0xbea387dc,2
+np.float32,0x67ad15,0x67ad15,2
+np.float32,0xbf68478f,0xbf38485a,2
+np.float32,0xff6f593b,0xbf800000,2
+np.float32,0xbeda26f2,0xbecdd806,2
+np.float32,0xbd216d50,0xbd2157ee,2
+np.float32,0x7a8544db,0x3f800000,2
+np.float32,0x801df20b,0x801df20b,2
+np.float32,0xbe14ba24,0xbe13b0a8,2
+np.float32,0xfdc6d8a8,0xbf800000,2
+np.float32,0x1d6b49,0x1d6b49,2
+np.float32,0x7f5ff1b8,0x3f800000,2
+np.float32,0x3f75e032,0x3f3e9625,2
+np.float32,0x7f2c5687,0x3f800000,2
+np.float32,0x3d95fb6c,0x3d95b6ee,2
+np.float32,0xbea515e4,0xbe9f97c8,2
+np.float32,0x7f2b2cd7,0x3f800000,2
+np.float32,0x3f076f7a,0x3ef8241e,2
+np.float32,0x5178ca,0x5178ca,2
+np.float32,0xbeb5976a,0xbeae5781,2
+np.float32,0x3e3c3563,0x3e3a1e13,2
+np.float32,0xbd208530,0xbd20702a,2
+np.float32,0x3eb03b04,0x3ea995ef,2
+np.float32,0x17fb9c,0x17fb9c,2
+np.float32,0xfca68e40,0xbf800000,2
+np.float32,0xbf5e7433,0xbf336a9f,2
+np.float32,0xff5b8d3d,0xbf800000,2
+np.float32,0x8003121d,0x8003121d,2
+np.float32,0xbe6dd344,0xbe69a3b0,2
+np.float32,0x67cc4,0x67cc4,2
+np.float32,0x9b01d,0x9b01d,2
+np.float32,0x127c13,0x127c13,2
+np.float32,0xfea5e3d6,0xbf800000,2
+np.float32,0xbdf5c610,0xbdf499c1,2
+np.float32,0x3aff4c00,0x3aff4beb,2
+np.float32,0x3b00afd0,0x3b00afc5,2
+np.float32,0x479618,0x479618,2
+np.float32,0x801cbd05,0x801cbd05,2
+np.float32,0x3ec9249f,0x3ebf6579,2
+np.float32,0x3535c4,0x3535c4,2
+np.float32,0xbeb4f662,0xbeadc915,2
+np.float32,0x8006fda6,0x8006fda6,2
+np.float32,0xbf4f3097,0xbf2b5239,2
+np.float32,0xbf3cb9a8,0xbf20a0e9,2
+np.float32,0x32ced0,0x32ced0,2
+np.float32,0x7ea34e76,0x3f800000,2
+np.float32,0x80063046,0x80063046,2
+np.float32,0x80727e8b,0x80727e8b,2
+np.float32,0xfd6b5780,0xbf800000,2
+np.float32,0x80109815,0x80109815,2
+np.float32,0xfdcc8a78,0xbf800000,2
+np.float32,0x81562,0x81562,2
+np.float32,0x803dfacc,0x803dfacc,2
+np.float32,0xbe204318,0xbe1ef75f,2
+np.float32,0xbf745d34,0xbf3de8e2,2
+np.float32,0xff13fdcc,0xbf800000,2
+np.float32,0x7f75ba8c,0x3f800000,2
+np.float32,0x806c04b4,0x806c04b4,2
+np.float32,0x3ec61ca6,0x3ebcc877,2
+np.float32,0xbeaea984,0xbea8301f,2
+np.float32,0xbf4dcd0e,0xbf2a8d34,2
+np.float32,0x802a01d3,0x802a01d3,2
+np.float32,0xbf747be5,0xbf3df6ad,2
+np.float32,0xbf75cbd2,0xbf3e8d0f,2
+np.float32,0x7db86576,0x3f800000,2
+np.float32,0xff49a2c3,0xbf800000,2
+np.float32,0xbedc5314,0xbecfa978,2
+np.float32,0x8078877b,0x8078877b,2
+np.float32,0xbead4824,0xbea6f499,2
+np.float32,0xbf3926e3,0xbf1e716c,2
+np.float32,0x807f4a1c,0x807f4a1c,2
+np.float32,0x7f2cd8fd,0x3f800000,2
+np.float32,0x806cfcca,0x806cfcca,2
+np.float32,0xff1aa048,0xbf800000,2
+np.float32,0x7eb9ea08,0x3f800000,2
+np.float32,0xbf1034bc,0xbf02ab3a,2
+np.float32,0xbd087830,0xbd086b44,2
+np.float32,0x7e071034,0x3f800000,2
+np.float32,0xbefcc9de,0xbeea122f,2
+np.float32,0x80796d7a,0x80796d7a,2
+np.float32,0x33ce46,0x33ce46,2
+np.float32,0x8074a783,0x8074a783,2
+np.float32,0xbe95a56a,0xbe918691,2
+np.float32,0xbf2ff3f4,0xbf18a42d,2
+np.float32,0x1633e9,0x1633e9,2
+np.float32,0x7f0f104b,0x3f800000,2
+np.float32,0xbf800000,0xbf42f7d6,2
+np.float32,0x3d2cd6,0x3d2cd6,2
+np.float32,0xfed43e16,0xbf800000,2
+np.float32,0x3ee6faec,0x3ed87d2c,2
+np.float32,0x3f2c32d0,0x3f163352,2
+np.float32,0xff4290c0,0xbf800000,2
+np.float32,0xbf66500e,0xbf37546a,2
+np.float32,0x7dfb8fe3,0x3f800000,2
+np.float32,0x3f20ba5d,0x3f0e7b16,2
+np.float32,0xff30c7ae,0xbf800000,2
+np.float32,0x1728a4,0x1728a4,2
+np.float32,0x340d82,0x340d82,2
+np.float32,0xff7870b7,0xbf800000,2
+np.float32,0xbeac6ac4,0xbea62ea7,2
+np.float32,0xbef936fc,0xbee73c36,2
+np.float32,0x3ec7e12c,0x3ebe4ef8,2
+np.float32,0x80673488,0x80673488,2
+np.float32,0xfdf14c90,0xbf800000,2
+np.float32,0x3f182568,0x3f08726e,2
+np.float32,0x7ed7dcd0,0x3f800000,2
+np.float32,0x3de4da34,0x3de3e790,2
+np.float32,0xff7fffff,0xbf800000,2
+np.float32,0x4ff90c,0x4ff90c,2
+np.float32,0x3efb0d1c,0x3ee8b1d6,2
+np.float32,0xbf66e952,0xbf379ef4,2
+np.float32,0xba9dc,0xba9dc,2
+np.float32,0xff67c766,0xbf800000,2
+np.float32,0x7f1ffc29,0x3f800000,2
+np.float32,0x3f51c906,0x3f2cbe99,2
+np.float32,0x3f2e5792,0x3f179968,2
+np.float32,0x3ecb9750,0x3ec17fa0,2
+np.float32,0x7f3fcefc,0x3f800000,2
+np.float32,0xbe4e30fc,0xbe4b72f9,2
+np.float32,0x7e9bc4ce,0x3f800000,2
+np.float32,0x7e70aa1f,0x3f800000,2
+np.float32,0x14c6e9,0x14c6e9,2
+np.float32,0xbcf327c0,0xbcf3157a,2
+np.float32,0xff1fd204,0xbf800000,2
+np.float32,0x7d934a03,0x3f800000,2
+np.float32,0x8028bf1e,0x8028bf1e,2
+np.float32,0x7f0800b7,0x3f800000,2
+np.float32,0xfe04825c,0xbf800000,2
+np.float32,0x807210ac,0x807210ac,2
+np.float32,0x3f7faf7c,0x3f42d5fd,2
+np.float32,0x3e04a543,0x3e03e899,2
+np.float32,0x3e98ea15,0x3e94863e,2
+np.float32,0x3d2a2e48,0x3d2a153b,2
+np.float32,0x7fa00000,0x7fe00000,2
+np.float32,0x20a488,0x20a488,2
+np.float32,0x3f6ba86a,0x3f39e51a,2
+np.float32,0x0,0x0,2
+np.float32,0x3e892ddd,0x3e85fcfe,2
+np.float32,0x3e2da627,0x3e2c00e0,2
+np.float32,0xff000a50,0xbf800000,2
+np.float32,0x3eb749f4,0x3eafd739,2
+np.float32,0x8024c0ae,0x8024c0ae,2
+np.float32,0xfc8f3b40,0xbf800000,2
+np.float32,0xbf685fc7,0xbf385405,2
+np.float32,0x3f1510e6,0x3f063a4f,2
+np.float32,0x3f68e8ad,0x3f3895d8,2
+np.float32,0x3dba8608,0x3dba0271,2
+np.float32,0xbf16ea10,0xbf079017,2
+np.float32,0xb3928,0xb3928,2
+np.float32,0xfe447c00,0xbf800000,2
+np.float32,0x3db9cd57,0x3db94b45,2
+np.float32,0x803b66b0,0x803b66b0,2
+np.float32,0x805b5e02,0x805b5e02,2
+np.float32,0x7ec93f61,0x3f800000,2
+np.float32,0x8005a126,0x8005a126,2
+np.float32,0x6d8888,0x6d8888,2
+np.float32,0x3e21b7de,0x3e206314,2
+np.float32,0xbec9c31e,0xbebfedc2,2
+np.float32,0xbea88aa8,0xbea2b4e5,2
+np.float32,0x3d8fc310,0x3d8f86bb,2
+np.float32,0xbf3cc68a,0xbf20a8b8,2
+np.float32,0x432690,0x432690,2
+np.float32,0xbe51d514,0xbe4ef1a3,2
+np.float32,0xbcda6d20,0xbcda5fe1,2
+np.float32,0xfe24e458,0xbf800000,2
+np.float32,0xfedc8c14,0xbf800000,2
+np.float32,0x7f7e9bd4,0x3f800000,2
+np.float32,0x3ebcc880,0x3eb4ab44,2
+np.float32,0xbe0aa490,0xbe09cd44,2
+np.float32,0x3dc9158c,0x3dc870c3,2
+np.float32,0x3e5c319e,0x3e58dc90,2
+np.float32,0x1d4527,0x1d4527,2
+np.float32,0x2dbf5,0x2dbf5,2
+np.float32,0xbf1f121f,0xbf0d5534,2
+np.float32,0x7e3e9ab5,0x3f800000,2
+np.float32,0x7f74b5c1,0x3f800000,2
+np.float32,0xbf6321ba,0xbf35c42b,2
+np.float32,0xbe5c7488,0xbe591c79,2
+np.float32,0x7e7b02cd,0x3f800000,2
+np.float32,0xfe7cbfa4,0xbf800000,2
+np.float32,0xbeace360,0xbea69a86,2
+np.float32,0x7e149b00,0x3f800000,2
+np.float32,0xbf61a700,0xbf35079a,2
+np.float32,0x7eb592a7,0x3f800000,2
+np.float32,0x3f2105e6,0x3f0eaf30,2
+np.float32,0xfd997a88,0xbf800000,2
+np.float32,0xff5d093b,0xbf800000,2
+np.float32,0x63aede,0x63aede,2
+np.float32,0x6907ee,0x6907ee,2
+np.float32,0xbf7578ee,0xbf3e680f,2
+np.float32,0xfea971e8,0xbf800000,2
+np.float32,0x3f21d0f5,0x3f0f3aed,2
+np.float32,0x3a50e2,0x3a50e2,2
+np.float32,0x7f0f5b1e,0x3f800000,2
+np.float32,0x805b9765,0x805b9765,2
+np.float32,0xbe764ab8,0xbe71a664,2
+np.float32,0x3eafac7f,0x3ea91701,2
+np.float32,0x807f4130,0x807f4130,2
+np.float32,0x7c5f31,0x7c5f31,2
+np.float32,0xbdbe0e30,0xbdbd8300,2
+np.float32,0x7ecfe4e0,0x3f800000,2
+np.float32,0xff7cb628,0xbf800000,2
+np.float32,0xff1842bc,0xbf800000,2
+np.float32,0xfd4163c0,0xbf800000,2
+np.float32,0x800e11f7,0x800e11f7,2
+np.float32,0x7f3adec8,0x3f800000,2
+np.float32,0x7f597514,0x3f800000,2
+np.float32,0xbe986e14,0xbe9414a4,2
+np.float32,0x800fa9d7,0x800fa9d7,2
+np.float32,0xff5b79c4,0xbf800000,2
+np.float32,0x80070565,0x80070565,2
+np.float32,0xbee5628e,0xbed72d60,2
+np.float32,0x3f438ef2,0x3f24b3ca,2
+np.float32,0xcda91,0xcda91,2
+np.float32,0x7e64151a,0x3f800000,2
+np.float32,0xbe95d584,0xbe91b2c7,2
+np.float32,0x8022c2a1,0x8022c2a1,2
+np.float32,0x7e7097bf,0x3f800000,2
+np.float32,0x80139035,0x80139035,2
+np.float32,0x804de2cb,0x804de2cb,2
+np.float32,0xfde5d178,0xbf800000,2
+np.float32,0x6d238,0x6d238,2
+np.float32,0x807abedc,0x807abedc,2
+np.float32,0x3f450a12,0x3f259129,2
+np.float32,0x3ef1c120,0x3ee141f2,2
+np.float32,0xfeb64dae,0xbf800000,2
+np.float32,0x8001732c,0x8001732c,2
+np.float32,0x3f76062e,0x3f3ea711,2
+np.float32,0x3eddd550,0x3ed0ebc8,2
+np.float32,0xff5ca1d4,0xbf800000,2
+np.float32,0xbf49dc5e,0xbf285673,2
+np.float32,0x7e9e5438,0x3f800000,2
+np.float32,0x7e83625e,0x3f800000,2
+np.float32,0x3f5dc41c,0x3f3310da,2
+np.float32,0x3f583efa,0x3f30342f,2
+np.float32,0xbe26bf88,0xbe254a2d,2
+np.float32,0xff1e0beb,0xbf800000,2
+np.float32,0xbe2244c8,0xbe20ec86,2
+np.float32,0xff0b1630,0xbf800000,2
+np.float32,0xff338dd6,0xbf800000,2
+np.float32,0x3eafc22c,0x3ea92a51,2
+np.float32,0x800ea07f,0x800ea07f,2
+np.float32,0x3f46f006,0x3f26aa7e,2
+np.float32,0x3e5f57cd,0x3e5bde16,2
+np.float32,0xbf1b2d8e,0xbf0a9a93,2
+np.float32,0xfeacdbe0,0xbf800000,2
+np.float32,0x7e5ea4bc,0x3f800000,2
+np.float32,0xbf51cbe2,0xbf2cc027,2
+np.float32,0x8073644c,0x8073644c,2
+np.float32,0xff2d6bfe,0xbf800000,2
+np.float32,0x3f65f0f6,0x3f37260a,2
+np.float32,0xff4b37a6,0xbf800000,2
+np.float32,0x712df7,0x712df7,2
+np.float32,0x7f71ef17,0x3f800000,2
+np.float32,0x8042245c,0x8042245c,2
+np.float32,0x3e5dde7b,0x3e5a760d,2
+np.float32,0x8069317d,0x8069317d,2
+np.float32,0x807932dd,0x807932dd,2
+np.float32,0x802f847e,0x802f847e,2
+np.float32,0x7e9300,0x7e9300,2
+np.float32,0x8040b4ab,0x8040b4ab,2
+np.float32,0xff76ef8e,0xbf800000,2
+np.float32,0x4aae3a,0x4aae3a,2
+np.float32,0x8058de73,0x8058de73,2
+np.float32,0x7e4d58c0,0x3f800000,2
+np.float32,0x3d811b30,0x3d80ef79,2
+np.float32,0x7ec952cc,0x3f800000,2
+np.float32,0xfe162b1c,0xbf800000,2
+np.float32,0x3f0f1187,0x3f01d367,2
+np.float32,0xbf2f3458,0xbf182878,2
+np.float32,0x5ceb14,0x5ceb14,2
+np.float32,0xbec29476,0xbeb9b939,2
+np.float32,0x3e71f943,0x3e6d9176,2
+np.float32,0x3ededefc,0x3ed1c909,2
+np.float32,0x805df6ac,0x805df6ac,2
+np.float32,0x3e5ae2c8,0x3e579ca8,2
+np.float32,0x3f6ad2c3,0x3f397fdf,2
+np.float32,0x7d5f94d3,0x3f800000,2
+np.float32,0xbeec7fe4,0xbedd0037,2
+np.float32,0x3f645304,0x3f365b0d,2
+np.float32,0xbf69a087,0xbf38edef,2
+np.float32,0x8025102e,0x8025102e,2
+np.float32,0x800db486,0x800db486,2
+np.float32,0x4df6c7,0x4df6c7,2
+np.float32,0x806d8cdd,0x806d8cdd,2
+np.float32,0x7f0c78cc,0x3f800000,2
+np.float32,0x7e1cf70b,0x3f800000,2
+np.float32,0x3e0ae570,0x3e0a0cf7,2
+np.float32,0x80176ef8,0x80176ef8,2
+np.float32,0x3f38b60c,0x3f1e2bbb,2
+np.float32,0x3d3071e0,0x3d3055f5,2
+np.float32,0x3ebfcfdd,0x3eb750a9,2
+np.float32,0xfe2cdec0,0xbf800000,2
+np.float32,0x7eeb2eed,0x3f800000,2
+np.float32,0x8026c904,0x8026c904,2
+np.float32,0xbec79bde,0xbebe133a,2
+np.float32,0xbf7dfab6,0xbf421d47,2
+np.float32,0x805b3cfd,0x805b3cfd,2
+np.float32,0xfdfcfb68,0xbf800000,2
+np.float32,0xbd537ec0,0xbd534eaf,2
+np.float32,0x52ce73,0x52ce73,2
+np.float32,0xfeac6ea6,0xbf800000,2
+np.float32,0x3f2c2990,0x3f162d41,2
+np.float32,0x3e3354e0,0x3e318539,2
+np.float32,0x802db22b,0x802db22b,2
+np.float32,0x7f0faa83,0x3f800000,2
+np.float32,0x7f10e161,0x3f800000,2
+np.float32,0x7f165c60,0x3f800000,2
+np.float32,0xbf5a756f,0xbf315c82,2
+np.float32,0x7f5a4b68,0x3f800000,2
+np.float32,0xbd77fbf0,0xbd77ae7c,2
+np.float32,0x65d83c,0x65d83c,2
+np.float32,0x3e5f28,0x3e5f28,2
+np.float32,0x8040ec92,0x8040ec92,2
+np.float32,0xbf2b41a6,0xbf1594d5,2
+np.float32,0x7f2f88f1,0x3f800000,2
+np.float32,0xfdb64ab8,0xbf800000,2
+np.float32,0xbf7a3ff1,0xbf4082f5,2
+np.float32,0x1948fc,0x1948fc,2
+np.float32,0x802c1039,0x802c1039,2
+np.float32,0x80119274,0x80119274,2
+np.float32,0x7e885d7b,0x3f800000,2
+np.float32,0xfaf6a,0xfaf6a,2
+np.float32,0x3eba28c4,0x3eb25e1d,2
+np.float32,0x3e4df370,0x3e4b37da,2
+np.float32,0xbf19eff6,0xbf09b97d,2
+np.float32,0xbeddd3c6,0xbed0ea7f,2
+np.float32,0xff6fc971,0xbf800000,2
+np.float32,0x7e93de29,0x3f800000,2
+np.float32,0x3eb12332,0x3eaa6485,2
+np.float32,0x3eb7c6e4,0x3eb04563,2
+np.float32,0x4a67ee,0x4a67ee,2
+np.float32,0xff1cafde,0xbf800000,2
+np.float32,0x3f5e2812,0x3f3343da,2
+np.float32,0x3f060e04,0x3ef605d4,2
+np.float32,0x3e9027d8,0x3e8c76a6,2
+np.float32,0xe2d33,0xe2d33,2
+np.float32,0xff4c94fc,0xbf800000,2
+np.float32,0xbf574908,0xbf2fb26b,2
+np.float32,0xbf786c08,0xbf3fb68e,2
+np.float32,0x8011ecab,0x8011ecab,2
+np.float32,0xbf061c6a,0xbef61bfa,2
+np.float32,0x7eea5f9d,0x3f800000,2
+np.float32,0x3ea2e19c,0x3e9d99a5,2
+np.float32,0x8071550c,0x8071550c,2
+np.float32,0x41c70b,0x41c70b,2
+np.float32,0x80291fc8,0x80291fc8,2
+np.float32,0x43b1ec,0x43b1ec,2
+np.float32,0x32f5a,0x32f5a,2
+np.float32,0xbe9310ec,0xbe8f2692,2
+np.float32,0x7f75f6bf,0x3f800000,2
+np.float32,0x3e6642a6,0x3e6274d2,2
+np.float32,0x3ecb88e0,0x3ec1733f,2
+np.float32,0x804011b6,0x804011b6,2
+np.float32,0x80629cca,0x80629cca,2
+np.float32,0x8016b914,0x8016b914,2
+np.float32,0xbdd05fc0,0xbdcfa870,2
+np.float32,0x807b824d,0x807b824d,2
+np.float32,0xfeec2576,0xbf800000,2
+np.float32,0xbf54bf22,0xbf2e584c,2
+np.float32,0xbf185eb0,0xbf089b6b,2
+np.float32,0xfbc09480,0xbf800000,2
+np.float32,0x3f413054,0x3f234e25,2
+np.float32,0x7e9e32b8,0x3f800000,2
+np.float32,0x266296,0x266296,2
+np.float32,0x460284,0x460284,2
+np.float32,0x3eb0b056,0x3ea9fe5a,2
+np.float32,0x1a7be5,0x1a7be5,2
+np.float32,0x7f099895,0x3f800000,2
+np.float32,0x3f3614f0,0x3f1c88ef,2
+np.float32,0x7e757dc2,0x3f800000,2
+np.float32,0x801fc91e,0x801fc91e,2
+np.float32,0x3f5ce37d,0x3f329ddb,2
+np.float32,0x3e664d70,0x3e627f15,2
+np.float32,0xbf38ed78,0xbf1e4dfa,2
+np.float32,0xbf5c563d,0xbf325543,2
+np.float32,0xbe91cc54,0xbe8dfb24,2
+np.float32,0x3d767fbe,0x3d7633ac,2
+np.float32,0xbf6aeb40,0xbf398b7f,2
+np.float32,0x7f40508b,0x3f800000,2
+np.float32,0x2650df,0x2650df,2
+np.float32,0xbe8cea3c,0xbe897628,2
+np.float32,0x80515af8,0x80515af8,2
+np.float32,0x7f423986,0x3f800000,2
+np.float32,0xbdf250e8,0xbdf1310c,2
+np.float32,0xfe89288a,0xbf800000,2
+np.float32,0x397b3b,0x397b3b,2
+np.float32,0x7e5e91b0,0x3f800000,2
+np.float32,0x6866e2,0x6866e2,2
+np.float32,0x7f4d8877,0x3f800000,2
+np.float32,0x3e6c4a21,0x3e682ee3,2
+np.float32,0xfc3d5980,0xbf800000,2
+np.float32,0x7eae2cd0,0x3f800000,2
+np.float32,0xbf241222,0xbf10c579,2
+np.float32,0xfebc02de,0xbf800000,2
+np.float32,0xff6e0645,0xbf800000,2
+np.float32,0x802030b6,0x802030b6,2
+np.float32,0x7ef9a441,0x3f800000,2
+np.float32,0x3fcf9f,0x3fcf9f,2
+np.float32,0xbf0ccf13,0xbf0023cc,2
+np.float32,0xfefee688,0xbf800000,2
+np.float32,0xbf6c8e0c,0xbf3a5160,2
+np.float32,0xfe749c28,0xbf800000,2
+np.float32,0x7f7fffff,0x3f800000,2
+np.float32,0x58c1a0,0x58c1a0,2
+np.float32,0x3f2de0a1,0x3f174c17,2
+np.float32,0xbf5f7138,0xbf33eb03,2
+np.float32,0x3da15270,0x3da0fd3c,2
+np.float32,0x3da66560,0x3da607e4,2
+np.float32,0xbf306f9a,0xbf18f3c6,2
+np.float32,0x3e81a4de,0x3e7de293,2
+np.float32,0xbebb5fb8,0xbeb36f1a,2
+np.float32,0x14bf64,0x14bf64,2
+np.float32,0xbeac46c6,0xbea60e73,2
+np.float32,0xbdcdf210,0xbdcd4111,2
+np.float32,0x3f7e3cd9,0x3f42395e,2
+np.float32,0xbc4be640,0xbc4be38e,2
+np.float32,0xff5f53b4,0xbf800000,2
+np.float32,0xbf1315ae,0xbf04c90b,2
+np.float32,0x80000000,0x80000000,2
+np.float32,0xbf6a4149,0xbf393aaa,2
+np.float32,0x3f66b8ee,0x3f378772,2
+np.float32,0xff29293e,0xbf800000,2
+np.float32,0xbcc989c0,0xbcc97f58,2
+np.float32,0xbd9a1b70,0xbd99d125,2
+np.float32,0xfef353cc,0xbf800000,2
+np.float32,0xbdc30cf0,0xbdc27683,2
+np.float32,0xfdfd6768,0xbf800000,2
+np.float32,0x7ebac44c,0x3f800000,2
+np.float32,0xff453cd6,0xbf800000,2
+np.float32,0x3ef07720,0x3ee03787,2
+np.float32,0x80219c14,0x80219c14,2
+np.float32,0x805553a8,0x805553a8,2
+np.float32,0x80703928,0x80703928,2
+np.float32,0xff16d3a7,0xbf800000,2
+np.float32,0x3f1472bc,0x3f05c77b,2
+np.float32,0x3eeea37a,0x3edebcf9,2
+np.float32,0x3db801e6,0x3db7838d,2
+np.float32,0x800870d2,0x800870d2,2
+np.float32,0xbea1172c,0xbe9bfa32,2
+np.float32,0x3f1f5e7c,0x3f0d8a42,2
+np.float32,0x123cdb,0x123cdb,2
+np.float32,0x7f6e6b06,0x3f800000,2
+np.float32,0x3ed80573,0x3ecc0def,2
+np.float32,0xfea31b82,0xbf800000,2
+np.float32,0x6744e0,0x6744e0,2
+np.float32,0x695e8b,0x695e8b,2
+np.float32,0xbee3888a,0xbed5a67d,2
+np.float32,0x7f64bc2a,0x3f800000,2
+np.float32,0x7f204244,0x3f800000,2
+np.float32,0x7f647102,0x3f800000,2
+np.float32,0x3dd8ebc0,0x3dd81d03,2
+np.float32,0x801e7ab1,0x801e7ab1,2
+np.float32,0x7d034b56,0x3f800000,2
+np.float32,0x7fc00000,0x7fc00000,2
+np.float32,0x80194193,0x80194193,2
+np.float32,0xfe31c8d4,0xbf800000,2
+np.float32,0x7fc0c4,0x7fc0c4,2
+np.float32,0xd95bf,0xd95bf,2
+np.float32,0x7e4f991d,0x3f800000,2
+np.float32,0x7fc563,0x7fc563,2
+np.float32,0xbe3fcccc,0xbe3d968a,2
+np.float32,0xfdaaa1c8,0xbf800000,2
+np.float32,0xbf48e449,0xbf27c949,2
+np.float32,0x3eb6c584,0x3eaf625e,2
+np.float32,0xbea35a74,0xbe9e0702,2
+np.float32,0x3eeab47a,0x3edb89d5,2
+np.float32,0xbed99556,0xbecd5de5,2
+np.float64,0xbfb94a81e0329500,0xbfb935867ba761fe,2
+np.float64,0xbfec132f1678265e,0xbfe6900eb097abc3,2
+np.float64,0x5685ea72ad0be,0x5685ea72ad0be,2
+np.float64,0xbfd74d3169ae9a62,0xbfd652e09b9daf32,2
+np.float64,0xbfe28df53d651bea,0xbfe0b8a7f50ab433,2
+np.float64,0x0,0x0,2
+np.float64,0xbfed912738bb224e,0xbfe749e3732831ae,2
+np.float64,0x7fcc6faed838df5d,0x3ff0000000000000,2
+np.float64,0xbfe95fe9a432bfd3,0xbfe51f6349919910,2
+np.float64,0xbfc4d5900b29ab20,0xbfc4a6f496179b8b,2
+np.float64,0xbfcd6025033ac04c,0xbfccded7b34b49b0,2
+np.float64,0xbfdfa655b43f4cac,0xbfdd4ca1e5bb9db8,2
+np.float64,0xe7ea5c7fcfd4c,0xe7ea5c7fcfd4c,2
+np.float64,0xffa5449ca42a8940,0xbff0000000000000,2
+np.float64,0xffe63294c1ac6529,0xbff0000000000000,2
+np.float64,0x7feb9cbae7f73975,0x3ff0000000000000,2
+np.float64,0x800eb07c3e3d60f9,0x800eb07c3e3d60f9,2
+np.float64,0x3fc95777e932aef0,0x3fc9040391e20c00,2
+np.float64,0x800736052dee6c0b,0x800736052dee6c0b,2
+np.float64,0x3fe9ae4afd335c96,0x3fe54b569bab45c7,2
+np.float64,0x7fee4c94217c9927,0x3ff0000000000000,2
+np.float64,0x80094b594bd296b3,0x80094b594bd296b3,2
+np.float64,0xffe5adbcee6b5b7a,0xbff0000000000000,2
+np.float64,0x3fecb8eab47971d5,0x3fe6e236be6f27e9,2
+np.float64,0x44956914892ae,0x44956914892ae,2
+np.float64,0xbfe3bd18ef677a32,0xbfe190bf1e07200c,2
+np.float64,0x800104e5b46209cc,0x800104e5b46209cc,2
+np.float64,0x8008fbcecf71f79e,0x8008fbcecf71f79e,2
+np.float64,0x800f0a46a0be148d,0x800f0a46a0be148d,2
+np.float64,0x7fe657a0702caf40,0x3ff0000000000000,2
+np.float64,0xffd3ff1a9027fe36,0xbff0000000000000,2
+np.float64,0x3fe78bc87bef1790,0x3fe40d2e63aaf029,2
+np.float64,0x7feeabdc4c7d57b8,0x3ff0000000000000,2
+np.float64,0xbfabd28d8437a520,0xbfabcb8ce03a0e56,2
+np.float64,0xbfddc3a133bb8742,0xbfdbc9fdb2594451,2
+np.float64,0x7fec911565b9222a,0x3ff0000000000000,2
+np.float64,0x71302604e2605,0x71302604e2605,2
+np.float64,0xee919d2bdd234,0xee919d2bdd234,2
+np.float64,0xbfc04fcff3209fa0,0xbfc0395a739a2ce4,2
+np.float64,0xffe4668a36e8cd14,0xbff0000000000000,2
+np.float64,0xbfeeafeebefd5fde,0xbfe7cd5f3d61a3ec,2
+np.float64,0x7fddb34219bb6683,0x3ff0000000000000,2
+np.float64,0xbfd2cac6cba5958e,0xbfd24520abb2ff36,2
+np.float64,0xbfb857e49630afc8,0xbfb8452d5064dec2,2
+np.float64,0x3fd2dbf90b25b7f2,0x3fd254eaf48484c2,2
+np.float64,0x800af65c94f5ecba,0x800af65c94f5ecba,2
+np.float64,0xa0eef4bf41ddf,0xa0eef4bf41ddf,2
+np.float64,0xffd8e0a4adb1c14a,0xbff0000000000000,2
+np.float64,0xffe858f6e870b1ed,0xbff0000000000000,2
+np.float64,0x3f94c2c308298580,0x3f94c208a4bb006d,2
+np.float64,0xffb45f0d7428be18,0xbff0000000000000,2
+np.float64,0x800ed4f43dbda9e9,0x800ed4f43dbda9e9,2
+np.float64,0x8002dd697e85bad4,0x8002dd697e85bad4,2
+np.float64,0x787ceab2f0f9e,0x787ceab2f0f9e,2
+np.float64,0xbfdff5fcc2bfebfa,0xbfdd8b736b128589,2
+np.float64,0x7fdb2b4294365684,0x3ff0000000000000,2
+np.float64,0xffe711e5e92e23cc,0xbff0000000000000,2
+np.float64,0x800b1c93f1163928,0x800b1c93f1163928,2
+np.float64,0x7fc524d2f22a49a5,0x3ff0000000000000,2
+np.float64,0x7fc88013b5310026,0x3ff0000000000000,2
+np.float64,0x3fe1a910c5e35222,0x3fe00fd779ebaa2a,2
+np.float64,0xbfb57ec9ca2afd90,0xbfb571e47ecb9335,2
+np.float64,0x7fd7594b20aeb295,0x3ff0000000000000,2
+np.float64,0x7fba4641ca348c83,0x3ff0000000000000,2
+np.float64,0xffe61393706c2726,0xbff0000000000000,2
+np.float64,0x7fd54f3c7baa9e78,0x3ff0000000000000,2
+np.float64,0xffe65ffb12ecbff6,0xbff0000000000000,2
+np.float64,0xbfba3b0376347608,0xbfba239cbbbd1b11,2
+np.float64,0x800200886d640112,0x800200886d640112,2
+np.float64,0xbfecf0ba4679e174,0xbfe6fd59de44a3ec,2
+np.float64,0xffe5c57e122b8afc,0xbff0000000000000,2
+np.float64,0x7fdaad0143355a02,0x3ff0000000000000,2
+np.float64,0x46ab32c08d567,0x46ab32c08d567,2
+np.float64,0x7ff8000000000000,0x7ff8000000000000,2
+np.float64,0xbfda7980fdb4f302,0xbfd90fa9c8066109,2
+np.float64,0x3fe237703c646ee0,0x3fe07969f8d8805a,2
+np.float64,0x8000e9fcfc21d3fb,0x8000e9fcfc21d3fb,2
+np.float64,0xbfdfe6e958bfcdd2,0xbfdd7f952fe87770,2
+np.float64,0xbd7baf217af8,0xbd7baf217af8,2
+np.float64,0xbfceba9e4b3d753c,0xbfce26e54359869a,2
+np.float64,0xb95a2caf72b46,0xb95a2caf72b46,2
+np.float64,0x3fb407e25a280fc5,0x3fb3fd71e457b628,2
+np.float64,0xa1da09d943b41,0xa1da09d943b41,2
+np.float64,0xbfe9c7271cf38e4e,0xbfe559296b471738,2
+np.float64,0x3fefae6170ff5cc3,0x3fe83c70ba82f0e1,2
+np.float64,0x7fe7375348ae6ea6,0x3ff0000000000000,2
+np.float64,0xffe18c9cc6e31939,0xbff0000000000000,2
+np.float64,0x800483d13a6907a3,0x800483d13a6907a3,2
+np.float64,0x7fe772a18caee542,0x3ff0000000000000,2
+np.float64,0xffefff64e7bffec9,0xbff0000000000000,2
+np.float64,0x7fcffc31113ff861,0x3ff0000000000000,2
+np.float64,0x3fd91e067e323c0d,0x3fd7e70bf365a7b3,2
+np.float64,0xb0a6673d614cd,0xb0a6673d614cd,2
+np.float64,0xffef9a297e3f3452,0xbff0000000000000,2
+np.float64,0xffe87cc15e70f982,0xbff0000000000000,2
+np.float64,0xffefd6ad8e7fad5a,0xbff0000000000000,2
+np.float64,0x7fe3aaa3a8a75546,0x3ff0000000000000,2
+np.float64,0xddab0341bb561,0xddab0341bb561,2
+np.float64,0x3fe996d6d7332dae,0x3fe53e3ed5be2922,2
+np.float64,0x3fdbe66a18b7ccd4,0x3fda41e6053c1512,2
+np.float64,0x8914775d1228f,0x8914775d1228f,2
+np.float64,0x3fe44621d4688c44,0x3fe1ef9c7225f8bd,2
+np.float64,0xffab29a2a4365340,0xbff0000000000000,2
+np.float64,0xffc8d4a0c431a940,0xbff0000000000000,2
+np.float64,0xbfd426e085284dc2,0xbfd382e2a9617b87,2
+np.float64,0xbfd3b0a525a7614a,0xbfd3176856faccf1,2
+np.float64,0x80036dedcb06dbdc,0x80036dedcb06dbdc,2
+np.float64,0x3feb13823b762704,0x3fe60ca3facdb696,2
+np.float64,0x3fd7246b7bae48d8,0x3fd62f08afded155,2
+np.float64,0x1,0x1,2
+np.float64,0x3fe8ade4b9715bc9,0x3fe4b97cc1387d27,2
+np.float64,0x3fdf2dbec53e5b7e,0x3fdcecfeee33de95,2
+np.float64,0x3fe4292bf9685258,0x3fe1dbb5a6704090,2
+np.float64,0xbfd21acbb8243598,0xbfd1a2ff42174cae,2
+np.float64,0xdd0d2d01ba1a6,0xdd0d2d01ba1a6,2
+np.float64,0x3fa3f3d2f427e7a0,0x3fa3f13d6f101555,2
+np.float64,0x7fdabf4aceb57e95,0x3ff0000000000000,2
+np.float64,0xd4d9e39ba9b3d,0xd4d9e39ba9b3d,2
+np.float64,0xffec773396f8ee66,0xbff0000000000000,2
+np.float64,0x3fa88cc79031198f,0x3fa887f7ade722ba,2
+np.float64,0xffe63a92066c7524,0xbff0000000000000,2
+np.float64,0xbfcf514e2e3ea29c,0xbfceb510e99aaa19,2
+np.float64,0x9d78c19d3af18,0x9d78c19d3af18,2
+np.float64,0x7fdd748bfbbae917,0x3ff0000000000000,2
+np.float64,0xffb3594c4626b298,0xbff0000000000000,2
+np.float64,0x80068ce5b32d19cc,0x80068ce5b32d19cc,2
+np.float64,0x3fec63d60e78c7ac,0x3fe6b85536e44217,2
+np.float64,0x80080bad4dd0175b,0x80080bad4dd0175b,2
+np.float64,0xbfec6807baf8d010,0xbfe6ba69740f9687,2
+np.float64,0x7fedbae0bbfb75c0,0x3ff0000000000000,2
+np.float64,0x8001cb7aa3c396f6,0x8001cb7aa3c396f6,2
+np.float64,0x7fe1f1f03563e3df,0x3ff0000000000000,2
+np.float64,0x7fd83d3978307a72,0x3ff0000000000000,2
+np.float64,0xbfc05ffe9d20bffc,0xbfc049464e3f0af2,2
+np.float64,0xfe6e053ffcdc1,0xfe6e053ffcdc1,2
+np.float64,0xbfd3bdf39d277be8,0xbfd32386edf12726,2
+np.float64,0x800f41b27bde8365,0x800f41b27bde8365,2
+np.float64,0xbfe2c98390e59307,0xbfe0e3c9260fe798,2
+np.float64,0xffdd6206bcbac40e,0xbff0000000000000,2
+np.float64,0x67f35ef4cfe6c,0x67f35ef4cfe6c,2
+np.float64,0x800337e02ae66fc1,0x800337e02ae66fc1,2
+np.float64,0x3fe0ff70afe1fee1,0x3fdf1f46434330df,2
+np.float64,0x3fd7e0a1df2fc144,0x3fd6d3f82c8031e4,2
+np.float64,0x8008da5cd1b1b4ba,0x8008da5cd1b1b4ba,2
+np.float64,0x80065ec9e4ccbd95,0x80065ec9e4ccbd95,2
+np.float64,0x3fe1d1e559a3a3cb,0x3fe02e4f146aa1ab,2
+np.float64,0x7feb7d2f0836fa5d,0x3ff0000000000000,2
+np.float64,0xbfcb33ce9736679c,0xbfcaccd431b205bb,2
+np.float64,0x800e6d0adf5cda16,0x800e6d0adf5cda16,2
+np.float64,0x7fe46f272ca8de4d,0x3ff0000000000000,2
+np.float64,0x4fdfc73e9fbfa,0x4fdfc73e9fbfa,2
+np.float64,0x800958a13112b143,0x800958a13112b143,2
+np.float64,0xbfea01f877f403f1,0xbfe579a541594247,2
+np.float64,0xeefaf599ddf5f,0xeefaf599ddf5f,2
+np.float64,0x80038766c5e70ece,0x80038766c5e70ece,2
+np.float64,0x7fd31bc28ba63784,0x3ff0000000000000,2
+np.float64,0xbfe4df77eee9bef0,0xbfe257abe7083b77,2
+np.float64,0x7fe6790c78acf218,0x3ff0000000000000,2
+np.float64,0xffe7c66884af8cd0,0xbff0000000000000,2
+np.float64,0x800115e36f422bc8,0x800115e36f422bc8,2
+np.float64,0x3fc601945d2c0329,0x3fc5cab917bb20bc,2
+np.float64,0x3fd6ac9546ad592b,0x3fd5c55437ec3508,2
+np.float64,0xa7bd59294f7ab,0xa7bd59294f7ab,2
+np.float64,0x8005c26c8b8b84da,0x8005c26c8b8b84da,2
+np.float64,0x8257501704aea,0x8257501704aea,2
+np.float64,0x5b12aae0b6256,0x5b12aae0b6256,2
+np.float64,0x800232fe02c465fd,0x800232fe02c465fd,2
+np.float64,0x800dae28f85b5c52,0x800dae28f85b5c52,2
+np.float64,0x3fdade1ac135bc36,0x3fd964a2000ace25,2
+np.float64,0x3fed72ca04fae594,0x3fe73b9170d809f9,2
+np.float64,0x7fc6397e2b2c72fb,0x3ff0000000000000,2
+np.float64,0x3fe1f5296d23ea53,0x3fe048802d17621e,2
+np.float64,0xffe05544b920aa89,0xbff0000000000000,2
+np.float64,0xbfdb2e1588365c2c,0xbfd9a7e4113c713e,2
+np.float64,0xbfed6a06fa3ad40e,0xbfe7376be60535f8,2
+np.float64,0xbfe31dcaf5e63b96,0xbfe120417c46cac1,2
+np.float64,0xbfb7ed67ae2fdad0,0xbfb7dba14af33b00,2
+np.float64,0xffd32bb7eb265770,0xbff0000000000000,2
+np.float64,0x80039877b04730f0,0x80039877b04730f0,2
+np.float64,0x3f832e5630265cac,0x3f832e316f47f218,2
+np.float64,0xffe7fa7f732ff4fe,0xbff0000000000000,2
+np.float64,0x9649b87f2c937,0x9649b87f2c937,2
+np.float64,0xffaee447183dc890,0xbff0000000000000,2
+np.float64,0x7fe4e02dd869c05b,0x3ff0000000000000,2
+np.float64,0x3fe1d35e7463a6bd,0x3fe02f67bd21e86e,2
+np.float64,0xffe57f40fe2afe82,0xbff0000000000000,2
+np.float64,0xbfea1362b93426c6,0xbfe5833421dba8fc,2
+np.float64,0xffe9c689fe338d13,0xbff0000000000000,2
+np.float64,0xffc592dd102b25bc,0xbff0000000000000,2
+np.float64,0x3fd283c7aba5078f,0x3fd203d61d1398c3,2
+np.float64,0x8001d6820243ad05,0x8001d6820243ad05,2
+np.float64,0x3fe0ad5991e15ab4,0x3fdea14ef0d47fbd,2
+np.float64,0x3fe3916f2ee722de,0x3fe1722684a9ffb1,2
+np.float64,0xffef9e54e03f3ca9,0xbff0000000000000,2
+np.float64,0x7fe864faebb0c9f5,0x3ff0000000000000,2
+np.float64,0xbfed3587c3fa6b10,0xbfe71e7112df8a68,2
+np.float64,0xbfdd9efc643b3df8,0xbfdbac3a16caf208,2
+np.float64,0xbfd5ac08feab5812,0xbfd4e14575a6e41b,2
+np.float64,0xffda90fae6b521f6,0xbff0000000000000,2
+np.float64,0x8001380ecf22701e,0x8001380ecf22701e,2
+np.float64,0x7fed266fa5fa4cde,0x3ff0000000000000,2
+np.float64,0xffec6c0ac3b8d815,0xbff0000000000000,2
+np.float64,0x3fe7de43c32fbc88,0x3fe43ef62821a5a6,2
+np.float64,0x800bf4ffc357ea00,0x800bf4ffc357ea00,2
+np.float64,0x3fe125c975624b93,0x3fdf59b2de3eff5d,2
+np.float64,0x8004714c1028e299,0x8004714c1028e299,2
+np.float64,0x3fef1bfbf5fe37f8,0x3fe7fd2ba1b63c8a,2
+np.float64,0x800cae15c3195c2c,0x800cae15c3195c2c,2
+np.float64,0x7fde708e083ce11b,0x3ff0000000000000,2
+np.float64,0x7fbcee5df639dcbb,0x3ff0000000000000,2
+np.float64,0x800b1467141628cf,0x800b1467141628cf,2
+np.float64,0x3fe525e0d36a4bc2,0x3fe286b6e59e30f5,2
+np.float64,0xffe987f8b8330ff1,0xbff0000000000000,2
+np.float64,0x7e0a8284fc151,0x7e0a8284fc151,2
+np.float64,0x8006f982442df305,0x8006f982442df305,2
+np.float64,0xbfd75a3cb62eb47a,0xbfd65e54cee981c9,2
+np.float64,0x258e91104b1d3,0x258e91104b1d3,2
+np.float64,0xbfecd0056779a00b,0xbfe6ed7ae97fff1b,2
+np.float64,0x7fc3a4f9122749f1,0x3ff0000000000000,2
+np.float64,0x6e2b1024dc563,0x6e2b1024dc563,2
+np.float64,0x800d575ad4daaeb6,0x800d575ad4daaeb6,2
+np.float64,0xbfceafb1073d5f64,0xbfce1c93023d8414,2
+np.float64,0xffe895cb5f312b96,0xbff0000000000000,2
+np.float64,0x7fe7811ed4ef023d,0x3ff0000000000000,2
+np.float64,0xbfd93f952f327f2a,0xbfd803e6b5576b99,2
+np.float64,0xffdd883a3fbb1074,0xbff0000000000000,2
+np.float64,0x7fee5624eefcac49,0x3ff0000000000000,2
+np.float64,0xbfe264bb2624c976,0xbfe09a9b7cc896e7,2
+np.float64,0xffef14b417be2967,0xbff0000000000000,2
+np.float64,0xbfecbd0d94397a1b,0xbfe6e43bef852d9f,2
+np.float64,0xbfe20d9e4ba41b3c,0xbfe05a98e05846d9,2
+np.float64,0x10000000000000,0x10000000000000,2
+np.float64,0x7fefde93f7bfbd27,0x3ff0000000000000,2
+np.float64,0x80076b9e232ed73d,0x80076b9e232ed73d,2
+np.float64,0xbfe80df52c701bea,0xbfe45b754b433792,2
+np.float64,0x7fe3b5a637676b4b,0x3ff0000000000000,2
+np.float64,0x2c81d14c5903b,0x2c81d14c5903b,2
+np.float64,0x80038945c767128c,0x80038945c767128c,2
+np.float64,0xffeebaf544bd75ea,0xbff0000000000000,2
+np.float64,0xffdb1867d2b630d0,0xbff0000000000000,2
+np.float64,0x3fe3376eaee66ede,0x3fe13285579763d8,2
+np.float64,0xffddf65ca43becba,0xbff0000000000000,2
+np.float64,0xffec8e3e04791c7b,0xbff0000000000000,2
+np.float64,0x80064f4bde2c9e98,0x80064f4bde2c9e98,2
+np.float64,0x7fe534a085ea6940,0x3ff0000000000000,2
+np.float64,0xbfcbabe31d3757c8,0xbfcb3f8e70adf7e7,2
+np.float64,0xbfe45ca11e28b942,0xbfe1ff04515ef809,2
+np.float64,0x65f4df02cbe9d,0x65f4df02cbe9d,2
+np.float64,0xb08b0cbb61162,0xb08b0cbb61162,2
+np.float64,0x3feae2e8b975c5d1,0x3fe5f302b5e8eda2,2
+np.float64,0x7fcf277ff93e4eff,0x3ff0000000000000,2
+np.float64,0x80010999c4821334,0x80010999c4821334,2
+np.float64,0xbfd7f65911afecb2,0xbfd6e6e9cd098f8b,2
+np.float64,0x800e0560ec3c0ac2,0x800e0560ec3c0ac2,2
+np.float64,0x7fec4152ba3882a4,0x3ff0000000000000,2
+np.float64,0xbfb5c77cd42b8ef8,0xbfb5ba1336084908,2
+np.float64,0x457ff1b68afff,0x457ff1b68afff,2
+np.float64,0x5323ec56a647e,0x5323ec56a647e,2
+np.float64,0xbfeed16cf8bda2da,0xbfe7dc49fc9ae549,2
+np.float64,0xffe8446106b088c1,0xbff0000000000000,2
+np.float64,0xffb93cd13c3279a0,0xbff0000000000000,2
+np.float64,0x7fe515c2aeea2b84,0x3ff0000000000000,2
+np.float64,0x80099df83f933bf1,0x80099df83f933bf1,2
+np.float64,0x7fb3a375562746ea,0x3ff0000000000000,2
+np.float64,0x7fcd7efa243afdf3,0x3ff0000000000000,2
+np.float64,0xffe40cddb12819bb,0xbff0000000000000,2
+np.float64,0x8008b68eecd16d1e,0x8008b68eecd16d1e,2
+np.float64,0x2aec688055d8e,0x2aec688055d8e,2
+np.float64,0xffe23750bc646ea1,0xbff0000000000000,2
+np.float64,0x5adacf60b5b7,0x5adacf60b5b7,2
+np.float64,0x7fefb29b1cbf6535,0x3ff0000000000000,2
+np.float64,0xbfeadbf90175b7f2,0xbfe5ef55e2194794,2
+np.float64,0xeaad2885d55a5,0xeaad2885d55a5,2
+np.float64,0xffd7939fba2f2740,0xbff0000000000000,2
+np.float64,0x3fd187ea3aa30fd4,0x3fd11af023472386,2
+np.float64,0xbf6eb579c03d6b00,0xbf6eb57052f47019,2
+np.float64,0x3fefb67b3bff6cf6,0x3fe83fe4499969ac,2
+np.float64,0xbfe5183aacea3076,0xbfe27da1aa0b61a0,2
+np.float64,0xbfb83e47a2307c90,0xbfb82bcb0e12db42,2
+np.float64,0x80088849b1b11094,0x80088849b1b11094,2
+np.float64,0x800ceeed7399dddb,0x800ceeed7399dddb,2
+np.float64,0x80097cd90892f9b2,0x80097cd90892f9b2,2
+np.float64,0x7ec73feefd8e9,0x7ec73feefd8e9,2
+np.float64,0x7fe3291de5a6523b,0x3ff0000000000000,2
+np.float64,0xbfd537086daa6e10,0xbfd4787af5f60653,2
+np.float64,0x800e8ed4455d1da9,0x800e8ed4455d1da9,2
+np.float64,0x800ef8d19cbdf1a3,0x800ef8d19cbdf1a3,2
+np.float64,0x800dc4fa3a5b89f5,0x800dc4fa3a5b89f5,2
+np.float64,0xaa8b85cd55171,0xaa8b85cd55171,2
+np.float64,0xffd67a5f40acf4be,0xbff0000000000000,2
+np.float64,0xbfb7496db22e92d8,0xbfb7390a48130861,2
+np.float64,0x3fd86a8e7ab0d51d,0x3fd74bfba0f72616,2
+np.float64,0xffb7f5b7fc2feb70,0xbff0000000000000,2
+np.float64,0xbfea0960a7f412c1,0xbfe57db6d0ff4191,2
+np.float64,0x375f4fc26ebeb,0x375f4fc26ebeb,2
+np.float64,0x800c537e70b8a6fd,0x800c537e70b8a6fd,2
+np.float64,0x800b3f4506d67e8a,0x800b3f4506d67e8a,2
+np.float64,0x7fe61f2d592c3e5a,0x3ff0000000000000,2
+np.float64,0xffefffffffffffff,0xbff0000000000000,2
+np.float64,0x8005d0bb84eba178,0x8005d0bb84eba178,2
+np.float64,0x800c78b0ec18f162,0x800c78b0ec18f162,2
+np.float64,0xbfc42cccfb285998,0xbfc4027392f66b0d,2
+np.float64,0x3fd8fdc73fb1fb8e,0x3fd7cb46f928153f,2
+np.float64,0x800c71754298e2eb,0x800c71754298e2eb,2
+np.float64,0x3fe4aa7a96a954f5,0x3fe233f5d3bc1352,2
+np.float64,0x7fd53841f6aa7083,0x3ff0000000000000,2
+np.float64,0x3fd0a887b8a15110,0x3fd04ac3b9c0d1ca,2
+np.float64,0x8007b8e164cf71c4,0x8007b8e164cf71c4,2
+np.float64,0xbfddc35c66bb86b8,0xbfdbc9c5dddfb014,2
+np.float64,0x6a3756fed46eb,0x6a3756fed46eb,2
+np.float64,0xffd3dcd05527b9a0,0xbff0000000000000,2
+np.float64,0xbfd7dc75632fb8ea,0xbfd6d0538b340a98,2
+np.float64,0x17501f822ea05,0x17501f822ea05,2
+np.float64,0xbfe1f98b99a3f317,0xbfe04bbf8f8b6cb3,2
+np.float64,0x66ea65d2cdd4d,0x66ea65d2cdd4d,2
+np.float64,0xbfd12241e2224484,0xbfd0bc62f46ea5e1,2
+np.float64,0x3fed6e6fb3fadcdf,0x3fe7398249097285,2
+np.float64,0x3fe0b5ebeba16bd8,0x3fdeae84b3000a47,2
+np.float64,0x66d1bce8cda38,0x66d1bce8cda38,2
+np.float64,0x3fdd728db3bae51b,0x3fdb880f28c52713,2
+np.float64,0xffb45dbe5228bb80,0xbff0000000000000,2
+np.float64,0x1ff8990c3ff14,0x1ff8990c3ff14,2
+np.float64,0x800a68e8f294d1d2,0x800a68e8f294d1d2,2
+np.float64,0xbfe4d08b84a9a117,0xbfe24da40bff6be7,2
+np.float64,0x3fe0177f0ee02efe,0x3fddb83c5971df51,2
+np.float64,0xffc56893692ad128,0xbff0000000000000,2
+np.float64,0x51b44f6aa368b,0x51b44f6aa368b,2
+np.float64,0x2258ff4e44b21,0x2258ff4e44b21,2
+np.float64,0x3fe913649e7226c9,0x3fe4f3f119530f53,2
+np.float64,0xffe3767df766ecfc,0xbff0000000000000,2
+np.float64,0xbfe62ae12fec55c2,0xbfe33108f1f22a94,2
+np.float64,0x7fb6a6308e2d4c60,0x3ff0000000000000,2
+np.float64,0xbfe00f2085e01e41,0xbfddab19b6fc77d1,2
+np.float64,0x3fb66447dc2cc890,0x3fb655b4f46844f0,2
+np.float64,0x3fd80238f6b00470,0x3fd6f143be1617d6,2
+np.float64,0xbfd05bfeb3a0b7fe,0xbfd0031ab3455e15,2
+np.float64,0xffc3a50351274a08,0xbff0000000000000,2
+np.float64,0xffd8f4241cb1e848,0xbff0000000000000,2
+np.float64,0xbfca72a88c34e550,0xbfca13ebe85f2aca,2
+np.float64,0x3fd47d683ba8fad0,0x3fd3d13f1176ed8c,2
+np.float64,0x3fb6418e642c831d,0x3fb6333ebe479ff2,2
+np.float64,0x800fde8e023fbd1c,0x800fde8e023fbd1c,2
+np.float64,0x8001fb01e323f605,0x8001fb01e323f605,2
+np.float64,0x3febb21ff9f76440,0x3fe65ed788d52fee,2
+np.float64,0x3fe47553ffe8eaa8,0x3fe20fe01f853603,2
+np.float64,0x7fca20b3f9344167,0x3ff0000000000000,2
+np.float64,0x3fe704f4ec6e09ea,0x3fe3ba7277201805,2
+np.float64,0xf864359df0c87,0xf864359df0c87,2
+np.float64,0x4d96b01c9b2d7,0x4d96b01c9b2d7,2
+np.float64,0x3fe8a09fe9f14140,0x3fe4b1c6a2d2e095,2
+np.float64,0xffc46c61b228d8c4,0xbff0000000000000,2
+np.float64,0x3fe680a837ed0150,0x3fe3679d6eeb6485,2
+np.float64,0xbfecedc20f39db84,0xbfe6fbe9ee978bf6,2
+np.float64,0x3fb2314eae24629d,0x3fb2297ba6d55d2d,2
+np.float64,0x3fe9f0b8e7b3e172,0x3fe57026eae36db3,2
+np.float64,0x80097a132ed2f427,0x80097a132ed2f427,2
+np.float64,0x800ae5a41955cb49,0x800ae5a41955cb49,2
+np.float64,0xbfd7527279aea4e4,0xbfd6577de356e1bd,2
+np.float64,0x3fe27d3e01e4fa7c,0x3fe0ac7dd96f9179,2
+np.float64,0x7fedd8cb01bbb195,0x3ff0000000000000,2
+np.float64,0x78f8695af1f0e,0x78f8695af1f0e,2
+np.float64,0x800d2d0e927a5a1d,0x800d2d0e927a5a1d,2
+np.float64,0xffe74b46fb2e968e,0xbff0000000000000,2
+np.float64,0xbfdd12d4c8ba25aa,0xbfdb39dae49e1c10,2
+np.float64,0xbfd6c14710ad828e,0xbfd5d79ef5a8d921,2
+np.float64,0x921f4e55243ea,0x921f4e55243ea,2
+np.float64,0x800b4e4c80969c99,0x800b4e4c80969c99,2
+np.float64,0x7fe08c6ab7e118d4,0x3ff0000000000000,2
+np.float64,0xbfed290014fa5200,0xbfe71871f7e859ed,2
+np.float64,0x8008c1d5c59183ac,0x8008c1d5c59183ac,2
+np.float64,0x3fd339e68c2673cd,0x3fd2aaff3f165a9d,2
+np.float64,0xbfdd20d8113a41b0,0xbfdb4553ea2cb2fb,2
+np.float64,0x3fe52a25deea544c,0x3fe2898d5bf4442c,2
+np.float64,0x498602d4930c1,0x498602d4930c1,2
+np.float64,0x3fd8c450113188a0,0x3fd799b0b2a6c43c,2
+np.float64,0xbfd72bc2f2ae5786,0xbfd6357e15ba7f70,2
+np.float64,0xbfd076188ea0ec32,0xbfd01b8fce44d1af,2
+np.float64,0x9aace1713559c,0x9aace1713559c,2
+np.float64,0x8008a730e8914e62,0x8008a730e8914e62,2
+np.float64,0x7fe9e9a3d833d347,0x3ff0000000000000,2
+np.float64,0x800d3a0d69da741b,0x800d3a0d69da741b,2
+np.float64,0xbfe3e28a29e7c514,0xbfe1aad7643a2d19,2
+np.float64,0x7fe9894c71331298,0x3ff0000000000000,2
+np.float64,0xbfe7c6acb5ef8d5a,0xbfe430c9e258ce62,2
+np.float64,0xffb5a520a62b4a40,0xbff0000000000000,2
+np.float64,0x7fc02109ae204212,0x3ff0000000000000,2
+np.float64,0xb5c58f196b8b2,0xb5c58f196b8b2,2
+np.float64,0x3feb4ee82e769dd0,0x3fe62bae9a39d8b1,2
+np.float64,0x3fec5c3cf278b87a,0x3fe6b49000f12441,2
+np.float64,0x81f64b8103eca,0x81f64b8103eca,2
+np.float64,0xbfeab00d73f5601b,0xbfe5d7f755ab73d9,2
+np.float64,0x3fd016bf28a02d7e,0x3fcf843ea23bcd3c,2
+np.float64,0xbfa1db617423b6c0,0xbfa1d9872ddeb5a8,2
+np.float64,0x3fe83c879d70790f,0x3fe4771502d8f012,2
+np.float64,0x6b267586d64cf,0x6b267586d64cf,2
+np.float64,0x3fc91b6d3f3236d8,0x3fc8ca3eb4da25a9,2
+np.float64,0x7fd4e3f8f3a9c7f1,0x3ff0000000000000,2
+np.float64,0x800a75899214eb14,0x800a75899214eb14,2
+np.float64,0x7fdb1f2e07b63e5b,0x3ff0000000000000,2
+np.float64,0xffe7805a11ef00b4,0xbff0000000000000,2
+np.float64,0x3fc8e1b88a31c371,0x3fc892af45330818,2
+np.float64,0xbfe809fe447013fc,0xbfe45918f07da4d9,2
+np.float64,0xbfeb9d7f2ab73afe,0xbfe65446bfddc792,2
+np.float64,0x3fb47f0a5c28fe15,0x3fb473db9113e880,2
+np.float64,0x800a17ae3cb42f5d,0x800a17ae3cb42f5d,2
+np.float64,0xf5540945eaa81,0xf5540945eaa81,2
+np.float64,0xbfe577fc26aaeff8,0xbfe2bcfbf2cf69ff,2
+np.float64,0xbfb99b3e06333680,0xbfb98577b88e0515,2
+np.float64,0x7fd9290391b25206,0x3ff0000000000000,2
+np.float64,0x7fe1aa62ffa354c5,0x3ff0000000000000,2
+np.float64,0x7b0189a0f604,0x7b0189a0f604,2
+np.float64,0x3f9000ed602001db,0x3f900097fe168105,2
+np.float64,0x3fd576128d2aec25,0x3fd4b1002c92286f,2
+np.float64,0xffecc98ece79931d,0xbff0000000000000,2
+np.float64,0x800a1736c7f42e6e,0x800a1736c7f42e6e,2
+np.float64,0xbfed947548bb28eb,0xbfe74b71479ae739,2
+np.float64,0xa45c032148b9,0xa45c032148b9,2
+np.float64,0xbfc13d011c227a04,0xbfc1228447de5e9f,2
+np.float64,0xffed8baa6ebb1754,0xbff0000000000000,2
+np.float64,0x800ea2de243d45bc,0x800ea2de243d45bc,2
+np.float64,0x8001396be52272d9,0x8001396be52272d9,2
+np.float64,0xd018d1cda031a,0xd018d1cda031a,2
+np.float64,0x7fe1fece1fe3fd9b,0x3ff0000000000000,2
+np.float64,0x8009ac484c135891,0x8009ac484c135891,2
+np.float64,0x3fc560ad132ac15a,0x3fc52e5a9479f08e,2
+np.float64,0x3fd6f80ebe2df01d,0x3fd607f70ce8e3f4,2
+np.float64,0xbfd3e69e82a7cd3e,0xbfd34887c2a40699,2
+np.float64,0x3fe232d9baa465b3,0x3fe0760a822ada0c,2
+np.float64,0x3fe769bbc6eed378,0x3fe3f872680f6631,2
+np.float64,0xffe63dbd952c7b7a,0xbff0000000000000,2
+np.float64,0x4e0c00da9c181,0x4e0c00da9c181,2
+np.float64,0xffeae4d89735c9b0,0xbff0000000000000,2
+np.float64,0x3fe030bcbb606179,0x3fdddfc66660bfce,2
+np.float64,0x7fe35ca40d66b947,0x3ff0000000000000,2
+np.float64,0xbfd45bd66628b7ac,0xbfd3b2e04bfe7866,2
+np.float64,0x3fd1f0be2323e17c,0x3fd17c1c340d7a48,2
+np.float64,0x3fd7123b6cae2478,0x3fd61f0675aa9ae1,2
+np.float64,0xbfe918a377723147,0xbfe4f6efe66f5714,2
+np.float64,0x7fc400356f28006a,0x3ff0000000000000,2
+np.float64,0x7fd2dead70a5bd5a,0x3ff0000000000000,2
+np.float64,0xffe9c28f81f3851e,0xbff0000000000000,2
+np.float64,0x3fd09b1ec7a1363e,0x3fd03e3894320140,2
+np.float64,0x7fe6e80c646dd018,0x3ff0000000000000,2
+np.float64,0x7fec3760a4786ec0,0x3ff0000000000000,2
+np.float64,0x309eb6ee613d8,0x309eb6ee613d8,2
+np.float64,0x800731cb0ece6397,0x800731cb0ece6397,2
+np.float64,0xbfdb0c553db618aa,0xbfd98b8a4680ee60,2
+np.float64,0x3fd603a52eac074c,0x3fd52f6b53de7455,2
+np.float64,0x9ecb821b3d971,0x9ecb821b3d971,2
+np.float64,0x3feb7d64dc36faca,0x3fe643c2754bb7f4,2
+np.float64,0xffeb94825ef72904,0xbff0000000000000,2
+np.float64,0x24267418484cf,0x24267418484cf,2
+np.float64,0xbfa6b2fbac2d65f0,0xbfa6af2dca5bfa6f,2
+np.float64,0x8010000000000000,0x8010000000000000,2
+np.float64,0xffe6873978ed0e72,0xbff0000000000000,2
+np.float64,0x800447934ba88f27,0x800447934ba88f27,2
+np.float64,0x3fef305f09fe60be,0x3fe806156b8ca47c,2
+np.float64,0xffd441c697a8838e,0xbff0000000000000,2
+np.float64,0xbfa7684f6c2ed0a0,0xbfa764238d34830c,2
+np.float64,0xffb2c976142592f0,0xbff0000000000000,2
+np.float64,0xbfcc9d1585393a2c,0xbfcc25756bcbca1f,2
+np.float64,0xbfd477bb1ba8ef76,0xbfd3cc1d2114e77e,2
+np.float64,0xbfed1559983a2ab3,0xbfe70f03afd994ee,2
+np.float64,0xbfeb51139036a227,0xbfe62ccf56bc7fff,2
+np.float64,0x7d802890fb006,0x7d802890fb006,2
+np.float64,0x800e00af777c015f,0x800e00af777c015f,2
+np.float64,0x800647ce128c8f9d,0x800647ce128c8f9d,2
+np.float64,0x800a26da91d44db6,0x800a26da91d44db6,2
+np.float64,0x3fdc727eddb8e4fe,0x3fdab5fd9db630b3,2
+np.float64,0x7fd06def2ba0dbdd,0x3ff0000000000000,2
+np.float64,0xffe23678c4a46cf1,0xbff0000000000000,2
+np.float64,0xbfe7198e42ee331c,0xbfe3c7326c9c7553,2
+np.float64,0xffae465f3c3c8cc0,0xbff0000000000000,2
+np.float64,0xff9aea7c5035d500,0xbff0000000000000,2
+np.float64,0xbfeae49c0f35c938,0xbfe5f3e9326cb08b,2
+np.float64,0x3f9a16f300342de6,0x3f9a1581212be50f,2
+np.float64,0x8d99e2c31b33d,0x8d99e2c31b33d,2
+np.float64,0xffd58af253ab15e4,0xbff0000000000000,2
+np.float64,0xbfd205cd25a40b9a,0xbfd18f97155f8b25,2
+np.float64,0xbfebe839bbf7d074,0xbfe67a6024e8fefe,2
+np.float64,0xbfe4fb3595a9f66b,0xbfe26a42f99819ea,2
+np.float64,0x800e867c739d0cf9,0x800e867c739d0cf9,2
+np.float64,0x8bc4274f17885,0x8bc4274f17885,2
+np.float64,0xaec8914b5d912,0xaec8914b5d912,2
+np.float64,0x7fd1d64473a3ac88,0x3ff0000000000000,2
+np.float64,0xbfe6d6f69cedaded,0xbfe39dd61bc7e23e,2
+np.float64,0x7fed05039d7a0a06,0x3ff0000000000000,2
+np.float64,0xbfc40eab0f281d58,0xbfc3e50d14b79265,2
+np.float64,0x45179aec8a2f4,0x45179aec8a2f4,2
+np.float64,0xbfe717e362ee2fc7,0xbfe3c62a95b07d13,2
+np.float64,0xbfe5b8df0d6b71be,0xbfe2e76c7ec5013d,2
+np.float64,0x5c67ba6eb8cf8,0x5c67ba6eb8cf8,2
+np.float64,0xbfda72ce4cb4e59c,0xbfd909fdc7ecfe20,2
+np.float64,0x7fdf59a1e2beb343,0x3ff0000000000000,2
+np.float64,0xc4f7897f89ef1,0xc4f7897f89ef1,2
+np.float64,0x8fcd0a351f9a2,0x8fcd0a351f9a2,2
+np.float64,0x3fb161761022c2ec,0x3fb15aa31c464de2,2
+np.float64,0x8008a985be71530c,0x8008a985be71530c,2
+np.float64,0x3fca4ddb5e349bb7,0x3fc9f0a3b60e49c6,2
+np.float64,0x7fcc10a2d9382145,0x3ff0000000000000,2
+np.float64,0x78902b3af1206,0x78902b3af1206,2
+np.float64,0x7fe1e2765f23c4ec,0x3ff0000000000000,2
+np.float64,0xc1d288cf83a51,0xc1d288cf83a51,2
+np.float64,0x7fe8af692bb15ed1,0x3ff0000000000000,2
+np.float64,0x80057d90fb8afb23,0x80057d90fb8afb23,2
+np.float64,0x3fdc136b8fb826d8,0x3fda6749582b2115,2
+np.float64,0x800ec8ea477d91d5,0x800ec8ea477d91d5,2
+np.float64,0x4c0f4796981ea,0x4c0f4796981ea,2
+np.float64,0xec34c4a5d8699,0xec34c4a5d8699,2
+np.float64,0x7fce343dfb3c687b,0x3ff0000000000000,2
+np.float64,0xbfc95a98a332b530,0xbfc90705b2cc2fec,2
+np.float64,0x800d118e1dba231c,0x800d118e1dba231c,2
+np.float64,0x3fd354f310a6a9e8,0x3fd2c3bb90054154,2
+np.float64,0xbfdac0d4fab581aa,0xbfd94bf37424928e,2
+np.float64,0x3fe7f5391fefea72,0x3fe44cb49d51985b,2
+np.float64,0xd4c3c329a9879,0xd4c3c329a9879,2
+np.float64,0x3fc53977692a72f0,0x3fc50835d85c9ed1,2
+np.float64,0xbfd6989538ad312a,0xbfd5b3a2c08511fe,2
+np.float64,0xbfe329f2906653e5,0xbfe128ec1525a1c0,2
+np.float64,0x7ff0000000000000,0x3ff0000000000000,2
+np.float64,0xbfea57c90974af92,0xbfe5a87b04aa3116,2
+np.float64,0x7fdfba94043f7527,0x3ff0000000000000,2
+np.float64,0x3feedabddafdb57c,0x3fe7e06c0661978d,2
+np.float64,0x4bd9f3b697b3f,0x4bd9f3b697b3f,2
+np.float64,0x3fdd15bbfc3a2b78,0x3fdb3c3b8d070f7e,2
+np.float64,0x3fbd89ccd23b13a0,0x3fbd686b825cff80,2
+np.float64,0x7ff4000000000000,0x7ffc000000000000,2
+np.float64,0x3f9baa8928375512,0x3f9ba8d01ddd5300,2
+np.float64,0x4a3ebdf2947d8,0x4a3ebdf2947d8,2
+np.float64,0x3fe698d5c06d31ac,0x3fe376dff48312c8,2
+np.float64,0xffd5323df12a647c,0xbff0000000000000,2
+np.float64,0xffea7f111174fe22,0xbff0000000000000,2
+np.float64,0x3feb4656a9b68cad,0x3fe627392eb2156f,2
+np.float64,0x7fc1260e9c224c1c,0x3ff0000000000000,2
+np.float64,0x80056e45e5eadc8d,0x80056e45e5eadc8d,2
+np.float64,0x7fd0958ef6a12b1d,0x3ff0000000000000,2
+np.float64,0x8001f85664e3f0ae,0x8001f85664e3f0ae,2
+np.float64,0x3fe553853beaa70a,0x3fe2a4f5e7c83558,2
+np.float64,0xbfeb33ce6276679d,0xbfe61d8ec9e5ff8c,2
+np.float64,0xbfd1b24e21a3649c,0xbfd14245df6065e9,2
+np.float64,0x3fe286fc40650df9,0x3fe0b395c8059429,2
+np.float64,0xffed378058fa6f00,0xbff0000000000000,2
+np.float64,0xbfd0c4a2d7a18946,0xbfd06509a434d6a0,2
+np.float64,0xbfea31d581f463ab,0xbfe593d976139f94,2
+np.float64,0xbfe0705c85e0e0b9,0xbfde42efa978eb0c,2
+np.float64,0xe4c4c339c9899,0xe4c4c339c9899,2
+np.float64,0x3fd68befa9ad17df,0x3fd5a870b3f1f83e,2
+np.float64,0x8000000000000001,0x8000000000000001,2
+np.float64,0x3fe294256965284b,0x3fe0bd271e22d86b,2
+np.float64,0x8005327a862a64f6,0x8005327a862a64f6,2
+np.float64,0xbfdb8155ce3702ac,0xbfd9ed9ef97920f8,2
+np.float64,0xbff0000000000000,0xbfe85efab514f394,2
+np.float64,0xffe66988f1ecd312,0xbff0000000000000,2
+np.float64,0x3fb178a85e22f150,0x3fb171b9fbf95f1d,2
+np.float64,0x7f829b900025371f,0x3ff0000000000000,2
+np.float64,0x8000000000000000,0x8000000000000000,2
+np.float64,0x8006cb77f60d96f1,0x8006cb77f60d96f1,2
+np.float64,0x3fe0c5d53aa18baa,0x3fdec7012ab92b42,2
+np.float64,0x77266426ee4cd,0x77266426ee4cd,2
+np.float64,0xbfec95f468392be9,0xbfe6d11428f60136,2
+np.float64,0x3fedbf532dfb7ea6,0x3fe75f8436dd1d58,2
+np.float64,0x8002fadd3f85f5bb,0x8002fadd3f85f5bb,2
+np.float64,0xbfefebaa8d3fd755,0xbfe8566c6aa90fba,2
+np.float64,0xffc7dd2b712fba58,0xbff0000000000000,2
+np.float64,0x7fe5d3a6e8aba74d,0x3ff0000000000000,2
+np.float64,0x2da061525b40d,0x2da061525b40d,2
+np.float64,0x7fcb9b9953373732,0x3ff0000000000000,2
+np.float64,0x2ca2f6fc59460,0x2ca2f6fc59460,2
+np.float64,0xffeb84b05af70960,0xbff0000000000000,2
+np.float64,0xffe551e86c6aa3d0,0xbff0000000000000,2
+np.float64,0xbfdb311311366226,0xbfd9aa6688faafb9,2
+np.float64,0xbfd4f3875629e70e,0xbfd43bcd73534c66,2
+np.float64,0x7fe95666f932accd,0x3ff0000000000000,2
+np.float64,0x3fc73dfb482e7bf7,0x3fc6fd70c20ebf60,2
+np.float64,0x800cd9e40939b3c8,0x800cd9e40939b3c8,2
+np.float64,0x3fb0c9fa422193f0,0x3fb0c3d38879a2ac,2
+np.float64,0xffd59a38372b3470,0xbff0000000000000,2
+np.float64,0x3fa8320ef4306420,0x3fa82d739e937d35,2
+np.float64,0x3fd517f16caa2fe4,0x3fd45c8de1e93b37,2
+np.float64,0xaed921655db24,0xaed921655db24,2
+np.float64,0x93478fb9268f2,0x93478fb9268f2,2
+np.float64,0x1615e28a2c2bd,0x1615e28a2c2bd,2
+np.float64,0xbfead23010f5a460,0xbfe5ea24d5d8f820,2
+np.float64,0x774a6070ee94d,0x774a6070ee94d,2
+np.float64,0x3fdf5874bd3eb0e9,0x3fdd0ef121dd915c,2
+np.float64,0x8004b25f53a964bf,0x8004b25f53a964bf,2
+np.float64,0xbfddacdd2ebb59ba,0xbfdbb78198fab36b,2
+np.float64,0x8008a3acf271475a,0x8008a3acf271475a,2
+np.float64,0xbfdb537c8736a6fa,0xbfd9c741038bb8f0,2
+np.float64,0xbfe56a133f6ad426,0xbfe2b3d5b8d259a1,2
+np.float64,0xffda1db531343b6a,0xbff0000000000000,2
+np.float64,0x3fcbe05f3a37c0be,0x3fcb71a54a64ddfb,2
+np.float64,0x7fe1ccaa7da39954,0x3ff0000000000000,2
+np.float64,0x3faeadd8343d5bb0,0x3faea475608860e6,2
+np.float64,0x3fe662ba1c2cc574,0x3fe354a6176e90df,2
+np.float64,0xffe4d49f4e69a93e,0xbff0000000000000,2
+np.float64,0xbfeadbc424f5b788,0xbfe5ef39dbe66343,2
+np.float64,0x99cf66f1339ed,0x99cf66f1339ed,2
+np.float64,0x33af77a2675f0,0x33af77a2675f0,2
+np.float64,0x7fec7b32ecf8f665,0x3ff0000000000000,2
+np.float64,0xffef3e44993e7c88,0xbff0000000000000,2
+np.float64,0xffe8f8ceac31f19c,0xbff0000000000000,2
+np.float64,0x7fe0d15b6da1a2b6,0x3ff0000000000000,2
+np.float64,0x4ba795c2974f3,0x4ba795c2974f3,2
+np.float64,0x3fe361aa37a6c354,0x3fe15079021d6b15,2
+np.float64,0xffe709714f6e12e2,0xbff0000000000000,2
+np.float64,0xffe7ea6a872fd4d4,0xbff0000000000000,2
+np.float64,0xffdb9441c8b72884,0xbff0000000000000,2
+np.float64,0xffd5e11ae9abc236,0xbff0000000000000,2
+np.float64,0xffe092a08b612540,0xbff0000000000000,2
+np.float64,0x3fe1f27e1ca3e4fc,0x3fe04685b5131207,2
+np.float64,0xbfe71ce1bdee39c4,0xbfe3c940809a7081,2
+np.float64,0xffe8c3aa68318754,0xbff0000000000000,2
+np.float64,0x800d4e2919da9c52,0x800d4e2919da9c52,2
+np.float64,0x7fe6c8bca76d9178,0x3ff0000000000000,2
+np.float64,0x7fced8751e3db0e9,0x3ff0000000000000,2
+np.float64,0xd61d0c8bac3a2,0xd61d0c8bac3a2,2
+np.float64,0x3fec57732938aee6,0x3fe6b22f15f38352,2
+np.float64,0xff9251cc7024a3a0,0xbff0000000000000,2
+np.float64,0xf4a68cb9e94d2,0xf4a68cb9e94d2,2
+np.float64,0x3feed76703bdaece,0x3fe7def0fc9a080c,2
+np.float64,0xbfe8971ff7712e40,0xbfe4ac3eb8ebff07,2
+np.float64,0x3fe4825f682904bf,0x3fe218c1952fe67d,2
+np.float64,0xbfd60f7698ac1eee,0xbfd539f0979b4b0c,2
+np.float64,0x3fcf0845993e1088,0x3fce7032f7180144,2
+np.float64,0x7fc83443f3306887,0x3ff0000000000000,2
+np.float64,0x3fe93123ae726247,0x3fe504e4fc437e89,2
+np.float64,0x3fbf9eb8363f3d70,0x3fbf75cdfa6828d5,2
+np.float64,0xbf8b45e5d0368bc0,0xbf8b457c29dfe1a9,2
+np.float64,0x8006c2853d0d850b,0x8006c2853d0d850b,2
+np.float64,0xffef26e25ffe4dc4,0xbff0000000000000,2
+np.float64,0x7fefffffffffffff,0x3ff0000000000000,2
+np.float64,0xbfde98f2c2bd31e6,0xbfdc761bfab1c4cb,2
+np.float64,0xffb725e6222e4bd0,0xbff0000000000000,2
+np.float64,0x800c63ead5d8c7d6,0x800c63ead5d8c7d6,2
+np.float64,0x3fea087e95f410fd,0x3fe57d3ab440706c,2
+np.float64,0xbfdf9f8a603f3f14,0xbfdd4742d77dfa57,2
+np.float64,0xfff0000000000000,0xbff0000000000000,2
+np.float64,0xbfcdc0841d3b8108,0xbfcd3a401debba9a,2
+np.float64,0x800f0c8f4f7e191f,0x800f0c8f4f7e191f,2
+np.float64,0x800ba6e75fd74dcf,0x800ba6e75fd74dcf,2
+np.float64,0x7fee4927e8bc924f,0x3ff0000000000000,2
+np.float64,0x3fadf141903be283,0x3fade8878d9d3551,2
+np.float64,0x3efb1a267df64,0x3efb1a267df64,2
+np.float64,0xffebf55f22b7eabe,0xbff0000000000000,2
+np.float64,0x7fbe8045663d008a,0x3ff0000000000000,2
+np.float64,0x3fefc0129f7f8026,0x3fe843f8b7d6cf38,2
+np.float64,0xbfe846b420f08d68,0xbfe47d1709e43937,2
+np.float64,0x7fe8e87043f1d0e0,0x3ff0000000000000,2
+np.float64,0x3fcfb718453f6e31,0x3fcf14ecee7b32b4,2
+np.float64,0x7fe4306b71a860d6,0x3ff0000000000000,2
+np.float64,0x7fee08459f7c108a,0x3ff0000000000000,2
+np.float64,0x3fed705165fae0a3,0x3fe73a66369c5700,2
+np.float64,0x7fd0e63f4da1cc7e,0x3ff0000000000000,2
+np.float64,0xffd1a40c2ea34818,0xbff0000000000000,2
+np.float64,0xbfa369795c26d2f0,0xbfa36718218d46b3,2
+np.float64,0xef70b9f5dee17,0xef70b9f5dee17,2
+np.float64,0x3fb50a0a6e2a1410,0x3fb4fdf27724560a,2
+np.float64,0x7fe30a0f6166141e,0x3ff0000000000000,2
+np.float64,0xbfd7b3ca7daf6794,0xbfd6accb81032b2d,2
+np.float64,0x3fc21dceb3243b9d,0x3fc1ff15d5d277a3,2
+np.float64,0x3fe483e445a907c9,0x3fe219ca0e269552,2
+np.float64,0x3fb2b1e2a22563c0,0x3fb2a96554900eaf,2
+np.float64,0x4b1ff6409641,0x4b1ff6409641,2
+np.float64,0xbfd92eabc9b25d58,0xbfd7f55d7776d64e,2
+np.float64,0x8003b8604c8770c1,0x8003b8604c8770c1,2
+np.float64,0x800d20a9df1a4154,0x800d20a9df1a4154,2
+np.float64,0xecf8a535d9f15,0xecf8a535d9f15,2
+np.float64,0x3fe92d15bab25a2b,0x3fe50296aa15ae85,2
+np.float64,0x800239c205a47385,0x800239c205a47385,2
+np.float64,0x3fc48664a9290cc8,0x3fc459d126320ef6,2
+np.float64,0x3fe7620625eec40c,0x3fe3f3bcbee3e8c6,2
+np.float64,0x3fd242ff4ca48600,0x3fd1c81ed7a971c8,2
+np.float64,0xbfe39bafcfa73760,0xbfe17959c7a279db,2
+np.float64,0x7fdcd2567239a4ac,0x3ff0000000000000,2
+np.float64,0x3fe5f2f292ebe5e6,0x3fe30d12f05e2752,2
+np.float64,0x7fda3819d1347033,0x3ff0000000000000,2
+np.float64,0xffca5b4d4334b69c,0xbff0000000000000,2
+np.float64,0xb8a2b7cd71457,0xb8a2b7cd71457,2
+np.float64,0x3fee689603fcd12c,0x3fe7ad4ace26d6dd,2
+np.float64,0x7fe26541a564ca82,0x3ff0000000000000,2
+np.float64,0x3fe6912ee66d225e,0x3fe3720d242c4d82,2
+np.float64,0xffe6580c75ecb018,0xbff0000000000000,2
+np.float64,0x7fe01a3370603466,0x3ff0000000000000,2
+np.float64,0xffe84e3f84b09c7e,0xbff0000000000000,2
+np.float64,0x3ff0000000000000,0x3fe85efab514f394,2
+np.float64,0x3fe214d4266429a8,0x3fe05fec03a3c247,2
+np.float64,0x3fd00aec5da015d8,0x3fcf6e070ad4ad62,2
+np.float64,0x800aac8631f5590d,0x800aac8631f5590d,2
+np.float64,0xbfe7c4f5f76f89ec,0xbfe42fc1c57b4a13,2
+np.float64,0xaf146c7d5e28e,0xaf146c7d5e28e,2
+np.float64,0xbfe57188b66ae312,0xbfe2b8be4615ef75,2
+np.float64,0xffef8cb8e1ff1971,0xbff0000000000000,2
+np.float64,0x8001daf8aa63b5f2,0x8001daf8aa63b5f2,2
+np.float64,0x3fdddcc339bbb986,0x3fdbde5f3783538b,2
+np.float64,0xdd8c92c3bb193,0xdd8c92c3bb193,2
+np.float64,0xbfe861a148f0c342,0xbfe48cf1d228a336,2
+np.float64,0xffe260a32e24c146,0xbff0000000000000,2
+np.float64,0x1f7474b43ee8f,0x1f7474b43ee8f,2
+np.float64,0x3fe81dbd89703b7c,0x3fe464d78df92b7b,2
+np.float64,0x7fed0101177a0201,0x3ff0000000000000,2
+np.float64,0x7fd8b419a8316832,0x3ff0000000000000,2
+np.float64,0x3fe93debccf27bd8,0x3fe50c27727917f0,2
+np.float64,0xe5ead05bcbd5a,0xe5ead05bcbd5a,2
+np.float64,0xbfebbbc4cff7778a,0xbfe663c4ca003bbf,2
+np.float64,0xbfea343eb474687e,0xbfe59529f73ea151,2
+np.float64,0x3fbe74a5963ce94b,0x3fbe50123ed05d8d,2
+np.float64,0x3fd31d3a5d263a75,0x3fd290c026cb38a5,2
+np.float64,0xbfd79908acaf3212,0xbfd695620e31c3c6,2
+np.float64,0xbfc26a350324d46c,0xbfc249f335f3e465,2
+np.float64,0xbfac38d5583871b0,0xbfac31866d12a45e,2
+np.float64,0x3fe40cea672819d5,0x3fe1c83754e72c92,2
+np.float64,0xbfa74770642e8ee0,0xbfa74355fcf67332,2
+np.float64,0x7fc60942d32c1285,0x3ff0000000000000,2
diff --git a/numpy/core/tests/test__exceptions.py b/numpy/core/tests/test__exceptions.py
index 51c056936..c87412aa4 100644
--- a/numpy/core/tests/test__exceptions.py
+++ b/numpy/core/tests/test__exceptions.py
@@ -4,6 +4,7 @@ Tests of the ._exceptions module. Primarily for exercising the __str__ methods.
import pickle
+import pytest
import numpy as np
_ArrayMemoryError = np.core._exceptions._ArrayMemoryError
@@ -56,3 +57,32 @@ class TestUFuncNoLoopError:
def test_pickling(self):
""" Test that _UFuncNoLoopError can be pickled """
assert isinstance(pickle.dumps(_UFuncNoLoopError), bytes)
+
+
+@pytest.mark.parametrize("args", [
+ (2, 1, None),
+ (2, 1, "test_prefix"),
+ ("test message",),
+])
+class TestAxisError:
+ def test_attr(self, args):
+ """Validate attribute types."""
+ exc = np.AxisError(*args)
+ if len(args) == 1:
+ assert exc.axis is None
+ assert exc.ndim is None
+ else:
+ axis, ndim, *_ = args
+ assert exc.axis == axis
+ assert exc.ndim == ndim
+
+ def test_pickling(self, args):
+ """Test that `AxisError` can be pickled."""
+ exc = np.AxisError(*args)
+ exc2 = pickle.loads(pickle.dumps(exc))
+
+ assert type(exc) is type(exc2)
+ for name in ("axis", "ndim", "args"):
+ attr1 = getattr(exc, name)
+ attr2 = getattr(exc2, name)
+ assert attr1 == attr2, name
diff --git a/numpy/core/tests/test_api.py b/numpy/core/tests/test_api.py
index 0f42f7076..291cdae89 100644
--- a/numpy/core/tests/test_api.py
+++ b/numpy/core/tests/test_api.py
@@ -149,7 +149,7 @@ def test_array_impossible_casts(array):
rt = rational(1, 2)
if array:
rt = np.array(rt)
- with assert_raises(ValueError):
+ with assert_raises(TypeError):
np.array(rt, dtype="M8")
@@ -281,6 +281,19 @@ def test_array_astype():
a = np.array(1000, dtype='i4')
assert_raises(TypeError, a.astype, 'U1', casting='safe')
+@pytest.mark.parametrize("dt", ["S", "U"])
+def test_array_astype_to_string_discovery_empty(dt):
+ # See also gh-19085
+ arr = np.array([""], dtype=object)
+ # Note, the itemsize is the `0 -> 1` logic, which should change.
+ # The important part the test is rather that it does not error.
+ assert arr.astype(dt).dtype.itemsize == np.dtype(f"{dt}1").itemsize
+
+ # check the same thing for `np.can_cast` (since it accepts arrays)
+ assert np.can_cast(arr, dt, casting="unsafe")
+ assert not np.can_cast(arr, dt, casting="same_kind")
+ # as well as for the object as a descriptor:
+ assert np.can_cast("O", dt, casting="unsafe")
@pytest.mark.parametrize("dt", ["d", "f", "S13", "U32"])
def test_array_astype_to_void(dt):
diff --git a/numpy/core/tests/test_argparse.py b/numpy/core/tests/test_argparse.py
new file mode 100644
index 000000000..63a01dee4
--- /dev/null
+++ b/numpy/core/tests/test_argparse.py
@@ -0,0 +1,62 @@
+"""
+Tests for the private NumPy argument parsing functionality.
+They mainly exists to ensure good test coverage without having to try the
+weirder cases on actual numpy functions but test them in one place.
+
+The test function is defined in C to be equivalent to (errors may not always
+match exactly, and could be adjusted):
+
+ def func(arg1, /, arg2, *, arg3):
+ i = integer(arg1) # reproducing the 'i' parsing in Python.
+ return None
+"""
+
+import pytest
+
+import numpy as np
+from numpy.core._multiarray_tests import argparse_example_function as func
+
+
+def test_invalid_integers():
+ with pytest.raises(TypeError,
+ match="integer argument expected, got float"):
+ func(1.)
+ with pytest.raises(OverflowError):
+ func(2**100)
+
+
+def test_missing_arguments():
+ with pytest.raises(TypeError,
+ match="missing required positional argument 0"):
+ func()
+ with pytest.raises(TypeError,
+ match="missing required positional argument 0"):
+ func(arg2=1, arg3=4)
+ with pytest.raises(TypeError,
+ match=r"missing required argument \'arg2\' \(pos 1\)"):
+ func(1, arg3=5)
+
+
+def test_too_many_positional():
+ # the second argument is positional but can be passed as keyword.
+ with pytest.raises(TypeError,
+ match="takes from 2 to 3 positional arguments but 4 were given"):
+ func(1, 2, 3, 4)
+
+
+def test_multiple_values():
+ with pytest.raises(TypeError,
+ match=r"given by name \('arg2'\) and position \(position 1\)"):
+ func(1, 2, arg2=3)
+
+
+def test_string_fallbacks():
+ # We can (currently?) use numpy strings to test the "slow" fallbacks
+ # that should normally not be taken due to string interning.
+ arg2 = np.unicode_("arg2")
+ missing_arg = np.unicode_("missing_arg")
+ func(1, **{arg2: 3})
+ with pytest.raises(TypeError,
+ match="got an unexpected keyword argument 'missing_arg'"):
+ func(2, **{missing_arg: 3})
+
diff --git a/numpy/core/tests/test_array_coercion.py b/numpy/core/tests/test_array_coercion.py
index 78def9360..076d8e43f 100644
--- a/numpy/core/tests/test_array_coercion.py
+++ b/numpy/core/tests/test_array_coercion.py
@@ -38,8 +38,18 @@ def arraylikes():
yield subclass
+ class _SequenceLike():
+ # We are giving a warning that array-like's were also expected to be
+ # sequence-like in `np.array([array_like])`, this can be removed
+ # when the deprecation exired (started NumPy 1.20)
+ def __len__(self):
+ raise TypeError
+
+ def __getitem__(self):
+ raise TypeError
+
# Array-interface
- class ArrayDunder:
+ class ArrayDunder(_SequenceLike):
def __init__(self, a):
self.a = a
@@ -52,7 +62,7 @@ def arraylikes():
yield param(memoryview, id="memoryview")
# Array-interface
- class ArrayInterface:
+ class ArrayInterface(_SequenceLike):
def __init__(self, a):
self.a = a # need to hold on to keep interface valid
self.__array_interface__ = a.__array_interface__
@@ -60,7 +70,7 @@ def arraylikes():
yield param(ArrayInterface, id="__array_interface__")
# Array-Struct
- class ArrayStruct:
+ class ArrayStruct(_SequenceLike):
def __init__(self, a):
self.a = a # need to hold on to keep struct valid
self.__array_struct__ = a.__array_struct__
@@ -224,6 +234,7 @@ class TestScalarDiscovery:
# Additionally to string this test also runs into a corner case
# with datetime promotion (the difference is the promotion order).
+ @pytest.mark.filterwarnings("ignore:Promotion of numbers:FutureWarning")
def test_scalar_promotion(self):
for sc1, sc2 in product(scalar_instances(), scalar_instances()):
sc1, sc2 = sc1.values[0], sc2.values[0]
@@ -331,6 +342,20 @@ class TestScalarDiscovery:
ass[()] = scalar
assert_array_equal(ass, cast)
+ @pytest.mark.parametrize("pyscalar", [10, 10.32, 10.14j, 10**100])
+ def test_pyscalar_subclasses(self, pyscalar):
+ """NumPy arrays are read/write which means that anything but invariant
+ behaviour is on thin ice. However, we currently are happy to discover
+ subclasses of Python float, int, complex the same as the base classes.
+ This should potentially be deprecated.
+ """
+ class MyScalar(type(pyscalar)):
+ pass
+
+ res = np.array(MyScalar(pyscalar))
+ expected = np.array(pyscalar)
+ assert_array_equal(res, expected)
+
@pytest.mark.parametrize("dtype_char", np.typecodes["All"])
def test_default_dtype_instance(self, dtype_char):
if dtype_char in "SU":
@@ -689,3 +714,35 @@ class TestArrayLikes:
np.array(arr)
with pytest.raises(MemoryError):
np.array([arr])
+
+ @pytest.mark.parametrize("attribute",
+ ["__array_interface__", "__array__", "__array_struct__"])
+ @pytest.mark.parametrize("error", [RecursionError, MemoryError])
+ def test_bad_array_like_attributes(self, attribute, error):
+ # RecursionError and MemoryError are considered fatal. All errors
+ # (except AttributeError) should probably be raised in the future,
+ # but shapely made use of it, so it will require a deprecation.
+
+ class BadInterface:
+ def __getattr__(self, attr):
+ if attr == attribute:
+ raise error
+ super().__getattr__(attr)
+
+ with pytest.raises(error):
+ np.array(BadInterface())
+
+ @pytest.mark.parametrize("error", [RecursionError, MemoryError])
+ def test_bad_array_like_bad_length(self, error):
+ # RecursionError and MemoryError are considered "critical" in
+ # sequences. We could expand this more generally though. (NumPy 1.20)
+ class BadSequence:
+ def __len__(self):
+ raise error
+ def __getitem__(self):
+ # must have getitem to be a Sequence
+ return 1
+
+ with pytest.raises(error):
+ np.array(BadSequence())
+
diff --git a/numpy/core/tests/test_arraymethod.py b/numpy/core/tests/test_arraymethod.py
new file mode 100644
index 000000000..b1bc79b80
--- /dev/null
+++ b/numpy/core/tests/test_arraymethod.py
@@ -0,0 +1,58 @@
+"""
+This file tests the generic aspects of ArrayMethod. At the time of writing
+this is private API, but when added, public API may be added here.
+"""
+
+import pytest
+
+import numpy as np
+from numpy.core._multiarray_umath import _get_castingimpl as get_castingimpl
+
+
+class TestResolveDescriptors:
+ # Test mainly error paths of the resolve_descriptors function,
+ # note that the `casting_unittests` tests exercise this non-error paths.
+
+ # Casting implementations are the main/only current user:
+ method = get_castingimpl(type(np.dtype("d")), type(np.dtype("f")))
+
+ @pytest.mark.parametrize("args", [
+ (True,), # Not a tuple.
+ ((None,)), # Too few elements
+ ((None, None, None),), # Too many
+ ((None, None),), # Input dtype is None, which is invalid.
+ ((np.dtype("d"), True),), # Output dtype is not a dtype
+ ((np.dtype("f"), None),), # Input dtype does not match method
+ ])
+ def test_invalid_arguments(self, args):
+ with pytest.raises(TypeError):
+ self.method._resolve_descriptors(*args)
+
+
+class TestSimpleStridedCall:
+ # Test mainly error paths of the resolve_descriptors function,
+ # note that the `casting_unittests` tests exercise this non-error paths.
+
+ # Casting implementations are the main/only current user:
+ method = get_castingimpl(type(np.dtype("d")), type(np.dtype("f")))
+
+ @pytest.mark.parametrize(["args", "error"], [
+ ((True,), TypeError), # Not a tuple
+ (((None,),), TypeError), # Too few elements
+ ((None, None), TypeError), # Inputs are not arrays.
+ (((None, None, None),), TypeError), # Too many
+ (((np.arange(3), np.arange(3)),), TypeError), # Incorrect dtypes
+ (((np.ones(3, dtype=">d"), np.ones(3, dtype="<f")),),
+ TypeError), # Does not support byte-swapping
+ (((np.ones((2, 2), dtype="d"), np.ones((2, 2), dtype="f")),),
+ ValueError), # not 1-D
+ (((np.ones(3, dtype="d"), np.ones(4, dtype="f")),),
+ ValueError), # different length
+ (((np.frombuffer(b"\0x00"*3*2, dtype="d"),
+ np.frombuffer(b"\0x00"*3, dtype="f")),),
+ ValueError), # output not writeable
+ ])
+ def test_invalid_arguments(self, args, error):
+ # This is private API, which may be modified freely
+ with pytest.raises(error):
+ self.method._simple_strided_call(*args)
diff --git a/numpy/core/tests/test_arrayprint.py b/numpy/core/tests/test_arrayprint.py
index a2703d81b..09cc79f72 100644
--- a/numpy/core/tests/test_arrayprint.py
+++ b/numpy/core/tests/test_arrayprint.py
@@ -45,7 +45,7 @@ class TestArrayRepr:
return obj
def __getitem__(self, ind):
- ret = super(sub, self).__getitem__(ind)
+ ret = super().__getitem__(ind)
return sub(ret)
# test that object + subclass is OK:
@@ -67,7 +67,7 @@ class TestArrayRepr:
return obj
def __getitem__(self, ind):
- ret = super(sub, self).__getitem__(ind)
+ ret = super().__getitem__(ind)
return sub(ret)
x = sub(1)
@@ -101,7 +101,7 @@ class TestArrayRepr:
# gh-10663
class DuckCounter(np.ndarray):
def __getitem__(self, item):
- result = super(DuckCounter, self).__getitem__(item)
+ result = super().__getitem__(item)
if not isinstance(result, DuckCounter):
result = result[...].view(DuckCounter)
return result
@@ -759,6 +759,10 @@ class TestPrintOptions:
assert_equal(repr(c),
"array([1.00000000+1.00000000j, 1.12345679+1.12345679j])")
+ # test unique special case (gh-18609)
+ a = np.float64.fromhex('-1p-97')
+ assert_equal(np.float64(np.array2string(a, floatmode='unique')), a)
+
def test_legacy_mode_scalars(self):
# in legacy mode, str of floats get truncated, and complex scalars
# use * for non-finite imaginary part
@@ -923,6 +927,9 @@ class TestPrintOptions:
assert_raises(TypeError, np.set_printoptions, threshold='1')
assert_raises(TypeError, np.set_printoptions, threshold=b'1')
+ assert_raises(TypeError, np.set_printoptions, precision='1')
+ assert_raises(TypeError, np.set_printoptions, precision=1.5)
+
def test_unicode_object_array():
expected = "array(['é'], dtype=object)"
x = np.array([u'\xe9'], dtype=object)
diff --git a/numpy/core/tests/test_casting_unittests.py b/numpy/core/tests/test_casting_unittests.py
index fec0ae7c7..3f67f1832 100644
--- a/numpy/core/tests/test_casting_unittests.py
+++ b/numpy/core/tests/test_casting_unittests.py
@@ -9,19 +9,20 @@ than integration tests.
import pytest
import textwrap
import enum
+import itertools
+import random
import numpy as np
+from numpy.lib.stride_tricks import as_strided
-from numpy.core._multiarray_umath import (
- _get_castingimpl as get_castingimpl)
-from numpy.core._multiarray_tests import uses_new_casts
+from numpy.testing import assert_array_equal
+from numpy.core._multiarray_umath import _get_castingimpl as get_castingimpl
# Simple skips object, parametric and long double (unsupported by struct)
simple_dtypes = "?bhilqBHILQefdFD"
if np.dtype("l").itemsize != np.dtype("q").itemsize:
# Remove l and L, the table was generated with 64bit linux in mind.
- # TODO: Should have two tables or no a different solution.
simple_dtypes = simple_dtypes.replace("l", "").replace("L", "")
simple_dtypes = [type(np.dtype(c)) for c in simple_dtypes]
@@ -133,11 +134,7 @@ class TestChanges:
def test_float_to_string(self, floating, string):
assert np.can_cast(floating, string)
# 100 is long enough to hold any formatted floating
- if uses_new_casts():
- assert np.can_cast(floating, f"{string}100")
- else:
- assert not np.can_cast(floating, f"{string}100")
- assert np.can_cast(floating, f"{string}100", casting="same_kind")
+ assert np.can_cast(floating, f"{string}100")
def test_to_void(self):
# But in general, we do consider these safe:
@@ -145,20 +142,113 @@ class TestChanges:
assert np.can_cast("S20", "V")
# Do not consider it a safe cast if the void is too smaller:
- if uses_new_casts():
- assert not np.can_cast("d", "V1")
- assert not np.can_cast("S20", "V1")
- assert not np.can_cast("U1", "V1")
- # Structured to unstructured is just like any other:
- assert np.can_cast("d,i", "V", casting="same_kind")
- else:
- assert np.can_cast("d", "V1")
- assert np.can_cast("S20", "V1")
- assert np.can_cast("U1", "V1")
- assert not np.can_cast("d,i", "V", casting="same_kind")
+ assert not np.can_cast("d", "V1")
+ assert not np.can_cast("S20", "V1")
+ assert not np.can_cast("U1", "V1")
+ # Structured to unstructured is just like any other:
+ assert np.can_cast("d,i", "V", casting="same_kind")
+ # Unstructured void to unstructured is actually no cast at all:
+ assert np.can_cast("V3", "V", casting="no")
+ assert np.can_cast("V0", "V", casting="no")
class TestCasting:
+ size = 1500 # Best larger than NPY_LOWLEVEL_BUFFER_BLOCKSIZE * itemsize
+
+ def get_data(self, dtype1, dtype2):
+ if dtype2 is None or dtype1.itemsize >= dtype2.itemsize:
+ length = self.size // dtype1.itemsize
+ else:
+ length = self.size // dtype2.itemsize
+
+ # Assume that the base array is well enough aligned for all inputs.
+ arr1 = np.empty(length, dtype=dtype1)
+ assert arr1.flags.c_contiguous
+ assert arr1.flags.aligned
+
+ values = [random.randrange(-128, 128) for _ in range(length)]
+
+ for i, value in enumerate(values):
+ # Use item assignment to ensure this is not using casting:
+ arr1[i] = value
+
+ if dtype2 is None:
+ if dtype1.char == "?":
+ values = [bool(v) for v in values]
+ return arr1, values
+
+ if dtype2.char == "?":
+ values = [bool(v) for v in values]
+
+ arr2 = np.empty(length, dtype=dtype2)
+ assert arr2.flags.c_contiguous
+ assert arr2.flags.aligned
+
+ for i, value in enumerate(values):
+ # Use item assignment to ensure this is not using casting:
+ arr2[i] = value
+
+ return arr1, arr2, values
+
+ def get_data_variation(self, arr1, arr2, aligned=True, contig=True):
+ """
+ Returns a copy of arr1 that may be non-contiguous or unaligned, and a
+ matching array for arr2 (although not a copy).
+ """
+ if contig:
+ stride1 = arr1.dtype.itemsize
+ stride2 = arr2.dtype.itemsize
+ elif aligned:
+ stride1 = 2 * arr1.dtype.itemsize
+ stride2 = 2 * arr2.dtype.itemsize
+ else:
+ stride1 = arr1.dtype.itemsize + 1
+ stride2 = arr2.dtype.itemsize + 1
+
+ max_size1 = len(arr1) * 3 * arr1.dtype.itemsize + 1
+ max_size2 = len(arr2) * 3 * arr2.dtype.itemsize + 1
+ from_bytes = np.zeros(max_size1, dtype=np.uint8)
+ to_bytes = np.zeros(max_size2, dtype=np.uint8)
+
+ # Sanity check that the above is large enough:
+ assert stride1 * len(arr1) <= from_bytes.nbytes
+ assert stride2 * len(arr2) <= to_bytes.nbytes
+
+ if aligned:
+ new1 = as_strided(from_bytes[:-1].view(arr1.dtype),
+ arr1.shape, (stride1,))
+ new2 = as_strided(to_bytes[:-1].view(arr2.dtype),
+ arr2.shape, (stride2,))
+ else:
+ new1 = as_strided(from_bytes[1:].view(arr1.dtype),
+ arr1.shape, (stride1,))
+ new2 = as_strided(to_bytes[1:].view(arr2.dtype),
+ arr2.shape, (stride2,))
+
+ new1[...] = arr1
+
+ if not contig:
+ # Ensure we did not overwrite bytes that should not be written:
+ offset = arr1.dtype.itemsize if aligned else 0
+ buf = from_bytes[offset::stride1].tobytes()
+ assert buf.count(b"\0") == len(buf)
+
+ if contig:
+ assert new1.flags.c_contiguous
+ assert new2.flags.c_contiguous
+ else:
+ assert not new1.flags.c_contiguous
+ assert not new2.flags.c_contiguous
+
+ if aligned:
+ assert new1.flags.aligned
+ assert new2.flags.aligned
+ else:
+ assert not new1.flags.aligned or new1.dtype.alignment == 1
+ assert not new2.flags.aligned or new2.dtype.alignment == 1
+
+ return new1, new2
+
@pytest.mark.parametrize("from_Dt", simple_dtypes)
def test_simple_cancast(self, from_Dt):
for to_Dt in simple_dtypes:
@@ -193,6 +283,183 @@ class TestCasting:
assert(to_dt is to_res)
+ @pytest.mark.filterwarnings("ignore::numpy.ComplexWarning")
+ @pytest.mark.parametrize("from_dt", simple_dtype_instances())
+ def test_simple_direct_casts(self, from_dt):
+ """
+ This test checks numeric direct casts for dtypes supported also by the
+ struct module (plus complex). It tries to be test a wide range of
+ inputs, but skips over possibly undefined behaviour (e.g. int rollover).
+ Longdouble and CLongdouble are tested, but only using double precision.
+
+ If this test creates issues, it should possibly just be simplified
+ or even removed (checking whether unaligned/non-contiguous casts give
+ the same results is useful, though).
+ """
+ for to_dt in simple_dtype_instances():
+ to_dt = to_dt.values[0]
+ cast = get_castingimpl(type(from_dt), type(to_dt))
+
+ casting, (from_res, to_res) = cast._resolve_descriptors(
+ (from_dt, to_dt))
+
+ if from_res is not from_dt or to_res is not to_dt:
+ # Do not test this case, it is handled in multiple steps,
+ # each of which should is tested individually.
+ return
+
+ safe = (casting & ~Casting.cast_is_view) <= Casting.safe
+ del from_res, to_res, casting
+
+ arr1, arr2, values = self.get_data(from_dt, to_dt)
+
+ cast._simple_strided_call((arr1, arr2))
+
+ # Check via python list
+ assert arr2.tolist() == values
+
+ # Check that the same results are achieved for strided loops
+ arr1_o, arr2_o = self.get_data_variation(arr1, arr2, True, False)
+ cast._simple_strided_call((arr1_o, arr2_o))
+
+ assert_array_equal(arr2_o, arr2)
+ assert arr2_o.tobytes() == arr2.tobytes()
+
+ # Check if alignment makes a difference, but only if supported
+ # and only if the alignment can be wrong
+ if ((from_dt.alignment == 1 and to_dt.alignment == 1) or
+ not cast._supports_unaligned):
+ return
+
+ arr1_o, arr2_o = self.get_data_variation(arr1, arr2, False, True)
+ cast._simple_strided_call((arr1_o, arr2_o))
+
+ assert_array_equal(arr2_o, arr2)
+ assert arr2_o.tobytes() == arr2.tobytes()
+
+ arr1_o, arr2_o = self.get_data_variation(arr1, arr2, False, False)
+ cast._simple_strided_call((arr1_o, arr2_o))
+
+ assert_array_equal(arr2_o, arr2)
+ assert arr2_o.tobytes() == arr2.tobytes()
+
+ del arr1_o, arr2_o, cast
+
+ @pytest.mark.parametrize("from_Dt", simple_dtypes)
+ def test_numeric_to_times(self, from_Dt):
+ # We currently only implement contiguous loops, so only need to
+ # test those.
+ from_dt = from_Dt()
+
+ time_dtypes = [np.dtype("M8"), np.dtype("M8[ms]"), np.dtype("M8[4D]"),
+ np.dtype("m8"), np.dtype("m8[ms]"), np.dtype("m8[4D]")]
+ for time_dt in time_dtypes:
+ cast = get_castingimpl(type(from_dt), type(time_dt))
+
+ casting, (from_res, to_res) = cast._resolve_descriptors(
+ (from_dt, time_dt))
+
+ assert from_res is from_dt
+ assert to_res is time_dt
+ del from_res, to_res
+
+ assert(casting & CAST_TABLE[from_Dt][type(time_dt)])
+
+ int64_dt = np.dtype(np.int64)
+ arr1, arr2, values = self.get_data(from_dt, int64_dt)
+ arr2 = arr2.view(time_dt)
+ arr2[...] = np.datetime64("NaT")
+
+ if time_dt == np.dtype("M8"):
+ # This is a bit of a strange path, and could probably be removed
+ arr1[-1] = 0 # ensure at least one value is not NaT
+
+ # The cast currently succeeds, but the values are invalid:
+ cast._simple_strided_call((arr1, arr2))
+ with pytest.raises(ValueError):
+ str(arr2[-1]) # e.g. conversion to string fails
+ return
+
+ cast._simple_strided_call((arr1, arr2))
+
+ assert [int(v) for v in arr2.tolist()] == values
+
+ # Check that the same results are achieved for strided loops
+ arr1_o, arr2_o = self.get_data_variation(arr1, arr2, True, False)
+ cast._simple_strided_call((arr1_o, arr2_o))
+
+ assert_array_equal(arr2_o, arr2)
+ assert arr2_o.tobytes() == arr2.tobytes()
+
+ @pytest.mark.parametrize(
+ ["from_dt", "to_dt", "expected_casting", "nom", "denom"],
+ [("M8[ns]", None,
+ Casting.no | Casting.cast_is_view, 1, 1),
+ (str(np.dtype("M8[ns]").newbyteorder()), None, Casting.equiv, 1, 1),
+ ("M8", "M8[ms]", Casting.safe | Casting.cast_is_view, 1, 1),
+ ("M8[ms]", "M8", Casting.unsafe, 1, 1), # should be invalid cast
+ ("M8[5ms]", "M8[5ms]", Casting.no | Casting.cast_is_view, 1, 1),
+ ("M8[ns]", "M8[ms]", Casting.same_kind, 1, 10**6),
+ ("M8[ms]", "M8[ns]", Casting.safe, 10**6, 1),
+ ("M8[ms]", "M8[7ms]", Casting.same_kind, 1, 7),
+ ("M8[4D]", "M8[1M]", Casting.same_kind, None,
+ # give full values based on NumPy 1.19.x
+ [-2**63, 0, -1, 1314, -1315, 564442610]),
+ ("m8[ns]", None, Casting.no | Casting.cast_is_view, 1, 1),
+ (str(np.dtype("m8[ns]").newbyteorder()), None, Casting.equiv, 1, 1),
+ ("m8", "m8[ms]", Casting.safe | Casting.cast_is_view, 1, 1),
+ ("m8[ms]", "m8", Casting.unsafe, 1, 1), # should be invalid cast
+ ("m8[5ms]", "m8[5ms]", Casting.no | Casting.cast_is_view, 1, 1),
+ ("m8[ns]", "m8[ms]", Casting.same_kind, 1, 10**6),
+ ("m8[ms]", "m8[ns]", Casting.safe, 10**6, 1),
+ ("m8[ms]", "m8[7ms]", Casting.same_kind, 1, 7),
+ ("m8[4D]", "m8[1M]", Casting.unsafe, None,
+ # give full values based on NumPy 1.19.x
+ [-2**63, 0, 0, 1314, -1315, 564442610])])
+ def test_time_to_time(self, from_dt, to_dt, expected_casting, nom, denom):
+ from_dt = np.dtype(from_dt)
+ if to_dt is not None:
+ to_dt = np.dtype(to_dt)
+
+ # Test a few values for casting (results generated with NumPy 1.19)
+ values = np.array([-2**63, 1, 2**63-1, 10000, -10000, 2**32])
+ values = values.astype(np.dtype("int64").newbyteorder(from_dt.byteorder))
+ assert values.dtype.byteorder == from_dt.byteorder
+ assert np.isnat(values.view(from_dt)[0])
+
+ DType = type(from_dt)
+ cast = get_castingimpl(DType, DType)
+ casting, (from_res, to_res) = cast._resolve_descriptors((from_dt, to_dt))
+ assert from_res is from_dt
+ assert to_res is to_dt or to_dt is None
+ assert casting == expected_casting
+
+ if nom is not None:
+ expected_out = (values * nom // denom).view(to_res)
+ expected_out[0] = "NaT"
+ else:
+ expected_out = np.empty_like(values)
+ expected_out[...] = denom
+ expected_out = expected_out.view(to_dt)
+
+ orig_arr = values.view(from_dt)
+ orig_out = np.empty_like(expected_out)
+
+ if casting == Casting.unsafe and (to_dt == "m8" or to_dt == "M8"):
+ # Casting from non-generic to generic units is an error and should
+ # probably be reported as an invalid cast earlier.
+ with pytest.raises(ValueError):
+ cast._simple_strided_call((orig_arr, orig_out))
+ return
+
+ for aligned in [True, True]:
+ for contig in [True, True]:
+ arr, out = self.get_data_variation(
+ orig_arr, orig_out, aligned, contig)
+ out[...] = 0
+ cast._simple_strided_call((arr, out))
+ assert_array_equal(out.view("int64"), expected_out.view("int64"))
+
def string_with_modified_length(self, dtype, change_length):
fact = 1 if dtype.char == "S" else 4
length = dtype.itemsize // fact + change_length
@@ -239,6 +506,67 @@ class TestCasting:
assert safety == Casting.unsafe
assert other_dt is res_dt # returns the singleton for simple dtypes
+ @pytest.mark.parametrize("string_char", ["S", "U"])
+ @pytest.mark.parametrize("other_dt", simple_dtype_instances())
+ def test_simple_string_casts_roundtrip(self, other_dt, string_char):
+ """
+ Tests casts from and to string by checking the roundtripping property.
+
+ The test also covers some string to string casts (but not all).
+
+ If this test creates issues, it should possibly just be simplified
+ or even removed (checking whether unaligned/non-contiguous casts give
+ the same results is useful, though).
+ """
+ string_DT = type(np.dtype(string_char))
+
+ cast = get_castingimpl(type(other_dt), string_DT)
+ cast_back = get_castingimpl(string_DT, type(other_dt))
+ _, (res_other_dt, string_dt) = cast._resolve_descriptors((other_dt, None))
+
+ if res_other_dt is not other_dt:
+ # do not support non-native byteorder, skip test in that case
+ assert other_dt.byteorder != res_other_dt.byteorder
+ return
+
+ orig_arr, values = self.get_data(other_dt, None)
+ str_arr = np.zeros(len(orig_arr), dtype=string_dt)
+ string_dt_short = self.string_with_modified_length(string_dt, -1)
+ str_arr_short = np.zeros(len(orig_arr), dtype=string_dt_short)
+ string_dt_long = self.string_with_modified_length(string_dt, 1)
+ str_arr_long = np.zeros(len(orig_arr), dtype=string_dt_long)
+
+ assert not cast._supports_unaligned # if support is added, should test
+ assert not cast_back._supports_unaligned
+
+ for contig in [True, False]:
+ other_arr, str_arr = self.get_data_variation(
+ orig_arr, str_arr, True, contig)
+ _, str_arr_short = self.get_data_variation(
+ orig_arr, str_arr_short.copy(), True, contig)
+ _, str_arr_long = self.get_data_variation(
+ orig_arr, str_arr_long, True, contig)
+
+ cast._simple_strided_call((other_arr, str_arr))
+
+ cast._simple_strided_call((other_arr, str_arr_short))
+ assert_array_equal(str_arr.astype(string_dt_short), str_arr_short)
+
+ cast._simple_strided_call((other_arr, str_arr_long))
+ assert_array_equal(str_arr, str_arr_long)
+
+ if other_dt.kind == "b":
+ # Booleans do not roundtrip
+ continue
+
+ other_arr[...] = 0
+ cast_back._simple_strided_call((str_arr, other_arr))
+ assert_array_equal(orig_arr, other_arr)
+
+ other_arr[...] = 0
+ cast_back._simple_strided_call((str_arr_long, other_arr))
+ assert_array_equal(orig_arr, other_arr)
+
@pytest.mark.parametrize("other_dt", ["S8", "<U8", ">U8"])
@pytest.mark.parametrize("string_char", ["S", "U"])
def test_string_to_string_cancast(self, other_dt, string_char):
@@ -283,6 +611,28 @@ class TestCasting:
elif change_length > 0:
assert safety == Casting.safe
+ @pytest.mark.parametrize("order1", [">", "<"])
+ @pytest.mark.parametrize("order2", [">", "<"])
+ def test_unicode_byteswapped_cast(self, order1, order2):
+ # Very specific tests (not using the castingimpl directly)
+ # that tests unicode bytedwaps including for unaligned array data.
+ dtype1 = np.dtype(f"{order1}U30")
+ dtype2 = np.dtype(f"{order2}U30")
+ data1 = np.empty(30 * 4 + 1, dtype=np.uint8)[1:].view(dtype1)
+ data2 = np.empty(30 * 4 + 1, dtype=np.uint8)[1:].view(dtype2)
+ if dtype1.alignment != 1:
+ # alignment should always be >1, but skip the check if not
+ assert not data1.flags.aligned
+ assert not data2.flags.aligned
+
+ element = "this is a ünicode string‽"
+ data1[()] = element
+ # Test both `data1` and `data1.copy()` (which should be aligned)
+ for data in [data1, data1.copy()]:
+ data2[...] = data1
+ assert data2[()] == element
+ assert data2.copy()[()] == element
+
def test_void_to_string_special_case(self):
# Cover a small special case in void to string casting that could
# probably just as well be turned into an error (compare
@@ -299,3 +649,52 @@ class TestCasting:
with pytest.raises(TypeError,
match="casting from object to the parametric DType"):
cast._resolve_descriptors((np.dtype("O"), None))
+
+ @pytest.mark.parametrize("dtype", simple_dtype_instances())
+ def test_object_and_simple_resolution(self, dtype):
+ # Simple test to exercise the cast when no instance is specified
+ object_dtype = type(np.dtype(object))
+ cast = get_castingimpl(object_dtype, type(dtype))
+
+ safety, (_, res_dt) = cast._resolve_descriptors((np.dtype("O"), dtype))
+ assert safety == Casting.unsafe
+ assert res_dt is dtype
+
+ safety, (_, res_dt) = cast._resolve_descriptors((np.dtype("O"), None))
+ assert safety == Casting.unsafe
+ assert res_dt == dtype.newbyteorder("=")
+
+ @pytest.mark.parametrize("dtype", simple_dtype_instances())
+ def test_simple_to_object_resolution(self, dtype):
+ # Simple test to exercise the cast when no instance is specified
+ object_dtype = type(np.dtype(object))
+ cast = get_castingimpl(type(dtype), object_dtype)
+
+ safety, (_, res_dt) = cast._resolve_descriptors((dtype, None))
+ assert safety == Casting.safe
+ assert res_dt is np.dtype("O")
+
+ @pytest.mark.parametrize("casting", ["no", "unsafe"])
+ def test_void_and_structured_with_subarray(self, casting):
+ # test case corresponding to gh-19325
+ dtype = np.dtype([("foo", "<f4", (3, 2))])
+ expected = casting == "unsafe"
+ assert np.can_cast("V4", dtype, casting=casting) == expected
+ assert np.can_cast(dtype, "V4", casting=casting) == expected
+
+ @pytest.mark.parametrize("dtype", np.typecodes["All"])
+ def test_object_casts_NULL_None_equivalence(self, dtype):
+ # None to <other> casts may succeed or fail, but a NULL'ed array must
+ # behave the same as one filled with None's.
+ arr_normal = np.array([None] * 5)
+ arr_NULLs = np.empty_like([None] * 5)
+ # If the check fails (maybe it should) the test would lose its purpose:
+ assert arr_NULLs.tobytes() == b"\x00" * arr_NULLs.nbytes
+
+ try:
+ expected = arr_normal.astype(dtype)
+ except TypeError:
+ with pytest.raises(TypeError):
+ arr_NULLs.astype(dtype)
+ else:
+ assert_array_equal(expected, arr_NULLs.astype(dtype))
diff --git a/numpy/core/tests/test_cpu_features.py b/numpy/core/tests/test_cpu_features.py
index bafa5a05f..2ccbff41c 100644
--- a/numpy/core/tests/test_cpu_features.py
+++ b/numpy/core/tests/test_cpu_features.py
@@ -48,7 +48,7 @@ def assert_features_equal(actual, desired, fname):
"%s"
) % (fname, actual, desired, error_report))
-class AbstractTest(object):
+class AbstractTest:
features = []
features_groups = {}
features_map = {}
@@ -104,9 +104,12 @@ class AbstractTest(object):
)
is_linux = sys.platform.startswith('linux')
+is_cygwin = sys.platform.startswith('cygwin')
machine = platform.machine()
is_x86 = re.match("^(amd64|x86|i386|i686)", machine, re.IGNORECASE)
-@pytest.mark.skipif(not is_linux or not is_x86, reason="Only for Linux and x86")
+@pytest.mark.skipif(
+ not (is_linux or is_cygwin) or not is_x86, reason="Only for Linux and x86"
+)
class Test_X86_Features(AbstractTest):
features = [
"MMX", "SSE", "SSE2", "SSE3", "SSSE3", "SSE41", "POPCNT", "SSE42",
diff --git a/numpy/core/tests/test_custom_dtypes.py b/numpy/core/tests/test_custom_dtypes.py
new file mode 100644
index 000000000..3ec2363b9
--- /dev/null
+++ b/numpy/core/tests/test_custom_dtypes.py
@@ -0,0 +1,135 @@
+import pytest
+
+import numpy as np
+from numpy.testing import assert_array_equal
+from numpy.core._multiarray_umath import (
+ _discover_array_parameters as discover_array_params, _get_sfloat_dtype)
+
+
+SF = _get_sfloat_dtype()
+
+
+class TestSFloat:
+ def _get_array(self, scaling, aligned=True):
+ if not aligned:
+ a = np.empty(3*8 + 1, dtype=np.uint8)[1:]
+ a = a.view(np.float64)
+ a[:] = [1., 2., 3.]
+ else:
+ a = np.array([1., 2., 3.])
+
+ a *= 1./scaling # the casting code also uses the reciprocal.
+ return a.view(SF(scaling))
+
+ def test_sfloat_rescaled(self):
+ sf = SF(1.)
+ sf2 = sf.scaled_by(2.)
+ assert sf2.get_scaling() == 2.
+ sf6 = sf2.scaled_by(3.)
+ assert sf6.get_scaling() == 6.
+
+ def test_class_discovery(self):
+ # This does not test much, since we always discover the scaling as 1.
+ # But most of NumPy (when writing) does not understand DType classes
+ dt, _ = discover_array_params([1., 2., 3.], dtype=SF)
+ assert dt == SF(1.)
+
+ @pytest.mark.parametrize("scaling", [1., -1., 2.])
+ def test_scaled_float_from_floats(self, scaling):
+ a = np.array([1., 2., 3.], dtype=SF(scaling))
+
+ assert a.dtype.get_scaling() == scaling
+ assert_array_equal(scaling * a.view(np.float64), [1., 2., 3.])
+
+ def test_repr(self):
+ # Check the repr, mainly to cover the code paths:
+ assert repr(SF(scaling=1.)) == "_ScaledFloatTestDType(scaling=1.0)"
+
+ @pytest.mark.parametrize("scaling", [1., -1., 2.])
+ def test_sfloat_from_float(self, scaling):
+ a = np.array([1., 2., 3.]).astype(dtype=SF(scaling))
+
+ assert a.dtype.get_scaling() == scaling
+ assert_array_equal(scaling * a.view(np.float64), [1., 2., 3.])
+
+ @pytest.mark.parametrize("aligned", [True, False])
+ @pytest.mark.parametrize("scaling", [1., -1., 2.])
+ def test_sfloat_getitem(self, aligned, scaling):
+ a = self._get_array(1., aligned)
+ assert a.tolist() == [1., 2., 3.]
+
+ @pytest.mark.parametrize("aligned", [True, False])
+ def test_sfloat_casts(self, aligned):
+ a = self._get_array(1., aligned)
+
+ assert np.can_cast(a, SF(-1.), casting="equiv")
+ assert not np.can_cast(a, SF(-1.), casting="no")
+ na = a.astype(SF(-1.))
+ assert_array_equal(-1 * na.view(np.float64), a.view(np.float64))
+
+ assert np.can_cast(a, SF(2.), casting="same_kind")
+ assert not np.can_cast(a, SF(2.), casting="safe")
+ a2 = a.astype(SF(2.))
+ assert_array_equal(2 * a2.view(np.float64), a.view(np.float64))
+
+ @pytest.mark.parametrize("aligned", [True, False])
+ def test_sfloat_cast_internal_errors(self, aligned):
+ a = self._get_array(2e300, aligned)
+
+ with pytest.raises(TypeError,
+ match="error raised inside the core-loop: non-finite factor!"):
+ a.astype(SF(2e-300))
+
+ def test_sfloat_promotion(self):
+ assert np.result_type(SF(2.), SF(3.)) == SF(3.)
+ assert np.result_type(SF(3.), SF(2.)) == SF(3.)
+ # Float64 -> SF(1.) and then promotes normally, so both of this work:
+ assert np.result_type(SF(3.), np.float64) == SF(3.)
+ assert np.result_type(np.float64, SF(0.5)) == SF(1.)
+
+ # Test an undefined promotion:
+ with pytest.raises(TypeError):
+ np.result_type(SF(1.), np.int64)
+
+ def test_basic_multiply(self):
+ a = self._get_array(2.)
+ b = self._get_array(4.)
+
+ res = a * b
+ # multiplies dtype scaling and content separately:
+ assert res.dtype.get_scaling() == 8.
+ expected_view = a.view(np.float64) * b.view(np.float64)
+ assert_array_equal(res.view(np.float64), expected_view)
+
+ def test_basic_addition(self):
+ a = self._get_array(2.)
+ b = self._get_array(4.)
+
+ res = a + b
+ # addition uses the type promotion rules for the result:
+ assert res.dtype == np.result_type(a.dtype, b.dtype)
+ expected_view = (a.astype(res.dtype).view(np.float64) +
+ b.astype(res.dtype).view(np.float64))
+ assert_array_equal(res.view(np.float64), expected_view)
+
+ def test_addition_cast_safety(self):
+ """The addition method is special for the scaled float, because it
+ includes the "cast" between different factors, thus cast-safety
+ is influenced by the implementation.
+ """
+ a = self._get_array(2.)
+ b = self._get_array(-2.)
+ c = self._get_array(3.)
+
+ # sign change is "equiv":
+ np.add(a, b, casting="equiv")
+ with pytest.raises(TypeError):
+ np.add(a, b, casting="no")
+
+ # Different factor is "same_kind" (default) so check that "safe" fails
+ with pytest.raises(TypeError):
+ np.add(a, c, casting="safe")
+
+ # Check that casting the output fails also (done by the ufunc here)
+ with pytest.raises(TypeError):
+ np.add(a, a, out=c, casting="safe")
diff --git a/numpy/core/tests/test_datetime.py b/numpy/core/tests/test_datetime.py
index 62f6381d5..b4146eadf 100644
--- a/numpy/core/tests/test_datetime.py
+++ b/numpy/core/tests/test_datetime.py
@@ -5,7 +5,7 @@ import datetime
import pytest
from numpy.testing import (
assert_, assert_equal, assert_raises, assert_warns, suppress_warnings,
- assert_raises_regex,
+ assert_raises_regex, assert_array_equal,
)
from numpy.compat import pickle
@@ -686,6 +686,63 @@ class TestDateTime:
str_b[...] = dt_a
assert_equal(str_a, str_b)
+ @pytest.mark.parametrize("time_dtype", ["m8[D]", "M8[Y]"])
+ def test_time_byteswapping(self, time_dtype):
+ times = np.array(["2017", "NaT"], dtype=time_dtype)
+ times_swapped = times.astype(times.dtype.newbyteorder())
+ assert_array_equal(times, times_swapped)
+
+ unswapped = times_swapped.view(np.int64).newbyteorder()
+ assert_array_equal(unswapped, times.view(np.int64))
+
+ @pytest.mark.parametrize(["time1", "time2"],
+ [("M8[s]", "M8[D]"), ("m8[s]", "m8[ns]")])
+ def test_time_byteswapped_cast(self, time1, time2):
+ dtype1 = np.dtype(time1)
+ dtype2 = np.dtype(time2)
+ times = np.array(["2017", "NaT"], dtype=dtype1)
+ expected = times.astype(dtype2)
+
+ # Test that every byte-swapping combination also returns the same
+ # results (previous tests check that this comparison works fine).
+ res = times.astype(dtype1.newbyteorder()).astype(dtype2)
+ assert_array_equal(res, expected)
+ res = times.astype(dtype2.newbyteorder())
+ assert_array_equal(res, expected)
+ res = times.astype(dtype1.newbyteorder()).astype(dtype2.newbyteorder())
+ assert_array_equal(res, expected)
+
+ @pytest.mark.parametrize("time_dtype", ["m8[D]", "M8[Y]"])
+ @pytest.mark.parametrize("str_dtype", ["U", "S"])
+ def test_datetime_conversions_byteorders(self, str_dtype, time_dtype):
+ times = np.array(["2017", "NaT"], dtype=time_dtype)
+ # Unfortunately, timedelta does not roundtrip:
+ from_strings = np.array(["2017", "NaT"], dtype=str_dtype)
+ to_strings = times.astype(str_dtype) # assume this is correct
+
+ # Check that conversion from times to string works if src is swapped:
+ times_swapped = times.astype(times.dtype.newbyteorder())
+ res = times_swapped.astype(str_dtype)
+ assert_array_equal(res, to_strings)
+ # And also if both are swapped:
+ res = times_swapped.astype(to_strings.dtype.newbyteorder())
+ assert_array_equal(res, to_strings)
+ # only destination is swapped:
+ res = times.astype(to_strings.dtype.newbyteorder())
+ assert_array_equal(res, to_strings)
+
+ # Check that conversion from string to times works if src is swapped:
+ from_strings_swapped = from_strings.astype(
+ from_strings.dtype.newbyteorder())
+ res = from_strings_swapped.astype(time_dtype)
+ assert_array_equal(res, times)
+ # And if both are swapped:
+ res = from_strings_swapped.astype(times.dtype.newbyteorder())
+ assert_array_equal(res, times)
+ # Only destination is swapped:
+ res = from_strings.astype(times.dtype.newbyteorder())
+ assert_array_equal(res, times)
+
def test_datetime_array_str(self):
a = np.array(['2011-03-16', '1920-01-01', '2013-05-19'], dtype='M')
assert_equal(str(a), "['2011-03-16' '1920-01-01' '2013-05-19']")
diff --git a/numpy/core/tests/test_deprecations.py b/numpy/core/tests/test_deprecations.py
index a67fe62c3..42e632e4a 100644
--- a/numpy/core/tests/test_deprecations.py
+++ b/numpy/core/tests/test_deprecations.py
@@ -13,7 +13,7 @@ import sys
import numpy as np
from numpy.testing import (
- assert_raises, assert_warns, assert_, assert_array_equal
+ assert_raises, assert_warns, assert_, assert_array_equal, SkipTest, KnownFailureException
)
from numpy.core._multiarray_tests import fromstring_null_term_c_api
@@ -329,6 +329,23 @@ class TestNumericStyleTypecodes(_DeprecationTestCase):
args=(dt,))
+class TestDTypeAttributeIsDTypeDeprecation(_DeprecationTestCase):
+ # Deprecated 2021-01-05, NumPy 1.21
+ message = r".*`.dtype` attribute"
+
+ def test_deprecation_dtype_attribute_is_dtype(self):
+ class dt:
+ dtype = "f8"
+
+ class vdt(np.void):
+ dtype = "f,f"
+
+ self.assert_deprecated(lambda: np.dtype(dt))
+ self.assert_deprecated(lambda: np.dtype(dt()))
+ self.assert_deprecated(lambda: np.dtype(vdt))
+ self.assert_deprecated(lambda: np.dtype(vdt(1)))
+
+
class TestTestDeprecated:
def test_assert_deprecated(self):
test_case_instance = _DeprecationTestCase()
@@ -670,16 +687,19 @@ class TestDeprecatedGlobals(_DeprecationTestCase):
reason='module-level __getattr__ not supported')
def test_type_aliases(self):
# from builtins
- self.assert_deprecated(lambda: np.bool)
- self.assert_deprecated(lambda: np.int)
- self.assert_deprecated(lambda: np.float)
- self.assert_deprecated(lambda: np.complex)
- self.assert_deprecated(lambda: np.object)
- self.assert_deprecated(lambda: np.str)
+ self.assert_deprecated(lambda: np.bool(True))
+ self.assert_deprecated(lambda: np.int(1))
+ self.assert_deprecated(lambda: np.float(1))
+ self.assert_deprecated(lambda: np.complex(1))
+ self.assert_deprecated(lambda: np.object())
+ self.assert_deprecated(lambda: np.str('abc'))
# from np.compat
- self.assert_deprecated(lambda: np.long)
- self.assert_deprecated(lambda: np.unicode)
+ self.assert_deprecated(lambda: np.long(1))
+ self.assert_deprecated(lambda: np.unicode('abc'))
+
+ # from np.core.numerictypes
+ self.assert_deprecated(lambda: np.typeDict)
class TestMatrixInOuter(_DeprecationTestCase):
@@ -773,6 +793,92 @@ class TestDeprecateSubarrayDTypeDuringArrayCoercion(_DeprecationTestCase):
self.assert_deprecated(check)
+class TestFutureWarningArrayLikeNotIterable(_DeprecationTestCase):
+ # Deprecated 2020-12-09, NumPy 1.20
+ warning_cls = FutureWarning
+ message = "The input object of type.*but not a sequence"
+
+ @pytest.mark.parametrize("protocol",
+ ["__array__", "__array_interface__", "__array_struct__"])
+ def test_deprecated(self, protocol):
+ """Test that these objects give a warning since they are not 0-D,
+ not coerced at the top level `np.array(obj)`, but nested, and do
+ *not* define the sequence protocol.
+
+ NOTE: Tests for the versions including __len__ and __getitem__ exist
+ in `test_array_coercion.py` and they can be modified or ammended
+ when this deprecation expired.
+ """
+ blueprint = np.arange(10)
+ MyArr = type("MyArr", (), {protocol: getattr(blueprint, protocol)})
+ self.assert_deprecated(lambda: np.array([MyArr()], dtype=object))
+
+ @pytest.mark.parametrize("protocol",
+ ["__array__", "__array_interface__", "__array_struct__"])
+ def test_0d_not_deprecated(self, protocol):
+ # 0-D always worked (albeit it would use __float__ or similar for the
+ # conversion, which may not happen anymore)
+ blueprint = np.array(1.)
+ MyArr = type("MyArr", (), {protocol: getattr(blueprint, protocol)})
+ myarr = MyArr()
+
+ self.assert_not_deprecated(lambda: np.array([myarr], dtype=object))
+ res = np.array([myarr], dtype=object)
+ expected = np.empty(1, dtype=object)
+ expected[0] = myarr
+ assert_array_equal(res, expected)
+
+ @pytest.mark.parametrize("protocol",
+ ["__array__", "__array_interface__", "__array_struct__"])
+ def test_unnested_not_deprecated(self, protocol):
+ blueprint = np.arange(10)
+ MyArr = type("MyArr", (), {protocol: getattr(blueprint, protocol)})
+ myarr = MyArr()
+
+ self.assert_not_deprecated(lambda: np.array(myarr))
+ res = np.array(myarr)
+ assert_array_equal(res, blueprint)
+
+ @pytest.mark.parametrize("protocol",
+ ["__array__", "__array_interface__", "__array_struct__"])
+ def test_strange_dtype_handling(self, protocol):
+ """The old code would actually use the dtype from the array, but
+ then end up not using the array (for dimension discovery)
+ """
+ blueprint = np.arange(10).astype("f4")
+ MyArr = type("MyArr", (), {protocol: getattr(blueprint, protocol),
+ "__float__": lambda _: 0.5})
+ myarr = MyArr()
+
+ # Make sure we warn (and capture the FutureWarning)
+ with pytest.warns(FutureWarning, match=self.message):
+ res = np.array([[myarr]])
+
+ assert res.shape == (1, 1)
+ assert res.dtype == "f4"
+ assert res[0, 0] == 0.5
+
+ @pytest.mark.parametrize("protocol",
+ ["__array__", "__array_interface__", "__array_struct__"])
+ def test_assignment_not_deprecated(self, protocol):
+ # If the result is dtype=object we do not unpack a nested array or
+ # array-like, if it is nested at exactly the right depth.
+ # NOTE: We actually do still call __array__, etc. but ignore the result
+ # in the end. For `dtype=object` we could optimize that away.
+ blueprint = np.arange(10).astype("f4")
+ MyArr = type("MyArr", (), {protocol: getattr(blueprint, protocol),
+ "__float__": lambda _: 0.5})
+ myarr = MyArr()
+
+ res = np.empty(3, dtype=object)
+ def set():
+ res[:] = [myarr, myarr, myarr]
+ self.assert_not_deprecated(set)
+ assert res[0] is myarr
+ assert res[1] is myarr
+ assert res[2] is myarr
+
+
class TestDeprecatedUnpickleObjectScalar(_DeprecationTestCase):
# Deprecated 2020-11-24, NumPy 1.20
"""
@@ -785,3 +891,286 @@ class TestDeprecatedUnpickleObjectScalar(_DeprecationTestCase):
def test_deprecated(self):
ctor = np.core.multiarray.scalar
self.assert_deprecated(lambda: ctor(np.dtype("O"), 1))
+
+try:
+ with warnings.catch_warnings():
+ warnings.simplefilter("always")
+ import nose # noqa: F401
+except ImportError:
+ HAVE_NOSE = False
+else:
+ HAVE_NOSE = True
+
+
+@pytest.mark.skipif(not HAVE_NOSE, reason="Needs nose")
+class TestNoseDecoratorsDeprecated(_DeprecationTestCase):
+ class DidntSkipException(Exception):
+ pass
+
+ def test_slow(self):
+ def _test_slow():
+ @np.testing.dec.slow
+ def slow_func(x, y, z):
+ pass
+
+ assert_(slow_func.slow)
+ self.assert_deprecated(_test_slow)
+
+ def test_setastest(self):
+ def _test_setastest():
+ @np.testing.dec.setastest()
+ def f_default(a):
+ pass
+
+ @np.testing.dec.setastest(True)
+ def f_istest(a):
+ pass
+
+ @np.testing.dec.setastest(False)
+ def f_isnottest(a):
+ pass
+
+ assert_(f_default.__test__)
+ assert_(f_istest.__test__)
+ assert_(not f_isnottest.__test__)
+ self.assert_deprecated(_test_setastest, num=3)
+
+ def test_skip_functions_hardcoded(self):
+ def _test_skip_functions_hardcoded():
+ @np.testing.dec.skipif(True)
+ def f1(x):
+ raise self.DidntSkipException
+
+ try:
+ f1('a')
+ except self.DidntSkipException:
+ raise Exception('Failed to skip')
+ except SkipTest().__class__:
+ pass
+
+ @np.testing.dec.skipif(False)
+ def f2(x):
+ raise self.DidntSkipException
+
+ try:
+ f2('a')
+ except self.DidntSkipException:
+ pass
+ except SkipTest().__class__:
+ raise Exception('Skipped when not expected to')
+ self.assert_deprecated(_test_skip_functions_hardcoded, num=2)
+
+ def test_skip_functions_callable(self):
+ def _test_skip_functions_callable():
+ def skip_tester():
+ return skip_flag == 'skip me!'
+
+ @np.testing.dec.skipif(skip_tester)
+ def f1(x):
+ raise self.DidntSkipException
+
+ try:
+ skip_flag = 'skip me!'
+ f1('a')
+ except self.DidntSkipException:
+ raise Exception('Failed to skip')
+ except SkipTest().__class__:
+ pass
+
+ @np.testing.dec.skipif(skip_tester)
+ def f2(x):
+ raise self.DidntSkipException
+
+ try:
+ skip_flag = 'five is right out!'
+ f2('a')
+ except self.DidntSkipException:
+ pass
+ except SkipTest().__class__:
+ raise Exception('Skipped when not expected to')
+ self.assert_deprecated(_test_skip_functions_callable, num=2)
+
+ def test_skip_generators_hardcoded(self):
+ def _test_skip_generators_hardcoded():
+ @np.testing.dec.knownfailureif(True, "This test is known to fail")
+ def g1(x):
+ yield from range(x)
+
+ try:
+ for j in g1(10):
+ pass
+ except KnownFailureException().__class__:
+ pass
+ else:
+ raise Exception('Failed to mark as known failure')
+
+ @np.testing.dec.knownfailureif(False, "This test is NOT known to fail")
+ def g2(x):
+ yield from range(x)
+ raise self.DidntSkipException('FAIL')
+
+ try:
+ for j in g2(10):
+ pass
+ except KnownFailureException().__class__:
+ raise Exception('Marked incorrectly as known failure')
+ except self.DidntSkipException:
+ pass
+ self.assert_deprecated(_test_skip_generators_hardcoded, num=2)
+
+ def test_skip_generators_callable(self):
+ def _test_skip_generators_callable():
+ def skip_tester():
+ return skip_flag == 'skip me!'
+
+ @np.testing.dec.knownfailureif(skip_tester, "This test is known to fail")
+ def g1(x):
+ yield from range(x)
+
+ try:
+ skip_flag = 'skip me!'
+ for j in g1(10):
+ pass
+ except KnownFailureException().__class__:
+ pass
+ else:
+ raise Exception('Failed to mark as known failure')
+
+ @np.testing.dec.knownfailureif(skip_tester, "This test is NOT known to fail")
+ def g2(x):
+ yield from range(x)
+ raise self.DidntSkipException('FAIL')
+
+ try:
+ skip_flag = 'do not skip'
+ for j in g2(10):
+ pass
+ except KnownFailureException().__class__:
+ raise Exception('Marked incorrectly as known failure')
+ except self.DidntSkipException:
+ pass
+ self.assert_deprecated(_test_skip_generators_callable, num=2)
+
+ def test_deprecated(self):
+ def _test_deprecated():
+ @np.testing.dec.deprecated(True)
+ def non_deprecated_func():
+ pass
+
+ @np.testing.dec.deprecated()
+ def deprecated_func():
+ import warnings
+ warnings.warn("TEST: deprecated func", DeprecationWarning, stacklevel=1)
+
+ @np.testing.dec.deprecated()
+ def deprecated_func2():
+ import warnings
+ warnings.warn("AHHHH", stacklevel=1)
+ raise ValueError
+
+ @np.testing.dec.deprecated()
+ def deprecated_func3():
+ import warnings
+ warnings.warn("AHHHH", stacklevel=1)
+
+ # marked as deprecated, but does not raise DeprecationWarning
+ assert_raises(AssertionError, non_deprecated_func)
+ # should be silent
+ deprecated_func()
+ with warnings.catch_warnings(record=True):
+ warnings.simplefilter("always") # do not propagate unrelated warnings
+ # fails if deprecated decorator just disables test. See #1453.
+ assert_raises(ValueError, deprecated_func2)
+ # warning is not a DeprecationWarning
+ assert_raises(AssertionError, deprecated_func3)
+ self.assert_deprecated(_test_deprecated, num=4)
+
+ def test_parametrize(self):
+ def _test_parametrize():
+ # dec.parametrize assumes that it is being run by nose. Because
+ # we are running under pytest, we need to explicitly check the
+ # results.
+ @np.testing.dec.parametrize('base, power, expected',
+ [(1, 1, 1),
+ (2, 1, 2),
+ (2, 2, 4)])
+ def check_parametrize(base, power, expected):
+ assert_(base**power == expected)
+
+ count = 0
+ for test in check_parametrize():
+ test[0](*test[1:])
+ count += 1
+ assert_(count == 3)
+ self.assert_deprecated(_test_parametrize)
+
+
+class TestSingleElementSignature(_DeprecationTestCase):
+ # Deprecated 2021-04-01, NumPy 1.21
+ message = r"The use of a length 1"
+
+ def test_deprecated(self):
+ self.assert_deprecated(lambda: np.add(1, 2, signature="d"))
+ self.assert_deprecated(lambda: np.add(1, 2, sig=(np.dtype("l"),)))
+
+
+class TestComparisonBadDType(_DeprecationTestCase):
+ # Deprecated 2021-04-01, NumPy 1.21
+ message = r"using `dtype=` in comparisons is only useful for"
+
+ def test_deprecated(self):
+ self.assert_deprecated(lambda: np.equal(1, 1, dtype=np.int64))
+ # Not an error only for the transition
+ self.assert_deprecated(lambda: np.equal(1, 1, sig=(None, None, "l")))
+
+ def test_not_deprecated(self):
+ np.equal(True, False, dtype=bool)
+ np.equal(3, 5, dtype=bool, casting="unsafe")
+ np.equal([None], [4], dtype=object)
+
+class TestComparisonBadObjectDType(_DeprecationTestCase):
+ # Deprecated 2021-04-01, NumPy 1.21 (different branch of the above one)
+ message = r"using `dtype=object` \(or equivalent signature\) will"
+ warning_cls = FutureWarning
+
+ def test_deprecated(self):
+ self.assert_deprecated(lambda: np.equal(1, 1, dtype=object))
+ self.assert_deprecated(
+ lambda: np.equal(1, 1, sig=(None, None, object)))
+
+
+class TestSpecialAttributeLookupFailure(_DeprecationTestCase):
+ message = r"An exception was ignored while fetching the attribute"
+
+ class WeirdArrayLike:
+ @property
+ def __array__(self):
+ raise RuntimeError("oops!")
+
+ class WeirdArrayInterface:
+ @property
+ def __array_interface__(self):
+ raise RuntimeError("oops!")
+
+ def test_deprecated(self):
+ self.assert_deprecated(lambda: np.array(self.WeirdArrayLike()))
+ self.assert_deprecated(lambda: np.array(self.WeirdArrayInterface()))
+
+
+class TestCtypesGetter(_DeprecationTestCase):
+ # Deprecated 2021-05-18, Numpy 1.21.0
+ warning_cls = DeprecationWarning
+ ctypes = np.array([1]).ctypes
+
+ @pytest.mark.parametrize(
+ "name", ["get_data", "get_shape", "get_strides", "get_as_parameter"]
+ )
+ def test_deprecated(self, name: str) -> None:
+ func = getattr(self.ctypes, name)
+ self.assert_deprecated(lambda: func())
+
+ @pytest.mark.parametrize(
+ "name", ["data", "shape", "strides", "_as_parameter_"]
+ )
+ def test_not_deprecated(self, name: str) -> None:
+ self.assert_not_deprecated(lambda: getattr(self.ctypes, name))
diff --git a/numpy/core/tests/test_dtype.py b/numpy/core/tests/test_dtype.py
index 0ebcc72da..4f52268f5 100644
--- a/numpy/core/tests/test_dtype.py
+++ b/numpy/core/tests/test_dtype.py
@@ -3,15 +3,18 @@ import operator
import pytest
import ctypes
import gc
+import warnings
import numpy as np
from numpy.core._rational_tests import rational
from numpy.core._multiarray_tests import create_custom_field_dtype
from numpy.testing import (
- assert_, assert_equal, assert_array_equal, assert_raises, HAS_REFCOUNT)
+ assert_, assert_equal, assert_array_equal, assert_raises, HAS_REFCOUNT,
+ IS_PYSTON)
from numpy.compat import pickle
from itertools import permutations
+
def assert_dtype_equal(a, b):
assert_equal(a, b)
assert_equal(hash(a), hash(b),
@@ -87,6 +90,24 @@ class TestBuiltin:
assert_raises(TypeError, np.dtype, 'q8')
assert_raises(TypeError, np.dtype, 'Q8')
+ def test_richcompare_invalid_dtype_equality(self):
+ # Make sure objects that cannot be converted to valid
+ # dtypes results in False/True when compared to valid dtypes.
+ # Here 7 cannot be converted to dtype. No exceptions should be raised
+
+ assert not np.dtype(np.int32) == 7, "dtype richcompare failed for =="
+ assert np.dtype(np.int32) != 7, "dtype richcompare failed for !="
+
+ @pytest.mark.parametrize(
+ 'operation',
+ [operator.le, operator.lt, operator.ge, operator.gt])
+ def test_richcompare_invalid_dtype_comparison(self, operation):
+ # Make sure TypeError is raised for comparison operators
+ # for invalid dtypes. Here 7 is an invalid dtype.
+
+ with pytest.raises(TypeError):
+ operation(np.dtype(np.int32), 7)
+
@pytest.mark.parametrize("dtype",
['Bool', 'Complex32', 'Complex64', 'Float16', 'Float32', 'Float64',
'Int8', 'Int16', 'Int32', 'Int64', 'Object0', 'Timedelta64',
@@ -750,8 +771,6 @@ class TestStructuredDtypeSparseFields:
sparse_dtype = np.dtype([('a', {'names':['ab'], 'formats':['f'],
'offsets':[4]}, (2, 3))])
- @pytest.mark.xfail(reason="inaccessible data is changed see gh-12686.")
- @pytest.mark.valgrind_error(reason="reads from uninitialized buffers.")
def test_sparse_field_assignment(self):
arr = np.zeros(3, self.dtype)
sparse_arr = arr.view(self.sparse_dtype)
@@ -788,12 +807,14 @@ class TestMonsterType:
('yi', np.dtype((a, (3, 2))))])
assert_dtype_equal(c, d)
+ @pytest.mark.skipif(IS_PYSTON, reason="Pyston disables recursion checking")
def test_list_recursion(self):
l = list()
l.append(('f', l))
with pytest.raises(RecursionError):
np.dtype(l)
+ @pytest.mark.skipif(IS_PYSTON, reason="Pyston disables recursion checking")
def test_tuple_recursion(self):
d = np.int32
for i in range(100000):
@@ -801,6 +822,7 @@ class TestMonsterType:
with pytest.raises(RecursionError):
np.dtype(d)
+ @pytest.mark.skipif(IS_PYSTON, reason="Pyston disables recursion checking")
def test_dict_recursion(self):
d = dict(names=['self'], formats=[None], offsets=[0])
d['formats'][0] = d
@@ -1018,7 +1040,12 @@ class TestPickling:
def check_pickling(self, dtype):
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
- pickled = pickle.loads(pickle.dumps(dtype, proto))
+ buf = pickle.dumps(dtype, proto)
+ # The dtype pickling itself pickles `np.dtype` if it is pickled
+ # as a singleton `dtype` should be stored in the buffer:
+ assert b"_DType_reconstruct" not in buf
+ assert b"dtype" in buf
+ pickled = pickle.loads(buf)
assert_equal(pickled, dtype)
assert_equal(pickled.descr, dtype.descr)
if dtype.metadata is not None:
@@ -1074,6 +1101,112 @@ class TestPickling:
dt = np.dtype(int, metadata={'datum': 1})
self.check_pickling(dt)
+ @pytest.mark.parametrize("DType",
+ [type(np.dtype(t)) for t in np.typecodes['All']] +
+ [np.dtype(rational), np.dtype])
+ def test_pickle_types(self, DType):
+ # Check that DTypes (the classes/types) roundtrip when pickling
+ for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+ roundtrip_DType = pickle.loads(pickle.dumps(DType, proto))
+ assert roundtrip_DType is DType
+
+
+class TestPromotion:
+ """Test cases related to more complex DType promotions. Further promotion
+ tests are defined in `test_numeric.py`
+ """
+ @pytest.mark.parametrize(["other", "expected"],
+ [(2**16-1, np.complex64),
+ (2**32-1, np.complex128),
+ (np.float16(2), np.complex64),
+ (np.float32(2), np.complex64),
+ (np.longdouble(2), np.complex64),
+ # Base of the double value to sidestep any rounding issues:
+ (np.longdouble(np.nextafter(1.7e308, 0.)), np.complex128),
+ # Additionally use "nextafter" so the cast can't round down:
+ (np.longdouble(np.nextafter(1.7e308, np.inf)), np.clongdouble),
+ # repeat for complex scalars:
+ (np.complex64(2), np.complex64),
+ (np.clongdouble(2), np.complex64),
+ # Base of the double value to sidestep any rounding issues:
+ (np.clongdouble(np.nextafter(1.7e308, 0.) * 1j), np.complex128),
+ # Additionally use "nextafter" so the cast can't round down:
+ (np.clongdouble(np.nextafter(1.7e308, np.inf)), np.clongdouble),
+ ])
+ def test_complex_other_value_based(self, other, expected):
+ # This would change if we modify the value based promotion
+ min_complex = np.dtype(np.complex64)
+
+ res = np.result_type(other, min_complex)
+ assert res == expected
+ # Check the same for a simple ufunc call that uses the same logic:
+ res = np.minimum(other, np.ones(3, dtype=min_complex)).dtype
+ assert res == expected
+
+ @pytest.mark.parametrize(["other", "expected"],
+ [(np.bool_, np.complex128),
+ (np.int64, np.complex128),
+ (np.float16, np.complex64),
+ (np.float32, np.complex64),
+ (np.float64, np.complex128),
+ (np.longdouble, np.clongdouble),
+ (np.complex64, np.complex64),
+ (np.complex128, np.complex128),
+ (np.clongdouble, np.clongdouble),
+ ])
+ def test_complex_scalar_value_based(self, other, expected):
+ # This would change if we modify the value based promotion
+ complex_scalar = 1j
+
+ res = np.result_type(other, complex_scalar)
+ assert res == expected
+ # Check the same for a simple ufunc call that uses the same logic:
+ res = np.minimum(np.ones(3, dtype=other), complex_scalar).dtype
+ assert res == expected
+
+ def test_complex_pyscalar_promote_rational(self):
+ with pytest.raises(TypeError,
+ match=r".* do not have a common DType"):
+ np.result_type(1j, rational)
+
+ with pytest.raises(TypeError,
+ match=r".* no common DType exists for the given inputs"):
+ np.result_type(1j, rational(1, 2))
+
+ @pytest.mark.parametrize(["other", "expected"],
+ [(1, rational), (1., np.float64)])
+ def test_float_int_pyscalar_promote_rational(self, other, expected):
+ # Note that rationals are a bit akward as they promote with float64
+ # or default ints, but not float16 or uint8/int8 (which looks
+ # inconsistent here)
+ with pytest.raises(TypeError,
+ match=r".* do not have a common DType"):
+ np.result_type(other, rational)
+
+ assert np.result_type(other, rational(1, 2)) == expected
+
+ @pytest.mark.parametrize(["dtypes", "expected"], [
+ # These promotions are not associative/commutative:
+ ([np.uint16, np.int16, np.float16], np.float32),
+ ([np.uint16, np.int8, np.float16], np.float32),
+ ([np.uint8, np.int16, np.float16], np.float32),
+ # The following promotions are not ambiguous, but cover code
+ # paths of abstract promotion (no particular logic being tested)
+ ([1, 1, np.float64], np.float64),
+ ([1, 1., np.complex128], np.complex128),
+ ([1, 1j, np.float64], np.complex128),
+ ([1., 1., np.int64], np.float64),
+ ([1., 1j, np.float64], np.complex128),
+ ([1j, 1j, np.float64], np.complex128),
+ ([1, True, np.bool_], np.int_),
+ ])
+ def test_permutations_do_not_influence_result(self, dtypes, expected):
+ # Tests that most permutations do not influence the result. In the
+ # above some uint and int combintations promote to a larger integer
+ # type, which would then promote to a larger than necessary float.
+ for perm in permutations(dtypes):
+ assert np.result_type(*perm) == expected
+
def test_rational_dtype():
# test for bug gh-5719
@@ -1106,11 +1239,12 @@ def test_keyword_argument():
class TestFromDTypeAttribute:
def test_simple(self):
class dt:
- dtype = "f8"
+ dtype = np.dtype("f8")
assert np.dtype(dt) == np.float64
assert np.dtype(dt()) == np.float64
+ @pytest.mark.skipif(IS_PYSTON, reason="Pyston disables recursion checking")
def test_recursion(self):
class dt:
pass
@@ -1130,22 +1264,22 @@ class TestFromDTypeAttribute:
# what this should be useful for. Note that if np.void is used
# numpy will think we are deallocating a base type [1.17, 2019-02].
dtype = np.dtype("f,f")
- pass
np.dtype(dt)
np.dtype(dt(1))
+ @pytest.mark.skipif(IS_PYSTON, reason="Pyston disables recursion checking")
def test_void_subtype_recursion(self):
- class dt(np.void):
+ class vdt(np.void):
pass
- dt.dtype = dt
+ vdt.dtype = vdt
with pytest.raises(RecursionError):
- np.dtype(dt)
+ np.dtype(vdt)
with pytest.raises(RecursionError):
- np.dtype(dt(1))
+ np.dtype(vdt(1))
class TestDTypeClasses:
diff --git a/numpy/core/tests/test_getlimits.py b/numpy/core/tests/test_getlimits.py
index bcf8cf659..de7b3e769 100644
--- a/numpy/core/tests/test_getlimits.py
+++ b/numpy/core/tests/test_getlimits.py
@@ -1,6 +1,7 @@
""" Test functions for limits module.
"""
+import warnings
import numpy as np
from numpy.core import finfo, iinfo
from numpy import half, single, double, longdouble
@@ -47,7 +48,8 @@ class TestFinfo:
for dt1, dt2 in dts:
for attr in ('bits', 'eps', 'epsneg', 'iexp', 'machar', 'machep',
'max', 'maxexp', 'min', 'minexp', 'negep', 'nexp',
- 'nmant', 'precision', 'resolution', 'tiny'):
+ 'nmant', 'precision', 'resolution', 'tiny',
+ 'smallest_normal', 'smallest_subnormal'):
assert_equal(getattr(finfo(dt1), attr),
getattr(finfo(dt2), attr), attr)
assert_raises(ValueError, finfo, 'i4')
@@ -112,6 +114,28 @@ def test_known_types():
assert_ma_equal(ld_ma, _float_ma[128])
+def test_subnormal_warning():
+ """Test that the subnormal is zero warning is not being raised."""
+ with np.errstate(all='ignore'):
+ ld_ma = _discovered_machar(np.longdouble)
+ bytes = np.dtype(np.longdouble).itemsize
+ with warnings.catch_warnings(record=True) as w:
+ warnings.simplefilter('always')
+ if (ld_ma.it, ld_ma.maxexp) == (63, 16384) and bytes in (12, 16):
+ # 80-bit extended precision
+ ld_ma.smallest_subnormal
+ assert len(w) == 0
+ elif (ld_ma.it, ld_ma.maxexp) == (112, 16384) and bytes == 16:
+ # IEE 754 128-bit
+ ld_ma.smallest_subnormal
+ assert len(w) == 0
+ else:
+ # Double double
+ ld_ma.smallest_subnormal
+ # This test may fail on some platforms
+ assert len(w) == 0
+
+
def test_plausible_finfo():
# Assert that finfo returns reasonable results for all types
for ftype in np.sctypes['float'] + np.sctypes['complex']:
diff --git a/numpy/core/tests/test_half.py b/numpy/core/tests/test_half.py
index ae9827bc7..1b6fd21e1 100644
--- a/numpy/core/tests/test_half.py
+++ b/numpy/core/tests/test_half.py
@@ -67,6 +67,21 @@ class TestHalf:
j = np.array(i_f16, dtype=int)
assert_equal(i_int, j)
+ @pytest.mark.parametrize("string_dt", ["S", "U"])
+ def test_half_conversion_to_string(self, string_dt):
+ # Currently uses S/U32 (which is sufficient for float32)
+ expected_dt = np.dtype(f"{string_dt}32")
+ assert np.promote_types(np.float16, string_dt) == expected_dt
+ assert np.promote_types(string_dt, np.float16) == expected_dt
+
+ arr = np.ones(3, dtype=np.float16).astype(string_dt)
+ assert arr.dtype == expected_dt
+
+ @pytest.mark.parametrize("string_dt", ["S", "U"])
+ def test_half_conversion_from_string(self, string_dt):
+ string = np.array("3.1416", dtype=string_dt)
+ assert string.astype(np.float16) == np.array(3.1416, dtype=np.float16)
+
@pytest.mark.parametrize("offset", [None, "up", "down"])
@pytest.mark.parametrize("shift", [None, "up", "down"])
@pytest.mark.parametrize("float_t", [np.float32, np.float64])
diff --git a/numpy/core/tests/test_hashtable.py b/numpy/core/tests/test_hashtable.py
new file mode 100644
index 000000000..bace4c051
--- /dev/null
+++ b/numpy/core/tests/test_hashtable.py
@@ -0,0 +1,30 @@
+import pytest
+
+import random
+from numpy.core._multiarray_tests import identityhash_tester
+
+
+@pytest.mark.parametrize("key_length", [1, 3, 6])
+@pytest.mark.parametrize("length", [1, 16, 2000])
+def test_identity_hashtable(key_length, length):
+ # use a 30 object pool for everything (duplicates will happen)
+ pool = [object() for i in range(20)]
+ keys_vals = []
+ for i in range(length):
+ keys = tuple(random.choices(pool, k=key_length))
+ keys_vals.append((keys, random.choice(pool)))
+
+ dictionary = dict(keys_vals)
+
+ # add a random item at the end:
+ keys_vals.append(random.choice(keys_vals))
+ # the expected one could be different with duplicates:
+ expected = dictionary[keys_vals[-1][0]]
+
+ res = identityhash_tester(key_length, keys_vals, replace=True)
+ assert res is expected
+
+ # check that ensuring one duplicate definitely raises:
+ keys_vals.insert(0, keys_vals[-2])
+ with pytest.raises(RuntimeError):
+ identityhash_tester(key_length, keys_vals)
diff --git a/numpy/core/tests/test_indexing.py b/numpy/core/tests/test_indexing.py
index 667c49240..1c2253856 100644
--- a/numpy/core/tests/test_indexing.py
+++ b/numpy/core/tests/test_indexing.py
@@ -3,6 +3,8 @@ import warnings
import functools
import operator
+import pytest
+
import numpy as np
from numpy.core._multiarray_tests import array_indexing
from itertools import product
@@ -547,6 +549,45 @@ class TestIndexing:
assert_array_equal(arr[0], np.array("asdfg", dtype="c"))
assert arr[0, 1] == b"s" # make sure not all were set to "a" for both
+ @pytest.mark.parametrize("index",
+ [True, False, np.array([0])])
+ @pytest.mark.parametrize("num", [32, 40])
+ @pytest.mark.parametrize("original_ndim", [1, 32])
+ def test_too_many_advanced_indices(self, index, num, original_ndim):
+ # These are limitations based on the number of arguments we can process.
+ # For `num=32` (and all boolean cases), the result is actually define;
+ # but the use of NpyIter (NPY_MAXARGS) limits it for technical reasons.
+ arr = np.ones((1,) * original_ndim)
+ with pytest.raises(IndexError):
+ arr[(index,) * num]
+ with pytest.raises(IndexError):
+ arr[(index,) * num] = 1.
+
+ def test_structured_advanced_indexing(self):
+ # Test that copyswap(n) used by integer array indexing is threadsafe
+ # for structured datatypes, see gh-15387. This test can behave randomly.
+ from concurrent.futures import ThreadPoolExecutor
+
+ # Create a deeply nested dtype to make a failure more likely:
+ dt = np.dtype([("", "f8")])
+ dt = np.dtype([("", dt)] * 2)
+ dt = np.dtype([("", dt)] * 2)
+ # The array should be large enough to likely run into threading issues
+ arr = np.random.uniform(size=(6000, 8)).view(dt)[:, 0]
+
+ rng = np.random.default_rng()
+ def func(arr):
+ indx = rng.integers(0, len(arr), size=6000, dtype=np.intp)
+ arr[indx]
+
+ tpe = ThreadPoolExecutor(max_workers=8)
+ futures = [tpe.submit(func, arr) for _ in range(10)]
+ for f in futures:
+ f.result()
+
+ assert arr.dtype is dt
+
+
class TestFieldIndexing:
def test_scalar_return_type(self):
# Field access on an array should return an array, even if it
@@ -592,6 +633,22 @@ class TestBroadcastedAssignments:
assert_raises(ValueError, assign, a, s_[:, [0]], np.zeros((5, 0)))
assert_raises(ValueError, assign, a, s_[[0], :], np.zeros((2, 1)))
+ @pytest.mark.parametrize("index", [
+ (..., [1, 2], slice(None)),
+ ([0, 1], ..., 0),
+ (..., [1, 2], [1, 2])])
+ def test_broadcast_error_reports_correct_shape(self, index):
+ values = np.zeros((100, 100)) # will never broadcast below
+
+ arr = np.zeros((3, 4, 5, 6, 7))
+ # We currently report without any spaces (could be changed)
+ shape_str = str(arr[index].shape).replace(" ", "")
+
+ with pytest.raises(ValueError) as e:
+ arr[index] = values
+
+ assert str(e.value).endswith(shape_str)
+
def test_index_is_larger(self):
# Simple case of fancy index broadcasting of the index.
a = np.zeros((5, 5))
diff --git a/numpy/core/tests/test_longdouble.py b/numpy/core/tests/test_longdouble.py
index acef995f3..1a54e62d8 100644
--- a/numpy/core/tests/test_longdouble.py
+++ b/numpy/core/tests/test_longdouble.py
@@ -8,6 +8,7 @@ from numpy.testing import (
)
from numpy.core.tests._locales import CommaDecimalPointLocale
+
LD_INFO = np.finfo(np.longdouble)
longdouble_longer_than_double = (LD_INFO.eps < np.finfo(np.double).eps)
diff --git a/numpy/core/tests/test_mem_overlap.py b/numpy/core/tests/test_mem_overlap.py
index 675613de4..24bdf477f 100644
--- a/numpy/core/tests/test_mem_overlap.py
+++ b/numpy/core/tests/test_mem_overlap.py
@@ -666,6 +666,11 @@ class TestUFunc:
def test_unary_ufunc_call_fuzz(self):
self.check_unary_fuzz(np.invert, None, np.int16)
+ @pytest.mark.slow
+ def test_unary_ufunc_call_complex_fuzz(self):
+ # Complex typically has a smaller alignment than itemsize
+ self.check_unary_fuzz(np.negative, None, np.complex128, count=500)
+
def test_binary_ufunc_accumulate_fuzz(self):
def get_out_axis_size(a, b, axis):
if axis is None:
@@ -792,7 +797,7 @@ class TestUFunc:
check(np.add, a, ind, a[25:75])
def test_unary_ufunc_1d_manual(self):
- # Exercise branches in PyArray_EQUIVALENTLY_ITERABLE
+ # Exercise ufunc fast-paths (that avoid creation of an `np.nditer`)
def check(a, b):
a_orig = a.copy()
diff --git a/numpy/core/tests/test_memmap.py b/numpy/core/tests/test_memmap.py
index a1e0c8f8f..e4f0a6b3f 100644
--- a/numpy/core/tests/test_memmap.py
+++ b/numpy/core/tests/test_memmap.py
@@ -1,10 +1,9 @@
import sys
import os
-import shutil
import mmap
import pytest
from pathlib import Path
-from tempfile import NamedTemporaryFile, TemporaryFile, mktemp, mkdtemp
+from tempfile import NamedTemporaryFile, TemporaryFile
from numpy import (
memmap, sum, average, product, ndarray, isscalar, add, subtract, multiply)
@@ -18,7 +17,6 @@ from numpy.testing import (
class TestMemmap:
def setup(self):
self.tmpfp = NamedTemporaryFile(prefix='mmap')
- self.tempdir = mkdtemp()
self.shape = (3, 4)
self.dtype = 'float32'
self.data = arange(12, dtype=self.dtype)
@@ -30,7 +28,6 @@ class TestMemmap:
if IS_PYPY:
break_cycles()
break_cycles()
- shutil.rmtree(self.tempdir)
def test_roundtrip(self):
# Write data to file
@@ -46,8 +43,8 @@ class TestMemmap:
assert_array_equal(self.data, newfp)
assert_equal(newfp.flags.writeable, False)
- def test_open_with_filename(self):
- tmpname = mktemp('', 'mmap', dir=self.tempdir)
+ def test_open_with_filename(self, tmp_path):
+ tmpname = tmp_path / 'mmap'
fp = memmap(tmpname, dtype=self.dtype, mode='w+',
shape=self.shape)
fp[:] = self.data[:]
@@ -67,11 +64,11 @@ class TestMemmap:
assert_equal(mode, fp.mode)
del fp
- def test_filename(self):
- tmpname = mktemp('', 'mmap', dir=self.tempdir)
+ def test_filename(self, tmp_path):
+ tmpname = tmp_path / "mmap"
fp = memmap(tmpname, dtype=self.dtype, mode='w+',
shape=self.shape)
- abspath = os.path.abspath(tmpname)
+ abspath = Path(os.path.abspath(tmpname))
fp[:] = self.data[:]
assert_equal(abspath, fp.filename)
b = fp[:1]
@@ -79,8 +76,8 @@ class TestMemmap:
del b
del fp
- def test_path(self):
- tmpname = mktemp('', 'mmap', dir=self.tempdir)
+ def test_path(self, tmp_path):
+ tmpname = tmp_path / "mmap"
fp = memmap(Path(tmpname), dtype=self.dtype, mode='w+',
shape=self.shape)
# os.path.realpath does not resolve symlinks on Windows
diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py
index bd8c51ab7..5f0a725d2 100644
--- a/numpy/core/tests/test_multiarray.py
+++ b/numpy/core/tests/test_multiarray.py
@@ -1,7 +1,6 @@
import collections.abc
import tempfile
import sys
-import shutil
import warnings
import operator
import io
@@ -26,8 +25,8 @@ from numpy.core._rational_tests import rational
from numpy.testing import (
assert_, assert_raises, assert_warns, assert_equal, assert_almost_equal,
assert_array_equal, assert_raises_regex, assert_array_almost_equal,
- assert_allclose, IS_PYPY, HAS_REFCOUNT, assert_array_less, runstring,
- temppath, suppress_warnings, break_cycles,
+ assert_allclose, IS_PYPY, IS_PYSTON, HAS_REFCOUNT, assert_array_less,
+ runstring, temppath, suppress_warnings, break_cycles,
)
from numpy.testing._private.utils import _no_tracing
from numpy.core.tests._locales import CommaDecimalPointLocale
@@ -207,7 +206,7 @@ class TestFlags:
a[2] = 10
# only warn once
assert_(len(w) == 1)
-
+
@pytest.mark.parametrize(["flag", "flag_value", "writeable"],
[("writeable", True, True),
# Delete _warn_on_write after deprecation and simplify
@@ -484,6 +483,33 @@ class TestArrayConstruction:
assert_(np.ascontiguousarray(d).flags.c_contiguous)
assert_(np.asfortranarray(d).flags.f_contiguous)
+ @pytest.mark.parametrize("func",
+ [np.array,
+ np.asarray,
+ np.asanyarray,
+ np.ascontiguousarray,
+ np.asfortranarray])
+ def test_bad_arguments_error(self, func):
+ with pytest.raises(TypeError):
+ func(3, dtype="bad dtype")
+ with pytest.raises(TypeError):
+ func() # missing arguments
+ with pytest.raises(TypeError):
+ func(1, 2, 3, 4, 5, 6, 7, 8) # too many arguments
+
+ @pytest.mark.parametrize("func",
+ [np.array,
+ np.asarray,
+ np.asanyarray,
+ np.ascontiguousarray,
+ np.asfortranarray])
+ def test_array_as_keyword(self, func):
+ # This should likely be made positional only, but do not change
+ # the name accidentally.
+ if func is np.array:
+ func(object=3)
+ else:
+ func(a=3)
class TestAssignment:
def test_assignment_broadcasting(self):
@@ -1418,11 +1444,11 @@ class TestStructured:
a = np.array([(1,2)], dtype=[('a', 'i4'), ('b', 'i4')])
a[['a', 'b']] = a[['b', 'a']]
assert_equal(a[0].item(), (2,1))
-
+
def test_scalar_assignment(self):
with assert_raises(ValueError):
- arr = np.arange(25).reshape(5, 5)
- arr.itemset(3)
+ arr = np.arange(25).reshape(5, 5)
+ arr.itemset(3)
def test_structuredscalar_indexing(self):
# test gh-7262
@@ -3390,6 +3416,15 @@ class TestMethods:
assert_raises(TypeError, lambda: a.conj())
assert_raises(TypeError, lambda: a.conjugate())
+ def test_conjugate_out(self):
+ # Minimal test for the out argument being passed on correctly
+ # NOTE: The ability to pass `out` is currently undocumented!
+ a = np.array([1-1j, 1+1j, 23+23.0j])
+ out = np.empty_like(a)
+ res = a.conjugate(out)
+ assert res is out
+ assert_array_equal(out, a.conjugate())
+
def test__complex__(self):
dtypes = ['i1', 'i2', 'i4', 'i8',
'u1', 'u2', 'u4', 'u8',
@@ -4157,6 +4192,176 @@ class TestStringCompare:
assert_array_equal(g1 < g2, [g1[i] < g2[i] for i in [0, 1, 2]])
assert_array_equal(g1 > g2, [g1[i] > g2[i] for i in [0, 1, 2]])
+class TestArgmaxArgminCommon:
+
+ sizes = [(), (3,), (3, 2), (2, 3),
+ (3, 3), (2, 3, 4), (4, 3, 2),
+ (1, 2, 3, 4), (2, 3, 4, 1),
+ (3, 4, 1, 2), (4, 1, 2, 3)]
+
+ @pytest.mark.parametrize("size, axis", itertools.chain(*[[(size, axis)
+ for axis in list(range(-len(size), len(size))) + [None]]
+ for size in sizes]))
+ @pytest.mark.parametrize('method', [np.argmax, np.argmin])
+ def test_np_argmin_argmax_keepdims(self, size, axis, method):
+
+ arr = np.random.normal(size=size)
+
+ # contiguous arrays
+ if axis is None:
+ new_shape = [1 for _ in range(len(size))]
+ else:
+ new_shape = list(size)
+ new_shape[axis] = 1
+ new_shape = tuple(new_shape)
+
+ _res_orig = method(arr, axis=axis)
+ res_orig = _res_orig.reshape(new_shape)
+ res = method(arr, axis=axis, keepdims=True)
+ assert_equal(res, res_orig)
+ assert_(res.shape == new_shape)
+ outarray = np.empty(res.shape, dtype=res.dtype)
+ res1 = method(arr, axis=axis, out=outarray,
+ keepdims=True)
+ assert_(res1 is outarray)
+ assert_equal(res, outarray)
+
+ if len(size) > 0:
+ wrong_shape = list(new_shape)
+ if axis is not None:
+ wrong_shape[axis] = 2
+ else:
+ wrong_shape[0] = 2
+ wrong_outarray = np.empty(wrong_shape, dtype=res.dtype)
+ with pytest.raises(ValueError):
+ method(arr.T, axis=axis,
+ out=wrong_outarray, keepdims=True)
+
+ # non-contiguous arrays
+ if axis is None:
+ new_shape = [1 for _ in range(len(size))]
+ else:
+ new_shape = list(size)[::-1]
+ new_shape[axis] = 1
+ new_shape = tuple(new_shape)
+
+ _res_orig = method(arr.T, axis=axis)
+ res_orig = _res_orig.reshape(new_shape)
+ res = method(arr.T, axis=axis, keepdims=True)
+ assert_equal(res, res_orig)
+ assert_(res.shape == new_shape)
+ outarray = np.empty(new_shape[::-1], dtype=res.dtype)
+ outarray = outarray.T
+ res1 = method(arr.T, axis=axis, out=outarray,
+ keepdims=True)
+ assert_(res1 is outarray)
+ assert_equal(res, outarray)
+
+ if len(size) > 0:
+ # one dimension lesser for non-zero sized
+ # array should raise an error
+ with pytest.raises(ValueError):
+ method(arr[0], axis=axis,
+ out=outarray, keepdims=True)
+
+ if len(size) > 0:
+ wrong_shape = list(new_shape)
+ if axis is not None:
+ wrong_shape[axis] = 2
+ else:
+ wrong_shape[0] = 2
+ wrong_outarray = np.empty(wrong_shape, dtype=res.dtype)
+ with pytest.raises(ValueError):
+ method(arr.T, axis=axis,
+ out=wrong_outarray, keepdims=True)
+
+ @pytest.mark.parametrize('method', ['max', 'min'])
+ def test_all(self, method):
+ a = np.random.normal(0, 1, (4, 5, 6, 7, 8))
+ arg_method = getattr(a, 'arg' + method)
+ val_method = getattr(a, method)
+ for i in range(a.ndim):
+ a_maxmin = val_method(i)
+ aarg_maxmin = arg_method(i)
+ axes = list(range(a.ndim))
+ axes.remove(i)
+ assert_(np.all(a_maxmin == aarg_maxmin.choose(
+ *a.transpose(i, *axes))))
+
+ @pytest.mark.parametrize('method', ['argmax', 'argmin'])
+ def test_output_shape(self, method):
+ # see also gh-616
+ a = np.ones((10, 5))
+ arg_method = getattr(a, method)
+ # Check some simple shape mismatches
+ out = np.ones(11, dtype=np.int_)
+ assert_raises(ValueError, arg_method, -1, out)
+
+ out = np.ones((2, 5), dtype=np.int_)
+ assert_raises(ValueError, arg_method, -1, out)
+
+ # these could be relaxed possibly (used to allow even the previous)
+ out = np.ones((1, 10), dtype=np.int_)
+ assert_raises(ValueError, arg_method, -1, out)
+
+ out = np.ones(10, dtype=np.int_)
+ arg_method(-1, out=out)
+ assert_equal(out, arg_method(-1))
+
+ @pytest.mark.parametrize('ndim', [0, 1])
+ @pytest.mark.parametrize('method', ['argmax', 'argmin'])
+ def test_ret_is_out(self, ndim, method):
+ a = np.ones((4,) + (3,)*ndim)
+ arg_method = getattr(a, method)
+ out = np.empty((3,)*ndim, dtype=np.intp)
+ ret = arg_method(axis=0, out=out)
+ assert ret is out
+
+ @pytest.mark.parametrize('np_array, method, idx, val',
+ [(np.zeros, 'argmax', 5942, "as"),
+ (np.ones, 'argmin', 6001, "0")])
+ def test_unicode(self, np_array, method, idx, val):
+ d = np_array(6031, dtype='<U9')
+ arg_method = getattr(d, method)
+ d[idx] = val
+ assert_equal(arg_method(), idx)
+
+ @pytest.mark.parametrize('arr_method, np_method',
+ [('argmax', np.argmax),
+ ('argmin', np.argmin)])
+ def test_np_vs_ndarray(self, arr_method, np_method):
+ # make sure both ndarray.argmax/argmin and
+ # numpy.argmax/argmin support out/axis args
+ a = np.random.normal(size=(2, 3))
+ arg_method = getattr(a, arr_method)
+
+ # check positional args
+ out1 = np.zeros(2, dtype=int)
+ out2 = np.zeros(2, dtype=int)
+ assert_equal(arg_method(1, out1), np_method(a, 1, out2))
+ assert_equal(out1, out2)
+
+ # check keyword args
+ out1 = np.zeros(3, dtype=int)
+ out2 = np.zeros(3, dtype=int)
+ assert_equal(arg_method(out=out1, axis=0),
+ np_method(a, out=out2, axis=0))
+ assert_equal(out1, out2)
+
+ @pytest.mark.leaks_references(reason="replaces None with NULL.")
+ @pytest.mark.parametrize('method, vals',
+ [('argmax', (10, 30)),
+ ('argmin', (30, 10))])
+ def test_object_with_NULLs(self, method, vals):
+ # See gh-6032
+ a = np.empty(4, dtype='O')
+ arg_method = getattr(a, method)
+ ctypes.memset(a.ctypes.data, 0, a.nbytes)
+ assert_equal(arg_method(), 0)
+ a[3] = vals[0]
+ assert_equal(arg_method(), 3)
+ a[1] = vals[1]
+ assert_equal(arg_method(), 1)
class TestArgmax:
@@ -4223,81 +4428,30 @@ class TestArgmax:
([True, False, True, False, False], 0),
]
- def test_all(self):
- a = np.random.normal(0, 1, (4, 5, 6, 7, 8))
- for i in range(a.ndim):
- amax = a.max(i)
- aargmax = a.argmax(i)
- axes = list(range(a.ndim))
- axes.remove(i)
- assert_(np.all(amax == aargmax.choose(*a.transpose(i,*axes))))
-
- def test_combinations(self):
- for arr, pos in self.nan_arr:
- with suppress_warnings() as sup:
- sup.filter(RuntimeWarning,
- "invalid value encountered in reduce")
- max_val = np.max(arr)
-
- assert_equal(np.argmax(arr), pos, err_msg="%r" % arr)
- assert_equal(arr[np.argmax(arr)], max_val, err_msg="%r" % arr)
-
- def test_output_shape(self):
- # see also gh-616
- a = np.ones((10, 5))
- # Check some simple shape mismatches
- out = np.ones(11, dtype=np.int_)
- assert_raises(ValueError, a.argmax, -1, out)
-
- out = np.ones((2, 5), dtype=np.int_)
- assert_raises(ValueError, a.argmax, -1, out)
-
- # these could be relaxed possibly (used to allow even the previous)
- out = np.ones((1, 10), dtype=np.int_)
- assert_raises(ValueError, a.argmax, -1, out)
-
- out = np.ones(10, dtype=np.int_)
- a.argmax(-1, out=out)
- assert_equal(out, a.argmax(-1))
-
- @pytest.mark.parametrize('ndim', [0, 1])
- def test_ret_is_out(self, ndim):
- a = np.ones((4,) + (3,)*ndim)
- out = np.empty((3,)*ndim, dtype=np.intp)
- ret = a.argmax(axis=0, out=out)
- assert ret is out
+ @pytest.mark.parametrize('data', nan_arr)
+ def test_combinations(self, data):
+ arr, pos = data
+ with suppress_warnings() as sup:
+ sup.filter(RuntimeWarning,
+ "invalid value encountered in reduce")
+ val = np.max(arr)
- def test_argmax_unicode(self):
- d = np.zeros(6031, dtype='<U9')
- d[5942] = "as"
- assert_equal(d.argmax(), 5942)
+ assert_equal(np.argmax(arr), pos, err_msg="%r" % arr)
+ assert_equal(arr[np.argmax(arr)], val, err_msg="%r" % arr)
+
+ def test_maximum_signed_integers(self):
- def test_np_vs_ndarray(self):
- # make sure both ndarray.argmax and numpy.argmax support out/axis args
- a = np.random.normal(size=(2,3))
+ a = np.array([1, 2**7 - 1, -2**7], dtype=np.int8)
+ assert_equal(np.argmax(a), 1)
- # check positional args
- out1 = np.zeros(2, dtype=int)
- out2 = np.zeros(2, dtype=int)
- assert_equal(a.argmax(1, out1), np.argmax(a, 1, out2))
- assert_equal(out1, out2)
+ a = np.array([1, 2**15 - 1, -2**15], dtype=np.int16)
+ assert_equal(np.argmax(a), 1)
- # check keyword args
- out1 = np.zeros(3, dtype=int)
- out2 = np.zeros(3, dtype=int)
- assert_equal(a.argmax(out=out1, axis=0), np.argmax(a, out=out2, axis=0))
- assert_equal(out1, out2)
+ a = np.array([1, 2**31 - 1, -2**31], dtype=np.int32)
+ assert_equal(np.argmax(a), 1)
- @pytest.mark.leaks_references(reason="replaces None with NULL.")
- def test_object_argmax_with_NULLs(self):
- # See gh-6032
- a = np.empty(4, dtype='O')
- ctypes.memset(a.ctypes.data, 0, a.nbytes)
- assert_equal(a.argmax(), 0)
- a[3] = 10
- assert_equal(a.argmax(), 3)
- a[1] = 30
- assert_equal(a.argmax(), 1)
+ a = np.array([1, 2**63 - 1, -2**63], dtype=np.int64)
+ assert_equal(np.argmax(a), 1)
class TestArgmin:
@@ -4365,15 +4519,6 @@ class TestArgmin:
([False, True, False, True, True], 0),
]
- def test_all(self):
- a = np.random.normal(0, 1, (4, 5, 6, 7, 8))
- for i in range(a.ndim):
- amin = a.min(i)
- aargmin = a.argmin(i)
- axes = list(range(a.ndim))
- axes.remove(i)
- assert_(np.all(amin == aargmin.choose(*a.transpose(i,*axes))))
-
def test_combinations(self):
for arr, pos in self.nan_arr:
with suppress_warnings() as sup:
@@ -4386,75 +4531,18 @@ class TestArgmin:
def test_minimum_signed_integers(self):
- a = np.array([1, -2**7, -2**7 + 1], dtype=np.int8)
+ a = np.array([1, -2**7, -2**7 + 1, 2**7 - 1], dtype=np.int8)
assert_equal(np.argmin(a), 1)
- a = np.array([1, -2**15, -2**15 + 1], dtype=np.int16)
+ a = np.array([1, -2**15, -2**15 + 1, 2**15 - 1], dtype=np.int16)
assert_equal(np.argmin(a), 1)
- a = np.array([1, -2**31, -2**31 + 1], dtype=np.int32)
+ a = np.array([1, -2**31, -2**31 + 1, 2**31 - 1], dtype=np.int32)
assert_equal(np.argmin(a), 1)
- a = np.array([1, -2**63, -2**63 + 1], dtype=np.int64)
+ a = np.array([1, -2**63, -2**63 + 1, 2**63 - 1], dtype=np.int64)
assert_equal(np.argmin(a), 1)
- def test_output_shape(self):
- # see also gh-616
- a = np.ones((10, 5))
- # Check some simple shape mismatches
- out = np.ones(11, dtype=np.int_)
- assert_raises(ValueError, a.argmin, -1, out)
-
- out = np.ones((2, 5), dtype=np.int_)
- assert_raises(ValueError, a.argmin, -1, out)
-
- # these could be relaxed possibly (used to allow even the previous)
- out = np.ones((1, 10), dtype=np.int_)
- assert_raises(ValueError, a.argmin, -1, out)
-
- out = np.ones(10, dtype=np.int_)
- a.argmin(-1, out=out)
- assert_equal(out, a.argmin(-1))
-
- @pytest.mark.parametrize('ndim', [0, 1])
- def test_ret_is_out(self, ndim):
- a = np.ones((4,) + (3,)*ndim)
- out = np.empty((3,)*ndim, dtype=np.intp)
- ret = a.argmin(axis=0, out=out)
- assert ret is out
-
- def test_argmin_unicode(self):
- d = np.ones(6031, dtype='<U9')
- d[6001] = "0"
- assert_equal(d.argmin(), 6001)
-
- def test_np_vs_ndarray(self):
- # make sure both ndarray.argmin and numpy.argmin support out/axis args
- a = np.random.normal(size=(2, 3))
-
- # check positional args
- out1 = np.zeros(2, dtype=int)
- out2 = np.ones(2, dtype=int)
- assert_equal(a.argmin(1, out1), np.argmin(a, 1, out2))
- assert_equal(out1, out2)
-
- # check keyword args
- out1 = np.zeros(3, dtype=int)
- out2 = np.ones(3, dtype=int)
- assert_equal(a.argmin(out=out1, axis=0), np.argmin(a, out=out2, axis=0))
- assert_equal(out1, out2)
-
- @pytest.mark.leaks_references(reason="replaces None with NULL.")
- def test_object_argmin_with_NULLs(self):
- # See gh-6032
- a = np.empty(4, dtype='O')
- ctypes.memset(a.ctypes.data, 0, a.nbytes)
- assert_equal(a.argmin(), 0)
- a[3] = 30
- assert_equal(a.argmin(), 3)
- a[1] = 10
- assert_equal(a.argmin(), 1)
-
class TestMinMax:
@@ -4643,6 +4731,13 @@ class TestPutmask:
np.putmask(x[1:4], x[:3], [True, False, True])
assert_equal(x, np.array([True, True, True, True]))
+ def test_writeable(self):
+ a = np.arange(5)
+ a.flags.writeable = False
+
+ with pytest.raises(ValueError):
+ np.putmask(a, a >= 2, 3)
+
class TestTake:
def tst_basic(self, x):
@@ -4768,17 +4863,23 @@ class TestLexsort:
class TestIO:
"""Test tofile, fromfile, tobytes, and fromstring"""
- def setup(self):
+ @pytest.fixture()
+ def x(self):
shape = (2, 4, 3)
rand = np.random.random
- self.x = rand(shape) + rand(shape).astype(complex)*1j
- self.x[0,:, 1] = [np.nan, np.inf, -np.inf, np.nan]
- self.dtype = self.x.dtype
- self.tempdir = tempfile.mkdtemp()
- self.filename = tempfile.mktemp(dir=self.tempdir)
+ x = rand(shape) + rand(shape).astype(complex) * 1j
+ x[0, :, 1] = [np.nan, np.inf, -np.inf, np.nan]
+ return x
- def teardown(self):
- shutil.rmtree(self.tempdir)
+ @pytest.fixture(params=["string", "path_obj"])
+ def tmp_filename(self, tmp_path, request):
+ # This fixture covers two cases:
+ # one where the filename is a string and
+ # another where it is a pathlib object
+ filename = tmp_path / "file"
+ if request.param == "string":
+ filename = str(filename)
+ yield filename
def test_nofile(self):
# this should probably be supported as a file
@@ -4809,54 +4910,48 @@ class TestIO:
d = np.fromstring("1,2", sep=",", dtype=np.int64, count=0)
assert d.shape == (0,)
- def test_empty_files_binary(self):
- with open(self.filename, 'w') as f:
+ def test_empty_files_text(self, tmp_filename):
+ with open(tmp_filename, 'w') as f:
pass
- y = np.fromfile(self.filename)
+ y = np.fromfile(tmp_filename)
assert_(y.size == 0, "Array not empty")
- def test_empty_files_text(self):
- with open(self.filename, 'wb') as f:
+ def test_empty_files_binary(self, tmp_filename):
+ with open(tmp_filename, 'wb') as f:
pass
- y = np.fromfile(self.filename, sep=" ")
+ y = np.fromfile(tmp_filename, sep=" ")
assert_(y.size == 0, "Array not empty")
- def test_roundtrip_file(self):
- with open(self.filename, 'wb') as f:
- self.x.tofile(f)
+ def test_roundtrip_file(self, x, tmp_filename):
+ with open(tmp_filename, 'wb') as f:
+ x.tofile(f)
# NB. doesn't work with flush+seek, due to use of C stdio
- with open(self.filename, 'rb') as f:
- y = np.fromfile(f, dtype=self.dtype)
- assert_array_equal(y, self.x.flat)
-
- def test_roundtrip_filename(self):
- self.x.tofile(self.filename)
- y = np.fromfile(self.filename, dtype=self.dtype)
- assert_array_equal(y, self.x.flat)
-
- def test_roundtrip_pathlib(self):
- p = pathlib.Path(self.filename)
- self.x.tofile(p)
- y = np.fromfile(p, dtype=self.dtype)
- assert_array_equal(y, self.x.flat)
-
- def test_roundtrip_dump_pathlib(self):
- p = pathlib.Path(self.filename)
- self.x.dump(p)
+ with open(tmp_filename, 'rb') as f:
+ y = np.fromfile(f, dtype=x.dtype)
+ assert_array_equal(y, x.flat)
+
+ def test_roundtrip(self, x, tmp_filename):
+ x.tofile(tmp_filename)
+ y = np.fromfile(tmp_filename, dtype=x.dtype)
+ assert_array_equal(y, x.flat)
+
+ def test_roundtrip_dump_pathlib(self, x, tmp_filename):
+ p = pathlib.Path(tmp_filename)
+ x.dump(p)
y = np.load(p, allow_pickle=True)
- assert_array_equal(y, self.x)
+ assert_array_equal(y, x)
- def test_roundtrip_binary_str(self):
- s = self.x.tobytes()
- y = np.frombuffer(s, dtype=self.dtype)
- assert_array_equal(y, self.x.flat)
+ def test_roundtrip_binary_str(self, x):
+ s = x.tobytes()
+ y = np.frombuffer(s, dtype=x.dtype)
+ assert_array_equal(y, x.flat)
- s = self.x.tobytes('F')
- y = np.frombuffer(s, dtype=self.dtype)
- assert_array_equal(y, self.x.flatten('F'))
+ s = x.tobytes('F')
+ y = np.frombuffer(s, dtype=x.dtype)
+ assert_array_equal(y, x.flatten('F'))
- def test_roundtrip_str(self):
- x = self.x.real.ravel()
+ def test_roundtrip_str(self, x):
+ x = x.real.ravel()
s = "@".join(map(str, x))
y = np.fromstring(s, sep="@")
# NB. str imbues less precision
@@ -4864,79 +4959,79 @@ class TestIO:
assert_array_equal(x[nan_mask], y[nan_mask])
assert_array_almost_equal(x[~nan_mask], y[~nan_mask], decimal=5)
- def test_roundtrip_repr(self):
- x = self.x.real.ravel()
+ def test_roundtrip_repr(self, x):
+ x = x.real.ravel()
s = "@".join(map(repr, x))
y = np.fromstring(s, sep="@")
assert_array_equal(x, y)
- def test_unseekable_fromfile(self):
+ def test_unseekable_fromfile(self, x, tmp_filename):
# gh-6246
- self.x.tofile(self.filename)
+ x.tofile(tmp_filename)
def fail(*args, **kwargs):
raise IOError('Can not tell or seek')
- with io.open(self.filename, 'rb', buffering=0) as f:
+ with io.open(tmp_filename, 'rb', buffering=0) as f:
f.seek = fail
f.tell = fail
- assert_raises(IOError, np.fromfile, f, dtype=self.dtype)
+ assert_raises(IOError, np.fromfile, f, dtype=x.dtype)
- def test_io_open_unbuffered_fromfile(self):
+ def test_io_open_unbuffered_fromfile(self, x, tmp_filename):
# gh-6632
- self.x.tofile(self.filename)
- with io.open(self.filename, 'rb', buffering=0) as f:
- y = np.fromfile(f, dtype=self.dtype)
- assert_array_equal(y, self.x.flat)
+ x.tofile(tmp_filename)
+ with io.open(tmp_filename, 'rb', buffering=0) as f:
+ y = np.fromfile(f, dtype=x.dtype)
+ assert_array_equal(y, x.flat)
- def test_largish_file(self):
+ def test_largish_file(self, tmp_filename):
# check the fallocate path on files > 16MB
d = np.zeros(4 * 1024 ** 2)
- d.tofile(self.filename)
- assert_equal(os.path.getsize(self.filename), d.nbytes)
- assert_array_equal(d, np.fromfile(self.filename))
+ d.tofile(tmp_filename)
+ assert_equal(os.path.getsize(tmp_filename), d.nbytes)
+ assert_array_equal(d, np.fromfile(tmp_filename))
# check offset
- with open(self.filename, "r+b") as f:
+ with open(tmp_filename, "r+b") as f:
f.seek(d.nbytes)
d.tofile(f)
- assert_equal(os.path.getsize(self.filename), d.nbytes * 2)
+ assert_equal(os.path.getsize(tmp_filename), d.nbytes * 2)
# check append mode (gh-8329)
- open(self.filename, "w").close() # delete file contents
- with open(self.filename, "ab") as f:
+ open(tmp_filename, "w").close() # delete file contents
+ with open(tmp_filename, "ab") as f:
d.tofile(f)
- assert_array_equal(d, np.fromfile(self.filename))
- with open(self.filename, "ab") as f:
+ assert_array_equal(d, np.fromfile(tmp_filename))
+ with open(tmp_filename, "ab") as f:
d.tofile(f)
- assert_equal(os.path.getsize(self.filename), d.nbytes * 2)
+ assert_equal(os.path.getsize(tmp_filename), d.nbytes * 2)
- def test_io_open_buffered_fromfile(self):
+ def test_io_open_buffered_fromfile(self, x, tmp_filename):
# gh-6632
- self.x.tofile(self.filename)
- with io.open(self.filename, 'rb', buffering=-1) as f:
- y = np.fromfile(f, dtype=self.dtype)
- assert_array_equal(y, self.x.flat)
+ x.tofile(tmp_filename)
+ with io.open(tmp_filename, 'rb', buffering=-1) as f:
+ y = np.fromfile(f, dtype=x.dtype)
+ assert_array_equal(y, x.flat)
- def test_file_position_after_fromfile(self):
+ def test_file_position_after_fromfile(self, tmp_filename):
# gh-4118
sizes = [io.DEFAULT_BUFFER_SIZE//8,
io.DEFAULT_BUFFER_SIZE,
io.DEFAULT_BUFFER_SIZE*8]
for size in sizes:
- with open(self.filename, 'wb') as f:
+ with open(tmp_filename, 'wb') as f:
f.seek(size-1)
f.write(b'\0')
for mode in ['rb', 'r+b']:
err_msg = "%d %s" % (size, mode)
- with open(self.filename, mode) as f:
+ with open(tmp_filename, mode) as f:
f.read(2)
np.fromfile(f, dtype=np.float64, count=1)
pos = f.tell()
assert_equal(pos, 10, err_msg=err_msg)
- def test_file_position_after_tofile(self):
+ def test_file_position_after_tofile(self, tmp_filename):
# gh-4118
sizes = [io.DEFAULT_BUFFER_SIZE//8,
io.DEFAULT_BUFFER_SIZE,
@@ -4945,7 +5040,7 @@ class TestIO:
for size in sizes:
err_msg = "%d" % (size,)
- with open(self.filename, 'wb') as f:
+ with open(tmp_filename, 'wb') as f:
f.seek(size-1)
f.write(b'\0')
f.seek(10)
@@ -4954,88 +5049,145 @@ class TestIO:
pos = f.tell()
assert_equal(pos, 10 + 2 + 8, err_msg=err_msg)
- with open(self.filename, 'r+b') as f:
+ with open(tmp_filename, 'r+b') as f:
f.read(2)
f.seek(0, 1) # seek between read&write required by ANSI C
np.array([0], dtype=np.float64).tofile(f)
pos = f.tell()
assert_equal(pos, 10, err_msg=err_msg)
- def test_load_object_array_fromfile(self):
+ def test_load_object_array_fromfile(self, tmp_filename):
# gh-12300
- with open(self.filename, 'w') as f:
+ with open(tmp_filename, 'w') as f:
# Ensure we have a file with consistent contents
pass
- with open(self.filename, 'rb') as f:
+ with open(tmp_filename, 'rb') as f:
assert_raises_regex(ValueError, "Cannot read into object array",
np.fromfile, f, dtype=object)
assert_raises_regex(ValueError, "Cannot read into object array",
- np.fromfile, self.filename, dtype=object)
-
- def test_fromfile_offset(self):
- with open(self.filename, 'wb') as f:
- self.x.tofile(f)
-
- with open(self.filename, 'rb') as f:
- y = np.fromfile(f, dtype=self.dtype, offset=0)
- assert_array_equal(y, self.x.flat)
-
- with open(self.filename, 'rb') as f:
- count_items = len(self.x.flat) // 8
- offset_items = len(self.x.flat) // 4
- offset_bytes = self.dtype.itemsize * offset_items
- y = np.fromfile(f, dtype=self.dtype, count=count_items, offset=offset_bytes)
- assert_array_equal(y, self.x.flat[offset_items:offset_items+count_items])
+ np.fromfile, tmp_filename, dtype=object)
+
+ def test_fromfile_offset(self, x, tmp_filename):
+ with open(tmp_filename, 'wb') as f:
+ x.tofile(f)
+
+ with open(tmp_filename, 'rb') as f:
+ y = np.fromfile(f, dtype=x.dtype, offset=0)
+ assert_array_equal(y, x.flat)
+
+ with open(tmp_filename, 'rb') as f:
+ count_items = len(x.flat) // 8
+ offset_items = len(x.flat) // 4
+ offset_bytes = x.dtype.itemsize * offset_items
+ y = np.fromfile(
+ f, dtype=x.dtype, count=count_items, offset=offset_bytes
+ )
+ assert_array_equal(
+ y, x.flat[offset_items:offset_items+count_items]
+ )
# subsequent seeks should stack
- offset_bytes = self.dtype.itemsize
- z = np.fromfile(f, dtype=self.dtype, offset=offset_bytes)
- assert_array_equal(z, self.x.flat[offset_items+count_items+1:])
+ offset_bytes = x.dtype.itemsize
+ z = np.fromfile(f, dtype=x.dtype, offset=offset_bytes)
+ assert_array_equal(z, x.flat[offset_items+count_items+1:])
- with open(self.filename, 'wb') as f:
- self.x.tofile(f, sep=",")
+ with open(tmp_filename, 'wb') as f:
+ x.tofile(f, sep=",")
- with open(self.filename, 'rb') as f:
+ with open(tmp_filename, 'rb') as f:
assert_raises_regex(
TypeError,
"'offset' argument only permitted for binary files",
- np.fromfile, self.filename, dtype=self.dtype,
+ np.fromfile, tmp_filename, dtype=x.dtype,
sep=",", offset=1)
- def _check_from(self, s, value, **kw):
+ @pytest.mark.skipif(IS_PYPY, reason="bug in PyPy's PyNumber_AsSsize_t")
+ def test_fromfile_bad_dup(self, x, tmp_filename):
+ def dup_str(fd):
+ return 'abc'
+
+ def dup_bigint(fd):
+ return 2**68
+
+ old_dup = os.dup
+ try:
+ with open(tmp_filename, 'wb') as f:
+ x.tofile(f)
+ for dup, exc in ((dup_str, TypeError), (dup_bigint, OSError)):
+ os.dup = dup
+ assert_raises(exc, np.fromfile, f)
+ finally:
+ os.dup = old_dup
+
+ def _check_from(self, s, value, filename, **kw):
if 'sep' not in kw:
y = np.frombuffer(s, **kw)
else:
y = np.fromstring(s, **kw)
assert_array_equal(y, value)
- with open(self.filename, 'wb') as f:
+ with open(filename, 'wb') as f:
f.write(s)
- y = np.fromfile(self.filename, **kw)
+ y = np.fromfile(filename, **kw)
assert_array_equal(y, value)
- def test_nan(self):
+ @pytest.fixture(params=["period", "comma"])
+ def decimal_sep_localization(self, request):
+ """
+ Including this fixture in a test will automatically
+ execute it with both types of decimal separator.
+
+ So::
+
+ def test_decimal(decimal_sep_localization):
+ pass
+
+ is equivalent to the following two tests::
+
+ def test_decimal_period_separator():
+ pass
+
+ def test_decimal_comma_separator():
+ with CommaDecimalPointLocale():
+ pass
+ """
+ if request.param == "period":
+ yield
+ elif request.param == "comma":
+ with CommaDecimalPointLocale():
+ yield
+ else:
+ assert False, request.param
+
+ def test_nan(self, tmp_filename, decimal_sep_localization):
self._check_from(
b"nan +nan -nan NaN nan(foo) +NaN(BAR) -NAN(q_u_u_x_)",
[np.nan, np.nan, np.nan, np.nan, np.nan, np.nan, np.nan],
+ tmp_filename,
sep=' ')
- def test_inf(self):
+ def test_inf(self, tmp_filename, decimal_sep_localization):
self._check_from(
b"inf +inf -inf infinity -Infinity iNfInItY -inF",
[np.inf, np.inf, -np.inf, np.inf, -np.inf, np.inf, -np.inf],
+ tmp_filename,
sep=' ')
- def test_numbers(self):
- self._check_from(b"1.234 -1.234 .3 .3e55 -123133.1231e+133",
- [1.234, -1.234, .3, .3e55, -123133.1231e+133], sep=' ')
+ def test_numbers(self, tmp_filename, decimal_sep_localization):
+ self._check_from(
+ b"1.234 -1.234 .3 .3e55 -123133.1231e+133",
+ [1.234, -1.234, .3, .3e55, -123133.1231e+133],
+ tmp_filename,
+ sep=' ')
- def test_binary(self):
- self._check_from(b'\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@',
- np.array([1, 2, 3, 4]),
- dtype='<f4')
+ def test_binary(self, tmp_filename):
+ self._check_from(
+ b'\x00\x00\x80?\x00\x00\x00@\x00\x00@@\x00\x00\x80@',
+ np.array([1, 2, 3, 4]),
+ tmp_filename,
+ dtype='<f4')
@pytest.mark.slow # takes > 1 minute on mechanical hard drive
def test_big_binary(self):
@@ -5062,91 +5214,89 @@ class TestIO:
except (MemoryError, ValueError):
pass
- def test_string(self):
- self._check_from(b'1,2,3,4', [1., 2., 3., 4.], sep=',')
+ def test_string(self, tmp_filename):
+ self._check_from(b'1,2,3,4', [1., 2., 3., 4.], tmp_filename, sep=',')
- def test_counted_string(self):
- self._check_from(b'1,2,3,4', [1., 2., 3., 4.], count=4, sep=',')
- self._check_from(b'1,2,3,4', [1., 2., 3.], count=3, sep=',')
- self._check_from(b'1,2,3,4', [1., 2., 3., 4.], count=-1, sep=',')
+ def test_counted_string(self, tmp_filename, decimal_sep_localization):
+ self._check_from(
+ b'1,2,3,4', [1., 2., 3., 4.], tmp_filename, count=4, sep=',')
+ self._check_from(
+ b'1,2,3,4', [1., 2., 3.], tmp_filename, count=3, sep=',')
+ self._check_from(
+ b'1,2,3,4', [1., 2., 3., 4.], tmp_filename, count=-1, sep=',')
- def test_string_with_ws(self):
- self._check_from(b'1 2 3 4 ', [1, 2, 3, 4], dtype=int, sep=' ')
+ def test_string_with_ws(self, tmp_filename):
+ self._check_from(
+ b'1 2 3 4 ', [1, 2, 3, 4], tmp_filename, dtype=int, sep=' ')
- def test_counted_string_with_ws(self):
- self._check_from(b'1 2 3 4 ', [1, 2, 3], count=3, dtype=int,
- sep=' ')
+ def test_counted_string_with_ws(self, tmp_filename):
+ self._check_from(
+ b'1 2 3 4 ', [1, 2, 3], tmp_filename, count=3, dtype=int,
+ sep=' ')
- def test_ascii(self):
- self._check_from(b'1 , 2 , 3 , 4', [1., 2., 3., 4.], sep=',')
- self._check_from(b'1,2,3,4', [1., 2., 3., 4.], dtype=float, sep=',')
+ def test_ascii(self, tmp_filename, decimal_sep_localization):
+ self._check_from(
+ b'1 , 2 , 3 , 4', [1., 2., 3., 4.], tmp_filename, sep=',')
+ self._check_from(
+ b'1,2,3,4', [1., 2., 3., 4.], tmp_filename, dtype=float, sep=',')
- def test_malformed(self):
+ def test_malformed(self, tmp_filename, decimal_sep_localization):
with assert_warns(DeprecationWarning):
- self._check_from(b'1.234 1,234', [1.234, 1.], sep=' ')
+ self._check_from(
+ b'1.234 1,234', [1.234, 1.], tmp_filename, sep=' ')
- def test_long_sep(self):
- self._check_from(b'1_x_3_x_4_x_5', [1, 3, 4, 5], sep='_x_')
+ def test_long_sep(self, tmp_filename):
+ self._check_from(
+ b'1_x_3_x_4_x_5', [1, 3, 4, 5], tmp_filename, sep='_x_')
- def test_dtype(self):
+ def test_dtype(self, tmp_filename):
v = np.array([1, 2, 3, 4], dtype=np.int_)
- self._check_from(b'1,2,3,4', v, sep=',', dtype=np.int_)
+ self._check_from(b'1,2,3,4', v, tmp_filename, sep=',', dtype=np.int_)
- def test_dtype_bool(self):
+ def test_dtype_bool(self, tmp_filename):
# can't use _check_from because fromstring can't handle True/False
v = np.array([True, False, True, False], dtype=np.bool_)
s = b'1,0,-2.3,0'
- with open(self.filename, 'wb') as f:
+ with open(tmp_filename, 'wb') as f:
f.write(s)
- y = np.fromfile(self.filename, sep=',', dtype=np.bool_)
+ y = np.fromfile(tmp_filename, sep=',', dtype=np.bool_)
assert_(y.dtype == '?')
assert_array_equal(y, v)
- def test_tofile_sep(self):
+ def test_tofile_sep(self, tmp_filename, decimal_sep_localization):
x = np.array([1.51, 2, 3.51, 4], dtype=float)
- with open(self.filename, 'w') as f:
+ with open(tmp_filename, 'w') as f:
x.tofile(f, sep=',')
- with open(self.filename, 'r') as f:
+ with open(tmp_filename, 'r') as f:
s = f.read()
#assert_equal(s, '1.51,2.0,3.51,4.0')
y = np.array([float(p) for p in s.split(',')])
assert_array_equal(x,y)
- def test_tofile_format(self):
+ def test_tofile_format(self, tmp_filename, decimal_sep_localization):
x = np.array([1.51, 2, 3.51, 4], dtype=float)
- with open(self.filename, 'w') as f:
+ with open(tmp_filename, 'w') as f:
x.tofile(f, sep=',', format='%.2f')
- with open(self.filename, 'r') as f:
+ with open(tmp_filename, 'r') as f:
s = f.read()
assert_equal(s, '1.51,2.00,3.51,4.00')
- def test_tofile_cleanup(self):
+ def test_tofile_cleanup(self, tmp_filename):
x = np.zeros((10), dtype=object)
- with open(self.filename, 'wb') as f:
+ with open(tmp_filename, 'wb') as f:
assert_raises(IOError, lambda: x.tofile(f, sep=''))
# Dup-ed file handle should be closed or remove will fail on Windows OS
- os.remove(self.filename)
+ os.remove(tmp_filename)
# Also make sure that we close the Python handle
- assert_raises(IOError, lambda: x.tofile(self.filename))
- os.remove(self.filename)
-
- def test_locale(self):
- with CommaDecimalPointLocale():
- self.test_numbers()
- self.test_nan()
- self.test_inf()
- self.test_counted_string()
- self.test_ascii()
- self.test_malformed()
- self.test_tofile_sep()
- self.test_tofile_format()
-
- def test_fromfile_subarray_binary(self):
+ assert_raises(IOError, lambda: x.tofile(tmp_filename))
+ os.remove(tmp_filename)
+
+ def test_fromfile_subarray_binary(self, tmp_filename):
# Test subarray dtypes which are absorbed into the shape
x = np.arange(24, dtype="i4").reshape(2, 3, 4)
- x.tofile(self.filename)
- res = np.fromfile(self.filename, dtype="(3,4)i4")
+ x.tofile(tmp_filename)
+ res = np.fromfile(tmp_filename, dtype="(3,4)i4")
assert_array_equal(x, res)
x_str = x.tobytes()
@@ -5155,21 +5305,21 @@ class TestIO:
res = np.fromstring(x_str, dtype="(3,4)i4")
assert_array_equal(x, res)
- def test_parsing_subarray_unsupported(self):
+ def test_parsing_subarray_unsupported(self, tmp_filename):
# We currently do not support parsing subarray dtypes
data = "12,42,13," * 50
with pytest.raises(ValueError):
expected = np.fromstring(data, dtype="(3,)i", sep=",")
- with open(self.filename, "w") as f:
+ with open(tmp_filename, "w") as f:
f.write(data)
with pytest.raises(ValueError):
- np.fromfile(self.filename, dtype="(3,)i", sep=",")
+ np.fromfile(tmp_filename, dtype="(3,)i", sep=",")
- def test_read_shorter_than_count_subarray(self):
+ def test_read_shorter_than_count_subarray(self, tmp_filename):
# Test that requesting more values does not cause any problems
- # in conjuction with subarray dimensions being absored into the
+ # in conjunction with subarray dimensions being absorbed into the
# array dimension.
expected = np.arange(511 * 10, dtype="i").reshape(-1, 10)
@@ -5178,8 +5328,8 @@ class TestIO:
with pytest.warns(DeprecationWarning):
np.fromstring(binary, dtype="(10,)i", count=10000)
- expected.tofile(self.filename)
- res = np.fromfile(self.filename, dtype="(10,)i", count=10000)
+ expected.tofile(tmp_filename)
+ res = np.fromfile(tmp_filename, dtype="(10,)i", count=10000)
assert_array_equal(res, expected)
@@ -5267,6 +5417,17 @@ class TestFlat:
assert_(abs(sys.getrefcount(ind) - rc_ind) < 50)
assert_(abs(sys.getrefcount(indtype) - rc_indtype) < 50)
+ def test_index_getset(self):
+ it = np.arange(10).reshape(2, 1, 5).flat
+ with pytest.raises(AttributeError):
+ it.index = 10
+
+ for _ in it:
+ pass
+ # Check the value of `.index` is updated correctly (see also gh-19153)
+ # If the type was incorrect, this would show up on big-endian machines
+ assert it.index == it.base.size
+
class TestResize:
@@ -5713,6 +5874,15 @@ class TestStats:
np.array(_res))
assert_allclose(np.mean(a, axis=_ax, where=_wh),
np.array(_res))
+
+ a3d = np.arange(16).reshape((2, 2, 4))
+ _wh_partial = np.array([False, True, True, False])
+ _res = [[1.5, 5.5], [9.5, 13.5]]
+ assert_allclose(a3d.mean(axis=2, where=_wh_partial),
+ np.array(_res))
+ assert_allclose(np.mean(a3d, axis=2, where=_wh_partial),
+ np.array(_res))
+
with pytest.warns(RuntimeWarning) as w:
assert_allclose(a.mean(axis=1, where=wh_partial),
np.array([np.nan, 5.5, 9.5, np.nan]))
@@ -5788,6 +5958,15 @@ class TestStats:
np.array(_res))
assert_allclose(np.var(a, axis=_ax, where=_wh),
np.array(_res))
+
+ a3d = np.arange(16).reshape((2, 2, 4))
+ _wh_partial = np.array([False, True, True, False])
+ _res = [[0.25, 0.25], [0.25, 0.25]]
+ assert_allclose(a3d.var(axis=2, where=_wh_partial),
+ np.array(_res))
+ assert_allclose(np.var(a3d, axis=2, where=_wh_partial),
+ np.array(_res))
+
assert_allclose(np.var(a, axis=1, where=wh_full),
np.var(a[wh_full].reshape((5, 3)), axis=1))
assert_allclose(np.var(a, axis=0, where=wh_partial),
@@ -5827,6 +6006,14 @@ class TestStats:
assert_allclose(a.std(axis=_ax, where=_wh), _res)
assert_allclose(np.std(a, axis=_ax, where=_wh), _res)
+ a3d = np.arange(16).reshape((2, 2, 4))
+ _wh_partial = np.array([False, True, True, False])
+ _res = [[0.5, 0.5], [0.5, 0.5]]
+ assert_allclose(a3d.std(axis=2, where=_wh_partial),
+ np.array(_res))
+ assert_allclose(np.std(a3d, axis=2, where=_wh_partial),
+ np.array(_res))
+
assert_allclose(a.std(axis=1, where=whf),
np.std(a[whf].reshape((5,3)), axis=1))
assert_allclose(np.std(a, axis=1, where=whf),
@@ -5859,6 +6046,7 @@ class TestStats:
res = dat.var(1)
assert_(res.info == dat.info)
+
class TestVdot:
def test_basic(self):
dt_numeric = np.typecodes['AllFloat'] + np.typecodes['AllInteger']
@@ -6125,6 +6313,71 @@ class TestDot:
assert_equal(np.dot(b, a), res)
assert_equal(np.dot(b, b), res)
+ def test_accelerate_framework_sgemv_fix(self):
+
+ def aligned_array(shape, align, dtype, order='C'):
+ d = dtype(0)
+ N = np.prod(shape)
+ tmp = np.zeros(N * d.nbytes + align, dtype=np.uint8)
+ address = tmp.__array_interface__["data"][0]
+ for offset in range(align):
+ if (address + offset) % align == 0:
+ break
+ tmp = tmp[offset:offset+N*d.nbytes].view(dtype=dtype)
+ return tmp.reshape(shape, order=order)
+
+ def as_aligned(arr, align, dtype, order='C'):
+ aligned = aligned_array(arr.shape, align, dtype, order)
+ aligned[:] = arr[:]
+ return aligned
+
+ def assert_dot_close(A, X, desired):
+ assert_allclose(np.dot(A, X), desired, rtol=1e-5, atol=1e-7)
+
+ m = aligned_array(100, 15, np.float32)
+ s = aligned_array((100, 100), 15, np.float32)
+ np.dot(s, m) # this will always segfault if the bug is present
+
+ testdata = itertools.product((15, 32), (10000,), (200, 89), ('C', 'F'))
+ for align, m, n, a_order in testdata:
+ # Calculation in double precision
+ A_d = np.random.rand(m, n)
+ X_d = np.random.rand(n)
+ desired = np.dot(A_d, X_d)
+ # Calculation with aligned single precision
+ A_f = as_aligned(A_d, align, np.float32, order=a_order)
+ X_f = as_aligned(X_d, align, np.float32)
+ assert_dot_close(A_f, X_f, desired)
+ # Strided A rows
+ A_d_2 = A_d[::2]
+ desired = np.dot(A_d_2, X_d)
+ A_f_2 = A_f[::2]
+ assert_dot_close(A_f_2, X_f, desired)
+ # Strided A columns, strided X vector
+ A_d_22 = A_d_2[:, ::2]
+ X_d_2 = X_d[::2]
+ desired = np.dot(A_d_22, X_d_2)
+ A_f_22 = A_f_2[:, ::2]
+ X_f_2 = X_f[::2]
+ assert_dot_close(A_f_22, X_f_2, desired)
+ # Check the strides are as expected
+ if a_order == 'F':
+ assert_equal(A_f_22.strides, (8, 8 * m))
+ else:
+ assert_equal(A_f_22.strides, (8 * n, 8))
+ assert_equal(X_f_2.strides, (8,))
+ # Strides in A rows + cols only
+ X_f_2c = as_aligned(X_f_2, align, np.float32)
+ assert_dot_close(A_f_22, X_f_2c, desired)
+ # Strides just in A cols
+ A_d_12 = A_d[:, ::2]
+ desired = np.dot(A_d_12, X_d_2)
+ A_f_12 = A_f[:, ::2]
+ assert_dot_close(A_f_12, X_f_2c, desired)
+ # Strides in A cols and X
+ assert_dot_close(A_f_12, X_f_2, desired)
+
+
class MatmulCommon:
"""Common tests for '@' operator and numpy.matmul.
@@ -6377,6 +6630,16 @@ class TestMatmul(MatmulCommon):
c = c.astype(tgt.dtype)
assert_array_equal(c, tgt)
+ def test_empty_out(self):
+ # Check that the output cannot be broadcast, so that it cannot be
+ # size zero when the outer dimensions (iterator size) has size zero.
+ arr = np.ones((0, 1, 1))
+ out = np.ones((1, 1, 1))
+ assert self.matmul(arr, arr).shape == (0, 1, 1)
+
+ with pytest.raises(ValueError, match=r"non-broadcastable"):
+ self.matmul(arr, arr, out=out)
+
def test_out_contiguous(self):
a = np.ones((5, 2), dtype=float)
b = np.array([[1, 3], [5, 7]], dtype=float)
@@ -6524,7 +6787,7 @@ class TestMatmulOperator(MatmulCommon):
def test_matmul_raises(self):
assert_raises(TypeError, self.matmul, np.int8(5), np.int8(5))
assert_raises(TypeError, self.matmul, np.void(b'abc'), np.void(b'abc'))
- assert_raises(ValueError, self.matmul, np.arange(10), np.void(b'abc'))
+ assert_raises(TypeError, self.matmul, np.arange(10), np.void(b'abc'))
def test_matmul_inplace():
# It would be nice to support in-place matmul eventually, but for now
@@ -6748,6 +7011,13 @@ class TestNeighborhoodIter:
x, [-1, 0, -1, 1], 4, NEIGH_MODE['constant'])
assert_array_equal(l, r)
+ # Test with start in the middle
+ r = [np.array([[4, 0, 1], [4, 2, 3]], dtype=dt),
+ np.array([[0, 1, 4], [2, 3, 4]], dtype=dt)]
+ l = _multiarray_tests.test_neighborhood_iterator(
+ x, [-1, 0, -1, 1], 4, NEIGH_MODE['constant'], 2)
+ assert_array_equal(l, r)
+
def test_mirror2d(self, dt):
x = np.array([[0, 1], [2, 3]], dtype=dt)
r = [np.array([[0, 0, 1], [0, 0, 1]], dtype=dt),
@@ -7207,7 +7477,7 @@ class TestNewBufferProtocol:
self._check_roundtrip(x)
def test_roundtrip_single_types(self):
- for typ in np.typeDict.values():
+ for typ in np.sctypeDict.values():
dtype = np.dtype(typ)
if dtype.char in 'Mm':
@@ -7453,7 +7723,7 @@ class TestNewBufferProtocol:
memoryview(arr)
def test_max_dims(self):
- a = np.empty((1,) * 32)
+ a = np.ones((1,) * 32)
self._check_roundtrip(a)
@pytest.mark.slow
@@ -7814,6 +8084,8 @@ class TestConversion:
assert_raises(NotImplementedError, bool, np.array(NotConvertible()))
assert_raises(NotImplementedError, bool, np.array([NotConvertible()]))
+ if IS_PYSTON:
+ pytest.skip("Pyston disables recursion checking")
self_containing = np.array([None])
self_containing[0] = self_containing
@@ -8473,6 +8745,22 @@ class TestArange:
assert_raises(ZeroDivisionError, np.arange, 0, 0, 0)
assert_raises(ZeroDivisionError, np.arange, 0.0, 0.0, 0.0)
+ def test_require_range(self):
+ assert_raises(TypeError, np.arange)
+ assert_raises(TypeError, np.arange, step=3)
+ assert_raises(TypeError, np.arange, dtype='int64')
+ assert_raises(TypeError, np.arange, start=4)
+
+ def test_start_stop_kwarg(self):
+ keyword_stop = np.arange(stop=3)
+ keyword_zerotostop = np.arange(start=0, stop=3)
+ keyword_start_stop = np.arange(start=3, stop=9)
+
+ assert len(keyword_stop) == 3
+ assert len(keyword_zerotostop) == 3
+ assert len(keyword_start_stop) == 6
+ assert_array_equal(keyword_stop, keyword_zerotostop)
+
class TestArrayFinalize:
""" Tests __array_finalize__ """
@@ -8486,6 +8774,15 @@ class TestArrayFinalize:
a = np.array(1).view(SavesBase)
assert_(a.saved_base is a.base)
+ def test_bad_finalize(self):
+ class BadAttributeArray(np.ndarray):
+ @property
+ def __array_finalize__(self):
+ raise RuntimeError("boohoo!")
+
+ with pytest.raises(RuntimeError, match="boohoo!"):
+ np.arange(10).view(BadAttributeArray)
+
def test_lifetime_on_error(self):
# gh-11237
class RaisesInFinalize(np.ndarray):
@@ -8553,23 +8850,22 @@ def test_equal_override():
assert_equal(array != my_always_equal, 'ne')
-def test_npymath_complex():
+@pytest.mark.parametrize(
+ ["fun", "npfun"],
+ [
+ (_multiarray_tests.npy_cabs, np.absolute),
+ (_multiarray_tests.npy_carg, np.angle)
+ ]
+)
+@pytest.mark.parametrize("x", [1, np.inf, -np.inf, np.nan])
+@pytest.mark.parametrize("y", [1, np.inf, -np.inf, np.nan])
+@pytest.mark.parametrize("test_dtype", np.complexfloating.__subclasses__())
+def test_npymath_complex(fun, npfun, x, y, test_dtype):
# Smoketest npymath functions
- from numpy.core._multiarray_tests import (
- npy_cabs, npy_carg)
-
- funcs = {npy_cabs: np.absolute,
- npy_carg: np.angle}
- vals = (1, np.inf, -np.inf, np.nan)
- types = (np.complex64, np.complex128, np.clongdouble)
-
- for fun, npfun in funcs.items():
- for x, y in itertools.product(vals, vals):
- for t in types:
- z = t(complex(x, y))
- got = fun(z)
- expected = npfun(z)
- assert_allclose(got, expected)
+ z = test_dtype(complex(x, y))
+ got = fun(z)
+ expected = npfun(z)
+ assert_allclose(got, expected)
def test_npymath_real():
diff --git a/numpy/core/tests/test_nditer.py b/numpy/core/tests/test_nditer.py
index e10c7ad92..6b743ab27 100644
--- a/numpy/core/tests/test_nditer.py
+++ b/numpy/core/tests/test_nditer.py
@@ -1,6 +1,9 @@
import sys
import pytest
+import textwrap
+import subprocess
+
import numpy as np
import numpy.core._multiarray_tests as _multiarray_tests
from numpy import array, arange, nditer, all
@@ -182,6 +185,29 @@ def test_iter_c_or_f_order():
assert_equal([x for x in i],
aview.swapaxes(0, 1).ravel(order='A'))
+def test_nditer_multi_index_set():
+ # Test the multi_index set
+ a = np.arange(6).reshape(2, 3)
+ it = np.nditer(a, flags=['multi_index'])
+
+ # Removes the iteration on two first elements of a[0]
+ it.multi_index = (0, 2,)
+
+ assert_equal([i for i in it], [2, 3, 4, 5])
+
+@pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts")
+def test_nditer_multi_index_set_refcount():
+ # Test if the reference count on index variable is decreased
+
+ index = 0
+ i = np.nditer(np.array([111, 222, 333, 444]), flags=['multi_index'])
+
+ start_count = sys.getrefcount(index)
+ i.multi_index = (index,)
+ end_count = sys.getrefcount(index)
+
+ assert_equal(start_count, end_count)
+
def test_iter_best_order_multi_index_1d():
# The multi-indices should be correct with any reordering
@@ -1362,6 +1388,75 @@ def test_iter_copy():
j = i.copy()
assert_equal([x[()] for x in j], a.ravel(order='F'))
+
+@pytest.mark.parametrize("dtype", np.typecodes["All"])
+@pytest.mark.parametrize("loop_dtype", np.typecodes["All"])
+@pytest.mark.filterwarnings("ignore::numpy.ComplexWarning")
+def test_iter_copy_casts(dtype, loop_dtype):
+ # Ensure the dtype is never flexible:
+ if loop_dtype.lower() == "m":
+ loop_dtype = loop_dtype + "[ms]"
+ elif np.dtype(loop_dtype).itemsize == 0:
+ loop_dtype = loop_dtype + "50"
+
+ # Make things a bit more interesting by requiring a byte-swap as well:
+ arr = np.ones(1000, dtype=np.dtype(dtype).newbyteorder())
+ try:
+ expected = arr.astype(loop_dtype)
+ except Exception:
+ # Some casts are not possible, do not worry about them
+ return
+
+ it = np.nditer((arr,), ["buffered", "external_loop", "refs_ok"],
+ op_dtypes=[loop_dtype], casting="unsafe")
+
+ if np.issubdtype(np.dtype(loop_dtype), np.number):
+ # Casting to strings may be strange, but for simple dtypes do not rely
+ # on the cast being correct:
+ assert_array_equal(expected, np.ones(1000, dtype=loop_dtype))
+
+ it_copy = it.copy()
+ res = next(it)
+ del it
+ res_copy = next(it_copy)
+ del it_copy
+
+ assert_array_equal(res, expected)
+ assert_array_equal(res_copy, expected)
+
+
+def test_iter_copy_casts_structured():
+ # Test a complicated structured dtype for casting, as it requires
+ # both multiple steps and a more complex casting setup.
+ # Includes a structured -> unstructured (any to object), and many other
+ # casts, which cause this to require all steps in the casting machinery
+ # one level down as well as the iterator copy (which uses NpyAuxData clone)
+ in_dtype = np.dtype([("a", np.dtype("i,")),
+ ("b", np.dtype(">i,<i,>d,S17,>d,(3)f,O,i1"))])
+ out_dtype = np.dtype([("a", np.dtype("O")),
+ ("b", np.dtype(">i,>i,S17,>d,>U3,(3)d,i1,O"))])
+ arr = np.ones(1000, dtype=in_dtype)
+
+ it = np.nditer((arr,), ["buffered", "external_loop", "refs_ok"],
+ op_dtypes=[out_dtype], casting="unsafe")
+ it_copy = it.copy()
+
+ res1 = next(it)
+ del it
+ res2 = next(it_copy)
+ del it_copy
+
+ expected = arr["a"].astype(out_dtype["a"])
+ assert_array_equal(res1["a"], expected)
+ assert_array_equal(res2["a"], expected)
+
+ for field in in_dtype["b"].names:
+ # Note that the .base avoids the subarray field
+ expected = arr["b"][field].astype(out_dtype["b"][field].base)
+ assert_array_equal(res1["b"][field], expected)
+ assert_array_equal(res2["b"][field], expected)
+
+
def test_iter_allocate_output_simple():
# Check that the iterator will properly allocate outputs
@@ -1886,16 +1981,58 @@ def test_iter_buffered_cast_structured_type():
[np.array((1, 2, 3), dtype=sdt2),
np.array((4, 5, 6), dtype=sdt2)])
+
+def test_iter_buffered_cast_structured_type_failure_with_cleanup():
# make sure struct type -> struct type with different
# number of fields fails
sdt1 = [('a', 'f4'), ('b', 'i8'), ('d', 'O')]
sdt2 = [('b', 'O'), ('a', 'f8')]
a = np.array([(1, 2, 3), (4, 5, 6)], dtype=sdt1)
- assert_raises(ValueError, lambda : (
- nditer(a, ['buffered', 'refs_ok'], ['readwrite'],
- casting='unsafe',
- op_dtypes=sdt2)))
+ for intent in ["readwrite", "readonly", "writeonly"]:
+ # If the following assert fails, the place where the error is raised
+ # within nditer may change. That is fine, but it may make sense for
+ # a new (hard to design) test to replace it. The `simple_arr` is
+ # designed to require a multi-step cast (due to having fields).
+ assert np.can_cast(a.dtype, sdt2, casting="unsafe")
+ simple_arr = np.array([1, 2], dtype="i,i") # requires clean up
+ with pytest.raises(ValueError):
+ nditer((simple_arr, a), ['buffered', 'refs_ok'], [intent, intent],
+ casting='unsafe', op_dtypes=["f,f", sdt2])
+
+
+def test_buffered_cast_error_paths():
+ with pytest.raises(ValueError):
+ # The input is cast into an `S3` buffer
+ np.nditer((np.array("a", dtype="S1"),), op_dtypes=["i"],
+ casting="unsafe", flags=["buffered"])
+
+ # The `M8[ns]` is cast into the `S3` output
+ it = np.nditer((np.array(1, dtype="i"),), op_dtypes=["S1"],
+ op_flags=["writeonly"], casting="unsafe", flags=["buffered"])
+ with pytest.raises(ValueError):
+ with it:
+ buf = next(it)
+ buf[...] = "a" # cannot be converted to int.
+
+@pytest.mark.skipif(not HAS_REFCOUNT, reason="PyPy seems to not hit this.")
+def test_buffered_cast_error_paths_unraisable():
+ # The following gives an unraisable error. Pytest sometimes captures that
+ # (depending python and/or pytest version). So with Python>=3.8 this can
+ # probably be cleaned out in the future to check for
+ # pytest.PytestUnraisableExceptionWarning:
+ code = textwrap.dedent("""
+ import numpy as np
+
+ it = np.nditer((np.array(1, dtype="i"),), op_dtypes=["S1"],
+ op_flags=["writeonly"], casting="unsafe", flags=["buffered"])
+ buf = next(it)
+ buf[...] = "a"
+ del buf, it # Flushing only happens during deallocate right now.
+ """)
+ res = subprocess.check_output([sys.executable, "-c", code],
+ stderr=subprocess.STDOUT, text=True)
+ assert "ValueError" in res
def test_iter_buffered_cast_subarray():
@@ -2591,9 +2728,30 @@ def test_iter_writemasked_badinput():
op_dtypes=['f4', None],
casting='same_kind')
-def test_iter_writemasked():
- a = np.zeros((3,), dtype='f8')
- msk = np.array([True, True, False])
+def _is_buffered(iterator):
+ try:
+ iterator.itviews
+ except ValueError:
+ return True
+ return False
+
+@pytest.mark.parametrize("a",
+ [np.zeros((3,), dtype='f8'),
+ np.zeros((9876, 3*5), dtype='f8')[::2, :],
+ np.zeros((4, 312, 124, 3), dtype='f8')[::2, :, ::2, :],
+ # Also test with the last dimension strided (so it does not fit if
+ # there is repeated access)
+ np.zeros((9,), dtype='f8')[::3],
+ np.zeros((9876, 3*10), dtype='f8')[::2, ::5],
+ np.zeros((4, 312, 124, 3), dtype='f8')[::2, :, ::2, ::-1]])
+def test_iter_writemasked(a):
+ # Note, the slicing above is to ensure that nditer cannot combine multiple
+ # axes into one. The repetition is just to make things a bit more
+ # interesting.
+ shape = a.shape
+ reps = shape[-1] // 3
+ msk = np.empty(shape, dtype=bool)
+ msk[...] = [True, True, False] * reps
# When buffering is unused, 'writemasked' effectively does nothing.
# It's up to the user of the iterator to obey the requested semantics.
@@ -2604,18 +2762,31 @@ def test_iter_writemasked():
for x, m in it:
x[...] = 1
# Because we violated the semantics, all the values became 1
- assert_equal(a, [1, 1, 1])
+ assert_equal(a, np.broadcast_to([1, 1, 1] * reps, shape))
# Even if buffering is enabled, we still may be accessing the array
# directly.
it = np.nditer([a, msk], ['buffered'],
[['readwrite', 'writemasked'],
['readonly', 'arraymask']])
+ # @seberg: I honestly don't currently understand why a "buffered" iterator
+ # would end up not using a buffer for the small array here at least when
+ # "writemasked" is used, that seems confusing... Check by testing for
+ # actual memory overlap!
+ is_buffered = True
with it:
for x, m in it:
x[...] = 2.5
- # Because we violated the semantics, all the values became 2.5
- assert_equal(a, [2.5, 2.5, 2.5])
+ if np.may_share_memory(x, a):
+ is_buffered = False
+
+ if not is_buffered:
+ # Because we violated the semantics, all the values became 2.5
+ assert_equal(a, np.broadcast_to([2.5, 2.5, 2.5] * reps, shape))
+ else:
+ # For large sizes, the iterator may be buffered:
+ assert_equal(a, np.broadcast_to([2.5, 2.5, 1] * reps, shape))
+ a[...] = 2.5
# If buffering will definitely happening, for instance because of
# a cast, only the items selected by the mask will be copied back from
@@ -2630,7 +2801,38 @@ def test_iter_writemasked():
x[...] = 3
# Even though we violated the semantics, only the selected values
# were copied back
- assert_equal(a, [3, 3, 2.5])
+ assert_equal(a, np.broadcast_to([3, 3, 2.5] * reps, shape))
+
+def test_iter_writemasked_decref():
+ # force casting (to make it interesting) by using a structured dtype.
+ arr = np.arange(10000).astype(">i,O")
+ original = arr.copy()
+ mask = np.random.randint(0, 2, size=10000).astype(bool)
+
+ it = np.nditer([arr, mask], ['buffered', "refs_ok"],
+ [['readwrite', 'writemasked'],
+ ['readonly', 'arraymask']],
+ op_dtypes=["<i,O", "?"])
+ singleton = object()
+ if HAS_REFCOUNT:
+ count = sys.getrefcount(singleton)
+ for buf, mask_buf in it:
+ buf[...] = (3, singleton)
+
+ del buf, mask_buf, it # delete everything to ensure corrrect cleanup
+
+ if HAS_REFCOUNT:
+ # The buffer would have included additional items, they must be
+ # cleared correctly:
+ assert sys.getrefcount(singleton) - count == np.count_nonzero(mask)
+
+ assert_array_equal(arr[~mask], original[~mask])
+ assert (arr[mask] == np.array((3, singleton), arr.dtype)).all()
+ del arr
+
+ if HAS_REFCOUNT:
+ assert sys.getrefcount(singleton) == count
+
def test_iter_non_writable_attribute_deletion():
it = np.nditer(np.ones(2))
@@ -2724,6 +2926,46 @@ def test_0d_iter():
assert_equal(vals['c'], [[(0.5)]*3]*2)
assert_equal(vals['d'], 0.5)
+def test_object_iter_cleanup():
+ # see gh-18450
+ # object arrays can raise a python exception in ufunc inner loops using
+ # nditer, which should cause iteration to stop & cleanup. There were bugs
+ # in the nditer cleanup when decref'ing object arrays.
+ # This test would trigger valgrind "uninitialized read" before the bugfix.
+ assert_raises(TypeError, lambda: np.zeros((17000, 2), dtype='f4') * None)
+
+ # this more explicit code also triggers the invalid access
+ arr = np.arange(np.BUFSIZE * 10).reshape(10, -1).astype(str)
+ oarr = arr.astype(object)
+ oarr[:, -1] = None
+ assert_raises(TypeError, lambda: np.add(oarr[:, ::-1], arr[:, ::-1]))
+
+ # followup: this tests for a bug introduced in the first pass of gh-18450,
+ # caused by an incorrect fallthrough of the TypeError
+ class T:
+ def __bool__(self):
+ raise TypeError("Ambiguous")
+ assert_raises(TypeError, np.logical_or.reduce,
+ np.array([T(), T()], dtype='O'))
+
+def test_object_iter_cleanup_reduce():
+ # Similar as above, but a complex reduction case that was previously
+ # missed (see gh-18810).
+ # The following array is special in that it cannot be flattened:
+ arr = np.array([[None, 1], [-1, -1], [None, 2], [-1, -1]])[::2]
+ with pytest.raises(TypeError):
+ np.sum(arr)
+
+@pytest.mark.parametrize("arr", [
+ np.ones((8000, 4, 2), dtype=object)[:, ::2, :],
+ np.ones((8000, 4, 2), dtype=object, order="F")[:, ::2, :],
+ np.ones((8000, 4, 2), dtype=object)[:, ::2, :].copy("F")])
+def test_object_iter_cleanup_large_reduce(arr):
+ # More complicated calls are possible for large arrays:
+ out = np.ones(8000, dtype=np.intp)
+ # force casting with `dtype=object`
+ res = np.sum(arr, axis=(1, 2), dtype=object, out=out)
+ assert_array_equal(res, np.full(8000, 4, dtype=object))
def test_iter_too_large():
# The total size of the iterator must not exceed the maximum intp due
@@ -2870,6 +3112,10 @@ def test_close_raises():
assert_raises(StopIteration, next, it)
assert_raises(ValueError, getattr, it, 'operands')
+def test_close_parameters():
+ it = np.nditer(np.arange(3))
+ assert_raises(TypeError, it.close, 1)
+
@pytest.mark.skipif(not HAS_REFCOUNT, reason="Python lacks refcounts")
def test_warn_noclose():
a = np.arange(6, dtype='f4')
@@ -2945,3 +3191,84 @@ def test_partial_iteration_error(in_dtype, buf_dtype):
it.iternext()
assert count == sys.getrefcount(value)
+
+
+def test_debug_print(capfd):
+ """
+ Matches the expected output of a debug print with the actual output.
+ Note that the iterator dump should not be considered stable API,
+ this test is mainly to ensure the print does not crash.
+
+ Currently uses a subprocess to avoid dealing with the C level `printf`s.
+ """
+ # the expected output with all addresses and sizes stripped (they vary
+ # and/or are platform dependend).
+ expected = """
+ ------ BEGIN ITERATOR DUMP ------
+ | Iterator Address:
+ | ItFlags: BUFFER REDUCE REUSE_REDUCE_LOOPS
+ | NDim: 2
+ | NOp: 2
+ | IterSize: 50
+ | IterStart: 0
+ | IterEnd: 50
+ | IterIndex: 0
+ | Iterator SizeOf:
+ | BufferData SizeOf:
+ | AxisData SizeOf:
+ |
+ | Perm: 0 1
+ | DTypes:
+ | DTypes: dtype('float64') dtype('int32')
+ | InitDataPtrs:
+ | BaseOffsets: 0 0
+ | Operands:
+ | Operand DTypes: dtype('int64') dtype('float64')
+ | OpItFlags:
+ | Flags[0]: READ CAST ALIGNED
+ | Flags[1]: READ WRITE CAST ALIGNED REDUCE
+ |
+ | BufferData:
+ | BufferSize: 50
+ | Size: 5
+ | BufIterEnd: 5
+ | REDUCE Pos: 0
+ | REDUCE OuterSize: 10
+ | REDUCE OuterDim: 1
+ | Strides: 8 4
+ | Ptrs:
+ | REDUCE Outer Strides: 40 0
+ | REDUCE Outer Ptrs:
+ | ReadTransferFn:
+ | ReadTransferData:
+ | WriteTransferFn:
+ | WriteTransferData:
+ | Buffers:
+ |
+ | AxisData[0]:
+ | Shape: 5
+ | Index: 0
+ | Strides: 16 8
+ | Ptrs:
+ | AxisData[1]:
+ | Shape: 10
+ | Index: 0
+ | Strides: 80 0
+ | Ptrs:
+ ------- END ITERATOR DUMP -------
+ """.strip().splitlines()
+
+ arr1 = np.arange(100, dtype=np.int64).reshape(10, 10)[:, ::2]
+ arr2 = np.arange(5.)
+ it = np.nditer((arr1, arr2), op_dtypes=["d", "i4"], casting="unsafe",
+ flags=["reduce_ok", "buffered"],
+ op_flags=[["readonly"], ["readwrite"]])
+ it.debug_print()
+ res = capfd.readouterr().out
+ res = res.strip().splitlines()
+
+ assert len(res) == len(expected)
+ for res_line, expected_line in zip(res, expected):
+ # The actual output may have additional pointers listed that are
+ # stripped from the example output:
+ assert res_line.startswith(expected_line.strip())
diff --git a/numpy/core/tests/test_numeric.py b/numpy/core/tests/test_numeric.py
index 866a96e31..e2d648a3c 100644
--- a/numpy/core/tests/test_numeric.py
+++ b/numpy/core/tests/test_numeric.py
@@ -296,6 +296,7 @@ class TestNonarrayArgs:
B[0] = 1j
assert_almost_equal(np.var(B), 0.25)
+
class TestIsscalar:
def test_isscalar(self):
assert_(np.isscalar(3.1))
@@ -636,59 +637,65 @@ class TestFloatExceptions:
self.assert_raises_fpe(fpeerr, flop, sc1, sc2[()])
self.assert_raises_fpe(fpeerr, flop, sc1[()], sc2[()])
- def test_floating_exceptions(self):
+ # Test for all real and complex float types
+ @pytest.mark.parametrize("typecode", np.typecodes["AllFloat"])
+ def test_floating_exceptions(self, typecode):
# Test basic arithmetic function errors
with np.errstate(all='raise'):
- # Test for all real and complex float types
- for typecode in np.typecodes['AllFloat']:
- ftype = np.obj2sctype(typecode)
- if np.dtype(ftype).kind == 'f':
- # Get some extreme values for the type
- fi = np.finfo(ftype)
- ft_tiny = fi.tiny
- ft_max = fi.max
- ft_eps = fi.eps
- underflow = 'underflow'
- divbyzero = 'divide by zero'
- else:
- # 'c', complex, corresponding real dtype
- rtype = type(ftype(0).real)
- fi = np.finfo(rtype)
- ft_tiny = ftype(fi.tiny)
- ft_max = ftype(fi.max)
- ft_eps = ftype(fi.eps)
- # The complex types raise different exceptions
- underflow = ''
- divbyzero = ''
- overflow = 'overflow'
- invalid = 'invalid'
-
+ ftype = np.obj2sctype(typecode)
+ if np.dtype(ftype).kind == 'f':
+ # Get some extreme values for the type
+ fi = np.finfo(ftype)
+ ft_tiny = fi.machar.tiny
+ ft_max = fi.max
+ ft_eps = fi.eps
+ underflow = 'underflow'
+ divbyzero = 'divide by zero'
+ else:
+ # 'c', complex, corresponding real dtype
+ rtype = type(ftype(0).real)
+ fi = np.finfo(rtype)
+ ft_tiny = ftype(fi.machar.tiny)
+ ft_max = ftype(fi.max)
+ ft_eps = ftype(fi.eps)
+ # The complex types raise different exceptions
+ underflow = ''
+ divbyzero = ''
+ overflow = 'overflow'
+ invalid = 'invalid'
+
+ # The value of tiny for double double is NaN, so we need to
+ # pass the assert
+ if not np.isnan(ft_tiny):
self.assert_raises_fpe(underflow,
- lambda a, b: a/b, ft_tiny, ft_max)
+ lambda a, b: a/b, ft_tiny, ft_max)
self.assert_raises_fpe(underflow,
- lambda a, b: a*b, ft_tiny, ft_tiny)
- self.assert_raises_fpe(overflow,
- lambda a, b: a*b, ft_max, ftype(2))
- self.assert_raises_fpe(overflow,
- lambda a, b: a/b, ft_max, ftype(0.5))
- self.assert_raises_fpe(overflow,
- lambda a, b: a+b, ft_max, ft_max*ft_eps)
- self.assert_raises_fpe(overflow,
- lambda a, b: a-b, -ft_max, ft_max*ft_eps)
- self.assert_raises_fpe(overflow,
- np.power, ftype(2), ftype(2**fi.nexp))
- self.assert_raises_fpe(divbyzero,
- lambda a, b: a/b, ftype(1), ftype(0))
- self.assert_raises_fpe(invalid,
- lambda a, b: a/b, ftype(np.inf), ftype(np.inf))
- self.assert_raises_fpe(invalid,
- lambda a, b: a/b, ftype(0), ftype(0))
- self.assert_raises_fpe(invalid,
- lambda a, b: a-b, ftype(np.inf), ftype(np.inf))
- self.assert_raises_fpe(invalid,
- lambda a, b: a+b, ftype(np.inf), ftype(-np.inf))
- self.assert_raises_fpe(invalid,
- lambda a, b: a*b, ftype(0), ftype(np.inf))
+ lambda a, b: a*b, ft_tiny, ft_tiny)
+ self.assert_raises_fpe(overflow,
+ lambda a, b: a*b, ft_max, ftype(2))
+ self.assert_raises_fpe(overflow,
+ lambda a, b: a/b, ft_max, ftype(0.5))
+ self.assert_raises_fpe(overflow,
+ lambda a, b: a+b, ft_max, ft_max*ft_eps)
+ self.assert_raises_fpe(overflow,
+ lambda a, b: a-b, -ft_max, ft_max*ft_eps)
+ self.assert_raises_fpe(overflow,
+ np.power, ftype(2), ftype(2**fi.nexp))
+ self.assert_raises_fpe(divbyzero,
+ lambda a, b: a/b, ftype(1), ftype(0))
+ self.assert_raises_fpe(
+ invalid, lambda a, b: a/b, ftype(np.inf), ftype(np.inf)
+ )
+ self.assert_raises_fpe(invalid,
+ lambda a, b: a/b, ftype(0), ftype(0))
+ self.assert_raises_fpe(
+ invalid, lambda a, b: a-b, ftype(np.inf), ftype(np.inf)
+ )
+ self.assert_raises_fpe(
+ invalid, lambda a, b: a+b, ftype(np.inf), ftype(-np.inf)
+ )
+ self.assert_raises_fpe(invalid,
+ lambda a, b: a*b, ftype(0), ftype(np.inf))
def test_warnings(self):
# test warning code path
@@ -888,39 +895,42 @@ class TestTypes:
assert np.can_cast(rational_dt, double_dt)
assert np.promote_types(double_dt, rational_dt) is double_dt
- def test_promote_types_strings(self):
- assert_equal(np.promote_types('bool', 'S'), np.dtype('S5'))
- assert_equal(np.promote_types('b', 'S'), np.dtype('S4'))
- assert_equal(np.promote_types('u1', 'S'), np.dtype('S3'))
- assert_equal(np.promote_types('u2', 'S'), np.dtype('S5'))
- assert_equal(np.promote_types('u4', 'S'), np.dtype('S10'))
- assert_equal(np.promote_types('u8', 'S'), np.dtype('S20'))
- assert_equal(np.promote_types('i1', 'S'), np.dtype('S4'))
- assert_equal(np.promote_types('i2', 'S'), np.dtype('S6'))
- assert_equal(np.promote_types('i4', 'S'), np.dtype('S11'))
- assert_equal(np.promote_types('i8', 'S'), np.dtype('S21'))
- assert_equal(np.promote_types('bool', 'U'), np.dtype('U5'))
- assert_equal(np.promote_types('b', 'U'), np.dtype('U4'))
- assert_equal(np.promote_types('u1', 'U'), np.dtype('U3'))
- assert_equal(np.promote_types('u2', 'U'), np.dtype('U5'))
- assert_equal(np.promote_types('u4', 'U'), np.dtype('U10'))
- assert_equal(np.promote_types('u8', 'U'), np.dtype('U20'))
- assert_equal(np.promote_types('i1', 'U'), np.dtype('U4'))
- assert_equal(np.promote_types('i2', 'U'), np.dtype('U6'))
- assert_equal(np.promote_types('i4', 'U'), np.dtype('U11'))
- assert_equal(np.promote_types('i8', 'U'), np.dtype('U21'))
- assert_equal(np.promote_types('bool', 'S1'), np.dtype('S5'))
- assert_equal(np.promote_types('bool', 'S30'), np.dtype('S30'))
- assert_equal(np.promote_types('b', 'S1'), np.dtype('S4'))
- assert_equal(np.promote_types('b', 'S30'), np.dtype('S30'))
- assert_equal(np.promote_types('u1', 'S1'), np.dtype('S3'))
- assert_equal(np.promote_types('u1', 'S30'), np.dtype('S30'))
- assert_equal(np.promote_types('u2', 'S1'), np.dtype('S5'))
- assert_equal(np.promote_types('u2', 'S30'), np.dtype('S30'))
- assert_equal(np.promote_types('u4', 'S1'), np.dtype('S10'))
- assert_equal(np.promote_types('u4', 'S30'), np.dtype('S30'))
- assert_equal(np.promote_types('u8', 'S1'), np.dtype('S20'))
- assert_equal(np.promote_types('u8', 'S30'), np.dtype('S30'))
+ @pytest.mark.parametrize("swap", ["", "swap"])
+ @pytest.mark.parametrize("string_dtype", ["U", "S"])
+ def test_promote_types_strings(self, swap, string_dtype):
+ if swap == "swap":
+ promote_types = lambda a, b: np.promote_types(b, a)
+ else:
+ promote_types = np.promote_types
+
+ S = string_dtype
+
+ # Promote numeric with unsized string:
+ assert_equal(promote_types('bool', S), np.dtype(S+'5'))
+ assert_equal(promote_types('b', S), np.dtype(S+'4'))
+ assert_equal(promote_types('u1', S), np.dtype(S+'3'))
+ assert_equal(promote_types('u2', S), np.dtype(S+'5'))
+ assert_equal(promote_types('u4', S), np.dtype(S+'10'))
+ assert_equal(promote_types('u8', S), np.dtype(S+'20'))
+ assert_equal(promote_types('i1', S), np.dtype(S+'4'))
+ assert_equal(promote_types('i2', S), np.dtype(S+'6'))
+ assert_equal(promote_types('i4', S), np.dtype(S+'11'))
+ assert_equal(promote_types('i8', S), np.dtype(S+'21'))
+ # Promote numeric with sized string:
+ assert_equal(promote_types('bool', S+'1'), np.dtype(S+'5'))
+ assert_equal(promote_types('bool', S+'30'), np.dtype(S+'30'))
+ assert_equal(promote_types('b', S+'1'), np.dtype(S+'4'))
+ assert_equal(promote_types('b', S+'30'), np.dtype(S+'30'))
+ assert_equal(promote_types('u1', S+'1'), np.dtype(S+'3'))
+ assert_equal(promote_types('u1', S+'30'), np.dtype(S+'30'))
+ assert_equal(promote_types('u2', S+'1'), np.dtype(S+'5'))
+ assert_equal(promote_types('u2', S+'30'), np.dtype(S+'30'))
+ assert_equal(promote_types('u4', S+'1'), np.dtype(S+'10'))
+ assert_equal(promote_types('u4', S+'30'), np.dtype(S+'30'))
+ assert_equal(promote_types('u8', S+'1'), np.dtype(S+'20'))
+ assert_equal(promote_types('u8', S+'30'), np.dtype(S+'30'))
+ # Promote with object:
+ assert_equal(promote_types('O', S+'30'), np.dtype('O'))
@pytest.mark.parametrize(["dtype1", "dtype2"],
[[np.dtype("V6"), np.dtype("V10")],
@@ -970,6 +980,7 @@ class TestTypes:
assert res.isnative
@pytest.mark.slow
+ @pytest.mark.filterwarnings('ignore:Promotion of numbers:FutureWarning')
@pytest.mark.parametrize(["dtype1", "dtype2"],
itertools.product(
list(np.typecodes["All"]) +
@@ -1255,20 +1266,30 @@ class TestNonzero:
assert_equal(np.count_nonzero(x), 4)
assert_equal(np.nonzero(x), ([0, 2, 3, 6],))
- x = np.array([(1, 2), (0, 0), (1, 1), (-1, 3), (0, 7)],
- dtype=[('a', 'i4'), ('b', 'i2')])
+ # x = np.array([(1, 2), (0, 0), (1, 1), (-1, 3), (0, 7)],
+ # dtype=[('a', 'i4'), ('b', 'i2')])
+ x = np.array([(1, 2, -5, -3), (0, 0, 2, 7), (1, 1, 0, 1), (-1, 3, 1, 0), (0, 7, 0, 4)],
+ dtype=[('a', 'i4'), ('b', 'i2'), ('c', 'i1'), ('d', 'i8')])
assert_equal(np.count_nonzero(x['a']), 3)
assert_equal(np.count_nonzero(x['b']), 4)
+ assert_equal(np.count_nonzero(x['c']), 3)
+ assert_equal(np.count_nonzero(x['d']), 4)
assert_equal(np.nonzero(x['a']), ([0, 2, 3],))
assert_equal(np.nonzero(x['b']), ([0, 2, 3, 4],))
def test_nonzero_twodim(self):
x = np.array([[0, 1, 0], [2, 0, 3]])
- assert_equal(np.count_nonzero(x), 3)
+ assert_equal(np.count_nonzero(x.astype('i1')), 3)
+ assert_equal(np.count_nonzero(x.astype('i2')), 3)
+ assert_equal(np.count_nonzero(x.astype('i4')), 3)
+ assert_equal(np.count_nonzero(x.astype('i8')), 3)
assert_equal(np.nonzero(x), ([0, 1, 1], [1, 0, 2]))
x = np.eye(3)
- assert_equal(np.count_nonzero(x), 3)
+ assert_equal(np.count_nonzero(x.astype('i1')), 3)
+ assert_equal(np.count_nonzero(x.astype('i2')), 3)
+ assert_equal(np.count_nonzero(x.astype('i4')), 3)
+ assert_equal(np.count_nonzero(x.astype('i8')), 3)
assert_equal(np.nonzero(x), ([0, 1, 2], [0, 1, 2]))
x = np.array([[(0, 1), (0, 0), (1, 11)],
@@ -1515,6 +1536,27 @@ class TestNonzero:
a = np.array([[ThrowsAfter(15)]]*10)
assert_raises(ValueError, np.nonzero, a)
+ def test_structured_threadsafety(self):
+ # Nonzero (and some other functions) should be threadsafe for
+ # structured datatypes, see gh-15387. This test can behave randomly.
+ from concurrent.futures import ThreadPoolExecutor
+
+ # Create a deeply nested dtype to make a failure more likely:
+ dt = np.dtype([("", "f8")])
+ dt = np.dtype([("", dt)])
+ dt = np.dtype([("", dt)] * 2)
+ # The array should be large enough to likely run into threading issues
+ arr = np.random.uniform(size=(5000, 4)).view(dt)[:, 0]
+ def func(arr):
+ arr.nonzero()
+
+ tpe = ThreadPoolExecutor(max_workers=8)
+ futures = [tpe.submit(func, arr) for _ in range(10)]
+ for f in futures:
+ f.result()
+
+ assert arr.dtype is dt
+
class TestIndex:
def test_boolean(self):
@@ -1688,6 +1730,22 @@ class TestArrayComparisons:
assert_(not res)
assert_(type(res) is bool)
+ @pytest.mark.parametrize("dtype", ["V0", "V3", "V10"])
+ def test_compare_unstructured_voids(self, dtype):
+ zeros = np.zeros(3, dtype=dtype)
+
+ assert_array_equal(zeros, zeros)
+ assert not (zeros != zeros).any()
+
+ if dtype == "V0":
+ # Can't test != of actually different data
+ return
+
+ nonzeros = np.array([b"1", b"2", b"3"], dtype=dtype)
+
+ assert not (zeros == nonzeros).any()
+ assert (zeros != nonzeros).all()
+
def assert_array_strict_equal(x, y):
assert_array_equal(x, y)
@@ -2282,8 +2340,14 @@ class TestClip:
actual = np.clip(arr, amin, amax)
assert_equal(actual, expected)
- @given(data=st.data(), shape=hynp.array_shapes())
- def test_clip_property(self, data, shape):
+ @given(
+ data=st.data(),
+ arr=hynp.arrays(
+ dtype=hynp.integer_dtypes() | hynp.floating_dtypes(),
+ shape=hynp.array_shapes()
+ )
+ )
+ def test_clip_property(self, data, arr):
"""A property-based test using Hypothesis.
This aims for maximum generality: it could in principle generate *any*
@@ -2299,49 +2363,30 @@ class TestClip:
That accounts for most of the function; the actual test is just three
lines to calculate and compare actual vs expected results!
"""
- # Our base array and bounds should not need to be of the same type as
- # long as they are all compatible - so we allow any int or float type.
- dtype_strategy = hynp.integer_dtypes() | hynp.floating_dtypes()
-
- # The following line is a total hack to disable the varied-dtypes
- # component of this test, because result != expected if dtypes can vary.
- dtype_strategy = st.just(data.draw(dtype_strategy))
-
- # Generate an arbitrary array of the chosen shape and dtype
- # This is the value that we clip.
- arr = data.draw(hynp.arrays(dtype=dtype_strategy, shape=shape))
-
+ numeric_dtypes = hynp.integer_dtypes() | hynp.floating_dtypes()
# Generate shapes for the bounds which can be broadcast with each other
# and with the base shape. Below, we might decide to use scalar bounds,
# but it's clearer to generate these shapes unconditionally in advance.
in_shapes, result_shape = data.draw(
hynp.mutually_broadcastable_shapes(
- num_shapes=2,
- base_shape=shape,
- # Commenting out the min_dims line allows zero-dimensional arrays,
- # and zero-dimensional arrays containing NaN make the test fail.
- min_dims=1
-
+ num_shapes=2, base_shape=arr.shape
)
)
- amin = data.draw(
- dtype_strategy.flatmap(hynp.from_dtype)
- | hynp.arrays(dtype=dtype_strategy, shape=in_shapes[0])
- )
- amax = data.draw(
- dtype_strategy.flatmap(hynp.from_dtype)
- | hynp.arrays(dtype=dtype_strategy, shape=in_shapes[1])
- )
- # If we allow either bound to be a scalar `nan`, the test will fail -
- # so we just "assume" that away (if it is, this raises a special
- # exception and Hypothesis will try again with different inputs)
- assume(not np.isscalar(amin) or not np.isnan(amin))
- assume(not np.isscalar(amax) or not np.isnan(amax))
+ # Scalar `nan` is deprecated due to the differing behaviour it shows.
+ s = numeric_dtypes.flatmap(
+ lambda x: hynp.from_dtype(x, allow_nan=False))
+ amin = data.draw(s | hynp.arrays(dtype=numeric_dtypes,
+ shape=in_shapes[0], elements={"allow_nan": False}))
+ amax = data.draw(s | hynp.arrays(dtype=numeric_dtypes,
+ shape=in_shapes[1], elements={"allow_nan": False}))
# Then calculate our result and expected result and check that they're
- # equal! See gh-12519 for discussion deciding on this property.
+ # equal! See gh-12519 and gh-19457 for discussion deciding on this
+ # property and the result_type argument.
result = np.clip(arr, amin, amax)
- expected = np.minimum(amax, np.maximum(arr, amin))
+ t = np.result_type(arr, amin, amax)
+ expected = np.minimum(amax, np.maximum(arr, amin, dtype=t), dtype=t)
+ assert result.dtype == t
assert_array_equal(result, expected)
@@ -2567,6 +2612,15 @@ class TestIsclose:
assert_(np.isclose(0, np.inf) is np.False_)
assert_(type(np.isclose(0, np.inf)) is np.bool_)
+ def test_timedelta(self):
+ # Allclose currently works for timedelta64 as long as `atol` is
+ # an integer or also a timedelta64
+ a = np.array([[1, 2, 3, "NaT"]], dtype="m8[ns]")
+ assert np.isclose(a, a, atol=0, equal_nan=True).all()
+ assert np.isclose(a, a, atol=np.timedelta64(1, "ns"), equal_nan=True).all()
+ assert np.allclose(a, a, atol=0, equal_nan=True)
+ assert np.allclose(a, a, atol=np.timedelta64(1, "ns"), equal_nan=True)
+
class TestStdVar:
def setup(self):
@@ -2845,10 +2899,10 @@ class TestCorrelate:
self.x = np.array([1, 2, 3, 4, 5], dtype=dt)
self.xs = np.arange(1, 20)[::3]
self.y = np.array([-1, -2, -3], dtype=dt)
- self.z1 = np.array([ -3., -8., -14., -20., -26., -14., -5.], dtype=dt)
+ self.z1 = np.array([-3., -8., -14., -20., -26., -14., -5.], dtype=dt)
self.z1_4 = np.array([-2., -5., -8., -11., -14., -5.], dtype=dt)
- self.z1r = np.array([-15., -22., -22., -16., -10., -4., -1.], dtype=dt)
- self.z2 = np.array([-5., -14., -26., -20., -14., -8., -3.], dtype=dt)
+ self.z1r = np.array([-15., -22., -22., -16., -10., -4., -1.], dtype=dt)
+ self.z2 = np.array([-5., -14., -26., -20., -14., -8., -3.], dtype=dt)
self.z2r = np.array([-1., -4., -10., -16., -22., -22., -15.], dtype=dt)
self.zs = np.array([-3., -14., -30., -48., -66., -84.,
-102., -54., -19.], dtype=dt)
@@ -2896,6 +2950,22 @@ class TestCorrelate:
with pytest.raises(ValueError):
np.correlate(np.ones(1000), np.array([]), mode='full')
+ def test_mode(self):
+ d = np.ones(100)
+ k = np.ones(3)
+ default_mode = np.correlate(d, k, mode='valid')
+ with assert_warns(DeprecationWarning):
+ valid_mode = np.correlate(d, k, mode='v')
+ assert_array_equal(valid_mode, default_mode)
+ # integer mode
+ with assert_raises(ValueError):
+ np.correlate(d, k, mode=-1)
+ assert_array_equal(np.correlate(d, k, mode=0), valid_mode)
+ # illegal arguments
+ with assert_raises(TypeError):
+ np.correlate(d, k, mode=None)
+
+
class TestConvolve:
def test_object(self):
d = [1.] * 100
@@ -2909,6 +2979,21 @@ class TestConvolve:
assert_array_equal(d, np.ones(100))
assert_array_equal(k, np.ones(3))
+ def test_mode(self):
+ d = np.ones(100)
+ k = np.ones(3)
+ default_mode = np.convolve(d, k, mode='full')
+ with assert_warns(DeprecationWarning):
+ full_mode = np.convolve(d, k, mode='f')
+ assert_array_equal(full_mode, default_mode)
+ # integer mode
+ with assert_raises(ValueError):
+ np.convolve(d, k, mode=-1)
+ assert_array_equal(np.convolve(d, k, mode=2), full_mode)
+ # illegal arguments
+ with assert_raises(TypeError):
+ np.convolve(d, k, mode=None)
+
class TestArgwhere:
diff --git a/numpy/core/tests/test_overrides.py b/numpy/core/tests/test_overrides.py
index df0ea330c..9216a3f5f 100644
--- a/numpy/core/tests/test_overrides.py
+++ b/numpy/core/tests/test_overrides.py
@@ -1,5 +1,6 @@
import inspect
import sys
+import os
import tempfile
from io import StringIO
from unittest import mock
@@ -430,25 +431,27 @@ class TestNumPyFunctions:
class TestArrayLike:
+ def setup(self):
+ class MyArray():
+ def __init__(self, function=None):
+ self.function = function
- class MyArray():
-
- def __init__(self, function=None):
- self.function = function
+ def __array_function__(self, func, types, args, kwargs):
+ try:
+ my_func = getattr(self, func.__name__)
+ except AttributeError:
+ return NotImplemented
+ return my_func(*args, **kwargs)
- def __array_function__(self, func, types, args, kwargs):
- try:
- my_func = getattr(TestArrayLike.MyArray, func.__name__)
- except AttributeError:
- return NotImplemented
- return my_func(*args, **kwargs)
+ self.MyArray = MyArray
- class MyNoArrayFunctionArray():
+ class MyNoArrayFunctionArray():
+ def __init__(self, function=None):
+ self.function = function
- def __init__(self, function=None):
- self.function = function
+ self.MyNoArrayFunctionArray = MyNoArrayFunctionArray
- def add_method(name, arr_class, enable_value_error=False):
+ def add_method(self, name, arr_class, enable_value_error=False):
def _definition(*args, **kwargs):
# Check that `like=` isn't propagated downstream
assert 'like' not in kwargs
@@ -464,9 +467,9 @@ class TestArrayLike:
@requires_array_function
def test_array_like_not_implemented(self):
- TestArrayLike.add_method('array', TestArrayLike.MyArray)
+ self.add_method('array', self.MyArray)
- ref = TestArrayLike.MyArray.array()
+ ref = self.MyArray.array()
with assert_raises_regex(TypeError, 'no implementation found'):
array_like = np.asarray(1, like=ref)
@@ -497,15 +500,15 @@ class TestArrayLike:
@pytest.mark.parametrize('numpy_ref', [True, False])
@requires_array_function
def test_array_like(self, function, args, kwargs, numpy_ref):
- TestArrayLike.add_method('array', TestArrayLike.MyArray)
- TestArrayLike.add_method(function, TestArrayLike.MyArray)
+ self.add_method('array', self.MyArray)
+ self.add_method(function, self.MyArray)
np_func = getattr(np, function)
- my_func = getattr(TestArrayLike.MyArray, function)
+ my_func = getattr(self.MyArray, function)
if numpy_ref is True:
ref = np.array(1)
else:
- ref = TestArrayLike.MyArray.array()
+ ref = self.MyArray.array()
like_args = tuple(a() if callable(a) else a for a in args)
array_like = np_func(*like_args, **kwargs, like=ref)
@@ -523,20 +526,20 @@ class TestArrayLike:
assert_equal(array_like, np_arr)
else:
- assert type(array_like) is TestArrayLike.MyArray
+ assert type(array_like) is self.MyArray
assert array_like.function is my_func
@pytest.mark.parametrize('function, args, kwargs', _array_tests)
- @pytest.mark.parametrize('ref', [1, [1], MyNoArrayFunctionArray])
+ @pytest.mark.parametrize('ref', [1, [1], "MyNoArrayFunctionArray"])
@requires_array_function
def test_no_array_function_like(self, function, args, kwargs, ref):
- TestArrayLike.add_method('array', TestArrayLike.MyNoArrayFunctionArray)
- TestArrayLike.add_method(function, TestArrayLike.MyNoArrayFunctionArray)
+ self.add_method('array', self.MyNoArrayFunctionArray)
+ self.add_method(function, self.MyNoArrayFunctionArray)
np_func = getattr(np, function)
# Instantiate ref if it's the MyNoArrayFunctionArray class
- if ref is TestArrayLike.MyNoArrayFunctionArray:
- ref = ref.array()
+ if ref == "MyNoArrayFunctionArray":
+ ref = self.MyNoArrayFunctionArray.array()
like_args = tuple(a() if callable(a) else a for a in args)
@@ -546,38 +549,36 @@ class TestArrayLike:
@pytest.mark.parametrize('numpy_ref', [True, False])
def test_array_like_fromfile(self, numpy_ref):
- TestArrayLike.add_method('array', TestArrayLike.MyArray)
- TestArrayLike.add_method("fromfile", TestArrayLike.MyArray)
+ self.add_method('array', self.MyArray)
+ self.add_method("fromfile", self.MyArray)
if numpy_ref is True:
ref = np.array(1)
else:
- ref = TestArrayLike.MyArray.array()
+ ref = self.MyArray.array()
data = np.random.random(5)
- fname = tempfile.mkstemp()[1]
- data.tofile(fname)
+ with tempfile.TemporaryDirectory() as tmpdir:
+ fname = os.path.join(tmpdir, "testfile")
+ data.tofile(fname)
- array_like = np.fromfile(fname, like=ref)
- if numpy_ref is True:
- assert type(array_like) is np.ndarray
- np_res = np.fromfile(fname, like=ref)
- assert_equal(np_res, data)
- assert_equal(array_like, np_res)
- else:
- assert type(array_like) is TestArrayLike.MyArray
- assert array_like.function is TestArrayLike.MyArray.fromfile
+ array_like = np.fromfile(fname, like=ref)
+ if numpy_ref is True:
+ assert type(array_like) is np.ndarray
+ np_res = np.fromfile(fname, like=ref)
+ assert_equal(np_res, data)
+ assert_equal(array_like, np_res)
+ else:
+ assert type(array_like) is self.MyArray
+ assert array_like.function is self.MyArray.fromfile
@requires_array_function
def test_exception_handling(self):
- TestArrayLike.add_method(
- 'array',
- TestArrayLike.MyArray,
- enable_value_error=True,
- )
+ self.add_method('array', self.MyArray, enable_value_error=True)
- ref = TestArrayLike.MyArray.array()
+ ref = self.MyArray.array()
- with assert_raises(ValueError):
+ with assert_raises(TypeError):
+ # Raises the error about `value_error` being invalid first
np.array(1, value_error=True, like=ref)
diff --git a/numpy/core/tests/test_regression.py b/numpy/core/tests/test_regression.py
index 831e48e8b..21cc8c159 100644
--- a/numpy/core/tests/test_regression.py
+++ b/numpy/core/tests/test_regression.py
@@ -12,7 +12,7 @@ from numpy.testing import (
assert_, assert_equal, IS_PYPY, assert_almost_equal,
assert_array_equal, assert_array_almost_equal, assert_raises,
assert_raises_regex, assert_warns, suppress_warnings,
- _assert_valid_refcount, HAS_REFCOUNT,
+ _assert_valid_refcount, HAS_REFCOUNT, IS_PYSTON
)
from numpy.testing._private.utils import _no_tracing, requires_memory
from numpy.compat import asbytes, asunicode, pickle
@@ -22,6 +22,8 @@ try:
except NameError:
RecursionError = RuntimeError # python < 3.5
+
+
class TestRegression:
def test_invalid_round(self):
# Ticket #3
@@ -503,8 +505,8 @@ class TestRegression:
assert_equal(np.arange(4, dtype='<c8').real.max(), 3.0)
def test_object_array_from_list(self):
- # Ticket #270
- assert_(np.array([1, 'A', None]).shape == (3,))
+ # Ticket #270 (gh-868)
+ assert_(np.array([1, None, 'A']).shape == (3,))
def test_multiple_assign(self):
# Ticket #273
@@ -1531,7 +1533,7 @@ class TestRegression:
np.fromstring(b'aa, aa, 1.0', sep=',')
def test_ticket_1539(self):
- dtypes = [x for x in np.typeDict.values()
+ dtypes = [x for x in np.sctypeDict.values()
if (issubclass(x, np.number)
and not issubclass(x, np.timedelta64))]
a = np.array([], np.bool_) # not x[0] because it is unordered
@@ -1748,7 +1750,7 @@ class TestRegression:
# it is designed to simulate an old API
# expectation to guard against regression
def squeeze(self):
- return super(OldSqueeze, self).squeeze()
+ return super().squeeze()
oldsqueeze = OldSqueeze(np.array([[1],[2],[3]]))
@@ -1796,6 +1798,7 @@ class TestRegression:
assert_(a.flags.f_contiguous)
assert_(b.flags.c_contiguous)
+ @pytest.mark.skipif(IS_PYSTON, reason="Pyston disables recursion checking")
def test_object_array_self_reference(self):
# Object arrays with references to themselves can cause problems
a = np.array(0, dtype=object)
@@ -1804,6 +1807,7 @@ class TestRegression:
assert_raises(RecursionError, float, a)
a[()] = None
+ @pytest.mark.skipif(IS_PYSTON, reason="Pyston disables recursion checking")
def test_object_array_circular_reference(self):
# Test the same for a circular reference.
a = np.array(0, dtype=object)
@@ -2050,18 +2054,18 @@ class TestRegression:
def test_string_truncation(self):
# Ticket #1990 - Data can be truncated in creation of an array from a
- # mixed sequence of numeric values and strings
+ # mixed sequence of numeric values and strings (gh-2583)
for val in [True, 1234, 123.4, complex(1, 234)]:
- for tostr in [asunicode, asbytes]:
- b = np.array([val, tostr('xx')])
+ for tostr, dtype in [(asunicode, "U"), (asbytes, "S")]:
+ b = np.array([val, tostr('xx')], dtype=dtype)
assert_equal(tostr(b[0]), tostr(val))
- b = np.array([tostr('xx'), val])
+ b = np.array([tostr('xx'), val], dtype=dtype)
assert_equal(tostr(b[1]), tostr(val))
# test also with longer strings
- b = np.array([val, tostr('xxxxxxxxxx')])
+ b = np.array([val, tostr('xxxxxxxxxx')], dtype=dtype)
assert_equal(tostr(b[0]), tostr(val))
- b = np.array([tostr('xxxxxxxxxx'), val])
+ b = np.array([tostr('xxxxxxxxxx'), val], dtype=dtype)
assert_equal(tostr(b[1]), tostr(val))
def test_string_truncation_ucs2(self):
@@ -2102,7 +2106,8 @@ class TestRegression:
assert_raises(TypeError, np.searchsorted, a, 1.2)
# Ticket #2066, similar problem:
dtype = np.format_parser(['i4', 'i4'], [], [])
- a = np.recarray((2, ), dtype)
+ a = np.recarray((2,), dtype)
+ a[...] = [(1, 2), (3, 4)]
assert_raises(TypeError, np.searchsorted, a, 1)
def test_complex64_alignment(self):
@@ -2332,7 +2337,7 @@ class TestRegression:
def test_correct_hash_dict(self):
# gh-8887 - __hash__ would be None despite tp_hash being set
- all_types = set(np.typeDict.values()) - {np.void}
+ all_types = set(np.sctypeDict.values()) - {np.void}
for t in all_types:
val = t()
@@ -2459,7 +2464,7 @@ class TestRegression:
np.array([T()])
def test_2d__array__shape(self):
- class T(object):
+ class T:
def __array__(self):
return np.ndarray(shape=(0,0))
@@ -2524,3 +2529,36 @@ class TestRegression:
f = np.frompyfunc(cassé, 1, 1)
assert str(f) == "<ufunc 'cassé (vectorized)'>"
+
+ @pytest.mark.parametrize("operation", [
+ 'add', 'subtract', 'multiply', 'floor_divide',
+ 'conjugate', 'fmod', 'square', 'reciprocal',
+ 'power', 'absolute', 'negative', 'positive',
+ 'greater', 'greater_equal', 'less',
+ 'less_equal', 'equal', 'not_equal', 'logical_and',
+ 'logical_not', 'logical_or', 'bitwise_and', 'bitwise_or',
+ 'bitwise_xor', 'invert', 'left_shift', 'right_shift',
+ 'gcd', 'lcm'
+ ]
+ )
+ @pytest.mark.parametrize("order", [
+ ('b->', 'B->'),
+ ('h->', 'H->'),
+ ('i->', 'I->'),
+ ('l->', 'L->'),
+ ('q->', 'Q->'),
+ ]
+ )
+ def test_ufunc_order(self, operation, order):
+ # gh-18075
+ # Ensure signed types before unsigned
+ def get_idx(string, str_lst):
+ for i, s in enumerate(str_lst):
+ if string in s:
+ return i
+ raise ValueError(f"{string} not in list")
+ types = getattr(np, operation).types
+ assert get_idx(order[0], types) < get_idx(order[1], types), (
+ f"Unexpected types order of ufunc in {operation}"
+ f"for {order}. Possible fix: Use signed before unsigned"
+ "in generate_umath.py")
diff --git a/numpy/core/tests/test_scalar_methods.py b/numpy/core/tests/test_scalar_methods.py
index 4f5fd2988..3693bba59 100644
--- a/numpy/core/tests/test_scalar_methods.py
+++ b/numpy/core/tests/test_scalar_methods.py
@@ -89,7 +89,8 @@ class TestAsIntegerRatio:
])
def test_roundtrip(self, ftype, frac_vals, exp_vals):
for frac, exp in zip(frac_vals, exp_vals):
- f = np.ldexp(frac, exp, dtype=ftype)
+ f = np.ldexp(ftype(frac), exp)
+ assert f.dtype == ftype
n, d = f.as_integer_ratio()
try:
diff --git a/numpy/core/tests/test_scalarmath.py b/numpy/core/tests/test_scalarmath.py
index d8529418e..becd65b11 100644
--- a/numpy/core/tests/test_scalarmath.py
+++ b/numpy/core/tests/test_scalarmath.py
@@ -1,9 +1,12 @@
+import contextlib
import sys
import warnings
import itertools
import operator
import platform
import pytest
+from hypothesis import given, settings, Verbosity, assume
+from hypothesis.strategies import sampled_from
import numpy as np
from numpy.testing import (
@@ -304,8 +307,8 @@ class TestModulus:
# promotes to float which does not fit
a = np.array([1, 2], np.int64)
b = np.array([1, 2], np.uint64)
- pattern = 'could not be coerced to provided output parameter'
- with assert_raises_regex(TypeError, pattern):
+ with pytest.raises(TypeError,
+ match=r"Cannot cast ufunc 'floor_divide' output from"):
a //= b
@@ -404,15 +407,15 @@ class TestConversion:
assert_(res == tgt)
for code in np.typecodes['AllInteger']:
- res = np.typeDict[code](np.iinfo(code).max)
+ res = np.dtype(code).type(np.iinfo(code).max)
tgt = np.iinfo(code).max
assert_(res == tgt)
def test_int_raise_behaviour(self):
def overflow_error_func(dtype):
- np.typeDict[dtype](np.iinfo(dtype).max + 1)
+ dtype(np.iinfo(dtype).max + 1)
- for code in 'lLqQ':
+ for code in [np.int_, np.uint, np.longlong, np.ulonglong]:
assert_raises(OverflowError, overflow_error_func, code)
def test_int_from_infinite_longdouble(self):
@@ -653,33 +656,43 @@ class TestSubtract:
class TestAbs:
- def _test_abs_func(self, absfunc):
- for tp in floating_types + complex_floating_types:
- x = tp(-1.5)
- assert_equal(absfunc(x), 1.5)
- x = tp(0.0)
- res = absfunc(x)
- # assert_equal() checks zero signedness
- assert_equal(res, 0.0)
- x = tp(-0.0)
- res = absfunc(x)
- assert_equal(res, 0.0)
-
- x = tp(np.finfo(tp).max)
- assert_equal(absfunc(x), x.real)
+ def _test_abs_func(self, absfunc, test_dtype):
+ x = test_dtype(-1.5)
+ assert_equal(absfunc(x), 1.5)
+ x = test_dtype(0.0)
+ res = absfunc(x)
+ # assert_equal() checks zero signedness
+ assert_equal(res, 0.0)
+ x = test_dtype(-0.0)
+ res = absfunc(x)
+ assert_equal(res, 0.0)
+
+ x = test_dtype(np.finfo(test_dtype).max)
+ assert_equal(absfunc(x), x.real)
- x = tp(np.finfo(tp).tiny)
+ with suppress_warnings() as sup:
+ sup.filter(UserWarning)
+ x = test_dtype(np.finfo(test_dtype).tiny)
assert_equal(absfunc(x), x.real)
- x = tp(np.finfo(tp).min)
- assert_equal(absfunc(x), -x.real)
-
- def test_builtin_abs(self):
- self._test_abs_func(abs)
-
- def test_numpy_abs(self):
- self._test_abs_func(np.abs)
-
+ x = test_dtype(np.finfo(test_dtype).min)
+ assert_equal(absfunc(x), -x.real)
+
+ @pytest.mark.parametrize("dtype", floating_types + complex_floating_types)
+ def test_builtin_abs(self, dtype):
+ if sys.platform == "cygwin" and dtype == np.clongdouble:
+ pytest.xfail(
+ reason="absl is computed in double precision on cygwin"
+ )
+ self._test_abs_func(abs, dtype)
+
+ @pytest.mark.parametrize("dtype", floating_types + complex_floating_types)
+ def test_numpy_abs(self, dtype):
+ if sys.platform == "cygwin" and dtype == np.clongdouble:
+ pytest.xfail(
+ reason="absl is computed in double precision on cygwin"
+ )
+ self._test_abs_func(np.abs, dtype)
class TestBitShifts:
@@ -707,3 +720,115 @@ class TestBitShifts:
shift_arr = np.array([shift]*32, dtype=dt)
res_arr = op(val_arr, shift_arr)
assert_equal(res_arr, res_scl)
+
+
+class TestHash:
+ @pytest.mark.parametrize("type_code", np.typecodes['AllInteger'])
+ def test_integer_hashes(self, type_code):
+ scalar = np.dtype(type_code).type
+ for i in range(128):
+ assert hash(i) == hash(scalar(i))
+
+ @pytest.mark.parametrize("type_code", np.typecodes['AllFloat'])
+ def test_float_and_complex_hashes(self, type_code):
+ scalar = np.dtype(type_code).type
+ for val in [np.pi, np.inf, 3, 6.]:
+ numpy_val = scalar(val)
+ # Cast back to Python, in case the NumPy scalar has less precision
+ if numpy_val.dtype.kind == 'c':
+ val = complex(numpy_val)
+ else:
+ val = float(numpy_val)
+ assert val == numpy_val
+ print(repr(numpy_val), repr(val))
+ assert hash(val) == hash(numpy_val)
+
+ if hash(float(np.nan)) != hash(float(np.nan)):
+ # If Python distinguises different NaNs we do so too (gh-18833)
+ assert hash(scalar(np.nan)) != hash(scalar(np.nan))
+
+ @pytest.mark.parametrize("type_code", np.typecodes['Complex'])
+ def test_complex_hashes(self, type_code):
+ # Test some complex valued hashes specifically:
+ scalar = np.dtype(type_code).type
+ for val in [np.pi+1j, np.inf-3j, 3j, 6.+1j]:
+ numpy_val = scalar(val)
+ assert hash(complex(numpy_val)) == hash(numpy_val)
+
+
+@contextlib.contextmanager
+def recursionlimit(n):
+ o = sys.getrecursionlimit()
+ try:
+ sys.setrecursionlimit(n)
+ yield
+ finally:
+ sys.setrecursionlimit(o)
+
+
+objecty_things = [object(), None]
+reasonable_operators_for_scalars = [
+ operator.lt, operator.le, operator.eq, operator.ne, operator.ge,
+ operator.gt, operator.add, operator.floordiv, operator.mod,
+ operator.mul, operator.matmul, operator.pow, operator.sub,
+ operator.truediv,
+]
+
+
+@given(sampled_from(objecty_things),
+ sampled_from(reasonable_operators_for_scalars),
+ sampled_from(types))
+@settings(verbosity=Verbosity.verbose)
+def test_operator_object_left(o, op, type_):
+ try:
+ with recursionlimit(200):
+ op(o, type_(1))
+ except TypeError:
+ pass
+
+
+@given(sampled_from(objecty_things),
+ sampled_from(reasonable_operators_for_scalars),
+ sampled_from(types))
+def test_operator_object_right(o, op, type_):
+ try:
+ with recursionlimit(200):
+ op(type_(1), o)
+ except TypeError:
+ pass
+
+
+@given(sampled_from(reasonable_operators_for_scalars),
+ sampled_from(types),
+ sampled_from(types))
+def test_operator_scalars(op, type1, type2):
+ try:
+ op(type1(1), type2(1))
+ except TypeError:
+ pass
+
+
+@pytest.mark.parametrize("op", reasonable_operators_for_scalars)
+def test_longdouble_inf_loop(op):
+ try:
+ op(np.longdouble(3), None)
+ except TypeError:
+ pass
+ try:
+ op(None, np.longdouble(3))
+ except TypeError:
+ pass
+
+
+@pytest.mark.parametrize("op", reasonable_operators_for_scalars)
+def test_clongdouble_inf_loop(op):
+ if op in {operator.mod} and False:
+ pytest.xfail("The modulo operator is known to be broken")
+ try:
+ op(np.clongdouble(3), None)
+ except TypeError:
+ pass
+ try:
+ op(None, np.longdouble(3))
+ except TypeError:
+ pass
diff --git a/numpy/core/tests/test_scalarprint.py b/numpy/core/tests/test_scalarprint.py
index 6502ec4c1..2f1c3bc5e 100644
--- a/numpy/core/tests/test_scalarprint.py
+++ b/numpy/core/tests/test_scalarprint.py
@@ -9,7 +9,7 @@ import sys
from tempfile import TemporaryFile
import numpy as np
-from numpy.testing import assert_, assert_equal
+from numpy.testing import assert_, assert_equal, assert_raises
class TestRealScalars:
def test_str(self):
@@ -154,7 +154,8 @@ class TestRealScalars:
"0.00000000000000000000000000000000000000000000140129846432"
"4817070923729583289916131280261941876515771757068283889791"
"08268586060148663818836212158203125")
- assert_equal(fpos64(0.5**(1022 + 52), unique=False, precision=1074),
+
+ assert_equal(fpos64(5e-324, unique=False, precision=1074),
"0.00000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000000"
"0000000000000000000000000000000000000000000000000000000000"
@@ -176,7 +177,8 @@ class TestRealScalars:
"87538682506419718265533447265625")
# largest numbers
- assert_equal(fpos32(np.finfo(np.float32).max, **preckwd(0)),
+ f32x = np.finfo(np.float32).max
+ assert_equal(fpos32(f32x, **preckwd(0)),
"340282346638528859811704183484516925440.")
assert_equal(fpos64(np.finfo(np.float64).max, **preckwd(0)),
"1797693134862315708145274237317043567980705675258449965989"
@@ -186,10 +188,66 @@ class TestRealScalars:
"6580855933212334827479782620414472316873817718091929988125"
"0404026184124858368.")
# Warning: In unique mode only the integer digits necessary for
- # uniqueness are computed, the rest are 0. Should we change this?
- assert_equal(fpos32(np.finfo(np.float32).max, precision=0),
+ # uniqueness are computed, the rest are 0.
+ assert_equal(fpos32(f32x),
"340282350000000000000000000000000000000.")
+ # Further tests of zero-padding vs rounding in different combinations
+ # of unique, fractional, precision, min_digits
+ # precision can only reduce digits, not add them.
+ # min_digits can only extend digits, not reduce them.
+ assert_equal(fpos32(f32x, unique=True, fractional=True, precision=0),
+ "340282350000000000000000000000000000000.")
+ assert_equal(fpos32(f32x, unique=True, fractional=True, precision=4),
+ "340282350000000000000000000000000000000.")
+ assert_equal(fpos32(f32x, unique=True, fractional=True, min_digits=0),
+ "340282346638528859811704183484516925440.")
+ assert_equal(fpos32(f32x, unique=True, fractional=True, min_digits=4),
+ "340282346638528859811704183484516925440.0000")
+ assert_equal(fpos32(f32x, unique=True, fractional=True,
+ min_digits=4, precision=4),
+ "340282346638528859811704183484516925440.0000")
+ assert_raises(ValueError, fpos32, f32x, unique=True, fractional=False,
+ precision=0)
+ assert_equal(fpos32(f32x, unique=True, fractional=False, precision=4),
+ "340300000000000000000000000000000000000.")
+ assert_equal(fpos32(f32x, unique=True, fractional=False, precision=20),
+ "340282350000000000000000000000000000000.")
+ assert_equal(fpos32(f32x, unique=True, fractional=False, min_digits=4),
+ "340282350000000000000000000000000000000.")
+ assert_equal(fpos32(f32x, unique=True, fractional=False,
+ min_digits=20),
+ "340282346638528859810000000000000000000.")
+ assert_equal(fpos32(f32x, unique=True, fractional=False,
+ min_digits=15),
+ "340282346638529000000000000000000000000.")
+ assert_equal(fpos32(f32x, unique=False, fractional=False, precision=4),
+ "340300000000000000000000000000000000000.")
+ # test that unique rounding is preserved when precision is supplied
+ # but no extra digits need to be printed (gh-18609)
+ a = np.float64.fromhex('-1p-97')
+ assert_equal(fsci64(a, unique=True), '-6.310887241768095e-30')
+ assert_equal(fsci64(a, unique=False, precision=15),
+ '-6.310887241768094e-30')
+ assert_equal(fsci64(a, unique=True, precision=15),
+ '-6.310887241768095e-30')
+ assert_equal(fsci64(a, unique=True, min_digits=15),
+ '-6.310887241768095e-30')
+ assert_equal(fsci64(a, unique=True, precision=15, min_digits=15),
+ '-6.310887241768095e-30')
+ # adds/remove digits in unique mode with unbiased rnding
+ assert_equal(fsci64(a, unique=True, precision=14),
+ '-6.31088724176809e-30')
+ assert_equal(fsci64(a, unique=True, min_digits=16),
+ '-6.3108872417680944e-30')
+ assert_equal(fsci64(a, unique=True, precision=16),
+ '-6.310887241768095e-30')
+ assert_equal(fsci64(a, unique=True, min_digits=14),
+ '-6.310887241768095e-30')
+ # test min_digits in unique mode with different rounding cases
+ assert_equal(fsci64('1e120', min_digits=3), '1.000e+120')
+ assert_equal(fsci64('1e100', min_digits=3), '1.000e+100')
+
# test trailing zeros
assert_equal(fpos32('1.0', unique=False, precision=3), "1.000")
assert_equal(fpos64('1.0', unique=False, precision=3), "1.000")
@@ -200,7 +258,9 @@ class TestRealScalars:
assert_equal(fsci32('1.5', unique=False, precision=3), "1.500e+00")
assert_equal(fsci64('1.5', unique=False, precision=3), "1.500e+00")
# gh-10713
- assert_equal(fpos64('324', unique=False, precision=5, fractional=False), "324.00")
+ assert_equal(fpos64('324', unique=False, precision=5,
+ fractional=False), "324.00")
+
def test_dragon4_interface(self):
tps = [np.float16, np.float32, np.float64]
diff --git a/numpy/core/tests/test_shape_base.py b/numpy/core/tests/test_shape_base.py
index 4e56ace90..679e3c036 100644
--- a/numpy/core/tests/test_shape_base.py
+++ b/numpy/core/tests/test_shape_base.py
@@ -256,7 +256,7 @@ class TestConcatenate:
r = np.concatenate((a, b), axis=None)
assert_equal(r.size, a.size + len(b))
assert_equal(r.dtype, a.dtype)
- r = np.concatenate((a, b, c), axis=None)
+ r = np.concatenate((a, b, c), axis=None, dtype="U")
d = array(['0.0', '1.0', '2.0', '3.0',
'0', '1', '2', 'x'])
assert_array_equal(r, d)
@@ -343,7 +343,7 @@ class TestConcatenate:
concatenate((a, b), out=np.empty(4))
@pytest.mark.parametrize("axis", [None, 0])
- @pytest.mark.parametrize("out_dtype", ["c8", "f4", "f8", ">f8", "i8"])
+ @pytest.mark.parametrize("out_dtype", ["c8", "f4", "f8", ">f8", "i8", "S4"])
@pytest.mark.parametrize("casting",
['no', 'equiv', 'safe', 'same_kind', 'unsafe'])
def test_out_and_dtype(self, axis, out_dtype, casting):
@@ -369,6 +369,29 @@ class TestConcatenate:
with assert_raises(TypeError):
concatenate(to_concat, out=out, dtype=out_dtype, axis=axis)
+ @pytest.mark.parametrize("axis", [None, 0])
+ @pytest.mark.parametrize("string_dt", ["S", "U", "S0", "U0"])
+ @pytest.mark.parametrize("arrs",
+ [([0.],), ([0.], [1]), ([0], ["string"], [1.])])
+ def test_dtype_with_promotion(self, arrs, string_dt, axis):
+ # Note that U0 and S0 should be deprecated eventually and changed to
+ # actually give the empty string result (together with `np.array`)
+ res = np.concatenate(arrs, axis=axis, dtype=string_dt, casting="unsafe")
+ # The actual dtype should be identical to a cast (of a double array):
+ assert res.dtype == np.array(1.).astype(string_dt).dtype
+
+ @pytest.mark.parametrize("axis", [None, 0])
+ def test_string_dtype_does_not_inspect(self, axis):
+ with pytest.raises(TypeError):
+ np.concatenate(([None], [1]), dtype="S", axis=axis)
+ with pytest.raises(TypeError):
+ np.concatenate(([None], [1]), dtype="U", axis=axis)
+
+ @pytest.mark.parametrize("axis", [None, 0])
+ def test_subarray_error(self, axis):
+ with pytest.raises(TypeError, match=".*subarray dtype"):
+ np.concatenate(([1], [1]), dtype="(2,)i", axis=axis)
+
def test_stack():
# non-iterable input
diff --git a/numpy/core/tests/test_simd.py b/numpy/core/tests/test_simd.py
index 13e8d5ede..ea5bbe103 100644
--- a/numpy/core/tests/test_simd.py
+++ b/numpy/core/tests/test_simd.py
@@ -1,13 +1,17 @@
# NOTE: Please avoid the use of numpy.testing since NPYV intrinsics
# may be involved in their functionality.
-import pytest, math
+import pytest, math, re
+import itertools
from numpy.core._simd import targets
+from numpy.core._multiarray_umath import __cpu_baseline__
class _Test_Utility:
- # submodule of the desired SIMD extention, e.g. targets["AVX512F"]
+ # submodule of the desired SIMD extension, e.g. targets["AVX512F"]
npyv = None
# the current data type suffix e.g. 's8'
sfx = None
+ # target name can be 'baseline' or one or more of CPU features
+ target_name = None
def __getattr__(self, attr):
"""
@@ -92,6 +96,66 @@ class _Test_Utility:
v = self.npyv.setall_u32(0x7fc00000)
return self.npyv.reinterpret_f32_u32(v)[0]
+ def _cpu_features(self):
+ target = self.target_name
+ if target == "baseline":
+ target = __cpu_baseline__
+ else:
+ target = target.split('__') # multi-target separator
+ return ' '.join(target)
+
+class _SIMD_BOOL(_Test_Utility):
+ """
+ To test all boolean vector types at once
+ """
+ def _data(self, start=None, count=None, reverse=False):
+ nlanes = getattr(self.npyv, "nlanes_u" + self.sfx[1:])
+ true_mask = self._true_mask()
+ rng = range(nlanes)
+ if reverse:
+ rng = reversed(rng)
+ return [true_mask if x % 2 else 0 for x in rng]
+
+ def _load_b(self, data):
+ len_str = self.sfx[1:]
+ load = getattr(self.npyv, "load_u" + len_str)
+ cvt = getattr(self.npyv, f"cvt_b{len_str}_u{len_str}")
+ return cvt(load(data))
+
+ def test_operators_logical(self):
+ """
+ Logical operations for boolean types.
+ Test intrinsics:
+ npyv_xor_##SFX, npyv_and_##SFX, npyv_or_##SFX, npyv_not_##SFX
+ """
+ data_a = self._data()
+ data_b = self._data(reverse=True)
+ vdata_a = self._load_b(data_a)
+ vdata_b = self._load_b(data_b)
+
+ data_and = [a & b for a, b in zip(data_a, data_b)]
+ vand = getattr(self, "and")(vdata_a, vdata_b)
+ assert vand == data_and
+
+ data_or = [a | b for a, b in zip(data_a, data_b)]
+ vor = getattr(self, "or")(vdata_a, vdata_b)
+ assert vor == data_or
+
+ data_xor = [a ^ b for a, b in zip(data_a, data_b)]
+ vxor = getattr(self, "xor")(vdata_a, vdata_b)
+ assert vxor == data_xor
+
+ vnot = getattr(self, "not")(vdata_a)
+ assert vnot == data_b
+
+ def test_tobits(self):
+ data2bits = lambda data: sum([int(x != 0) << i for i, x in enumerate(data, 0)])
+ for data in (self._data(), self._data(reverse=True)):
+ vdata = self._load_b(data)
+ data_bits = data2bits(data)
+ tobits = bin(self.tobits(vdata))
+ assert tobits == bin(data_bits)
+
class _SIMD_INT(_Test_Utility):
"""
To test all integer vector types at once
@@ -110,14 +174,21 @@ class _SIMD_INT(_Test_Utility):
# left shift
shl = self.shl(vdata_a, count)
assert shl == data_shl_a
- # left shift by an immediate constant
- shli = self.shli(vdata_a, count)
- assert shli == data_shl_a
# load to cast
data_shr_a = self.load([a >> count for a in data_a])
# right shift
shr = self.shr(vdata_a, count)
assert shr == data_shr_a
+
+ # shift by zero or max or out-range immediate constant is not applicable and illogical
+ for count in range(1, self._scalar_size()):
+ # load to cast
+ data_shl_a = self.load([a << count for a in data_a])
+ # left shift by an immediate constant
+ shli = self.shli(vdata_a, count)
+ assert shli == data_shl_a
+ # load to cast
+ data_shr_a = self.load([a >> count for a in data_a])
# right shift by an immediate constant
shri = self.shri(vdata_a, count)
assert shri == data_shr_a
@@ -138,6 +209,59 @@ class _SIMD_INT(_Test_Utility):
subs = self.subs(vdata_a, vdata_b)
assert subs == data_subs
+ def test_math_max_min(self):
+ data_a = self._data()
+ data_b = self._data(self.nlanes)
+ vdata_a, vdata_b = self.load(data_a), self.load(data_b)
+
+ data_max = [max(a, b) for a, b in zip(data_a, data_b)]
+ simd_max = self.max(vdata_a, vdata_b)
+ assert simd_max == data_max
+
+ data_min = [min(a, b) for a, b in zip(data_a, data_b)]
+ simd_min = self.min(vdata_a, vdata_b)
+ assert simd_min == data_min
+
+class _SIMD_FP32(_Test_Utility):
+ """
+ To only test single precision
+ """
+ def test_conversions(self):
+ """
+ Round to nearest even integer, assume CPU control register is set to rounding.
+ Test intrinsics:
+ npyv_round_s32_##SFX
+ """
+ features = self._cpu_features()
+ if not self.npyv.simd_f64 and re.match(r".*(NEON|ASIMD)", features):
+ # very costly to emulate nearest even on Armv7
+ # instead we round halves to up. e.g. 0.5 -> 1, -0.5 -> -1
+ _round = lambda v: int(v + (0.5 if v >= 0 else -0.5))
+ else:
+ _round = round
+ vdata_a = self.load(self._data())
+ vdata_a = self.sub(vdata_a, self.setall(0.5))
+ data_round = [_round(x) for x in vdata_a]
+ vround = self.round_s32(vdata_a)
+ assert vround == data_round
+
+class _SIMD_FP64(_Test_Utility):
+ """
+ To only test double precision
+ """
+ def test_conversions(self):
+ """
+ Round to nearest even integer, assume CPU control register is set to rounding.
+ Test intrinsics:
+ npyv_round_s32_##SFX
+ """
+ vdata_a = self.load(self._data())
+ vdata_a = self.sub(vdata_a, self.setall(0.5))
+ vdata_b = self.mul(vdata_a, self.setall(-1.5))
+ data_round = [round(x) for x in list(vdata_a) + list(vdata_b)]
+ vround = self.round_s32(vdata_a, vdata_b)
+ assert vround == data_round
+
class _SIMD_FP(_Test_Utility):
"""
To test all float vector types at once
@@ -205,6 +329,68 @@ class _SIMD_FP(_Test_Utility):
data_square = [x*x for x in data]
square = self.square(vdata)
assert square == data_square
+
+ def test_max(self):
+ """
+ Test intrinsics:
+ npyv_max_##SFX
+ npyv_maxp_##SFX
+ """
+ data_a = self._data()
+ data_b = self._data(self.nlanes)
+ vdata_a, vdata_b = self.load(data_a), self.load(data_b)
+ data_max = [max(a, b) for a, b in zip(data_a, data_b)]
+ _max = self.max(vdata_a, vdata_b)
+ assert _max == data_max
+ maxp = self.maxp(vdata_a, vdata_b)
+ assert maxp == data_max
+ # test IEEE standards
+ pinf, ninf, nan = self._pinfinity(), self._ninfinity(), self._nan()
+ max_cases = ((nan, nan, nan), (nan, 10, 10), (10, nan, 10),
+ (pinf, pinf, pinf), (pinf, 10, pinf), (10, pinf, pinf),
+ (ninf, ninf, ninf), (ninf, 10, 10), (10, ninf, 10),
+ (10, 0, 10), (10, -10, 10))
+ for case_operand1, case_operand2, desired in max_cases:
+ data_max = [desired]*self.nlanes
+ vdata_a = self.setall(case_operand1)
+ vdata_b = self.setall(case_operand2)
+ maxp = self.maxp(vdata_a, vdata_b)
+ assert maxp == pytest.approx(data_max, nan_ok=True)
+ if nan in (case_operand1, case_operand2, desired):
+ continue
+ _max = self.max(vdata_a, vdata_b)
+ assert _max == data_max
+
+ def test_min(self):
+ """
+ Test intrinsics:
+ npyv_min_##SFX
+ npyv_minp_##SFX
+ """
+ data_a = self._data()
+ data_b = self._data(self.nlanes)
+ vdata_a, vdata_b = self.load(data_a), self.load(data_b)
+ data_min = [min(a, b) for a, b in zip(data_a, data_b)]
+ _min = self.min(vdata_a, vdata_b)
+ assert _min == data_min
+ minp = self.minp(vdata_a, vdata_b)
+ assert minp == data_min
+ # test IEEE standards
+ pinf, ninf, nan = self._pinfinity(), self._ninfinity(), self._nan()
+ min_cases = ((nan, nan, nan), (nan, 10, 10), (10, nan, 10),
+ (pinf, pinf, pinf), (pinf, 10, 10), (10, pinf, 10),
+ (ninf, ninf, ninf), (ninf, 10, ninf), (10, ninf, ninf),
+ (10, 0, 0), (10, -10, -10))
+ for case_operand1, case_operand2, desired in min_cases:
+ data_min = [desired]*self.nlanes
+ vdata_a = self.setall(case_operand1)
+ vdata_b = self.setall(case_operand2)
+ minp = self.minp(vdata_a, vdata_b)
+ assert minp == pytest.approx(data_min, nan_ok=True)
+ if nan in (case_operand1, case_operand2, desired):
+ continue
+ _min = self.min(vdata_a, vdata_b)
+ assert _min == data_min
def test_reciprocal(self):
pinf, ninf, nan = self._pinfinity(), self._ninfinity(), self._nan()
@@ -221,6 +407,14 @@ class _SIMD_FP(_Test_Utility):
recip = self.recip(vdata)
assert recip == data_recip
+ def test_special_cases(self):
+ """
+ Compare Not NaN. Test intrinsics:
+ npyv_notnan_##SFX
+ """
+ nnan = self.notnan(self.setall(self._nan()))
+ assert nnan == [0]*self.nlanes
+
class _SIMD_ALL(_Test_Utility):
"""
To test all vector types at once
@@ -414,7 +608,7 @@ class _SIMD_ALL(_Test_Utility):
vsetf = self.setf(10, *data_a)
assert vsetf == data_a
- # We're testing the sainty of _simd's type-vector,
+ # We're testing the sanity of _simd's type-vector,
# reinterpret* intrinsics itself are tested via compiler
# during the build of _simd module
sfxes = ["u8", "s8", "u16", "s16", "u32", "s32", "u64", "s64", "f32"]
@@ -459,6 +653,18 @@ class _SIMD_ALL(_Test_Utility):
vzip = self.zip(vdata_a, vdata_b)
assert vzip == (data_zipl, data_ziph)
+ def test_reorder_rev64(self):
+ # Reverse elements of each 64-bit lane
+ ssize = self._scalar_size()
+ if ssize == 64:
+ return
+ data_rev64 = [
+ y for x in range(0, self.nlanes, 64//ssize)
+ for y in reversed(range(x, x + 64//ssize))
+ ]
+ rev64 = self.rev64(self.load(range(self.nlanes)))
+ assert rev64 == data_rev64
+
def test_operators_comparison(self):
if self._is_fp():
data_a = self._data()
@@ -540,6 +746,26 @@ class _SIMD_ALL(_Test_Utility):
true_vsfx = from_boolean(true_vb)
assert false_vsfx != true_vsfx
+ def test_conversion_expand(self):
+ """
+ Test expand intrinsics:
+ npyv_expand_u16_u8
+ npyv_expand_u32_u16
+ """
+ if self.sfx not in ("u8", "u16"):
+ return
+ totype = self.sfx[0]+str(int(self.sfx[1:])*2)
+ expand = getattr(self.npyv, f"expand_{totype}_{self.sfx}")
+ # close enough from the edge to detect any deviation
+ data = self._data(self._int_max() - self.nlanes)
+ vdata = self.load(data)
+ edata = expand(vdata)
+ # lower half part
+ data_lo = data[:self.nlanes//2]
+ # higher half part
+ data_hi = data[self.nlanes//2:]
+ assert edata == (data_lo, data_hi)
+
def test_arithmetic_subadd(self):
if self._is_fp():
data_a = self._data()
@@ -583,8 +809,84 @@ class _SIMD_ALL(_Test_Utility):
div = self.div(vdata_a, vdata_b)
assert div == data_div
+ def test_arithmetic_intdiv(self):
+ """
+ Test integer division intrinsics:
+ npyv_divisor_##sfx
+ npyv_divc_##sfx
+ """
+ if self._is_fp():
+ return
+
+ def trunc_div(a, d):
+ """
+ Divide towards zero works with large integers > 2^53,
+ and wrap around overflow similar to what C does.
+ """
+ if d == -1 and a == int_min:
+ return a
+ sign_a, sign_d = a < 0, d < 0
+ if a == 0 or sign_a == sign_d:
+ return a // d
+ return (a + sign_d - sign_a) // d + 1
+
+ int_min = self._int_min() if self._is_signed() else 1
+ int_max = self._int_max()
+ rdata = (
+ 0, 1, self.nlanes, int_max-self.nlanes,
+ int_min, int_min//2 + 1
+ )
+ divisors = (1, 2, 9, 13, self.nlanes, int_min, int_max, int_max//2)
+
+ for x, d in itertools.product(rdata, divisors):
+ data = self._data(x)
+ vdata = self.load(data)
+ data_divc = [trunc_div(a, d) for a in data]
+ divisor = self.divisor(d)
+ divc = self.divc(vdata, divisor)
+ assert divc == data_divc
+
+ if not self._is_signed():
+ return
+
+ safe_neg = lambda x: -x-1 if -x > int_max else -x
+ # test round divison for signed integers
+ for x, d in itertools.product(rdata, divisors):
+ d_neg = safe_neg(d)
+ data = self._data(x)
+ data_neg = [safe_neg(a) for a in data]
+ vdata = self.load(data)
+ vdata_neg = self.load(data_neg)
+ divisor = self.divisor(d)
+ divisor_neg = self.divisor(d_neg)
+
+ # round towards zero
+ data_divc = [trunc_div(a, d_neg) for a in data]
+ divc = self.divc(vdata, divisor_neg)
+ assert divc == data_divc
+ data_divc = [trunc_div(a, d) for a in data_neg]
+ divc = self.divc(vdata_neg, divisor)
+ assert divc == data_divc
+
+ # test truncate sign if the dividend is zero
+ vzero = self.zero()
+ for d in (-1, -10, -100, int_min//2, int_min):
+ divisor = self.divisor(d)
+ divc = self.divc(vzero, divisor)
+ assert divc == vzero
+
+ # test overflow
+ vmin = self.setall(int_min)
+ divisor = self.divisor(-1)
+ divc = self.divc(vmin, divisor)
+ assert divc == vmin
+
def test_arithmetic_reduce_sum(self):
- if not self._is_fp():
+ """
+ Test reduce sum intrinsics:
+ npyv_sum_##sfx
+ """
+ if self.sfx not in ("u32", "u64", "f32", "f64"):
return
# reduce sum
data = self._data()
@@ -594,12 +896,54 @@ class _SIMD_ALL(_Test_Utility):
vsum = self.sum(vdata)
assert vsum == data_sum
+ def test_arithmetic_reduce_sumup(self):
+ """
+ Test extend reduce sum intrinsics:
+ npyv_sumup_##sfx
+ """
+ if self.sfx not in ("u8", "u16"):
+ return
+ rdata = (0, self.nlanes, self._int_min(), self._int_max()-self.nlanes)
+ for r in rdata:
+ data = self._data(r)
+ vdata = self.load(data)
+ data_sum = sum(data)
+ vsum = self.sumup(vdata)
+ assert vsum == data_sum
+
+ def test_mask_conditional(self):
+ """
+ Conditional addition and subtraction for all supported data types.
+ Test intrinsics:
+ npyv_ifadd_##SFX, npyv_ifsub_##SFX
+ """
+ vdata_a = self.load(self._data())
+ vdata_b = self.load(self._data(reverse=True))
+ true_mask = self.cmpeq(self.zero(), self.zero())
+ false_mask = self.cmpneq(self.zero(), self.zero())
+
+ data_sub = self.sub(vdata_b, vdata_a)
+ ifsub = self.ifsub(true_mask, vdata_b, vdata_a, vdata_b)
+ assert ifsub == data_sub
+ ifsub = self.ifsub(false_mask, vdata_a, vdata_b, vdata_b)
+ assert ifsub == vdata_b
+
+ data_add = self.add(vdata_b, vdata_a)
+ ifadd = self.ifadd(true_mask, vdata_b, vdata_a, vdata_b)
+ assert ifadd == data_add
+ ifadd = self.ifadd(false_mask, vdata_a, vdata_b, vdata_b)
+ assert ifadd == vdata_b
+
+bool_sfx = ("b8", "b16", "b32", "b64")
int_sfx = ("u8", "s8", "u16", "s16", "u32", "s32", "u64", "s64")
fp_sfx = ("f32", "f64")
all_sfx = int_sfx + fp_sfx
tests_registry = {
+ bool_sfx: _SIMD_BOOL,
int_sfx : _SIMD_INT,
fp_sfx : _SIMD_FP,
+ ("f32",): _SIMD_FP32,
+ ("f64",): _SIMD_FP64,
all_sfx : _SIMD_ALL
}
for target_name, npyv in targets.items():
@@ -624,7 +968,7 @@ for target_name, npyv in targets.items():
for sfx in sfxes:
skip_m = skip_sfx.get(sfx, skip)
inhr = (cls,)
- attr = dict(npyv=targets[target_name], sfx=sfx)
+ attr = dict(npyv=targets[target_name], sfx=sfx, target_name=target_name)
tcls = type(f"Test{cls.__name__}_{simd_width}_{target_name}_{sfx}", inhr, attr)
if skip_m:
pytest.mark.skip(reason=skip_m)(tcls)
diff --git a/numpy/core/tests/test_ufunc.py b/numpy/core/tests/test_ufunc.py
index aa17d6b08..dab11d948 100644
--- a/numpy/core/tests/test_ufunc.py
+++ b/numpy/core/tests/test_ufunc.py
@@ -12,7 +12,7 @@ import numpy.core._rational_tests as _rational_tests
from numpy.testing import (
assert_, assert_equal, assert_raises, assert_array_equal,
assert_almost_equal, assert_array_almost_equal, assert_no_warnings,
- assert_allclose, HAS_REFCOUNT,
+ assert_allclose, HAS_REFCOUNT, suppress_warnings
)
from numpy.compat import pickle
@@ -34,13 +34,13 @@ class TestUfuncKwargs:
assert_raises(TypeError, np.add, 1, 2, wherex=[True])
def test_sig_signature(self):
- assert_raises(ValueError, np.add, 1, 2, sig='ii->i',
+ assert_raises(TypeError, np.add, 1, 2, sig='ii->i',
signature='ii->i')
def test_sig_dtype(self):
- assert_raises(RuntimeError, np.add, 1, 2, sig='ii->i',
+ assert_raises(TypeError, np.add, 1, 2, sig='ii->i',
dtype=int)
- assert_raises(RuntimeError, np.add, 1, 2, signature='ii->i',
+ assert_raises(TypeError, np.add, 1, 2, signature='ii->i',
dtype=int)
def test_extobj_refcount(self):
@@ -164,8 +164,9 @@ class TestUfuncGenericLoops:
except AttributeError:
return lambda: getattr(np.core.umath, attr)(val)
- num_arr = np.array([val], dtype=np.float64)
- obj_arr = np.array([MyFloat(val)], dtype="O")
+ # Use 0-D arrays, to ensure the same element call
+ num_arr = np.array(val, dtype=np.float64)
+ obj_arr = np.array(MyFloat(val), dtype="O")
with np.errstate(all="raise"):
try:
@@ -175,7 +176,7 @@ class TestUfuncGenericLoops:
ufunc(obj_arr)
else:
res_obj = ufunc(obj_arr)
- assert_array_equal(res_num.astype("O"), res_obj)
+ assert_array_almost_equal(res_num.astype("O"), res_obj)
def _pickleable_module_global():
@@ -410,9 +411,12 @@ class TestUfunc:
def test_forced_sig(self):
a = 0.5*np.arange(3, dtype='f8')
assert_equal(np.add(a, 0.5), [0.5, 1, 1.5])
- assert_equal(np.add(a, 0.5, sig='i', casting='unsafe'), [0, 0, 1])
+ with pytest.warns(DeprecationWarning):
+ assert_equal(np.add(a, 0.5, sig='i', casting='unsafe'), [0, 0, 1])
assert_equal(np.add(a, 0.5, sig='ii->i', casting='unsafe'), [0, 0, 1])
- assert_equal(np.add(a, 0.5, sig=('i4',), casting='unsafe'), [0, 0, 1])
+ with pytest.warns(DeprecationWarning):
+ assert_equal(np.add(a, 0.5, sig=('i4',), casting='unsafe'),
+ [0, 0, 1])
assert_equal(np.add(a, 0.5, sig=('i4', 'i4', 'i4'),
casting='unsafe'), [0, 0, 1])
@@ -420,18 +424,121 @@ class TestUfunc:
np.add(a, 0.5, out=b)
assert_equal(b, [0.5, 1, 1.5])
b[:] = 0
- np.add(a, 0.5, sig='i', out=b, casting='unsafe')
+ with pytest.warns(DeprecationWarning):
+ np.add(a, 0.5, sig='i', out=b, casting='unsafe')
assert_equal(b, [0, 0, 1])
b[:] = 0
np.add(a, 0.5, sig='ii->i', out=b, casting='unsafe')
assert_equal(b, [0, 0, 1])
b[:] = 0
- np.add(a, 0.5, sig=('i4',), out=b, casting='unsafe')
+ with pytest.warns(DeprecationWarning):
+ np.add(a, 0.5, sig=('i4',), out=b, casting='unsafe')
assert_equal(b, [0, 0, 1])
b[:] = 0
np.add(a, 0.5, sig=('i4', 'i4', 'i4'), out=b, casting='unsafe')
assert_equal(b, [0, 0, 1])
+ def test_signature_all_None(self):
+ # signature all None, is an acceptable alternative (since 1.21)
+ # to not providing a signature.
+ res1 = np.add([3], [4], sig=(None, None, None))
+ res2 = np.add([3], [4])
+ assert_array_equal(res1, res2)
+ res1 = np.maximum([3], [4], sig=(None, None, None))
+ res2 = np.maximum([3], [4])
+ assert_array_equal(res1, res2)
+
+ with pytest.raises(TypeError):
+ # special case, that would be deprecated anyway, so errors:
+ np.add(3, 4, signature=(None,))
+
+ def test_signature_dtype_type(self):
+ # Since that will be the normal behaviour (past NumPy 1.21)
+ # we do support the types already:
+ float_dtype = type(np.dtype(np.float64))
+ np.add(3, 4, signature=(float_dtype, float_dtype, None))
+
+ @pytest.mark.parametrize("casting", ["unsafe", "same_kind", "safe"])
+ def test_partial_signature_mismatch(self, casting):
+ # If the second argument matches already, no need to specify it:
+ res = np.ldexp(np.float32(1.), np.int_(2), dtype="d")
+ assert res.dtype == "d"
+ res = np.ldexp(np.float32(1.), np.int_(2), signature=(None, None, "d"))
+ assert res.dtype == "d"
+
+ # ldexp only has a loop for long input as second argument, overriding
+ # the output cannot help with that (no matter the casting)
+ with pytest.raises(TypeError):
+ np.ldexp(1., np.uint64(3), dtype="d")
+ with pytest.raises(TypeError):
+ np.ldexp(1., np.uint64(3), signature=(None, None, "d"))
+
+ def test_use_output_signature_for_all_arguments(self):
+ # Test that providing only `dtype=` or `signature=(None, None, dtype)`
+ # is sufficient if falling back to a homogeneous signature works.
+ # In this case, the `intp, intp -> intp` loop is chosen.
+ res = np.power(1.5, 2.8, dtype=np.intp, casting="unsafe")
+ assert res == 1 # the cast happens first.
+ res = np.power(1.5, 2.8, signature=(None, None, np.intp),
+ casting="unsafe")
+ assert res == 1
+ with pytest.raises(TypeError):
+ # the unsafe casting would normally cause errors though:
+ np.power(1.5, 2.8, dtype=np.intp)
+
+ def test_signature_errors(self):
+ with pytest.raises(TypeError,
+ match="the signature object to ufunc must be a string or"):
+ np.add(3, 4, signature=123.) # neither a string nor a tuple
+
+ with pytest.raises(ValueError):
+ # bad symbols that do not translate to dtypes
+ np.add(3, 4, signature="%^->#")
+
+ with pytest.raises(ValueError):
+ np.add(3, 4, signature=b"ii-i") # incomplete and byte string
+
+ with pytest.raises(ValueError):
+ np.add(3, 4, signature="ii>i") # incomplete string
+
+ with pytest.raises(ValueError):
+ np.add(3, 4, signature=(None, "f8")) # bad length
+
+ with pytest.raises(UnicodeDecodeError):
+ np.add(3, 4, signature=b"\xff\xff->i")
+
+ def test_forced_dtype_times(self):
+ # Signatures only set the type numbers (not the actual loop dtypes)
+ # so using `M` in a signature/dtype should generally work:
+ a = np.array(['2010-01-02', '1999-03-14', '1833-03'], dtype='>M8[D]')
+ np.maximum(a, a, dtype="M")
+ np.maximum.reduce(a, dtype="M")
+
+ arr = np.arange(10, dtype="m8[s]")
+ np.add(arr, arr, dtype="m")
+ np.maximum(arr, arr, dtype="m")
+
+ def test_forced_dtype_warning(self):
+ # does not warn (test relies on bad pickling behaviour, simply remove
+ # it if the `assert int64 is not int64_2` should start failing.
+ int64 = np.dtype("int64")
+ int64_2 = pickle.loads(pickle.dumps(int64))
+ assert int64 is not int64_2
+ np.add(3, 4, dtype=int64_2)
+
+ arr = np.arange(10, dtype="m8[s]")
+ msg = "The `dtype` and `signature` arguments to ufuncs only select the"
+ with pytest.raises(TypeError, match=msg):
+ np.add(3, 5, dtype=int64.newbyteorder())
+ with pytest.raises(TypeError, match=msg):
+ np.add(3, 5, dtype="m8[ns]") # previously used the "ns"
+ with pytest.raises(TypeError, match=msg):
+ np.add(arr, arr, dtype="m8[ns]") # never preserved the "ns"
+ with pytest.raises(TypeError, match=msg):
+ np.maximum(arr, arr, dtype="m8[ns]") # previously used the "ns"
+ with pytest.raises(TypeError, match=msg):
+ np.maximum.reduce(arr, dtype="m8[ns]") # never preserved the "ns"
+
def test_true_divide(self):
a = np.array(10)
b = np.array(20)
@@ -477,7 +584,13 @@ class TestUfunc:
else:
tgt = float(x)/float(y)
rtol = max(np.finfo(dtout).resolution, 1e-15)
- atol = max(np.finfo(dtout).tiny, 3e-308)
+ # The value of tiny for double double is NaN
+ with suppress_warnings() as sup:
+ sup.filter(UserWarning)
+ if not np.isnan(np.finfo(dtout).tiny):
+ atol = max(np.finfo(dtout).tiny, 3e-308)
+ else:
+ atol = 3e-308
# Some test values result in invalid for float16.
with np.errstate(invalid='ignore'):
res = np.true_divide(x, y, dtype=dtout)
@@ -490,7 +603,13 @@ class TestUfunc:
dtout = np.dtype(tcout)
tgt = complex(x)/complex(y)
rtol = max(np.finfo(dtout).resolution, 1e-15)
- atol = max(np.finfo(dtout).tiny, 3e-308)
+ # The value of tiny for double double is NaN
+ with suppress_warnings() as sup:
+ sup.filter(UserWarning)
+ if not np.isnan(np.finfo(dtout).tiny):
+ atol = max(np.finfo(dtout).tiny, 3e-308)
+ else:
+ atol = 3e-308
res = np.true_divide(x, y, dtype=dtout)
if not np.isfinite(res):
continue
@@ -1593,9 +1712,17 @@ class TestUfunc:
target = np.array([0, 2, 4], dtype=_rational_tests.rational)
assert_equal(result, target)
- # no output type should raise TypeError
+ # The new resolution means that we can (usually) find custom loops
+ # as long as they match exactly:
+ result = _rational_tests.test_add(a, b)
+ assert_equal(result, target)
+
+ # But since we use the old type resolver, this may not work
+ # for dtype variations unless the output dtype is given:
+ result = _rational_tests.test_add(a, b.astype(np.uint16), out=c)
+ assert_equal(result, target)
with assert_raises(TypeError):
- _rational_tests.test_add(a, b)
+ _rational_tests.test_add(a, b.astype(np.uint16))
def test_operand_flags(self):
a = np.arange(16, dtype='l').reshape(4, 4)
@@ -1911,8 +2038,7 @@ class TestUfunc:
np.true_divide, np.floor_divide, np.bitwise_and, np.bitwise_or,
np.bitwise_xor, np.left_shift, np.right_shift, np.fmax,
np.fmin, np.fmod, np.hypot, np.logaddexp, np.logaddexp2,
- np.logical_and, np.logical_or, np.logical_xor, np.maximum,
- np.minimum, np.mod,
+ np.maximum, np.minimum, np.mod,
np.greater, np.greater_equal, np.less, np.less_equal,
np.equal, np.not_equal]
diff --git a/numpy/core/tests/test_umath.py b/numpy/core/tests/test_umath.py
index 3f89cc59b..4f57c0088 100644
--- a/numpy/core/tests/test_umath.py
+++ b/numpy/core/tests/test_umath.py
@@ -4,7 +4,9 @@ import fnmatch
import itertools
import pytest
import sys
+import os
from fractions import Fraction
+from functools import reduce
import numpy.core.umath as ncu
from numpy.core import _umath_tests as ncu_tests
@@ -16,6 +18,20 @@ from numpy.testing import (
_gen_alignment_data, assert_array_almost_equal_nulp, assert_warns
)
+def get_glibc_version():
+ try:
+ ver = os.confstr('CS_GNU_LIBC_VERSION').rsplit(' ')[1]
+ except Exception as inst:
+ ver = '0.0'
+
+ return ver
+
+
+glibcver = get_glibc_version()
+glibc_newerthan_2_17 = pytest.mark.xfail(
+ glibcver != '0.0' and glibcver < '2.17',
+ reason="Older glibc versions may not raise appropriate FP exceptions")
+
def on_powerpc():
""" True if we are running on a Power PC platform."""
return platform.processor() == 'powerpc' or \
@@ -99,9 +115,9 @@ class TestOut:
# Out argument must be tuple, since there are multiple outputs.
r1, r2 = np.frexp(d, out=o1, subok=subok)
- assert_raises(ValueError, np.add, a, 2, o, o, subok=subok)
- assert_raises(ValueError, np.add, a, 2, o, out=o, subok=subok)
- assert_raises(ValueError, np.add, a, 2, None, out=o, subok=subok)
+ assert_raises(TypeError, np.add, a, 2, o, o, subok=subok)
+ assert_raises(TypeError, np.add, a, 2, o, out=o, subok=subok)
+ assert_raises(TypeError, np.add, a, 2, None, out=o, subok=subok)
assert_raises(ValueError, np.add, a, 2, out=(o, o), subok=subok)
assert_raises(ValueError, np.add, a, 2, out=(), subok=subok)
assert_raises(TypeError, np.add, a, 2, [], subok=subok)
@@ -249,6 +265,148 @@ class TestDivision:
assert_equal(x // 100, [0, 0, 0, 1, -1, -1, -1, -1, -2])
assert_equal(x % 100, [5, 10, 90, 0, 95, 90, 10, 0, 80])
+ @pytest.mark.parametrize("dtype,ex_val", itertools.product(
+ np.sctypes['int'] + np.sctypes['uint'], (
+ (
+ # dividend
+ "np.arange(fo.max-lsize, fo.max, dtype=dtype),"
+ # divisors
+ "np.arange(lsize, dtype=dtype),"
+ # scalar divisors
+ "range(15)"
+ ),
+ (
+ # dividend
+ "np.arange(fo.min, fo.min+lsize, dtype=dtype),"
+ # divisors
+ "np.arange(lsize//-2, lsize//2, dtype=dtype),"
+ # scalar divisors
+ "range(fo.min, fo.min + 15)"
+ ), (
+ # dividend
+ "np.arange(fo.max-lsize, fo.max, dtype=dtype),"
+ # divisors
+ "np.arange(lsize, dtype=dtype),"
+ # scalar divisors
+ "[1,3,9,13,neg, fo.min+1, fo.min//2, fo.max//3, fo.max//4]"
+ )
+ )
+ ))
+ def test_division_int_boundary(self, dtype, ex_val):
+ fo = np.iinfo(dtype)
+ neg = -1 if fo.min < 0 else 1
+ # Large enough to test SIMD loops and remaind elements
+ lsize = 512 + 7
+ a, b, divisors = eval(ex_val)
+ a_lst, b_lst = a.tolist(), b.tolist()
+
+ c_div = lambda n, d: (
+ 0 if d == 0 or (n and n == fo.min and d == -1) else n//d
+ )
+ with np.errstate(divide='ignore'):
+ ac = a.copy()
+ ac //= b
+ div_ab = a // b
+ div_lst = [c_div(x, y) for x, y in zip(a_lst, b_lst)]
+
+ msg = "Integer arrays floor division check (//)"
+ assert all(div_ab == div_lst), msg
+ msg_eq = "Integer arrays floor division check (//=)"
+ assert all(ac == div_lst), msg_eq
+
+ for divisor in divisors:
+ ac = a.copy()
+ with np.errstate(divide='ignore'):
+ div_a = a // divisor
+ ac //= divisor
+ div_lst = [c_div(i, divisor) for i in a_lst]
+
+ assert all(div_a == div_lst), msg
+ assert all(ac == div_lst), msg_eq
+
+ with np.errstate(divide='raise'):
+ if 0 in b or (fo.min and -1 in b and fo.min in a):
+ # Verify overflow case
+ with pytest.raises(FloatingPointError):
+ a // b
+ else:
+ a // b
+ if fo.min and fo.min in a:
+ with pytest.raises(FloatingPointError):
+ a // -1
+ elif fo.min:
+ a // -1
+ with pytest.raises(FloatingPointError):
+ a // 0
+ with pytest.raises(FloatingPointError):
+ ac = a.copy()
+ ac //= 0
+
+ np.array([], dtype=dtype) // 0
+
+ @pytest.mark.parametrize("dtype,ex_val", itertools.product(
+ np.sctypes['int'] + np.sctypes['uint'], (
+ "np.array([fo.max, 1, 2, 1, 1, 2, 3], dtype=dtype)",
+ "np.array([fo.min, 1, -2, 1, 1, 2, -3], dtype=dtype)",
+ "np.arange(fo.min, fo.min+(100*10), 10, dtype=dtype)",
+ "np.arange(fo.max-(100*7), fo.max, 7, dtype=dtype)",
+ )
+ ))
+ def test_division_int_reduce(self, dtype, ex_val):
+ fo = np.iinfo(dtype)
+ a = eval(ex_val)
+ lst = a.tolist()
+ c_div = lambda n, d: (
+ 0 if d == 0 or (n and n == fo.min and d == -1) else n//d
+ )
+
+ with np.errstate(divide='ignore'):
+ div_a = np.floor_divide.reduce(a)
+ div_lst = reduce(c_div, lst)
+ msg = "Reduce floor integer division check"
+ assert div_a == div_lst, msg
+
+ with np.errstate(divide='raise'):
+ with pytest.raises(FloatingPointError):
+ np.floor_divide.reduce(np.arange(-100, 100, dtype=dtype))
+ if fo.min:
+ with pytest.raises(FloatingPointError):
+ np.floor_divide.reduce(
+ np.array([fo.min, 1, -1], dtype=dtype)
+ )
+
+ @pytest.mark.parametrize(
+ "dividend,divisor,quotient",
+ [(np.timedelta64(2,'Y'), np.timedelta64(2,'M'), 12),
+ (np.timedelta64(2,'Y'), np.timedelta64(-2,'M'), -12),
+ (np.timedelta64(-2,'Y'), np.timedelta64(2,'M'), -12),
+ (np.timedelta64(-2,'Y'), np.timedelta64(-2,'M'), 12),
+ (np.timedelta64(2,'M'), np.timedelta64(-2,'Y'), -1),
+ (np.timedelta64(2,'Y'), np.timedelta64(0,'M'), 0),
+ (np.timedelta64(2,'Y'), 2, np.timedelta64(1,'Y')),
+ (np.timedelta64(2,'Y'), -2, np.timedelta64(-1,'Y')),
+ (np.timedelta64(-2,'Y'), 2, np.timedelta64(-1,'Y')),
+ (np.timedelta64(-2,'Y'), -2, np.timedelta64(1,'Y')),
+ (np.timedelta64(-2,'Y'), -2, np.timedelta64(1,'Y')),
+ (np.timedelta64(-2,'Y'), -3, np.timedelta64(0,'Y')),
+ (np.timedelta64(-2,'Y'), 0, np.timedelta64('Nat','Y')),
+ ])
+ def test_division_int_timedelta(self, dividend, divisor, quotient):
+ # If either divisor is 0 or quotient is Nat, check for division by 0
+ if divisor and (isinstance(quotient, int) or not np.isnat(quotient)):
+ msg = "Timedelta floor division check"
+ assert dividend // divisor == quotient, msg
+
+ # Test for arrays as well
+ msg = "Timedelta arrays floor division check"
+ dividend_array = np.array([dividend]*5)
+ quotient_array = np.array([quotient]*5)
+ assert all(dividend_array // divisor == quotient_array), msg
+ else:
+ with np.errstate(divide='raise', invalid='raise'):
+ with pytest.raises(FloatingPointError):
+ dividend // divisor
+
def test_division_complex(self):
# check that implementation is correct
msg = "Complex division implementation check"
@@ -275,16 +433,14 @@ class TestDivision:
assert_(np.isnan(y)[0])
def test_floor_division_complex(self):
- # check that implementation is correct
- msg = "Complex floor division implementation check"
+ # check that floor division, divmod and remainder raises type errors
x = np.array([.9 + 1j, -.1 + 1j, .9 + .5*1j, .9 + 2.*1j], dtype=np.complex128)
- y = np.array([0., -1., 0., 0.], dtype=np.complex128)
- assert_equal(np.floor_divide(x**2, x), y, err_msg=msg)
- # check overflow, underflow
- msg = "Complex floor division overflow/underflow check"
- x = np.array([1.e+110, 1.e-110], dtype=np.complex128)
- y = np.floor_divide(x**2, x)
- assert_equal(y, [1.e+110, 0], err_msg=msg)
+ with pytest.raises(TypeError):
+ x // 7
+ with pytest.raises(TypeError):
+ np.divmod(x, 7)
+ with pytest.raises(TypeError):
+ np.remainder(x, 7)
def test_floor_division_signed_zero(self):
# Check that the sign bit is correctly set when dividing positive and
@@ -302,10 +458,15 @@ class TestDivision:
# divide by zero error check
with np.errstate(divide='raise', invalid='ignore'):
assert_raises(FloatingPointError, np.floor_divide, fone, fzer)
- with np.errstate(invalid='raise'):
- assert_raises(FloatingPointError, np.floor_divide, fnan, fone)
- assert_raises(FloatingPointError, np.floor_divide, fone, fnan)
- assert_raises(FloatingPointError, np.floor_divide, fnan, fzer)
+ with np.errstate(divide='ignore', invalid='raise'):
+ np.floor_divide(fone, fzer)
+
+ # The following already contain a NaN and should not warn
+ with np.errstate(all='raise'):
+ np.floor_divide(fnan, fone)
+ np.floor_divide(fone, fnan)
+ np.floor_divide(fnan, fzer)
+ np.floor_divide(fzer, fnan)
@pytest.mark.parametrize('dtype', np.typecodes['Float'])
def test_floor_division_corner_cases(self, dtype):
@@ -402,6 +563,9 @@ class TestRemainder:
else:
assert_(b > rem >= 0, msg)
+ @pytest.mark.xfail(sys.platform.startswith("darwin"),
+ reason="MacOS seems to not give the correct 'invalid' warning for "
+ "`fmod`. Hopefully, others always do.")
@pytest.mark.parametrize('dtype', np.typecodes['Float'])
def test_float_divmod_errors(self, dtype):
# Check valid errors raised for divmod and remainder
@@ -422,8 +586,12 @@ class TestRemainder:
with np.errstate(divide='ignore', invalid='raise'):
assert_raises(FloatingPointError, np.divmod, finf, fzero)
with np.errstate(divide='raise', invalid='ignore'):
- assert_raises(FloatingPointError, np.divmod, finf, fzero)
+ # inf / 0 does not set any flags, only the modulo creates a NaN
+ np.divmod(finf, fzero)
+ @pytest.mark.xfail(sys.platform.startswith("darwin"),
+ reason="MacOS seems to not give the correct 'invalid' warning for "
+ "`fmod`. Hopefully, others always do.")
@pytest.mark.parametrize('dtype', np.typecodes['Float'])
@pytest.mark.parametrize('fn', [np.fmod, np.remainder])
def test_float_remainder_errors(self, dtype, fn):
@@ -431,11 +599,16 @@ class TestRemainder:
fone = np.array(1.0, dtype=dtype)
finf = np.array(np.inf, dtype=dtype)
fnan = np.array(np.nan, dtype=dtype)
- with np.errstate(invalid='raise'):
- assert_raises(FloatingPointError, fn, fone, fzero)
- assert_raises(FloatingPointError, fn, fnan, fzero)
- assert_raises(FloatingPointError, fn, fone, fnan)
- assert_raises(FloatingPointError, fn, fnan, fone)
+
+ # The following already contain a NaN and should not warn.
+ with np.errstate(all='raise'):
+ with pytest.raises(FloatingPointError,
+ match="invalid value"):
+ fn(fone, fzero)
+ fn(fnan, fzero)
+ fn(fzero, fnan)
+ fn(fone, fnan)
+ fn(fnan, fone)
def test_float_remainder_overflow(self):
a = np.finfo(np.float64).tiny
@@ -697,20 +870,20 @@ class TestFloat_power:
class TestLog2:
- def test_log2_values(self):
+ @pytest.mark.parametrize('dt', ['f', 'd', 'g'])
+ def test_log2_values(self, dt):
x = [1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024]
y = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
- for dt in ['f', 'd', 'g']:
- xf = np.array(x, dtype=dt)
- yf = np.array(y, dtype=dt)
- assert_almost_equal(np.log2(xf), yf)
+ xf = np.array(x, dtype=dt)
+ yf = np.array(y, dtype=dt)
+ assert_almost_equal(np.log2(xf), yf)
- def test_log2_ints(self):
+ @pytest.mark.parametrize("i", range(1, 65))
+ def test_log2_ints(self, i):
# a good log2 implementation should provide this,
# might fail on OS with bad libm
- for i in range(1, 65):
- v = np.log2(2.**i)
- assert_equal(v, float(i), err_msg='at exponent %d' % i)
+ v = np.log2(2.**i)
+ assert_equal(v, float(i), err_msg='at exponent %d' % i)
def test_log2_special(self):
assert_equal(np.log2(1.), 0.)
@@ -843,31 +1016,74 @@ class TestSpecialFloats:
yf = np.array(y, dtype=dt)
assert_equal(np.exp(yf), xf)
+ # Older version of glibc may not raise the correct FP exceptions
+ # See: https://github.com/numpy/numpy/issues/19192
+ @glibc_newerthan_2_17
+ def test_exp_exceptions(self):
with np.errstate(over='raise'):
assert_raises(FloatingPointError, np.exp, np.float32(100.))
assert_raises(FloatingPointError, np.exp, np.float32(1E19))
assert_raises(FloatingPointError, np.exp, np.float64(800.))
assert_raises(FloatingPointError, np.exp, np.float64(1E19))
+ with np.errstate(under='raise'):
+ assert_raises(FloatingPointError, np.exp, np.float32(-1000.))
+ assert_raises(FloatingPointError, np.exp, np.float32(-1E19))
+ assert_raises(FloatingPointError, np.exp, np.float64(-1000.))
+ assert_raises(FloatingPointError, np.exp, np.float64(-1E19))
+
def test_log_values(self):
with np.errstate(all='ignore'):
- x = [np.nan, np.nan, np.inf, np.nan, -np.inf, np.nan]
- y = [np.nan, -np.nan, np.inf, -np.inf, 0., -1.0]
+ x = [np.nan, np.nan, np.inf, np.nan, -np.inf, np.nan]
+ y = [np.nan, -np.nan, np.inf, -np.inf, 0.0, -1.0]
+ y1p = [np.nan, -np.nan, np.inf, -np.inf, -1.0, -2.0]
for dt in ['f', 'd', 'g']:
xf = np.array(x, dtype=dt)
yf = np.array(y, dtype=dt)
+ yf1p = np.array(y1p, dtype=dt)
assert_equal(np.log(yf), xf)
+ assert_equal(np.log2(yf), xf)
+ assert_equal(np.log10(yf), xf)
+ assert_equal(np.log1p(yf1p), xf)
with np.errstate(divide='raise'):
- assert_raises(FloatingPointError, np.log, np.float32(0.))
+ for dt in ['f', 'd']:
+ assert_raises(FloatingPointError, np.log,
+ np.array(0.0, dtype=dt))
+ assert_raises(FloatingPointError, np.log2,
+ np.array(0.0, dtype=dt))
+ assert_raises(FloatingPointError, np.log10,
+ np.array(0.0, dtype=dt))
+ assert_raises(FloatingPointError, np.log1p,
+ np.array(-1.0, dtype=dt))
with np.errstate(invalid='raise'):
- assert_raises(FloatingPointError, np.log, np.float32(-np.inf))
- assert_raises(FloatingPointError, np.log, np.float32(-1.0))
+ for dt in ['f', 'd']:
+ assert_raises(FloatingPointError, np.log,
+ np.array(-np.inf, dtype=dt))
+ assert_raises(FloatingPointError, np.log,
+ np.array(-1.0, dtype=dt))
+ assert_raises(FloatingPointError, np.log2,
+ np.array(-np.inf, dtype=dt))
+ assert_raises(FloatingPointError, np.log2,
+ np.array(-1.0, dtype=dt))
+ assert_raises(FloatingPointError, np.log10,
+ np.array(-np.inf, dtype=dt))
+ assert_raises(FloatingPointError, np.log10,
+ np.array(-1.0, dtype=dt))
+ assert_raises(FloatingPointError, np.log1p,
+ np.array(-np.inf, dtype=dt))
+ assert_raises(FloatingPointError, np.log1p,
+ np.array(-2.0, dtype=dt))
+
+ # See https://github.com/numpy/numpy/issues/18005
+ with assert_no_warnings():
+ a = np.array(1e9, dtype='float32')
+ np.log(a)
def test_sincos_values(self):
with np.errstate(all='ignore'):
- x = [np.nan, np.nan, np.nan, np.nan]
+ x = [np.nan, np.nan, np.nan, np.nan]
y = [np.nan, -np.nan, np.inf, -np.inf]
for dt in ['f', 'd', 'g']:
xf = np.array(x, dtype=dt)
@@ -881,18 +1097,19 @@ class TestSpecialFloats:
assert_raises(FloatingPointError, np.cos, np.float32(-np.inf))
assert_raises(FloatingPointError, np.cos, np.float32(np.inf))
- def test_sqrt_values(self):
+ @pytest.mark.parametrize('dt', ['f', 'd', 'g'])
+ def test_sqrt_values(self, dt):
with np.errstate(all='ignore'):
- x = [np.nan, np.nan, np.inf, np.nan, 0.]
+ x = [np.nan, np.nan, np.inf, np.nan, 0.]
y = [np.nan, -np.nan, np.inf, -np.inf, 0.]
- for dt in ['f', 'd', 'g']:
- xf = np.array(x, dtype=dt)
- yf = np.array(y, dtype=dt)
- assert_equal(np.sqrt(yf), xf)
+ xf = np.array(x, dtype=dt)
+ yf = np.array(y, dtype=dt)
+ assert_equal(np.sqrt(yf), xf)
- #with np.errstate(invalid='raise'):
- # for dt in ['f', 'd', 'g']:
- # assert_raises(FloatingPointError, np.sqrt, np.array(-100., dtype=dt))
+ # with np.errstate(invalid='raise'):
+ # assert_raises(
+ # FloatingPointError, np.sqrt, np.array(-100., dtype=dt)
+ # )
def test_abs_values(self):
x = [np.nan, np.nan, np.inf, np.inf, 0., 0., 1.0, 1.0]
@@ -912,8 +1129,10 @@ class TestSpecialFloats:
assert_equal(np.square(yf), xf)
with np.errstate(over='raise'):
- assert_raises(FloatingPointError, np.square, np.array(1E32, dtype='f'))
- assert_raises(FloatingPointError, np.square, np.array(1E200, dtype='d'))
+ assert_raises(FloatingPointError, np.square,
+ np.array(1E32, dtype='f'))
+ assert_raises(FloatingPointError, np.square,
+ np.array(1E200, dtype='d'))
def test_reciprocal_values(self):
with np.errstate(all='ignore'):
@@ -926,7 +1145,153 @@ class TestSpecialFloats:
with np.errstate(divide='raise'):
for dt in ['f', 'd', 'g']:
- assert_raises(FloatingPointError, np.reciprocal, np.array(-0.0, dtype=dt))
+ assert_raises(FloatingPointError, np.reciprocal,
+ np.array(-0.0, dtype=dt))
+
+ def test_tan(self):
+ with np.errstate(all='ignore'):
+ in_ = [np.nan, -np.nan, 0.0, -0.0, np.inf, -np.inf]
+ out = [np.nan, np.nan, 0.0, -0.0, np.nan, np.nan]
+ for dt in ['f', 'd']:
+ in_arr = np.array(in_, dtype=dt)
+ out_arr = np.array(out, dtype=dt)
+ assert_equal(np.tan(in_arr), out_arr)
+
+ with np.errstate(invalid='raise'):
+ for dt in ['f', 'd']:
+ assert_raises(FloatingPointError, np.tan,
+ np.array(np.inf, dtype=dt))
+ assert_raises(FloatingPointError, np.tan,
+ np.array(-np.inf, dtype=dt))
+
+ def test_arcsincos(self):
+ with np.errstate(all='ignore'):
+ in_ = [np.nan, -np.nan, np.inf, -np.inf]
+ out = [np.nan, np.nan, np.nan, np.nan]
+ for dt in ['f', 'd']:
+ in_arr = np.array(in_, dtype=dt)
+ out_arr = np.array(out, dtype=dt)
+ assert_equal(np.arcsin(in_arr), out_arr)
+ assert_equal(np.arccos(in_arr), out_arr)
+
+ for callable in [np.arcsin, np.arccos]:
+ for value in [np.inf, -np.inf, 2.0, -2.0]:
+ for dt in ['f', 'd']:
+ with np.errstate(invalid='raise'):
+ assert_raises(FloatingPointError, callable,
+ np.array(value, dtype=dt))
+
+ def test_arctan(self):
+ with np.errstate(all='ignore'):
+ in_ = [np.nan, -np.nan]
+ out = [np.nan, np.nan]
+ for dt in ['f', 'd']:
+ in_arr = np.array(in_, dtype=dt)
+ out_arr = np.array(out, dtype=dt)
+ assert_equal(np.arctan(in_arr), out_arr)
+
+ def test_sinh(self):
+ in_ = [np.nan, -np.nan, np.inf, -np.inf]
+ out = [np.nan, np.nan, np.inf, -np.inf]
+ for dt in ['f', 'd']:
+ in_arr = np.array(in_, dtype=dt)
+ out_arr = np.array(out, dtype=dt)
+ assert_equal(np.sinh(in_arr), out_arr)
+
+ with np.errstate(over='raise'):
+ assert_raises(FloatingPointError, np.sinh,
+ np.array(120.0, dtype='f'))
+ assert_raises(FloatingPointError, np.sinh,
+ np.array(1200.0, dtype='d'))
+
+ def test_cosh(self):
+ in_ = [np.nan, -np.nan, np.inf, -np.inf]
+ out = [np.nan, np.nan, np.inf, np.inf]
+ for dt in ['f', 'd']:
+ in_arr = np.array(in_, dtype=dt)
+ out_arr = np.array(out, dtype=dt)
+ assert_equal(np.cosh(in_arr), out_arr)
+
+ with np.errstate(over='raise'):
+ assert_raises(FloatingPointError, np.cosh,
+ np.array(120.0, dtype='f'))
+ assert_raises(FloatingPointError, np.cosh,
+ np.array(1200.0, dtype='d'))
+
+ def test_tanh(self):
+ in_ = [np.nan, -np.nan, np.inf, -np.inf]
+ out = [np.nan, np.nan, 1.0, -1.0]
+ for dt in ['f', 'd']:
+ in_arr = np.array(in_, dtype=dt)
+ out_arr = np.array(out, dtype=dt)
+ assert_equal(np.tanh(in_arr), out_arr)
+
+ def test_arcsinh(self):
+ in_ = [np.nan, -np.nan, np.inf, -np.inf]
+ out = [np.nan, np.nan, np.inf, -np.inf]
+ for dt in ['f', 'd']:
+ in_arr = np.array(in_, dtype=dt)
+ out_arr = np.array(out, dtype=dt)
+ assert_equal(np.arcsinh(in_arr), out_arr)
+
+ def test_arccosh(self):
+ with np.errstate(all='ignore'):
+ in_ = [np.nan, -np.nan, np.inf, -np.inf, 1.0, 0.0]
+ out = [np.nan, np.nan, np.inf, np.nan, 0.0, np.nan]
+ for dt in ['f', 'd']:
+ in_arr = np.array(in_, dtype=dt)
+ out_arr = np.array(out, dtype=dt)
+ assert_equal(np.arccosh(in_arr), out_arr)
+
+ for value in [0.0, -np.inf]:
+ with np.errstate(invalid='raise'):
+ for dt in ['f', 'd']:
+ assert_raises(FloatingPointError, np.arccosh,
+ np.array(value, dtype=dt))
+
+ def test_arctanh(self):
+ with np.errstate(all='ignore'):
+ in_ = [np.nan, -np.nan, np.inf, -np.inf, 1.0, -1.0, 2.0]
+ out = [np.nan, np.nan, np.nan, np.nan, np.inf, -np.inf, np.nan]
+ for dt in ['f', 'd']:
+ in_arr = np.array(in_, dtype=dt)
+ out_arr = np.array(out, dtype=dt)
+ assert_equal(np.arctanh(in_arr), out_arr)
+
+ for value in [1.01, np.inf, -np.inf, 1.0, -1.0]:
+ with np.errstate(invalid='raise', divide='raise'):
+ for dt in ['f', 'd']:
+ assert_raises(FloatingPointError, np.arctanh,
+ np.array(value, dtype=dt))
+
+ def test_exp2(self):
+ with np.errstate(all='ignore'):
+ in_ = [np.nan, -np.nan, np.inf, -np.inf]
+ out = [np.nan, np.nan, np.inf, 0.0]
+ for dt in ['f', 'd']:
+ in_arr = np.array(in_, dtype=dt)
+ out_arr = np.array(out, dtype=dt)
+ assert_equal(np.exp2(in_arr), out_arr)
+
+ for value in [2000.0, -2000.0]:
+ with np.errstate(over='raise', under='raise'):
+ for dt in ['f', 'd']:
+ assert_raises(FloatingPointError, np.exp2,
+ np.array(value, dtype=dt))
+
+ def test_expm1(self):
+ with np.errstate(all='ignore'):
+ in_ = [np.nan, -np.nan, np.inf, -np.inf]
+ out = [np.nan, np.nan, np.inf, -1.0]
+ for dt in ['f', 'd']:
+ in_arr = np.array(in_, dtype=dt)
+ out_arr = np.array(out, dtype=dt)
+ assert_equal(np.expm1(in_arr), out_arr)
+
+ for value in [200.0, 2000.0]:
+ with np.errstate(over='raise'):
+ assert_raises(FloatingPointError, np.expm1,
+ np.array(value, dtype='f'))
class TestFPClass:
@pytest.mark.parametrize("stride", [-4,-2,-1,1,2,4])
@@ -1886,7 +2251,7 @@ class TestSpecialMethods:
_wrap_args = None
_prepare_args = None
def __new__(cls):
- return np.empty(()).view(cls)
+ return np.zeros(()).view(cls)
def __array_wrap__(self, obj, context):
self._wrap_args = context[1]
return obj
@@ -1929,6 +2294,10 @@ class TestSpecialMethods:
do_test(lambda a: np.add(0, 0, out=a), lambda a: (0, 0, a))
do_test(lambda a: np.add(0, 0, out=(a,)), lambda a: (0, 0, a))
+ # Also check the where mask handling:
+ do_test(lambda a: np.add(a, 0, where=False), lambda a: (a, 0))
+ do_test(lambda a: np.add(0, 0, a, where=False), lambda a: (0, 0, a))
+
def test_wrap_with_iterable(self):
# test fix for bug #1026:
@@ -2078,7 +2447,8 @@ class TestSpecialMethods:
assert_equal(x, np.zeros(1))
assert_equal(type(x), np.ndarray)
- def test_prepare(self):
+ @pytest.mark.parametrize("use_where", [True, False])
+ def test_prepare(self, use_where):
class with_prepare(np.ndarray):
__array_priority__ = 10
@@ -2088,11 +2458,15 @@ class TestSpecialMethods:
return np.array(arr).view(type=with_prepare)
a = np.array(1).view(type=with_prepare)
- x = np.add(a, a)
+ if use_where:
+ x = np.add(a, a, where=np.array(True))
+ else:
+ x = np.add(a, a)
assert_equal(x, np.array(2))
assert_equal(type(x), with_prepare)
- def test_prepare_out(self):
+ @pytest.mark.parametrize("use_where", [True, False])
+ def test_prepare_out(self, use_where):
class with_prepare(np.ndarray):
__array_priority__ = 10
@@ -2101,7 +2475,10 @@ class TestSpecialMethods:
return np.array(arr).view(type=with_prepare)
a = np.array([1]).view(type=with_prepare)
- x = np.add(a, a, a)
+ if use_where:
+ x = np.add(a, a, a, where=[True])
+ else:
+ x = np.add(a, a, a)
# Returned array is new, because of the strange
# __array_prepare__ above
assert_(not np.shares_memory(x, a))
@@ -2119,10 +2496,11 @@ class TestSpecialMethods:
a = A()
assert_raises(RuntimeError, ncu.maximum, a, a)
+ assert_raises(RuntimeError, ncu.maximum, a, a, where=False)
def test_array_too_many_args(self):
- class A(object):
+ class A:
def __array__(self, dtype, context):
return np.zeros(1)
@@ -2298,12 +2676,14 @@ class TestSpecialMethods:
# __call__
a = A()
- res = np.multiply.__call__(1, a, foo='bar', answer=42)
+ with assert_raises(TypeError):
+ np.multiply.__call__(1, a, foo='bar', answer=42)
+ res = np.multiply.__call__(1, a, subok='bar', where=42)
assert_equal(res[0], a)
assert_equal(res[1], np.multiply)
assert_equal(res[2], '__call__')
assert_equal(res[3], (1, a))
- assert_equal(res[4], {'foo': 'bar', 'answer': 42})
+ assert_equal(res[4], {'subok': 'bar', 'where': 42})
# __call__, wrong args
assert_raises(TypeError, np.multiply, a)
@@ -2509,7 +2889,7 @@ class TestSpecialMethods:
assert_raises(TypeError, np.multiply, a, b, 'one', out='two')
assert_raises(TypeError, np.multiply, a, b, 'one', 'two')
assert_raises(ValueError, np.multiply, a, b, out=('one', 'two'))
- assert_raises(ValueError, np.multiply, a, out=())
+ assert_raises(TypeError, np.multiply, a, out=())
assert_raises(TypeError, np.modf, a, 'one', out=('two', 'three'))
assert_raises(TypeError, np.modf, a, 'one', 'two', 'three')
assert_raises(ValueError, np.modf, a, out=('one', 'two', 'three'))
@@ -2637,8 +3017,8 @@ class TestSpecialMethods:
if out_no:
info['outputs'] = out_no
- results = super(A, self).__array_ufunc__(ufunc, method,
- *args, **kwargs)
+ results = super().__array_ufunc__(ufunc, method,
+ *args, **kwargs)
if results is NotImplemented:
return NotImplemented
@@ -3137,7 +3517,7 @@ class TestSubclass:
assert_equal(a+a, a)
-class TestFrompyfunc(object):
+class TestFrompyfunc:
def test_identity(self):
def mul(a, b):
@@ -3260,8 +3640,14 @@ def test_nextafterl():
def test_nextafter_0():
for t, direction in itertools.product(np.sctypes['float'], (1, -1)):
- tiny = np.finfo(t).tiny
- assert_(0. < direction * np.nextafter(t(0), t(direction)) < tiny)
+ # The value of tiny for double double is NaN, so we need to pass the
+ # assert
+ with suppress_warnings() as sup:
+ sup.filter(UserWarning)
+ if not np.isnan(np.finfo(t).tiny):
+ tiny = np.finfo(t).tiny
+ assert_(
+ 0. < direction * np.nextafter(t(0), t(direction)) < tiny)
assert_equal(np.nextafter(t(0), t(direction)) / t(2.1), direction * 0.0)
def _test_spacing(t):
diff --git a/numpy/core/tests/test_umath_accuracy.py b/numpy/core/tests/test_umath_accuracy.py
index 33080edbb..a703c697a 100644
--- a/numpy/core/tests/test_umath_accuracy.py
+++ b/numpy/core/tests/test_umath_accuracy.py
@@ -1,5 +1,6 @@
import numpy as np
import platform
+import os
from os import path
import sys
import pytest
@@ -28,17 +29,15 @@ def convert(s, datatype="np.float32"):
return fp.contents.value # dereference the pointer, get the float
str_to_float = np.vectorize(convert)
-files = ['umath-validation-set-exp',
- 'umath-validation-set-log',
- 'umath-validation-set-sin',
- 'umath-validation-set-cos']
class TestAccuracy:
@platform_skip
def test_validate_transcendentals(self):
with np.errstate(all='ignore'):
+ data_dir = path.join(path.dirname(__file__), 'data')
+ files = os.listdir(data_dir)
+ files = list(filter(lambda f: f.endswith('.csv'), files))
for filename in files:
- data_dir = path.join(path.dirname(__file__), 'data')
filepath = path.join(data_dir, filename)
with open(filepath) as fid:
file_without_comments = (r for r in fid if not r[0] in ('$', '#'))
@@ -47,7 +46,8 @@ class TestAccuracy:
names=('type','input','output','ulperr'),
delimiter=',',
skip_header=1)
- npfunc = getattr(np, filename.split('-')[3])
+ npname = path.splitext(filename)[0].split('-')[3]
+ npfunc = getattr(np, npname)
for datatype in np.unique(data['type']):
data_subset = data[data['type'] == datatype]
inval = np.array(str_to_float(data_subset['input'].astype(str), data_subset['type'].astype(str)), dtype=eval(datatype))
diff --git a/numpy/core/tests/test_umath_complex.py b/numpy/core/tests/test_umath_complex.py
index 90a349da1..c051cd61b 100644
--- a/numpy/core/tests/test_umath_complex.py
+++ b/numpy/core/tests/test_umath_complex.py
@@ -541,7 +541,7 @@ def check_complex_value(f, x1, y1, x2, y2, exact=True):
else:
assert_almost_equal(f(z1), z2)
-class TestSpecialComplexAVX(object):
+class TestSpecialComplexAVX:
@pytest.mark.parametrize("stride", [-4,-2,-1,1,2,4])
@pytest.mark.parametrize("astype", [np.complex64, np.complex128])
def test_array(self, stride, astype):
@@ -568,7 +568,7 @@ class TestSpecialComplexAVX(object):
with np.errstate(invalid='ignore'):
assert_equal(np.square(arr[::stride]), sq_true[::stride])
-class TestComplexAbsoluteAVX(object):
+class TestComplexAbsoluteAVX:
@pytest.mark.parametrize("arraysize", [1,2,3,4,5,6,7,8,9,10,11,13,15,17,18,19])
@pytest.mark.parametrize("stride", [-4,-3,-2,-1,1,2,3,4])
@pytest.mark.parametrize("astype", [np.complex64, np.complex128])
@@ -579,7 +579,7 @@ class TestComplexAbsoluteAVX(object):
assert_equal(np.abs(arr[::stride]), abs_true[::stride])
# Testcase taken as is from https://github.com/numpy/numpy/issues/16660
-class TestComplexAbsoluteMixedDTypes(object):
+class TestComplexAbsoluteMixedDTypes:
@pytest.mark.parametrize("stride", [-4,-3,-2,-1,1,2,3,4])
@pytest.mark.parametrize("astype", [np.complex64, np.complex128])
@pytest.mark.parametrize("func", ['abs', 'square', 'conjugate'])
diff --git a/numpy/ctypeslib.py b/numpy/ctypeslib.py
index e8f7750fe..8ba6f15e5 100644
--- a/numpy/ctypeslib.py
+++ b/numpy/ctypeslib.py
@@ -4,7 +4,7 @@
============================
See Also
----------
+--------
load_library : Load a C library.
ndpointer : Array restype/argtype with verification.
as_ctypes : Create a ctypes array from an ndarray.
@@ -49,11 +49,12 @@ Then, we're ready to call ``foo_func``:
>>> _lib.foo_func(out, len(out)) #doctest: +SKIP
"""
-__all__ = ['load_library', 'ndpointer', 'c_intp', 'as_ctypes', 'as_array']
+__all__ = ['load_library', 'ndpointer', 'c_intp', 'as_ctypes', 'as_array',
+ 'as_ctypes_type']
import os
from numpy import (
- integer, ndarray, dtype as _dtype, array, frombuffer
+ integer, ndarray, dtype as _dtype, asarray, frombuffer
)
from numpy.core.multiarray import _flagdict, flagsobj
@@ -514,7 +515,7 @@ if ctypes is not None:
p_arr_type = ctypes.POINTER(_ctype_ndarray(obj._type_, shape))
obj = ctypes.cast(obj, p_arr_type).contents
- return array(obj, copy=False)
+ return asarray(obj)
def as_ctypes(obj):
diff --git a/numpy/ctypeslib.pyi b/numpy/ctypeslib.pyi
index cacc97d68..642017ba7 100644
--- a/numpy/ctypeslib.pyi
+++ b/numpy/ctypeslib.pyi
@@ -1,7 +1,15 @@
-from typing import Any
+from typing import List, Type
-load_library: Any
-ndpointer: Any
-c_intp: Any
-as_ctypes: Any
-as_array: Any
+# NOTE: Numpy's mypy plugin is used for importing the correct
+# platform-specific `ctypes._SimpleCData[int]` sub-type
+from ctypes import c_int64 as _c_intp
+
+__all__: List[str]
+
+c_intp = _c_intp
+
+def load_library(libname, loader_path): ...
+def ndpointer(dtype=..., ndim=..., shape=..., flags=...): ...
+def as_ctypes(obj): ...
+def as_array(obj, shape=...): ...
+def as_ctypes_type(dtype): ...
diff --git a/numpy/distutils/ccompiler.py b/numpy/distutils/ccompiler.py
index 106436e64..6d063ee4e 100644
--- a/numpy/distutils/ccompiler.py
+++ b/numpy/distutils/ccompiler.py
@@ -26,10 +26,8 @@ from numpy.distutils.misc_util import cyg2win32, is_sequence, mingw32, \
_commandline_dep_string
# globals for parallel build management
-try:
- import threading
-except ImportError:
- import dummy_threading as threading
+import threading
+
_job_semaphore = None
_global_lock = threading.Lock()
_processing_files = set()
@@ -386,6 +384,13 @@ def CCompiler_customize_cmd(self, cmd, ignore=()):
"""
log.info('customize %s using %s' % (self.__class__.__name__,
cmd.__class__.__name__))
+
+ if hasattr(self, 'compiler') and 'clang' in self.compiler[0]:
+ # clang defaults to a non-strict floating error point model.
+ # Since NumPy and most Python libs give warnings for these, override:
+ self.compiler.append('-ftrapping-math')
+ self.compiler_so.append('-ftrapping-math')
+
def allow(attr):
return getattr(cmd, attr, None) is not None and attr not in ignore
diff --git a/numpy/distutils/ccompiler_opt.py b/numpy/distutils/ccompiler_opt.py
index 3eba6e32a..47d07ad4a 100644
--- a/numpy/distutils/ccompiler_opt.py
+++ b/numpy/distutils/ccompiler_opt.py
@@ -259,7 +259,7 @@ class _Config:
AVX512_SKX = dict(
interest=42, implies="AVX512CD", group="AVX512VL AVX512BW AVX512DQ",
detect="AVX512_SKX", implies_detect=False,
- extra_checks="AVX512BW_MASK"
+ extra_checks="AVX512BW_MASK AVX512DQ_MASK"
),
AVX512_CLX = dict(
interest=43, implies="AVX512_SKX", group="AVX512VNNI",
@@ -276,7 +276,7 @@ class _Config:
),
# IBM/Power
## Power7/ISA 2.06
- VSX = dict(interest=1, headers="altivec.h"),
+ VSX = dict(interest=1, headers="altivec.h", extra_checks="VSX_ASM"),
## Power8/ISA 2.07
VSX2 = dict(interest=2, implies="VSX", implies_detect=False),
## Power9/ISA 3.00
@@ -543,16 +543,16 @@ class _Distutils:
def __init__(self, ccompiler):
self._ccompiler = ccompiler
- def dist_compile(self, sources, flags, **kwargs):
+ def dist_compile(self, sources, flags, ccompiler=None, **kwargs):
"""Wrap CCompiler.compile()"""
assert(isinstance(sources, list))
assert(isinstance(flags, list))
flags = kwargs.pop("extra_postargs", []) + flags
- return self._ccompiler.compile(
- sources, extra_postargs=flags, **kwargs
- )
+ if not ccompiler:
+ ccompiler = self._ccompiler
+ return ccompiler.compile(sources, extra_postargs=flags, **kwargs)
- def dist_test(self, source, flags):
+ def dist_test(self, source, flags, macros=[]):
"""Return True if 'CCompiler.compile()' able to compile
a source file with certain flags.
"""
@@ -569,7 +569,7 @@ class _Distutils:
test = False
try:
self.dist_compile(
- [source], flags, output_dir=self.conf_tmp_path
+ [source], flags, macros=macros, output_dir=self.conf_tmp_path
)
test = True
except CompileError as e:
@@ -579,45 +579,41 @@ class _Distutils:
return test
def dist_info(self):
- """Return a string containing all environment information, required
- by the abstract class '_CCompiler' to discovering the platform
- environment, also used as a cache factor in order to detect
- any changes from outside.
+ """
+ Return a tuple containing info about (platform, compiler, extra_args),
+ required by the abstract class '_CCompiler' for discovering the
+ platform environment. This is also used as a cache factor in order
+ to detect any changes happening from outside.
"""
if hasattr(self, "_dist_info"):
return self._dist_info
- # play it safe
- cc_info = ""
- compiler = getattr(self._ccompiler, "compiler", None)
- if compiler is not None:
- if isinstance(compiler, str):
- cc_info += compiler
- elif hasattr(compiler, "__iter__"):
- cc_info += ' '.join(compiler)
- # in case if 'compiler' attribute doesn't provide anything
- cc_type = getattr(self._ccompiler, "compiler_type", "")
- if cc_type in ("intelem", "intelemw", "mingw64"):
- cc_info += "x86_64"
+
+ cc_type = getattr(self._ccompiler, "compiler_type", '')
+ if cc_type in ("intelem", "intelemw"):
+ platform = "x86_64"
elif cc_type in ("intel", "intelw", "intele"):
- cc_info += "x86"
- elif cc_type in ("msvc", "mingw32"):
- import platform
- if platform.architecture()[0] == "32bit":
- cc_info += "x86"
+ platform = "x86"
+ else:
+ from distutils.util import get_platform
+ platform = get_platform()
+
+ cc_info = getattr(self._ccompiler, "compiler", getattr(self._ccompiler, "compiler_so", ''))
+ if not cc_type or cc_type == "unix":
+ if hasattr(cc_info, "__iter__"):
+ compiler = cc_info[0]
else:
- cc_info += "x86_64"
+ compiler = str(cc_info)
else:
- # the last hope, too bad for cross-compiling
- import platform
- cc_info += platform.machine()
+ compiler = cc_type
- cc_info += cc_type
- cflags = os.environ.get("CFLAGS", "")
- if cflags not in cc_info:
- cc_info += cflags
+ if hasattr(cc_info, "__iter__") and len(cc_info) > 1:
+ extra_args = ' '.join(cc_info[1:])
+ else:
+ extra_args = os.environ.get("CFLAGS", "")
+ extra_args += os.environ.get("CPPFLAGS", "")
- self._dist_info = cc_info
- return cc_info
+ self._dist_info = (platform, compiler, extra_args)
+ return self._dist_info
@staticmethod
def dist_error(*args):
@@ -751,12 +747,14 @@ class _Cache:
self.cache_me = {}
self.cache_private = set()
self.cache_infile = False
+ self._cache_path = None
if self.conf_nocache:
self.dist_log("cache is disabled by `Config`")
return
- chash = self.cache_hash(*factors, *self.conf_cache_factors)
+ self._cache_hash = self.cache_hash(*factors, *self.conf_cache_factors)
+ self._cache_path = cache_path
if cache_path:
if os.path.exists(cache_path):
self.dist_log("load cache from file ->", cache_path)
@@ -769,7 +767,7 @@ class _Cache:
elif not hasattr(cache_mod, "hash") or \
not hasattr(cache_mod, "data"):
self.dist_log("invalid cache file", stderr=True)
- elif chash == cache_mod.hash:
+ elif self._cache_hash == cache_mod.hash:
self.dist_log("hit the file cache")
for attr, val in cache_mod.data.items():
setattr(self, attr, val)
@@ -777,10 +775,8 @@ class _Cache:
else:
self.dist_log("miss the file cache")
- atexit.register(self._cache_write, cache_path, chash)
-
if not self.cache_infile:
- other_cache = _share_cache.get(chash)
+ other_cache = _share_cache.get(self._cache_hash)
if other_cache:
self.dist_log("hit the memory cache")
for attr, val in other_cache.__dict__.items():
@@ -789,32 +785,41 @@ class _Cache:
continue
setattr(self, attr, val)
- _share_cache[chash] = self
+ _share_cache[self._cache_hash] = self
+ atexit.register(self.cache_flush)
def __del__(self):
- # TODO: remove the cache form share on del
- pass
+ for h, o in _share_cache.items():
+ if o == self:
+ _share_cache.pop(h)
+ break
- def _cache_write(self, cache_path, cache_hash):
+ def cache_flush(self):
+ """
+ Force update the cache.
+ """
+ if not self._cache_path:
+ return
# TODO: don't write if the cache doesn't change
- self.dist_log("write cache to path ->", cache_path)
- for attr in list(self.__dict__.keys()):
+ self.dist_log("write cache to path ->", self._cache_path)
+ cdict = self.__dict__.copy()
+ for attr in self.__dict__.keys():
if re.match(self._cache_ignore, attr):
- self.__dict__.pop(attr)
+ cdict.pop(attr)
- d = os.path.dirname(cache_path)
+ d = os.path.dirname(self._cache_path)
if not os.path.exists(d):
os.makedirs(d)
- repr_dict = pprint.pformat(self.__dict__, compact=True)
- with open(cache_path, "w") as f:
+ repr_dict = pprint.pformat(cdict, compact=True)
+ with open(self._cache_path, "w") as f:
f.write(textwrap.dedent("""\
# AUTOGENERATED DON'T EDIT
# Please make changes to the code generator \
(distutils/ccompiler_opt.py)
hash = {}
data = \\
- """).format(cache_hash))
+ """).format(self._cache_hash))
f.write(repr_dict)
def cache_hash(self, *factors):
@@ -845,7 +850,7 @@ class _Cache:
return ccb
return cache_wrap_me
-class _CCompiler(object):
+class _CCompiler:
"""A helper class for `CCompilerOpt` containing all utilities that
related to the fundamental compiler's functions.
@@ -893,57 +898,56 @@ class _CCompiler(object):
def __init__(self):
if hasattr(self, "cc_is_cached"):
return
- to_detect = (
- # attr regex
- (
- ("cc_on_x64", "^(x|x86_|amd)64"),
- ("cc_on_x86", "^(x86|i386|i686)"),
- ("cc_on_ppc64le", "^(powerpc|ppc)64(el|le)"),
- ("cc_on_ppc64", "^(powerpc|ppc)64"),
- ("cc_on_armhf", "^arm"),
- ("cc_on_aarch64", "^aarch64"),
- # priority is given to first of string
- # if it fail we search in the rest, due
- # to append platform.machine() at the end,
- # check method 'dist_info()' for more clarification.
- ("cc_on_x64", ".*(x|x86_|amd)64.*"),
- ("cc_on_x86", ".*(x86|i386|i686).*"),
- ("cc_on_ppc64le", ".*(powerpc|ppc)64(el|le).*"),
- ("cc_on_ppc64", ".*(powerpc|ppc)64.*"),
- ("cc_on_armhf", ".*arm.*"),
- ("cc_on_aarch64", ".*aarch64.*"),
- # undefined platform
- ("cc_on_noarch", ""),
- ),
- (
- ("cc_is_gcc", r".*(gcc|gnu\-g).*"),
- ("cc_is_clang", ".*clang.*"),
- ("cc_is_iccw", ".*(intelw|intelemw|iccw).*"), # intel msvc like
- ("cc_is_icc", ".*(intel|icc).*"), # intel unix like
- ("cc_is_msvc", ".*msvc.*"),
- ("cc_is_nocc", ""),
- ),
- (("cc_has_debug", ".*(O0|Od|ggdb|coverage|debug:full).*"),),
- (("cc_has_native", ".*(-march=native|-xHost|/QxHost).*"),),
- # in case if the class run with -DNPY_DISABLE_OPTIMIZATION
- (("cc_noopt", ".*DISABLE_OPT.*"),),
+ # attr regex
+ detect_arch = (
+ ("cc_on_x64", ".*(x|x86_|amd)64.*"),
+ ("cc_on_x86", ".*(win32|x86|i386|i686).*"),
+ ("cc_on_ppc64le", ".*(powerpc|ppc)64(el|le).*"),
+ ("cc_on_ppc64", ".*(powerpc|ppc)64.*"),
+ ("cc_on_aarch64", ".*(aarch64|arm64).*"),
+ ("cc_on_armhf", ".*arm.*"),
+ # undefined platform
+ ("cc_on_noarch", ""),
+ )
+ detect_compiler = (
+ ("cc_is_gcc", r".*(gcc|gnu\-g).*"),
+ ("cc_is_clang", ".*clang.*"),
+ ("cc_is_iccw", ".*(intelw|intelemw|iccw).*"), # intel msvc like
+ ("cc_is_icc", ".*(intel|icc).*"), # intel unix like
+ ("cc_is_msvc", ".*msvc.*"),
+ # undefined compiler will be treat it as gcc
+ ("cc_is_nocc", ""),
+ )
+ detect_args = (
+ ("cc_has_debug", ".*(O0|Od|ggdb|coverage|debug:full).*"),
+ ("cc_has_native", ".*(-march=native|-xHost|/QxHost).*"),
+ # in case if the class run with -DNPY_DISABLE_OPTIMIZATION
+ ("cc_noopt", ".*DISABLE_OPT.*"),
)
- for section in to_detect:
- for attr, rgex in section:
- setattr(self, attr, False)
dist_info = self.dist_info()
- for section in to_detect:
+ platform, compiler_info, extra_args = dist_info
+ # set False to all attrs
+ for section in (detect_arch, detect_compiler, detect_args):
for attr, rgex in section:
- if rgex and not re.match(rgex, dist_info, re.IGNORECASE):
+ setattr(self, attr, False)
+
+ for detect, searchin in ((detect_arch, platform), (detect_compiler, compiler_info)):
+ for attr, rgex in detect:
+ if rgex and not re.match(rgex, searchin, re.IGNORECASE):
continue
setattr(self, attr, True)
break
+ for attr, rgex in detect_args:
+ if rgex and not re.match(rgex, extra_args, re.IGNORECASE):
+ continue
+ setattr(self, attr, True)
+
if self.cc_on_noarch:
self.dist_log(
- "unable to detect CPU arch via compiler info, "
- "optimization is disabled \ninfo << %s >> " % dist_info,
+ "unable to detect CPU architecture which lead to disable the optimization. "
+ f"check dist_info:<<\n{dist_info}\n>>",
stderr=True
)
self.cc_noopt = True
@@ -958,8 +962,9 @@ class _CCompiler(object):
but still has the same gcc optimization flags.
"""
self.dist_log(
- "unable to detect compiler name via info <<\n%s\n>> "
- "treating it as a gcc" % dist_info,
+ "unable to detect compiler type which leads to treating it as GCC. "
+ "this is a normal behavior if you're using gcc-like compiler such as MinGW or IBM/XLC."
+ f"check dist_info:<<\n{dist_info}\n>>",
stderr=True
)
self.cc_is_gcc = True
@@ -1167,20 +1172,23 @@ class _Feature:
self.feature_is_cached = True
- def feature_names(self, names=None, force_flags=None):
+ def feature_names(self, names=None, force_flags=None, macros=[]):
"""
Returns a set of CPU feature names that supported by platform and the **C** compiler.
Parameters
----------
- 'names': sequence or None, optional
+ names: sequence or None, optional
Specify certain CPU features to test it against the **C** compiler.
if None(default), it will test all current supported features.
**Note**: feature names must be in upper-case.
- 'force_flags': list or None, optional
- If None(default), default compiler flags for every CPU feature will be used
- during the test.
+ force_flags: list or None, optional
+ If None(default), default compiler flags for every CPU feature will
+ be used during the test.
+
+ macros : list of tuples, optional
+ A list of C macro definitions.
"""
assert(
names is None or (
@@ -1193,7 +1201,9 @@ class _Feature:
names = self.feature_supported.keys()
supported_names = set()
for f in names:
- if self.feature_is_supported(f, force_flags=force_flags):
+ if self.feature_is_supported(
+ f, force_flags=force_flags, macros=macros
+ ):
supported_names.add(f)
return supported_names
@@ -1428,20 +1438,23 @@ class _Feature:
return self.cc_normalize_flags(flags)
@_Cache.me
- def feature_test(self, name, force_flags=None):
+ def feature_test(self, name, force_flags=None, macros=[]):
"""
Test a certain CPU feature against the compiler through its own
check file.
Parameters
----------
- 'name': str
+ name: str
Supported CPU feature name.
- 'force_flags': list or None, optional
+ force_flags: list or None, optional
If None(default), the returned flags from `feature_flags()`
will be used.
- """
+
+ macros : list of tuples, optional
+ A list of C macro definitions.
+ """
if force_flags is None:
force_flags = self.feature_flags(name)
@@ -1457,24 +1470,29 @@ class _Feature:
if not os.path.exists(test_path):
self.dist_fatal("feature test file is not exist", test_path)
- test = self.dist_test(test_path, force_flags + self.cc_flags["werror"])
+ test = self.dist_test(
+ test_path, force_flags + self.cc_flags["werror"], macros=macros
+ )
if not test:
self.dist_log("testing failed", stderr=True)
return test
@_Cache.me
- def feature_is_supported(self, name, force_flags=None):
+ def feature_is_supported(self, name, force_flags=None, macros=[]):
"""
Check if a certain CPU feature is supported by the platform and compiler.
Parameters
----------
- 'name': str
+ name: str
CPU feature name in uppercase.
- 'force_flags': list or None, optional
- If None(default), default compiler flags for every CPU feature will be used
- during test.
+ force_flags: list or None, optional
+ If None(default), default compiler flags for every CPU feature will
+ be used during test.
+
+ macros : list of tuples, optional
+ A list of C macro definitions.
"""
assert(name.isupper())
assert(force_flags is None or isinstance(force_flags, list))
@@ -1482,9 +1500,9 @@ class _Feature:
supported = name in self.feature_supported
if supported:
for impl in self.feature_implies(name):
- if not self.feature_test(impl, force_flags):
+ if not self.feature_test(impl, force_flags, macros=macros):
return False
- if not self.feature_test(name, force_flags):
+ if not self.feature_test(name, force_flags, macros=macros):
return False
return supported
@@ -1774,7 +1792,7 @@ class _Parse:
tokens = tokens[start_pos:end_pos]
return self._parse_target_tokens(tokens)
- _parse_regex_arg = re.compile(r'\s|[,]|([+-])')
+ _parse_regex_arg = re.compile(r'\s|,|([+-])')
def _parse_arg_features(self, arg_name, req_features):
if not isinstance(req_features, str):
self.dist_fatal("expected a string in '%s'" % arg_name)
@@ -1807,7 +1825,9 @@ class _Parse:
self.dist_fatal(arg_name,
"native option isn't supported by the compiler"
)
- features_to = self.feature_names(force_flags=native)
+ features_to = self.feature_names(
+ force_flags=native, macros=[("DETECT_FEATURES", 1)]
+ )
elif TOK == "MAX":
features_to = self.feature_supported.keys()
elif TOK == "MIN":
@@ -2147,7 +2167,7 @@ class CCompilerOpt(_Config, _Distutils, _Cache, _CCompiler, _Feature, _Parse):
"""
return self.parse_dispatch_names
- def try_dispatch(self, sources, src_dir=None, **kwargs):
+ def try_dispatch(self, sources, src_dir=None, ccompiler=None, **kwargs):
"""
Compile one or more dispatch-able sources and generates object files,
also generates abstract C config headers and macros that
@@ -2170,6 +2190,11 @@ class CCompilerOpt(_Config, _Distutils, _Cache, _CCompiler, _Feature, _Parse):
Path of parent directory for the generated headers and wrapped sources.
If None(default) the files will generated in-place.
+ ccompiler: CCompiler
+ Distutils `CCompiler` instance to be used for compilation.
+ If None (default), the provided instance during the initialization
+ will be used instead.
+
**kwargs : any
Arguments to pass on to the `CCompiler.compile()`
@@ -2224,13 +2249,15 @@ class CCompilerOpt(_Config, _Distutils, _Cache, _CCompiler, _Feature, _Parse):
# among them.
objects = []
for flags, srcs in to_compile.items():
- objects += self.dist_compile(srcs, list(flags), **kwargs)
+ objects += self.dist_compile(
+ srcs, list(flags), ccompiler=ccompiler, **kwargs
+ )
return objects
def generate_dispatch_header(self, header_path):
"""
- Generate the dispatch header which containing all definitions
- and headers of instruction-sets for the enabled CPU baseline and
+ Generate the dispatch header which contains the #definitions and headers
+ for platform-specific instruction-sets for the enabled CPU baseline and
dispatch-able features.
Its highly recommended to take a look at the generated header
@@ -2244,6 +2271,14 @@ class CCompilerOpt(_Config, _Distutils, _Cache, _CCompiler, _Feature, _Parse):
baseline_len = len(baseline_names)
dispatch_len = len(dispatch_names)
+ header_dir = os.path.dirname(header_path)
+ if not os.path.exists(header_dir):
+ self.dist_log(
+ f"dispatch header dir {header_dir} does not exist, creating it",
+ stderr=True
+ )
+ os.makedirs(header_dir)
+
with open(header_path, 'w') as f:
baseline_calls = ' \\\n'.join([
(
@@ -2304,19 +2339,25 @@ class CCompilerOpt(_Config, _Distutils, _Cache, _CCompiler, _Feature, _Parse):
def report(self, full=False):
report = []
+ platform_rows = []
baseline_rows = []
dispatch_rows = []
+ report.append(("Platform", platform_rows))
+ report.append(("", ""))
report.append(("CPU baseline", baseline_rows))
report.append(("", ""))
report.append(("CPU dispatch", dispatch_rows))
+ ########## platform ##########
+ platform_rows.append(("Architecture", (
+ "unsupported" if self.cc_on_noarch else self.cc_march)
+ ))
+ platform_rows.append(("Compiler", (
+ "unix-like" if self.cc_is_nocc else self.cc_name)
+ ))
########## baseline ##########
if self.cc_noopt:
- baseline_rows.append((
- "Requested", "optimization disabled %s" % (
- "(unsupported arch)" if self.cc_on_noarch else ""
- )
- ))
+ baseline_rows.append(("Requested", "optimization disabled"))
else:
baseline_rows.append(("Requested", repr(self._requested_baseline)))
@@ -2337,11 +2378,7 @@ class CCompilerOpt(_Config, _Distutils, _Cache, _CCompiler, _Feature, _Parse):
########## dispatch ##########
if self.cc_noopt:
- dispatch_rows.append((
- "Requested", "optimization disabled %s" % (
- "(unsupported arch)" if self.cc_on_noarch else ""
- )
- ))
+ baseline_rows.append(("Requested", "optimization disabled"))
else:
dispatch_rows.append(("Requested", repr(self._requested_dispatch)))
@@ -2448,7 +2485,8 @@ class CCompilerOpt(_Config, _Distutils, _Cache, _CCompiler, _Feature, _Parse):
return wrap_path
def _generate_config(self, output_dir, dispatch_src, targets, has_baseline=False):
- config_path = os.path.basename(dispatch_src).replace(".c", ".h")
+ config_path = os.path.basename(dispatch_src)
+ config_path = os.path.splitext(config_path)[0] + '.h'
config_path = os.path.join(output_dir, config_path)
# check if targets didn't change to avoid recompiling
cache_hash = self.cache_hash(targets, has_baseline)
@@ -2506,30 +2544,24 @@ class CCompilerOpt(_Config, _Distutils, _Cache, _CCompiler, _Feature, _Parse):
))
return False
-def new_ccompiler_opt(compiler, **kwargs):
+def new_ccompiler_opt(compiler, dispatch_hpath, **kwargs):
"""
Create a new instance of 'CCompilerOpt' and generate the dispatch header
- inside NumPy source dir.
+ which contains the #definitions and headers of platform-specific instruction-sets for
+ the enabled CPU baseline and dispatch-able features.
Parameters
----------
- 'compiler' : CCompiler instance
- '**kwargs': passed as-is to `CCompilerOpt(...)`
+ compiler : CCompiler instance
+ dispatch_hpath : str
+ path of the dispatch header
+ **kwargs: passed as-is to `CCompilerOpt(...)`
Returns
-------
new instance of CCompilerOpt
"""
opt = CCompilerOpt(compiler, **kwargs)
- npy_path = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
- header_dir = os.path.join(npy_path, *("core/src/common".split("/")))
- header_path = os.path.join(header_dir, "_cpu_dispatch.h")
- if not os.path.exists(header_path) or not opt.is_cached():
- if not os.path.exists(header_dir):
- opt.dist_log(
- "dispatch header dir '%s' isn't exist, creating it" % header_dir,
- stderr=True
- )
- os.makedirs(header_dir)
- opt.generate_dispatch_header(header_path)
+ if not os.path.exists(dispatch_hpath) or not opt.is_cached():
+ opt.generate_dispatch_header(dispatch_hpath)
return opt
diff --git a/numpy/distutils/checks/cpu_avx.c b/numpy/distutils/checks/cpu_avx.c
index 737c0d2e9..26ae18466 100644
--- a/numpy/distutils/checks/cpu_avx.c
+++ b/numpy/distutils/checks/cpu_avx.c
@@ -1,7 +1,20 @@
+#if defined(DETECT_FEATURES) && defined(__INTEL_COMPILER)
+ /*
+ * Unlike GCC and CLANG, Intel Compiler exposes all supported intrinsics,
+ * whether or not the build options for those features are specified.
+ * Therefore, we must test #definitions of CPU features when option native/host
+ * is enabled via `--cpu-baseline` or through env var `CFLAGS` otherwise
+ * the test will be broken and leads to enable all possible features.
+ */
+ #ifndef __AVX__
+ #error "HOST/ARCH doesn't support AVX"
+ #endif
+#endif
+
#include <immintrin.h>
-int main(void)
+int main(int argc, char **argv)
{
- __m256 a = _mm256_add_ps(_mm256_setzero_ps(), _mm256_setzero_ps());
+ __m256 a = _mm256_add_ps(_mm256_loadu_ps((const float*)argv[argc-1]), _mm256_loadu_ps((const float*)argv[1]));
return (int)_mm_cvtss_f32(_mm256_castps256_ps128(a));
}
diff --git a/numpy/distutils/checks/cpu_avx2.c b/numpy/distutils/checks/cpu_avx2.c
index dfb11fd79..ddde868f1 100644
--- a/numpy/distutils/checks/cpu_avx2.c
+++ b/numpy/distutils/checks/cpu_avx2.c
@@ -1,7 +1,20 @@
+#if defined(DETECT_FEATURES) && defined(__INTEL_COMPILER)
+ /*
+ * Unlike GCC and CLANG, Intel Compiler exposes all supported intrinsics,
+ * whether or not the build options for those features are specified.
+ * Therefore, we must test #definitions of CPU features when option native/host
+ * is enabled via `--cpu-baseline` or through env var `CFLAGS` otherwise
+ * the test will be broken and leads to enable all possible features.
+ */
+ #ifndef __AVX2__
+ #error "HOST/ARCH doesn't support AVX2"
+ #endif
+#endif
+
#include <immintrin.h>
-int main(void)
+int main(int argc, char **argv)
{
- __m256i a = _mm256_abs_epi16(_mm256_setzero_si256());
+ __m256i a = _mm256_abs_epi16(_mm256_loadu_si256((const __m256i*)argv[argc-1]));
return _mm_cvtsi128_si32(_mm256_castsi256_si128(a));
}
diff --git a/numpy/distutils/checks/cpu_avx512_clx.c b/numpy/distutils/checks/cpu_avx512_clx.c
index 71dad83a7..81edcd067 100644
--- a/numpy/distutils/checks/cpu_avx512_clx.c
+++ b/numpy/distutils/checks/cpu_avx512_clx.c
@@ -1,8 +1,22 @@
+#if defined(DETECT_FEATURES) && defined(__INTEL_COMPILER)
+ /*
+ * Unlike GCC and CLANG, Intel Compiler exposes all supported intrinsics,
+ * whether or not the build options for those features are specified.
+ * Therefore, we must test #definitions of CPU features when option native/host
+ * is enabled via `--cpu-baseline` or through env var `CFLAGS` otherwise
+ * the test will be broken and leads to enable all possible features.
+ */
+ #ifndef __AVX512VNNI__
+ #error "HOST/ARCH doesn't support CascadeLake AVX512 features"
+ #endif
+#endif
+
#include <immintrin.h>
-int main(void)
+int main(int argc, char **argv)
{
/* VNNI */
- __m512i a = _mm512_dpbusd_epi32(_mm512_setzero_si512(), _mm512_setzero_si512(), _mm512_setzero_si512());
+ __m512i a = _mm512_loadu_si512((const __m512i*)argv[argc-1]);
+ a = _mm512_dpbusd_epi32(a, _mm512_setzero_si512(), a);
return _mm_cvtsi128_si32(_mm512_castsi512_si128(a));
}
diff --git a/numpy/distutils/checks/cpu_avx512_cnl.c b/numpy/distutils/checks/cpu_avx512_cnl.c
index dfab4436d..5799f122b 100644
--- a/numpy/distutils/checks/cpu_avx512_cnl.c
+++ b/numpy/distutils/checks/cpu_avx512_cnl.c
@@ -1,10 +1,24 @@
+#if defined(DETECT_FEATURES) && defined(__INTEL_COMPILER)
+ /*
+ * Unlike GCC and CLANG, Intel Compiler exposes all supported intrinsics,
+ * whether or not the build options for those features are specified.
+ * Therefore, we must test #definitions of CPU features when option native/host
+ * is enabled via `--cpu-baseline` or through env var `CFLAGS` otherwise
+ * the test will be broken and leads to enable all possible features.
+ */
+ #if !defined(__AVX512VBMI__) || !defined(__AVX512IFMA__)
+ #error "HOST/ARCH doesn't support CannonLake AVX512 features"
+ #endif
+#endif
+
#include <immintrin.h>
-int main(void)
+int main(int argc, char **argv)
{
+ __m512i a = _mm512_loadu_si512((const __m512i*)argv[argc-1]);
/* IFMA */
- __m512i a = _mm512_madd52hi_epu64(_mm512_setzero_si512(), _mm512_setzero_si512(), _mm512_setzero_si512());
+ a = _mm512_madd52hi_epu64(a, a, _mm512_setzero_si512());
/* VMBI */
- a = _mm512_permutex2var_epi8(a, _mm512_setzero_si512(), _mm512_setzero_si512());
+ a = _mm512_permutex2var_epi8(a, _mm512_setzero_si512(), a);
return _mm_cvtsi128_si32(_mm512_castsi512_si128(a));
}
diff --git a/numpy/distutils/checks/cpu_avx512_icl.c b/numpy/distutils/checks/cpu_avx512_icl.c
index cf2706b3b..3cf44d731 100644
--- a/numpy/distutils/checks/cpu_avx512_icl.c
+++ b/numpy/distutils/checks/cpu_avx512_icl.c
@@ -1,9 +1,23 @@
+#if defined(DETECT_FEATURES) && defined(__INTEL_COMPILER)
+ /*
+ * Unlike GCC and CLANG, Intel Compiler exposes all supported intrinsics,
+ * whether or not the build options for those features are specified.
+ * Therefore, we must test #definitions of CPU features when option native/host
+ * is enabled via `--cpu-baseline` or through env var `CFLAGS` otherwise
+ * the test will be broken and leads to enable all possible features.
+ */
+ #if !defined(__AVX512VPOPCNTDQ__) || !defined(__AVX512BITALG__) || !defined(__AVX512VPOPCNTDQ__)
+ #error "HOST/ARCH doesn't support IceLake AVX512 features"
+ #endif
+#endif
+
#include <immintrin.h>
-int main(void)
+int main(int argc, char **argv)
{
+ __m512i a = _mm512_loadu_si512((const __m512i*)argv[argc-1]);
/* VBMI2 */
- __m512i a = _mm512_shrdv_epi64(_mm512_setzero_si512(), _mm512_setzero_si512(), _mm512_setzero_si512());
+ a = _mm512_shrdv_epi64(a, a, _mm512_setzero_si512());
/* BITLAG */
a = _mm512_popcnt_epi8(a);
/* VPOPCNTDQ */
diff --git a/numpy/distutils/checks/cpu_avx512_knl.c b/numpy/distutils/checks/cpu_avx512_knl.c
index 0699f37a6..b3f4f6976 100644
--- a/numpy/distutils/checks/cpu_avx512_knl.c
+++ b/numpy/distutils/checks/cpu_avx512_knl.c
@@ -1,10 +1,24 @@
+#if defined(DETECT_FEATURES) && defined(__INTEL_COMPILER)
+ /*
+ * Unlike GCC and CLANG, Intel Compiler exposes all supported intrinsics,
+ * whether or not the build options for those features are specified.
+ * Therefore, we must test #definitions of CPU features when option native/host
+ * is enabled via `--cpu-baseline` or through env var `CFLAGS` otherwise
+ * the test will be broken and leads to enable all possible features.
+ */
+ #if !defined(__AVX512ER__) || !defined(__AVX512PF__)
+ #error "HOST/ARCH doesn't support Knights Landing AVX512 features"
+ #endif
+#endif
+
#include <immintrin.h>
-int main(void)
+int main(int argc, char **argv)
{
int base[128];
+ __m512d ad = _mm512_loadu_pd((const __m512d*)argv[argc-1]);
/* ER */
- __m512i a = _mm512_castpd_si512(_mm512_exp2a23_pd(_mm512_setzero_pd()));
+ __m512i a = _mm512_castpd_si512(_mm512_exp2a23_pd(ad));
/* PF */
_mm512_mask_prefetch_i64scatter_pd(base, _mm512_cmpeq_epi64_mask(a, a), a, 1, _MM_HINT_T1);
return base[0];
diff --git a/numpy/distutils/checks/cpu_avx512_knm.c b/numpy/distutils/checks/cpu_avx512_knm.c
index db61b4bfa..2c426462b 100644
--- a/numpy/distutils/checks/cpu_avx512_knm.c
+++ b/numpy/distutils/checks/cpu_avx512_knm.c
@@ -1,9 +1,22 @@
+#if defined(DETECT_FEATURES) && defined(__INTEL_COMPILER)
+ /*
+ * Unlike GCC and CLANG, Intel Compiler exposes all supported intrinsics,
+ * whether or not the build options for those features are specified.
+ * Therefore, we must test #definitions of CPU features when option native/host
+ * is enabled via `--cpu-baseline` or through env var `CFLAGS` otherwise
+ * the test will be broken and leads to enable all possible features.
+ */
+ #if !defined(__AVX5124FMAPS__) || !defined(__AVX5124VNNIW__) || !defined(__AVX512VPOPCNTDQ__)
+ #error "HOST/ARCH doesn't support Knights Mill AVX512 features"
+ #endif
+#endif
+
#include <immintrin.h>
-int main(void)
+int main(int argc, char **argv)
{
- __m512i a = _mm512_setzero_si512();
- __m512 b = _mm512_setzero_ps();
+ __m512i a = _mm512_loadu_si512((const __m512i*)argv[argc-1]);
+ __m512 b = _mm512_loadu_ps((const __m512*)argv[argc-2]);
/* 4FMAPS */
b = _mm512_4fmadd_ps(b, b, b, b, b, NULL);
diff --git a/numpy/distutils/checks/cpu_avx512_skx.c b/numpy/distutils/checks/cpu_avx512_skx.c
index 1d5e15b5e..8840efb7e 100644
--- a/numpy/distutils/checks/cpu_avx512_skx.c
+++ b/numpy/distutils/checks/cpu_avx512_skx.c
@@ -1,9 +1,23 @@
+#if defined(DETECT_FEATURES) && defined(__INTEL_COMPILER)
+ /*
+ * Unlike GCC and CLANG, Intel Compiler exposes all supported intrinsics,
+ * whether or not the build options for those features are specified.
+ * Therefore, we must test #definitions of CPU features when option native/host
+ * is enabled via `--cpu-baseline` or through env var `CFLAGS` otherwise
+ * the test will be broken and leads to enable all possible features.
+ */
+ #if !defined(__AVX512VL__) || !defined(__AVX512BW__) || !defined(__AVX512DQ__)
+ #error "HOST/ARCH doesn't support SkyLake AVX512 features"
+ #endif
+#endif
+
#include <immintrin.h>
-int main(void)
+int main(int argc, char **argv)
{
+ __m512i aa = _mm512_abs_epi32(_mm512_loadu_si512((const __m512i*)argv[argc-1]));
/* VL */
- __m256i a = _mm256_abs_epi64(_mm256_setzero_si256());
+ __m256i a = _mm256_abs_epi64(_mm512_extracti64x4_epi64(aa, 1));
/* DQ */
__m512i b = _mm512_broadcast_i32x8(a);
/* BW */
diff --git a/numpy/distutils/checks/cpu_avx512cd.c b/numpy/distutils/checks/cpu_avx512cd.c
index 61bef6b82..5e29c79e3 100644
--- a/numpy/distutils/checks/cpu_avx512cd.c
+++ b/numpy/distutils/checks/cpu_avx512cd.c
@@ -1,7 +1,20 @@
+#if defined(DETECT_FEATURES) && defined(__INTEL_COMPILER)
+ /*
+ * Unlike GCC and CLANG, Intel Compiler exposes all supported intrinsics,
+ * whether or not the build options for those features are specified.
+ * Therefore, we must test #definitions of CPU features when option native/host
+ * is enabled via `--cpu-baseline` or through env var `CFLAGS` otherwise
+ * the test will be broken and leads to enable all possible features.
+ */
+ #ifndef __AVX512CD__
+ #error "HOST/ARCH doesn't support AVX512CD"
+ #endif
+#endif
+
#include <immintrin.h>
-int main(void)
+int main(int argc, char **argv)
{
- __m512i a = _mm512_lzcnt_epi32(_mm512_setzero_si512());
+ __m512i a = _mm512_lzcnt_epi32(_mm512_loadu_si512((const __m512i*)argv[argc-1]));
return _mm_cvtsi128_si32(_mm512_castsi512_si128(a));
}
diff --git a/numpy/distutils/checks/cpu_avx512f.c b/numpy/distutils/checks/cpu_avx512f.c
index f60cc09dd..d0eb7b1ad 100644
--- a/numpy/distutils/checks/cpu_avx512f.c
+++ b/numpy/distutils/checks/cpu_avx512f.c
@@ -1,7 +1,20 @@
+#if defined(DETECT_FEATURES) && defined(__INTEL_COMPILER)
+ /*
+ * Unlike GCC and CLANG, Intel Compiler exposes all supported intrinsics,
+ * whether or not the build options for those features are specified.
+ * Therefore, we must test #definitions of CPU features when option native/host
+ * is enabled via `--cpu-baseline` or through env var `CFLAGS` otherwise
+ * the test will be broken and leads to enable all possible features.
+ */
+ #ifndef __AVX512F__
+ #error "HOST/ARCH doesn't support AVX512F"
+ #endif
+#endif
+
#include <immintrin.h>
-int main(void)
+int main(int argc, char **argv)
{
- __m512i a = _mm512_abs_epi32(_mm512_setzero_si512());
+ __m512i a = _mm512_abs_epi32(_mm512_loadu_si512((const __m512i*)argv[argc-1]));
return _mm_cvtsi128_si32(_mm512_castsi512_si128(a));
}
diff --git a/numpy/distutils/checks/cpu_f16c.c b/numpy/distutils/checks/cpu_f16c.c
index a5a343e2d..fdf36cec5 100644
--- a/numpy/distutils/checks/cpu_f16c.c
+++ b/numpy/distutils/checks/cpu_f16c.c
@@ -1,9 +1,22 @@
+#if defined(DETECT_FEATURES) && defined(__INTEL_COMPILER)
+ /*
+ * Unlike GCC and CLANG, Intel Compiler exposes all supported intrinsics,
+ * whether or not the build options for those features are specified.
+ * Therefore, we must test #definitions of CPU features when option native/host
+ * is enabled via `--cpu-baseline` or through env var `CFLAGS` otherwise
+ * the test will be broken and leads to enable all possible features.
+ */
+ #ifndef __F16C__
+ #error "HOST/ARCH doesn't support F16C"
+ #endif
+#endif
+
#include <emmintrin.h>
#include <immintrin.h>
-int main(void)
+int main(int argc, char **argv)
{
- __m128 a = _mm_cvtph_ps(_mm_setzero_si128());
- __m256 a8 = _mm256_cvtph_ps(_mm_setzero_si128());
+ __m128 a = _mm_cvtph_ps(_mm_loadu_si128((const __m128i*)argv[argc-1]));
+ __m256 a8 = _mm256_cvtph_ps(_mm_loadu_si128((const __m128i*)argv[argc-2]));
return (int)(_mm_cvtss_f32(a) + _mm_cvtss_f32(_mm256_castps256_ps128(a8)));
}
diff --git a/numpy/distutils/checks/cpu_fma3.c b/numpy/distutils/checks/cpu_fma3.c
index cf34c6cb1..bfeef22b5 100644
--- a/numpy/distutils/checks/cpu_fma3.c
+++ b/numpy/distutils/checks/cpu_fma3.c
@@ -1,8 +1,22 @@
+#if defined(DETECT_FEATURES) && defined(__INTEL_COMPILER)
+ /*
+ * Unlike GCC and CLANG, Intel Compiler exposes all supported intrinsics,
+ * whether or not the build options for those features are specified.
+ * Therefore, we must test #definitions of CPU features when option native/host
+ * is enabled via `--cpu-baseline` or through env var `CFLAGS` otherwise
+ * the test will be broken and leads to enable all possible features.
+ */
+ #if !defined(__FMA__) && !defined(__AVX2__)
+ #error "HOST/ARCH doesn't support FMA3"
+ #endif
+#endif
+
#include <xmmintrin.h>
#include <immintrin.h>
-int main(void)
+int main(int argc, char **argv)
{
- __m256 a = _mm256_fmadd_ps(_mm256_setzero_ps(), _mm256_setzero_ps(), _mm256_setzero_ps());
+ __m256 a = _mm256_loadu_ps((const float*)argv[argc-1]);
+ a = _mm256_fmadd_ps(a, a, a);
return (int)_mm_cvtss_f32(_mm256_castps256_ps128(a));
}
diff --git a/numpy/distutils/checks/cpu_fma4.c b/numpy/distutils/checks/cpu_fma4.c
index 1ad717033..0ff17a483 100644
--- a/numpy/distutils/checks/cpu_fma4.c
+++ b/numpy/distutils/checks/cpu_fma4.c
@@ -5,8 +5,9 @@
#include <x86intrin.h>
#endif
-int main(void)
+int main(int argc, char **argv)
{
- __m256 a = _mm256_macc_ps(_mm256_setzero_ps(), _mm256_setzero_ps(), _mm256_setzero_ps());
+ __m256 a = _mm256_loadu_ps((const float*)argv[argc-1]);
+ a = _mm256_macc_ps(a, a, a);
return (int)_mm_cvtss_f32(_mm256_castps256_ps128(a));
}
diff --git a/numpy/distutils/checks/cpu_popcnt.c b/numpy/distutils/checks/cpu_popcnt.c
index e6a80fb40..813c461f0 100644
--- a/numpy/distutils/checks/cpu_popcnt.c
+++ b/numpy/distutils/checks/cpu_popcnt.c
@@ -1,23 +1,32 @@
+#if defined(DETECT_FEATURES) && defined(__INTEL_COMPILER)
+ /*
+ * Unlike GCC and CLANG, Intel Compiler exposes all supported intrinsics,
+ * whether or not the build options for those features are specified.
+ * Therefore, we must test #definitions of CPU features when option native/host
+ * is enabled via `--cpu-baseline` or through env vr `CFLAGS` otherwise
+ * the test will be broken and leads to enable all possible features.
+ */
+ #if !defined(__SSE4_2__) && !defined(__POPCNT__)
+ #error "HOST/ARCH doesn't support POPCNT"
+ #endif
+#endif
+
#ifdef _MSC_VER
#include <nmmintrin.h>
#else
#include <popcntintrin.h>
#endif
-int main(void)
+int main(int argc, char **argv)
{
- long long a = 0;
- int b;
-#ifdef _MSC_VER
- #ifdef _M_X64
- a = _mm_popcnt_u64(1);
- #endif
- b = _mm_popcnt_u32(1);
-#else
- #ifdef __x86_64__
- a = __builtin_popcountll(1);
- #endif
- b = __builtin_popcount(1);
+ // To make sure popcnt instructions are generated
+ // and been tested against the assembler
+ unsigned long long a = *((unsigned long long*)argv[argc-1]);
+ unsigned int b = *((unsigned int*)argv[argc-2]);
+
+#if defined(_M_X64) || defined(__x86_64__)
+ a = _mm_popcnt_u64(a);
#endif
+ b = _mm_popcnt_u32(b);
return (int)a + b;
}
diff --git a/numpy/distutils/checks/cpu_sse.c b/numpy/distutils/checks/cpu_sse.c
index bb98bf63c..602b74e7b 100644
--- a/numpy/distutils/checks/cpu_sse.c
+++ b/numpy/distutils/checks/cpu_sse.c
@@ -1,3 +1,16 @@
+#if defined(DETECT_FEATURES) && defined(__INTEL_COMPILER)
+ /*
+ * Unlike GCC and CLANG, Intel Compiler exposes all supported intrinsics,
+ * whether or not the build options for those features are specified.
+ * Therefore, we must test #definitions of CPU features when option native/host
+ * is enabled via `--cpu-baseline` or through env var `CFLAGS` otherwise
+ * the test will be broken and leads to enable all possible features.
+ */
+ #ifndef __SSE__
+ #error "HOST/ARCH doesn't support SSE"
+ #endif
+#endif
+
#include <xmmintrin.h>
int main(void)
diff --git a/numpy/distutils/checks/cpu_sse2.c b/numpy/distutils/checks/cpu_sse2.c
index 658afc9b4..33826a9ed 100644
--- a/numpy/distutils/checks/cpu_sse2.c
+++ b/numpy/distutils/checks/cpu_sse2.c
@@ -1,3 +1,16 @@
+#if defined(DETECT_FEATURES) && defined(__INTEL_COMPILER)
+ /*
+ * Unlike GCC and CLANG, Intel Compiler exposes all supported intrinsics,
+ * whether or not the build options for those features are specified.
+ * Therefore, we must test #definitions of CPU features when option native/host
+ * is enabled via `--cpu-baseline` or through env var `CFLAGS` otherwise
+ * the test will be broken and leads to enable all possible features.
+ */
+ #ifndef __SSE2__
+ #error "HOST/ARCH doesn't support SSE2"
+ #endif
+#endif
+
#include <emmintrin.h>
int main(void)
diff --git a/numpy/distutils/checks/cpu_sse3.c b/numpy/distutils/checks/cpu_sse3.c
index aece1e601..d47c20f74 100644
--- a/numpy/distutils/checks/cpu_sse3.c
+++ b/numpy/distutils/checks/cpu_sse3.c
@@ -1,3 +1,16 @@
+#if defined(DETECT_FEATURES) && defined(__INTEL_COMPILER)
+ /*
+ * Unlike GCC and CLANG, Intel Compiler exposes all supported intrinsics,
+ * whether or not the build options for those features are specified.
+ * Therefore, we must test #definitions of CPU features when option native/host
+ * is enabled via `--cpu-baseline` or through env var `CFLAGS` otherwise
+ * the test will be broken and leads to enable all possible features.
+ */
+ #ifndef __SSE3__
+ #error "HOST/ARCH doesn't support SSE3"
+ #endif
+#endif
+
#include <pmmintrin.h>
int main(void)
diff --git a/numpy/distutils/checks/cpu_sse41.c b/numpy/distutils/checks/cpu_sse41.c
index bfdb9feac..7c80238a3 100644
--- a/numpy/distutils/checks/cpu_sse41.c
+++ b/numpy/distutils/checks/cpu_sse41.c
@@ -1,3 +1,16 @@
+#if defined(DETECT_FEATURES) && defined(__INTEL_COMPILER)
+ /*
+ * Unlike GCC and CLANG, Intel Compiler exposes all supported intrinsics,
+ * whether or not the build options for those features are specified.
+ * Therefore, we must test #definitions of CPU features when option native/host
+ * is enabled via `--cpu-baseline` or through env var `CFLAGS` otherwise
+ * the test will be broken and leads to enable all possible features.
+ */
+ #ifndef __SSE4_1__
+ #error "HOST/ARCH doesn't support SSE41"
+ #endif
+#endif
+
#include <smmintrin.h>
int main(void)
diff --git a/numpy/distutils/checks/cpu_sse42.c b/numpy/distutils/checks/cpu_sse42.c
index 24f5d93fe..f60e18f3c 100644
--- a/numpy/distutils/checks/cpu_sse42.c
+++ b/numpy/distutils/checks/cpu_sse42.c
@@ -1,3 +1,16 @@
+#if defined(DETECT_FEATURES) && defined(__INTEL_COMPILER)
+ /*
+ * Unlike GCC and CLANG, Intel Compiler exposes all supported intrinsics,
+ * whether or not the build options for those features are specified.
+ * Therefore, we must test #definitions of CPU features when option native/host
+ * is enabled via `--cpu-baseline` or through env var `CFLAGS` otherwise
+ * the test will be broken and leads to enable all possible features.
+ */
+ #ifndef __SSE4_2__
+ #error "HOST/ARCH doesn't support SSE42"
+ #endif
+#endif
+
#include <smmintrin.h>
int main(void)
diff --git a/numpy/distutils/checks/cpu_ssse3.c b/numpy/distutils/checks/cpu_ssse3.c
index ad0abc1e6..fde390d6a 100644
--- a/numpy/distutils/checks/cpu_ssse3.c
+++ b/numpy/distutils/checks/cpu_ssse3.c
@@ -1,3 +1,16 @@
+#if defined(DETECT_FEATURES) && defined(__INTEL_COMPILER)
+ /*
+ * Unlike GCC and CLANG, Intel Compiler exposes all supported intrinsics,
+ * whether or not the build options for those features are specified.
+ * Therefore, we must test #definitions of CPU features when option native/host
+ * is enabled via `--cpu-baseline` or through env var `CFLAGS` otherwise
+ * the test will be broken and leads to enable all possible features.
+ */
+ #ifndef __SSSE3__
+ #error "HOST/ARCH doesn't support SSSE3"
+ #endif
+#endif
+
#include <tmmintrin.h>
int main(void)
diff --git a/numpy/distutils/checks/extra_avx512dq_mask.c b/numpy/distutils/checks/extra_avx512dq_mask.c
new file mode 100644
index 000000000..f0dc88bdd
--- /dev/null
+++ b/numpy/distutils/checks/extra_avx512dq_mask.c
@@ -0,0 +1,16 @@
+#include <immintrin.h>
+/**
+ * Test DQ mask operations due to:
+ * - MSVC has supported it since vs2019 see,
+ * https://developercommunity.visualstudio.com/content/problem/518298/missing-avx512bw-mask-intrinsics.html
+ * - Clang >= v8.0
+ * - GCC >= v7.1
+ */
+int main(void)
+{
+ __mmask8 m8 = _mm512_cmpeq_epi64_mask(_mm512_set1_epi64(1), _mm512_set1_epi64(1));
+ m8 = _kor_mask8(m8, m8);
+ m8 = _kxor_mask8(m8, m8);
+ m8 = _cvtu32_mask8(_cvtmask8_u32(m8));
+ return (int)_cvtmask8_u32(m8);
+}
diff --git a/numpy/distutils/checks/extra_avx512f_reduce.c b/numpy/distutils/checks/extra_avx512f_reduce.c
index f979d504e..db01aaeef 100644
--- a/numpy/distutils/checks/extra_avx512f_reduce.c
+++ b/numpy/distutils/checks/extra_avx512f_reduce.c
@@ -8,7 +8,7 @@ int main(void)
{
__m512 one_ps = _mm512_set1_ps(1.0f);
__m512d one_pd = _mm512_set1_pd(1.0);
- __m512i one_i64 = _mm512_set1_epi64(1.0);
+ __m512i one_i64 = _mm512_set1_epi64(1);
// add
float sum_ps = _mm512_reduce_add_ps(one_ps);
double sum_pd = _mm512_reduce_add_pd(one_pd);
diff --git a/numpy/distutils/checks/extra_vsx_asm.c b/numpy/distutils/checks/extra_vsx_asm.c
new file mode 100644
index 000000000..b73a6f438
--- /dev/null
+++ b/numpy/distutils/checks/extra_vsx_asm.c
@@ -0,0 +1,36 @@
+/**
+ * Testing ASM VSX register number fixer '%x<n>'
+ *
+ * old versions of CLANG doesn't support %x<n> in the inline asm template
+ * which fixes register number when using any of the register constraints wa, wd, wf.
+ *
+ * xref:
+ * - https://bugs.llvm.org/show_bug.cgi?id=31837
+ * - https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html
+ */
+#ifndef __VSX__
+ #error "VSX is not supported"
+#endif
+#include <altivec.h>
+
+#if (defined(__GNUC__) && !defined(vec_xl)) || (defined(__clang__) && !defined(__IBMC__))
+ #define vsx_ld vec_vsx_ld
+ #define vsx_st vec_vsx_st
+#else
+ #define vsx_ld vec_xl
+ #define vsx_st vec_xst
+#endif
+
+int main(void)
+{
+ float z4[] = {0, 0, 0, 0};
+ signed int zout[] = {0, 0, 0, 0};
+
+ __vector float vz4 = vsx_ld(0, z4);
+ __vector signed int asm_ret = vsx_ld(0, zout);
+
+ __asm__ ("xvcvspsxws %x0,%x1" : "=wa" (vz4) : "wa" (asm_ret));
+
+ vsx_st(asm_ret, 0, zout);
+ return zout[0];
+}
diff --git a/numpy/distutils/command/build_clib.py b/numpy/distutils/command/build_clib.py
index a0db6f31f..0e31a7dee 100644
--- a/numpy/distutils/command/build_clib.py
+++ b/numpy/distutils/command/build_clib.py
@@ -118,23 +118,31 @@ class build_clib(old_build_clib):
self.compiler.show_customization()
if not self.disable_optimization:
+ dispatch_hpath = os.path.join("numpy", "distutils", "include", "npy_cpu_dispatch_config.h")
+ dispatch_hpath = os.path.join(self.get_finalized_command("build_src").build_src, dispatch_hpath)
opt_cache_path = os.path.abspath(
- os.path.join(self.build_temp, 'ccompiler_opt_cache_clib.py'
- ))
- self.compiler_opt = new_ccompiler_opt(
- compiler=self.compiler, cpu_baseline=self.cpu_baseline,
- cpu_dispatch=self.cpu_dispatch, cache_path=opt_cache_path
+ os.path.join(self.build_temp, 'ccompiler_opt_cache_clib.py')
)
- if not self.compiler_opt.is_cached():
- log.info("Detected changes on compiler optimizations, force rebuilding")
- self.force = True
+ if hasattr(self, "compiler_opt"):
+ # By default `CCompilerOpt` update the cache at the exit of
+ # the process, which may lead to duplicate building
+ # (see build_extension()/force_rebuild) if run() called
+ # multiple times within the same os process/thread without
+ # giving the chance the previous instances of `CCompilerOpt`
+ # to update the cache.
+ self.compiler_opt.cache_flush()
- import atexit
- def report():
+ self.compiler_opt = new_ccompiler_opt(
+ compiler=self.compiler, dispatch_hpath=dispatch_hpath,
+ cpu_baseline=self.cpu_baseline, cpu_dispatch=self.cpu_dispatch,
+ cache_path=opt_cache_path
+ )
+ def report(copt):
log.info("\n########### CLIB COMPILER OPTIMIZATION ###########")
- log.info(self.compiler_opt.report(full=True))
+ log.info(copt.report(full=True))
- atexit.register(report)
+ import atexit
+ atexit.register(report, self.compiler_opt)
if self.have_f_sources():
from numpy.distutils.fcompiler import new_fcompiler
@@ -209,7 +217,12 @@ class build_clib(old_build_clib):
lib_file = compiler.library_filename(lib_name,
output_dir=self.build_clib)
depends = sources + build_info.get('depends', [])
- if not (self.force or newer_group(depends, lib_file, 'newer')):
+
+ force_rebuild = self.force
+ if not self.disable_optimization and not self.compiler_opt.is_cached():
+ log.debug("Detected changes on compiler optimizations")
+ force_rebuild = True
+ if not (force_rebuild or newer_group(depends, lib_file, 'newer')):
log.debug("skipping '%s' library (up-to-date)", lib_name)
return
else:
@@ -268,19 +281,44 @@ class build_clib(old_build_clib):
# filtering C dispatch-table sources when optimization is not disabled,
# otherwise treated as normal sources.
copt_c_sources = []
+ copt_cxx_sources = []
copt_baseline_flags = []
copt_macros = []
if not self.disable_optimization:
- copt_build_src = None if self.inplace else self.get_finalized_command("build_src").build_src
- copt_c_sources = [
- c_sources.pop(c_sources.index(src))
- for src in c_sources[:] if src.endswith(".dispatch.c")
- ]
+ bsrc_dir = self.get_finalized_command("build_src").build_src
+ dispatch_hpath = os.path.join("numpy", "distutils", "include")
+ dispatch_hpath = os.path.join(bsrc_dir, dispatch_hpath)
+ include_dirs.append(dispatch_hpath)
+
+ copt_build_src = None if self.inplace else bsrc_dir
+ for _srcs, _dst, _ext in (
+ ((c_sources,), copt_c_sources, ('.dispatch.c',)),
+ ((c_sources, cxx_sources), copt_cxx_sources,
+ ('.dispatch.cpp', '.dispatch.cxx'))
+ ):
+ for _src in _srcs:
+ _dst += [
+ _src.pop(_src.index(s))
+ for s in _src[:] if s.endswith(_ext)
+ ]
copt_baseline_flags = self.compiler_opt.cpu_baseline_flags()
else:
copt_macros.append(("NPY_DISABLE_OPTIMIZATION", 1))
objects = []
+ if copt_cxx_sources:
+ log.info("compiling C++ dispatch-able sources")
+ objects += self.compiler_opt.try_dispatch(
+ copt_c_sources,
+ output_dir=self.build_temp,
+ src_dir=copt_build_src,
+ macros=macros + copt_macros,
+ include_dirs=include_dirs,
+ debug=self.debug,
+ extra_postargs=extra_postargs,
+ ccompiler=cxx_compiler
+ )
+
if copt_c_sources:
log.info("compiling C dispatch-able sources")
objects += self.compiler_opt.try_dispatch(copt_c_sources,
diff --git a/numpy/distutils/command/build_ext.py b/numpy/distutils/command/build_ext.py
index ca6f8bcd2..84ec8aa2c 100644
--- a/numpy/distutils/command/build_ext.py
+++ b/numpy/distutils/command/build_ext.py
@@ -146,20 +146,31 @@ class build_ext (old_build_ext):
self.compiler.show_customization()
if not self.disable_optimization:
- opt_cache_path = os.path.abspath(os.path.join(self.build_temp, 'ccompiler_opt_cache_ext.py'))
- self.compiler_opt = new_ccompiler_opt(compiler=self.compiler,
- cpu_baseline=self.cpu_baseline,
- cpu_dispatch=self.cpu_dispatch,
- cache_path=opt_cache_path)
- if not self.compiler_opt.is_cached():
- log.info("Detected changes on compiler optimizations, force rebuilding")
- self.force = True
+ dispatch_hpath = os.path.join("numpy", "distutils", "include", "npy_cpu_dispatch_config.h")
+ dispatch_hpath = os.path.join(self.get_finalized_command("build_src").build_src, dispatch_hpath)
+ opt_cache_path = os.path.abspath(
+ os.path.join(self.build_temp, 'ccompiler_opt_cache_ext.py')
+ )
+ if hasattr(self, "compiler_opt"):
+ # By default `CCompilerOpt` update the cache at the exit of
+ # the process, which may lead to duplicate building
+ # (see build_extension()/force_rebuild) if run() called
+ # multiple times within the same os process/thread without
+ # giving the chance the previous instances of `CCompilerOpt`
+ # to update the cache.
+ self.compiler_opt.cache_flush()
+
+ self.compiler_opt = new_ccompiler_opt(
+ compiler=self.compiler, dispatch_hpath=dispatch_hpath,
+ cpu_baseline=self.cpu_baseline, cpu_dispatch=self.cpu_dispatch,
+ cache_path=opt_cache_path
+ )
+ def report(copt):
+ log.info("\n########### EXT COMPILER OPTIMIZATION ###########")
+ log.info(copt.report(full=True))
import atexit
- def report():
- log.info("\n########### EXT COMPILER OPTIMIZATION ###########")
- log.info(self.compiler_opt.report(full=True))
- atexit.register(report)
+ atexit.register(report, self.compiler_opt)
# Setup directory for storing generated extra DLL files on Windows
self.extra_dll_dir = os.path.join(self.build_temp, '.libs')
@@ -354,7 +365,11 @@ class build_ext (old_build_ext):
self.get_ext_filename(fullname))
depends = sources + ext.depends
- if not (self.force or newer_group(depends, ext_filename, 'newer')):
+ force_rebuild = self.force
+ if not self.disable_optimization and not self.compiler_opt.is_cached():
+ log.debug("Detected changes on compiler optimizations")
+ force_rebuild = True
+ if not (force_rebuild or newer_group(depends, ext_filename, 'newer')):
log.debug("skipping '%s' extension (up-to-date)", ext.name)
return
else:
@@ -413,19 +428,44 @@ class build_ext (old_build_ext):
# filtering C dispatch-table sources when optimization is not disabled,
# otherwise treated as normal sources.
copt_c_sources = []
+ copt_cxx_sources = []
copt_baseline_flags = []
copt_macros = []
if not self.disable_optimization:
- copt_build_src = None if self.inplace else self.get_finalized_command("build_src").build_src
- copt_c_sources = [
- c_sources.pop(c_sources.index(src))
- for src in c_sources[:] if src.endswith(".dispatch.c")
- ]
+ bsrc_dir = self.get_finalized_command("build_src").build_src
+ dispatch_hpath = os.path.join("numpy", "distutils", "include")
+ dispatch_hpath = os.path.join(bsrc_dir, dispatch_hpath)
+ include_dirs.append(dispatch_hpath)
+
+ copt_build_src = None if self.inplace else bsrc_dir
+ for _srcs, _dst, _ext in (
+ ((c_sources,), copt_c_sources, ('.dispatch.c',)),
+ ((c_sources, cxx_sources), copt_cxx_sources,
+ ('.dispatch.cpp', '.dispatch.cxx'))
+ ):
+ for _src in _srcs:
+ _dst += [
+ _src.pop(_src.index(s))
+ for s in _src[:] if s.endswith(_ext)
+ ]
copt_baseline_flags = self.compiler_opt.cpu_baseline_flags()
else:
copt_macros.append(("NPY_DISABLE_OPTIMIZATION", 1))
c_objects = []
+ if copt_cxx_sources:
+ log.info("compiling C++ dispatch-able sources")
+ c_objects += self.compiler_opt.try_dispatch(
+ copt_cxx_sources,
+ output_dir=output_dir,
+ src_dir=copt_build_src,
+ macros=macros + copt_macros,
+ include_dirs=include_dirs,
+ debug=self.debug,
+ extra_postargs=extra_args,
+ ccompiler=cxx_compiler,
+ **kws
+ )
if copt_c_sources:
log.info("compiling C dispatch-able sources")
c_objects += self.compiler_opt.try_dispatch(copt_c_sources,
@@ -559,8 +599,11 @@ class build_ext (old_build_ext):
objects = list(objects)
unlinkable_fobjects = list(unlinkable_fobjects)
- # Expand possible fake static libraries to objects
- for lib in libraries:
+ # Expand possible fake static libraries to objects;
+ # make sure to iterate over a copy of the list as
+ # "fake" libraries will be removed as they are
+ # enountered
+ for lib in libraries[:]:
for libdir in library_dirs:
fake_lib = os.path.join(libdir, lib + '.fobjects')
if os.path.isfile(fake_lib):
diff --git a/numpy/distutils/command/build_src.py b/numpy/distutils/command/build_src.py
index 303d6197c..5581011f6 100644
--- a/numpy/distutils/command/build_src.py
+++ b/numpy/distutils/command/build_src.py
@@ -715,14 +715,14 @@ class build_src(build_ext.build_ext):
return new_sources + py_files
-_f_pyf_ext_match = re.compile(r'.*[.](f90|f95|f77|for|ftn|f|pyf)\Z', re.I).match
-_header_ext_match = re.compile(r'.*[.](inc|h|hpp)\Z', re.I).match
+_f_pyf_ext_match = re.compile(r'.*\.(f90|f95|f77|for|ftn|f|pyf)\Z', re.I).match
+_header_ext_match = re.compile(r'.*\.(inc|h|hpp)\Z', re.I).match
#### SWIG related auxiliary functions ####
_swig_module_name_match = re.compile(r'\s*%module\s*(.*\(\s*package\s*=\s*"(?P<package>[\w_]+)".*\)|)\s*(?P<name>[\w_]+)',
re.I).match
-_has_c_header = re.compile(r'-[*]-\s*c\s*-[*]-', re.I).search
-_has_cpp_header = re.compile(r'-[*]-\s*c[+][+]\s*-[*]-', re.I).search
+_has_c_header = re.compile(r'-\*-\s*c\s*-\*-', re.I).search
+_has_cpp_header = re.compile(r'-\*-\s*c\+\+\s*-\*-', re.I).search
def get_swig_target(source):
with open(source, 'r') as f:
diff --git a/numpy/distutils/command/config.py b/numpy/distutils/command/config.py
index 60881f4a3..1f4037bb5 100644
--- a/numpy/distutils/command/config.py
+++ b/numpy/distutils/command/config.py
@@ -64,7 +64,7 @@ class config(old_config):
% (e, self.compiler.__class__.__name__)
print(textwrap.dedent("""\
============================================================================"""))
- raise distutils.errors.DistutilsPlatformError(msg)
+ raise distutils.errors.DistutilsPlatformError(msg) from e
# After MSVC is initialized, add an explicit /MANIFEST to linker
# flags. See issues gh-4245 and gh-4101 for details. Also
@@ -92,12 +92,13 @@ class config(old_config):
save_compiler = self.compiler
if lang in ['f77', 'f90']:
self.compiler = self.fcompiler
+ if self.compiler is None:
+ raise CompileError('%s compiler is not set' % (lang,))
try:
ret = mth(*((self,)+args))
except (DistutilsExecError, CompileError) as e:
- str(e)
self.compiler = save_compiler
- raise CompileError
+ raise CompileError from e
self.compiler = save_compiler
return ret
diff --git a/numpy/distutils/conv_template.py b/numpy/distutils/conv_template.py
index d08015fdf..c8933d1d4 100644
--- a/numpy/distutils/conv_template.py
+++ b/numpy/distutils/conv_template.py
@@ -137,7 +137,7 @@ def paren_repl(obj):
numrep = obj.group(2)
return ','.join([torep]*int(numrep))
-parenrep = re.compile(r"[(]([^)]*)[)]\*(\d+)")
+parenrep = re.compile(r"\(([^)]*)\)\*(\d+)")
plainrep = re.compile(r"([^*]+)\*(\d+)")
def parse_values(astr):
# replaces all occurrences of '(a,b,c)*4' in astr
@@ -207,7 +207,7 @@ def parse_loop_header(loophead) :
dlist.append(tmp)
return dlist
-replace_re = re.compile(r"@([\w]+)@")
+replace_re = re.compile(r"@(\w+)@")
def parse_string(astr, env, level, line) :
lineno = "#line %d\n" % line
@@ -218,7 +218,7 @@ def parse_string(astr, env, level, line) :
val = env[name]
except KeyError:
msg = 'line %d: no definition of key "%s"'%(line, name)
- raise ValueError(msg)
+ raise ValueError(msg) from None
return val
code = [lineno]
@@ -271,7 +271,6 @@ def resolve_includes(source):
if not os.path.isabs(fn):
fn = os.path.join(d, fn)
if os.path.isfile(fn):
- print('Including file', fn)
lines.extend(resolve_includes(fn))
else:
lines.append(line)
@@ -285,7 +284,7 @@ def process_file(source):
try:
code = process_str(''.join(lines))
except ValueError as e:
- raise ValueError('In "%s" loop at %s' % (sourcefile, e))
+ raise ValueError('In "%s" loop at %s' % (sourcefile, e)) from None
return '#line 1 "%s"\n%s' % (sourcefile, code)
@@ -322,7 +321,7 @@ def main():
try:
writestr = process_str(allstr)
except ValueError as e:
- raise ValueError("In %s loop at %s" % (file, e))
+ raise ValueError("In %s loop at %s" % (file, e)) from None
outfile.write(writestr)
diff --git a/numpy/distutils/extension.py b/numpy/distutils/extension.py
index 67114ef2e..c90b5d725 100644
--- a/numpy/distutils/extension.py
+++ b/numpy/distutils/extension.py
@@ -10,8 +10,8 @@ import re
from distutils.extension import Extension as old_Extension
-cxx_ext_re = re.compile(r'.*[.](cpp|cxx|cc)\Z', re.I).match
-fortran_pyf_ext_re = re.compile(r'.*[.](f90|f95|f77|for|ftn|f|pyf)\Z', re.I).match
+cxx_ext_re = re.compile(r'.*\.(cpp|cxx|cc)\Z', re.I).match
+fortran_pyf_ext_re = re.compile(r'.*\.(f90|f95|f77|for|ftn|f|pyf)\Z', re.I).match
class Extension(old_Extension):
diff --git a/numpy/distutils/fcompiler/__init__.py b/numpy/distutils/fcompiler/__init__.py
index 1f340a412..d7579e976 100644
--- a/numpy/distutils/fcompiler/__init__.py
+++ b/numpy/distutils/fcompiler/__init__.py
@@ -610,7 +610,7 @@ class FCompiler(CCompiler):
self.spawn(command, display=display)
except DistutilsExecError as e:
msg = str(e)
- raise CompileError(msg)
+ raise CompileError(msg) from None
def module_options(self, module_dirs, module_build_dir):
options = []
@@ -678,7 +678,7 @@ class FCompiler(CCompiler):
self.spawn(command)
except DistutilsExecError as e:
msg = str(e)
- raise LinkError(msg)
+ raise LinkError(msg) from None
else:
log.debug("skipping %s (up-to-date)", output_filename)
@@ -744,7 +744,7 @@ _default_compilers = (
'intelvem', 'intelem', 'flang')),
('cygwin.*', ('gnu', 'intelv', 'absoft', 'compaqv', 'intelev', 'gnu95', 'g95')),
('linux.*', ('gnu95', 'intel', 'lahey', 'pg', 'nv', 'absoft', 'nag', 'vast', 'compaq',
- 'intele', 'intelem', 'gnu', 'g95', 'pathf95', 'nagfor')),
+ 'intele', 'intelem', 'gnu', 'g95', 'pathf95', 'nagfor', 'fujitsu')),
('darwin.*', ('gnu95', 'nag', 'absoft', 'ibm', 'intel', 'gnu', 'g95', 'pg')),
('sunos.*', ('sun', 'gnu', 'gnu95', 'g95')),
('irix.*', ('mips', 'gnu', 'gnu95',)),
@@ -962,10 +962,10 @@ def dummy_fortran_file():
return name[:-2]
-is_f_file = re.compile(r'.*[.](for|ftn|f77|f)\Z', re.I).match
-_has_f_header = re.compile(r'-[*]-\s*fortran\s*-[*]-', re.I).search
-_has_f90_header = re.compile(r'-[*]-\s*f90\s*-[*]-', re.I).search
-_has_fix_header = re.compile(r'-[*]-\s*fix\s*-[*]-', re.I).search
+is_f_file = re.compile(r'.*\.(for|ftn|f77|f)\Z', re.I).match
+_has_f_header = re.compile(r'-\*-\s*fortran\s*-\*-', re.I).search
+_has_f90_header = re.compile(r'-\*-\s*f90\s*-\*-', re.I).search
+_has_fix_header = re.compile(r'-\*-\s*fix\s*-\*-', re.I).search
_free_f90_start = re.compile(r'[^c*!]\s*[^\s\d\t]', re.I).match
def is_free_format(file):
@@ -976,7 +976,7 @@ def is_free_format(file):
with open(file, encoding='latin1') as f:
line = f.readline()
n = 10000 # the number of non-comment lines to scan for hints
- if _has_f_header(line):
+ if _has_f_header(line) or _has_fix_header(line):
n = 0
elif _has_f90_header(line):
n = 0
diff --git a/numpy/distutils/fcompiler/compaq.py b/numpy/distutils/fcompiler/compaq.py
index 6ce590c7c..351a43dd7 100644
--- a/numpy/distutils/fcompiler/compaq.py
+++ b/numpy/distutils/fcompiler/compaq.py
@@ -80,18 +80,18 @@ class CompaqVisualFCompiler(FCompiler):
except DistutilsPlatformError:
pass
except AttributeError as e:
- if '_MSVCCompiler__root' in str(msg):
- print('Ignoring "%s" (I think it is msvccompiler.py bug)' % (msg))
+ if '_MSVCCompiler__root' in str(e):
+ print('Ignoring "%s" (I think it is msvccompiler.py bug)' % (e))
else:
raise
except IOError as e:
if not "vcvarsall.bat" in str(e):
print("Unexpected IOError in", __file__)
- raise e
+ raise
except ValueError as e:
if not "'path'" in str(e):
print("Unexpected ValueError in", __file__)
- raise e
+ raise
executables = {
'version_cmd' : ['<F90>', "/what"],
diff --git a/numpy/distutils/fcompiler/fujitsu.py b/numpy/distutils/fcompiler/fujitsu.py
new file mode 100644
index 000000000..ddce67456
--- /dev/null
+++ b/numpy/distutils/fcompiler/fujitsu.py
@@ -0,0 +1,46 @@
+"""
+fujitsu
+
+Supports Fujitsu compiler function.
+This compiler is developed by Fujitsu and is used in A64FX on Fugaku.
+"""
+from numpy.distutils.fcompiler import FCompiler
+
+compilers = ['FujitsuFCompiler']
+
+class FujitsuFCompiler(FCompiler):
+ compiler_type = 'fujitsu'
+ description = 'Fujitsu Fortran Compiler'
+
+ possible_executables = ['frt']
+ version_pattern = r'frt \(FRT\) (?P<version>[a-z\d.]+)'
+ # $ frt --version
+ # frt (FRT) x.x.x yyyymmdd
+
+ executables = {
+ 'version_cmd' : ["<F77>", "--version"],
+ 'compiler_f77' : ["frt", "-Fixed"],
+ 'compiler_fix' : ["frt", "-Fixed"],
+ 'compiler_f90' : ["frt"],
+ 'linker_so' : ["frt", "-shared"],
+ 'archiver' : ["ar", "-cr"],
+ 'ranlib' : ["ranlib"]
+ }
+ pic_flags = ['-KPIC']
+ module_dir_switch = '-M'
+ module_include_switch = '-I'
+
+ def get_flags_opt(self):
+ return ['-O3']
+ def get_flags_debug(self):
+ return ['-g']
+ def runtime_library_dir_option(self, dir):
+ return f'-Wl,-rpath={dir}'
+ def get_libraries(self):
+ return ['fj90f', 'fj90i', 'fjsrcinfo']
+
+if __name__ == '__main__':
+ from distutils import log
+ from numpy.distutils import customized_fcompiler
+ log.set_verbosity(2)
+ print(customized_fcompiler('fujitsu').get_version())
diff --git a/numpy/distutils/fcompiler/gnu.py b/numpy/distutils/fcompiler/gnu.py
index 0d9d769c2..02372f5e6 100644
--- a/numpy/distutils/fcompiler/gnu.py
+++ b/numpy/distutils/fcompiler/gnu.py
@@ -32,7 +32,8 @@ class GnuFCompiler(FCompiler):
"""Handle the different versions of GNU fortran compilers"""
# Strip warning(s) that may be emitted by gfortran
while version_string.startswith('gfortran: warning'):
- version_string = version_string[version_string.find('\n') + 1:]
+ version_string =\
+ version_string[version_string.find('\n') + 1:].strip()
# Gfortran versions from after 2010 will output a simple string
# (usually "x.y", "x.y.z" or "x.y.z-q") for ``-dumpversion``; older
@@ -126,7 +127,7 @@ class GnuFCompiler(FCompiler):
target = '10.9'
s = f'Env. variable MACOSX_DEPLOYMENT_TARGET set to {target}'
warnings.warn(s, stacklevel=2)
- os.environ['MACOSX_DEPLOYMENT_TARGET'] = target
+ os.environ['MACOSX_DEPLOYMENT_TARGET'] = str(target)
opt.extend(['-undefined', 'dynamic_lookup', '-bundle'])
else:
opt.append("-shared")
@@ -246,7 +247,7 @@ class GnuFCompiler(FCompiler):
return []
def runtime_library_dir_option(self, dir):
- if sys.platform == 'win32':
+ if sys.platform == 'win32' or sys.platform == 'cygwin':
# Linux/Solaris/Unix support RPATH, Windows does not
raise NotImplementedError
diff --git a/numpy/distutils/fcompiler/ibm.py b/numpy/distutils/fcompiler/ibm.py
index 4a83682e5..eff24401a 100644
--- a/numpy/distutils/fcompiler/ibm.py
+++ b/numpy/distutils/fcompiler/ibm.py
@@ -77,7 +77,7 @@ class IBMFCompiler(FCompiler):
fo, new_cfg = make_temp_file(suffix='_xlf.cfg')
log.info('Creating '+new_cfg)
with open(xlf_cfg, 'r') as fi:
- crt1_match = re.compile(r'\s*crt\s*[=]\s*(?P<path>.*)/crt1.o').match
+ crt1_match = re.compile(r'\s*crt\s*=\s*(?P<path>.*)/crt1.o').match
for line in fi:
m = crt1_match(line)
if m:
diff --git a/numpy/distutils/fcompiler/intel.py b/numpy/distutils/fcompiler/intel.py
index c7b3c2340..f97c5b348 100644
--- a/numpy/distutils/fcompiler/intel.py
+++ b/numpy/distutils/fcompiler/intel.py
@@ -59,7 +59,8 @@ class IntelFCompiler(BaseIntelFCompiler):
def get_flags_opt(self): # Scipy test failures with -O2
v = self.get_version()
mpopt = 'openmp' if v and v < '15' else 'qopenmp'
- return ['-fp-model', 'strict', '-O1', '-{}'.format(mpopt)]
+ return ['-fp-model', 'strict', '-O1',
+ '-assume', 'minus0', '-{}'.format(mpopt)]
def get_flags_arch(self):
return []
@@ -119,17 +120,6 @@ class IntelEM64TFCompiler(IntelFCompiler):
'ranlib' : ["ranlib"]
}
- def get_flags(self):
- return ['-fPIC']
-
- def get_flags_opt(self): # Scipy test failures with -O2
- v = self.get_version()
- mpopt = 'openmp' if v and v < '15' else 'qopenmp'
- return ['-fp-model', 'strict', '-O1', '-{}'.format(mpopt)]
-
- def get_flags_arch(self):
- return []
-
# Is there no difference in the version string between the above compilers
# and the Visual compilers?
@@ -174,7 +164,7 @@ class IntelVisualFCompiler(BaseIntelFCompiler):
return ['/4Yb', '/d2']
def get_flags_opt(self):
- return ['/O1'] # Scipy test failures with /O2
+ return ['/O1', '/assume:minus0'] # Scipy test failures with /O2
def get_flags_arch(self):
return ["/arch:IA32", "/QaxSSE3"]
diff --git a/numpy/distutils/fcompiler/nag.py b/numpy/distutils/fcompiler/nag.py
index 908e724e6..7df8ffe2c 100644
--- a/numpy/distutils/fcompiler/nag.py
+++ b/numpy/distutils/fcompiler/nag.py
@@ -19,7 +19,7 @@ class BaseNAGFCompiler(FCompiler):
def get_flags_opt(self):
return ['-O4']
def get_flags_arch(self):
- return ['']
+ return []
class NAGFCompiler(BaseNAGFCompiler):
diff --git a/numpy/distutils/fcompiler/nv.py b/numpy/distutils/fcompiler/nv.py
index 8e9f16835..212f34806 100644
--- a/numpy/distutils/fcompiler/nv.py
+++ b/numpy/distutils/fcompiler/nv.py
@@ -1,5 +1,3 @@
-import sys
-
from numpy.distutils.fcompiler import FCompiler
compilers = ['NVHPCFCompiler']
diff --git a/numpy/distutils/from_template.py b/numpy/distutils/from_template.py
index 070b7d8b8..90d1f4c38 100644
--- a/numpy/distutils/from_template.py
+++ b/numpy/distutils/from_template.py
@@ -206,7 +206,7 @@ def process_str(allstr):
return writestr
-include_src_re = re.compile(r"(\n|\A)\s*include\s*['\"](?P<name>[\w\d./\\]+[.]src)['\"]", re.I)
+include_src_re = re.compile(r"(\n|\A)\s*include\s*['\"](?P<name>[\w\d./\\]+\.src)['\"]", re.I)
def resolve_includes(source):
d = os.path.dirname(source)
@@ -219,7 +219,6 @@ def resolve_includes(source):
if not os.path.isabs(fn):
fn = os.path.join(d, fn)
if os.path.isfile(fn):
- print('Including file', fn)
lines.extend(resolve_includes(fn))
else:
lines.append(line)
diff --git a/numpy/distutils/intelccompiler.py b/numpy/distutils/intelccompiler.py
index 0388ad577..0fa1c11dd 100644
--- a/numpy/distutils/intelccompiler.py
+++ b/numpy/distutils/intelccompiler.py
@@ -58,7 +58,7 @@ class IntelEM64TCCompiler(UnixCCompiler):
v = self.get_version()
mpopt = 'openmp' if v and v < '15' else 'qopenmp'
- self.cc_exe = ('icc -m64 -fPIC -fp-model strict -O3 '
+ self.cc_exe = ('icc -std=c99 -m64 -fPIC -fp-model strict -O3 '
'-fomit-frame-pointer -{}').format(mpopt)
compiler = self.cc_exe
diff --git a/numpy/distutils/mingw32ccompiler.py b/numpy/distutils/mingw32ccompiler.py
index 3358695a8..4681d403b 100644
--- a/numpy/distutils/mingw32ccompiler.py
+++ b/numpy/distutils/mingw32ccompiler.py
@@ -566,7 +566,7 @@ def msvc_manifest_xml(maj, min):
fullver = _MSVCRVER_TO_FULLVER[str(maj * 10 + min)]
except KeyError:
raise ValueError("Version %d,%d of MSVCRT not supported yet" %
- (maj, min))
+ (maj, min)) from None
# Don't be fooled, it looks like an XML, but it is not. In particular, it
# should not have any space before starting, and its size should be
# divisible by 4, most likely for alignment constraints when the xml is
diff --git a/numpy/distutils/misc_util.py b/numpy/distutils/misc_util.py
index a8e19d52c..9c65ff43e 100644
--- a/numpy/distutils/misc_util.py
+++ b/numpy/distutils/misc_util.py
@@ -10,13 +10,10 @@ import shutil
import multiprocessing
import textwrap
import importlib.util
+from threading import local as tlocal
import distutils
from distutils.errors import DistutilsError
-try:
- from threading import local as tlocal
-except ImportError:
- from dummy_threading import local as tlocal
# stores temporary directory of each thread to only create one per thread
_tdata = tlocal()
@@ -379,10 +376,42 @@ def blue_text(s):
#########################
-def cyg2win32(path):
- if sys.platform=='cygwin' and path.startswith('/cygdrive'):
- path = path[10] + ':' + os.path.normcase(path[11:])
- return path
+def cyg2win32(path: str) -> str:
+ """Convert a path from Cygwin-native to Windows-native.
+
+ Uses the cygpath utility (part of the Base install) to do the
+ actual conversion. Falls back to returning the original path if
+ this fails.
+
+ Handles the default ``/cygdrive`` mount prefix as well as the
+ ``/proc/cygdrive`` portable prefix, custom cygdrive prefixes such
+ as ``/`` or ``/mnt``, and absolute paths such as ``/usr/src/`` or
+ ``/home/username``
+
+ Parameters
+ ----------
+ path : str
+ The path to convert
+
+ Returns
+ -------
+ converted_path : str
+ The converted path
+
+ Notes
+ -----
+ Documentation for cygpath utility:
+ https://cygwin.com/cygwin-ug-net/cygpath.html
+ Documentation for the C function it wraps:
+ https://cygwin.com/cygwin-api/func-cygwin-conv-path.html
+
+ """
+ if sys.platform != "cygwin":
+ return path
+ return subprocess.check_output(
+ ["/usr/bin/cygpath", "--windows", path], universal_newlines=True
+ )
+
def mingw32():
"""Return true when using mingw32 environment.
@@ -428,9 +457,9 @@ def msvc_runtime_major():
#########################
#XXX need support for .C that is also C++
-cxx_ext_match = re.compile(r'.*[.](cpp|cxx|cc)\Z', re.I).match
-fortran_ext_match = re.compile(r'.*[.](f90|f95|f77|for|ftn|f)\Z', re.I).match
-f90_ext_match = re.compile(r'.*[.](f90|f95)\Z', re.I).match
+cxx_ext_match = re.compile(r'.*\.(cpp|cxx|cc)\Z', re.I).match
+fortran_ext_match = re.compile(r'.*\.(f90|f95|f77|for|ftn|f)\Z', re.I).match
+f90_ext_match = re.compile(r'.*\.(f90|f95)\Z', re.I).match
f90_module_name_match = re.compile(r'\s*module\s*(?P<name>[\w_]+)', re.I).match
def _get_f90_modules(source):
"""Return a list of Fortran f90 module names that
@@ -1968,6 +1997,13 @@ class Configuration:
version = getattr(version_module, a, None)
if version is not None:
break
+
+ # Try if versioneer module
+ try:
+ version = version_module.get_versions()['version']
+ except AttributeError:
+ pass
+
if version is not None:
break
@@ -2340,19 +2376,47 @@ def generate_config_py(target):
Notes
-----
- Classes specifying the information to be printed are defined
- in the `numpy.distutils.system_info` module.
-
- Information may include:
-
- * ``language``: language used to write the libraries (mostly
- C or f77)
- * ``libraries``: names of libraries found in the system
- * ``library_dirs``: directories containing the libraries
- * ``include_dirs``: directories containing library header files
- * ``src_dirs``: directories containing library source files
- * ``define_macros``: preprocessor macros used by
- ``distutils.setup``
+ 1. Classes specifying the information to be printed are defined
+ in the `numpy.distutils.system_info` module.
+
+ Information may include:
+
+ * ``language``: language used to write the libraries (mostly
+ C or f77)
+ * ``libraries``: names of libraries found in the system
+ * ``library_dirs``: directories containing the libraries
+ * ``include_dirs``: directories containing library header files
+ * ``src_dirs``: directories containing library source files
+ * ``define_macros``: preprocessor macros used by
+ ``distutils.setup``
+ * ``baseline``: minimum CPU features required
+ * ``found``: dispatched features supported in the system
+ * ``not found``: dispatched features that are not supported
+ in the system
+
+ 2. NumPy BLAS/LAPACK Installation Notes
+
+ Installing a numpy wheel (``pip install numpy`` or force it
+ via ``pip install numpy --only-binary :numpy: numpy``) includes
+ an OpenBLAS implementation of the BLAS and LAPACK linear algebra
+ APIs. In this case, ``library_dirs`` reports the original build
+ time configuration as compiled with gcc/gfortran; at run time
+ the OpenBLAS library is in
+ ``site-packages/numpy.libs/`` (linux), or
+ ``site-packages/numpy/.dylibs/`` (macOS), or
+ ``site-packages/numpy/.libs/`` (windows).
+
+ Installing numpy from source
+ (``pip install numpy --no-binary numpy``) searches for BLAS and
+ LAPACK dynamic link libraries at build time as influenced by
+ environment variables NPY_BLAS_LIBS, NPY_CBLAS_LIBS, and
+ NPY_LAPACK_LIBS; or NPY_BLAS_ORDER and NPY_LAPACK_ORDER;
+ or the optional file ``~/.numpy-site.cfg``.
+ NumPy remembers those locations and expects to load the same
+ libraries at run-time.
+ In NumPy 1.21+ on macOS, 'accelerate' (Apple's Accelerate BLAS
+ library) is in the default build-time search order after
+ 'openblas'.
Examples
--------
@@ -2364,6 +2428,9 @@ def generate_config_py(target):
libraries = ['openblas', 'openblas']
library_dirs = ['/usr/local/lib']
"""
+ from numpy.core._multiarray_umath import (
+ __cpu_features__, __cpu_baseline__, __cpu_dispatch__
+ )
for name,info_dict in globals().items():
if name[0] == "_" or type(info_dict) is not type({}): continue
print(name + ":")
@@ -2374,6 +2441,19 @@ def generate_config_py(target):
if k == "sources" and len(v) > 200:
v = v[:60] + " ...\n... " + v[-60:]
print(" %s = %s" % (k,v))
+
+ features_found, features_not_found = [], []
+ for feature in __cpu_dispatch__:
+ if __cpu_features__[feature]:
+ features_found.append(feature)
+ else:
+ features_not_found.append(feature)
+
+ print("Supported SIMD extensions in this NumPy install:")
+ print(" baseline = %s" % (','.join(__cpu_baseline__)))
+ print(" found = %s" % (','.join(features_found)))
+ print(" not found = %s" % (','.join(features_not_found)))
+
'''))
return target
diff --git a/numpy/distutils/system_info.py b/numpy/distutils/system_info.py
index 13f9da0fb..2846d754e 100644
--- a/numpy/distutils/system_info.py
+++ b/numpy/distutils/system_info.py
@@ -114,6 +114,19 @@ Currently, the following classes are available, along with their section names:
x11_info:x11
xft_info:xft
+Note that blas_opt_info and lapack_opt_info honor the NPY_BLAS_ORDER
+and NPY_LAPACK_ORDER environment variables to determine the order in which
+specific BLAS and LAPACK libraries are searched for.
+
+This search (or autodetection) can be bypassed by defining the environment
+variables NPY_BLAS_LIBS and NPY_LAPACK_LIBS, which should then contain the
+exact linker flags to use (language will be set to F77). Building against
+Netlib BLAS/LAPACK or stub files, in order to be able to switch BLAS and LAPACK
+implementations at runtime. If using this to build NumPy itself, it is
+recommended to also define NPY_CBLAS_LIBS (assuming your BLAS library has a
+CBLAS interface) to enable CBLAS usage for matrix multiplication (unoptimized
+otherwise).
+
Example:
----------
[DEFAULT]
@@ -314,7 +327,7 @@ else:
'/opt/local/lib', '/sw/lib'], platform_bits)
default_runtime_dirs = []
default_include_dirs = ['/usr/local/include',
- '/opt/include', '/usr/include',
+ '/opt/include',
# path of umfpack under macports
'/opt/local/include/ufsparse',
'/opt/local/include', '/sw/include',
@@ -323,8 +336,7 @@ else:
default_x11_lib_dirs = libpaths(['/usr/X11R6/lib', '/usr/X11/lib',
'/usr/lib'], platform_bits)
- default_x11_include_dirs = ['/usr/X11R6/include', '/usr/X11/include',
- '/usr/include']
+ default_x11_include_dirs = ['/usr/X11R6/include', '/usr/X11/include']
if os.path.exists('/usr/lib/X11'):
globbed_x11_dir = glob('/usr/lib/*/libX11.so')
@@ -363,22 +375,6 @@ default_src_dirs = [_m for _m in default_src_dirs if os.path.isdir(_m)]
so_ext = get_shared_lib_extension()
-def is_symlink_to_accelerate(filename):
- accelpath = '/System/Library/Frameworks/Accelerate.framework'
- return (sys.platform == 'darwin' and os.path.islink(filename) and
- os.path.realpath(filename).startswith(accelpath))
-
-
-_accel_msg = (
- 'Found {filename}, but that file is a symbolic link to the '
- 'MacOS Accelerate framework, which is not supported by NumPy. '
- 'You must configure the build to use a different optimized library, '
- 'or disable the use of optimized BLAS and LAPACK by setting the '
- 'environment variables NPY_BLAS_ORDER="" and NPY_LAPACK_ORDER="" '
- 'before building NumPy.'
-)
-
-
def get_standard_file(fname):
"""Returns a list of files named 'fname' from
1) System-wide directory (directory-location of this module)
@@ -527,6 +523,7 @@ def get_info(name, notfound_action=0):
'blis': blis_info, # use blas_opt instead
'lapack_mkl': lapack_mkl_info, # use lapack_opt instead
'blas_mkl': blas_mkl_info, # use blas_opt instead
+ 'accelerate': accelerate_info, # use blas_opt instead
'openblas64_': openblas64__info,
'openblas64__lapack': openblas64__lapack_info,
'openblas_ilp64': openblas_ilp64_info,
@@ -1017,9 +1014,6 @@ class system_info:
for prefix in lib_prefixes:
p = self.combine_paths(lib_dir, prefix + lib + ext)
if p:
- # p[0] is the full path to the binary library file.
- if is_symlink_to_accelerate(p[0]):
- raise RuntimeError(_accel_msg.format(filename=p[0]))
break
if p:
assert len(p) == 1
@@ -1348,8 +1342,6 @@ class atlas_info(system_info):
lapack = None
atlas_1 = None
for d in lib_dirs:
- # FIXME: lapack_atlas is unused
- lapack_atlas = self.check_libs2(d, ['lapack_atlas'], [])
atlas = self.check_libs2(d, atlas_libs, [])
if atlas is not None:
lib_dirs2 = [d] + self.combine_paths(d, ['atlas*', 'ATLAS*'])
@@ -1549,6 +1541,9 @@ class lapack_info(system_info):
class lapack_src_info(system_info):
+ # LAPACK_SRC is deprecated, please do not use this!
+ # Build or install a BLAS library via your package manager or from
+ # source separately.
section = 'lapack_src'
dir_env_var = 'LAPACK_SRC'
notfounderror = LapackSrcNotFoundError
@@ -1751,8 +1746,10 @@ def get_atlas_version(**config):
class lapack_opt_info(system_info):
notfounderror = LapackNotFoundError
+
# List of all known LAPACK libraries, in the default order
- lapack_order = ['mkl', 'openblas', 'flame', 'atlas', 'lapack']
+ lapack_order = ['mkl', 'openblas', 'flame',
+ 'accelerate', 'atlas', 'lapack']
order_env_var_name = 'NPY_LAPACK_ORDER'
def _calc_info_mkl(self):
@@ -1845,6 +1842,16 @@ class lapack_opt_info(system_info):
return True
return False
+ def _calc_info_from_envvar(self):
+ info = {}
+ info['language'] = 'f77'
+ info['libraries'] = []
+ info['include_dirs'] = []
+ info['define_macros'] = []
+ info['extra_link_args'] = os.environ['NPY_LAPACK_LIBS'].split()
+ self.set_info(**info)
+ return True
+
def _calc_info(self, name):
return getattr(self, '_calc_info_{}'.format(name))()
@@ -1855,6 +1862,12 @@ class lapack_opt_info(system_info):
"LAPACK order has unacceptable "
"values: {}".format(unknown_order))
+ if 'NPY_LAPACK_LIBS' in os.environ:
+ # Bypass autodetection, set language to F77 and use env var linker
+ # flags directly
+ self._calc_info_from_envvar()
+ return
+
for lapack in lapack_order:
if self._calc_info(lapack):
return
@@ -1911,7 +1924,9 @@ class lapack64__opt_info(lapack_ilp64_opt_info):
class blas_opt_info(system_info):
notfounderror = BlasNotFoundError
# List of all known BLAS libraries, in the default order
- blas_order = ['mkl', 'blis', 'openblas', 'atlas', 'blas']
+
+ blas_order = ['mkl', 'blis', 'openblas',
+ 'accelerate', 'atlas', 'blas']
order_env_var_name = 'NPY_BLAS_ORDER'
def _calc_info_mkl(self):
@@ -1977,6 +1992,20 @@ class blas_opt_info(system_info):
self.set_info(**info)
return True
+ def _calc_info_from_envvar(self):
+ info = {}
+ info['language'] = 'f77'
+ info['libraries'] = []
+ info['include_dirs'] = []
+ info['define_macros'] = []
+ info['extra_link_args'] = os.environ['NPY_BLAS_LIBS'].split()
+ if 'NPY_CBLAS_LIBS' in os.environ:
+ info['define_macros'].append(('HAVE_CBLAS', None))
+ info['extra_link_args'].extend(
+ os.environ['NPY_CBLAS_LIBS'].split())
+ self.set_info(**info)
+ return True
+
def _calc_info(self, name):
return getattr(self, '_calc_info_{}'.format(name))()
@@ -1985,6 +2014,12 @@ class blas_opt_info(system_info):
if len(unknown_order) > 0:
raise ValueError("blas_opt_info user defined BLAS order has unacceptable values: {}".format(unknown_order))
+ if 'NPY_BLAS_LIBS' in os.environ:
+ # Bypass autodetection, set language to F77 and use env var linker
+ # flags directly
+ self._calc_info_from_envvar()
+ return
+
for blas in blas_order:
if self._calc_info(blas):
return
@@ -2443,8 +2478,6 @@ class accelerate_info(system_info):
'accelerate' in libraries):
if intel:
args.extend(['-msse3'])
- else:
- args.extend(['-faltivec'])
args.extend([
'-I/System/Library/Frameworks/vecLib.framework/Headers'])
link_args.extend(['-Wl,-framework', '-Wl,Accelerate'])
@@ -2453,8 +2486,6 @@ class accelerate_info(system_info):
'veclib' in libraries):
if intel:
args.extend(['-msse3'])
- else:
- args.extend(['-faltivec'])
args.extend([
'-I/System/Library/Frameworks/vecLib.framework/Headers'])
link_args.extend(['-Wl,-framework', '-Wl,vecLib'])
@@ -2468,6 +2499,9 @@ class accelerate_info(system_info):
return
class blas_src_info(system_info):
+ # BLAS_SRC is deprecated, please do not use this!
+ # Build or install a BLAS library via your package manager or from
+ # source separately.
section = 'blas_src'
dir_env_var = 'BLAS_SRC'
notfounderror = BlasSrcNotFoundError
@@ -3071,8 +3105,9 @@ def show_all(argv=None):
del show_only[show_only.index(name)]
conf = c()
conf.verbosity = 2
- # FIXME: r not used
- r = conf.get_info()
+ # we don't need the result, but we want
+ # the side effect of printing diagnostics
+ conf.get_info()
if show_only:
log.info('Info classes not defined: %s', ','.join(show_only))
diff --git a/numpy/distutils/tests/test_build_ext.py b/numpy/distutils/tests/test_build_ext.py
new file mode 100644
index 000000000..c007159f5
--- /dev/null
+++ b/numpy/distutils/tests/test_build_ext.py
@@ -0,0 +1,72 @@
+'''Tests for numpy.distutils.build_ext.'''
+
+import os
+import subprocess
+import sys
+from textwrap import indent, dedent
+import pytest
+
+@pytest.mark.slow
+def test_multi_fortran_libs_link(tmp_path):
+ '''
+ Ensures multiple "fake" static libraries are correctly linked.
+ see gh-18295
+ '''
+
+ # We need to make sure we actually have an f77 compiler.
+ # This is nontrivial, so we'll borrow the utilities
+ # from f2py tests:
+ from numpy.f2py.tests.util import has_f77_compiler
+ if not has_f77_compiler():
+ pytest.skip('No F77 compiler found')
+
+ # make some dummy sources
+ with open(tmp_path / '_dummy1.f', 'w') as fid:
+ fid.write(indent(dedent('''\
+ FUNCTION dummy_one()
+ RETURN
+ END FUNCTION'''), prefix=' '*6))
+ with open(tmp_path / '_dummy2.f', 'w') as fid:
+ fid.write(indent(dedent('''\
+ FUNCTION dummy_two()
+ RETURN
+ END FUNCTION'''), prefix=' '*6))
+ with open(tmp_path / '_dummy.c', 'w') as fid:
+ # doesn't need to load - just needs to exist
+ fid.write('int PyInit_dummyext;')
+
+ # make a setup file
+ with open(tmp_path / 'setup.py', 'w') as fid:
+ srctree = os.path.join(os.path.dirname(__file__), '..', '..', '..')
+ fid.write(dedent(f'''\
+ def configuration(parent_package="", top_path=None):
+ from numpy.distutils.misc_util import Configuration
+ config = Configuration("", parent_package, top_path)
+ config.add_library("dummy1", sources=["_dummy1.f"])
+ config.add_library("dummy2", sources=["_dummy2.f"])
+ config.add_extension("dummyext", sources=["_dummy.c"], libraries=["dummy1", "dummy2"])
+ return config
+
+
+ if __name__ == "__main__":
+ import sys
+ sys.path.insert(0, r"{srctree}")
+ from numpy.distutils.core import setup
+ setup(**configuration(top_path="").todict())'''))
+
+ # build the test extensino and "install" into a temporary directory
+ build_dir = tmp_path
+ subprocess.check_call([sys.executable, 'setup.py', 'build', 'install',
+ '--prefix', str(tmp_path / 'installdir'),
+ '--record', str(tmp_path / 'tmp_install_log.txt'),
+ ],
+ cwd=str(build_dir),
+ )
+ # get the path to the so
+ so = None
+ with open(tmp_path /'tmp_install_log.txt') as fid:
+ for line in fid:
+ if 'dummyext' in line:
+ so = line.strip()
+ break
+ assert so is not None
diff --git a/numpy/distutils/tests/test_ccompiler_opt.py b/numpy/distutils/tests/test_ccompiler_opt.py
index a789be1ea..9c54ed66b 100644
--- a/numpy/distutils/tests/test_ccompiler_opt.py
+++ b/numpy/distutils/tests/test_ccompiler_opt.py
@@ -73,7 +73,7 @@ class FakeCCompilerOpt(CCompilerOpt):
def dist_log(*args, stderr=False):
pass
-class _Test_CCompilerOpt(object):
+class _Test_CCompilerOpt:
arch = None # x86_64
cc = None # gcc
@@ -82,7 +82,7 @@ class _Test_CCompilerOpt(object):
self._opt = None
def nopt(self, *args, **kwargs):
- FakeCCompilerOpt.fake_info = self.arch + '_' + self.cc
+ FakeCCompilerOpt.fake_info = (self.arch, self.cc, "")
return FakeCCompilerOpt(*args, **kwargs)
def opt(self):
@@ -112,7 +112,7 @@ class _Test_CCompilerOpt(object):
gflags = {}
fake_objects = opt.try_dispatch([file])
for source, flags in fake_objects:
- gtar = source.split('.')[1:-1]
+ gtar = path.basename(source).split('.')[1:-1]
glen = len(gtar)
if glen == 0:
gtar = "baseline"
diff --git a/numpy/distutils/tests/test_ccompiler_opt_conf.py b/numpy/distutils/tests/test_ccompiler_opt_conf.py
index 244748e58..09c1fad40 100644
--- a/numpy/distutils/tests/test_ccompiler_opt_conf.py
+++ b/numpy/distutils/tests/test_ccompiler_opt_conf.py
@@ -19,7 +19,7 @@ arch_compilers = dict(
)
class FakeCCompilerOpt(CCompilerOpt):
- fake_info = ""
+ fake_info = ("arch", "compiler", "extra_args")
def __init__(self, *args, **kwargs):
CCompilerOpt.__init__(self, None, **kwargs)
def dist_compile(self, sources, flags, **kwargs):
@@ -169,7 +169,7 @@ class TestConfFeatures(unittest.TestCase):
def test_features(self):
for arch, compilers in arch_compilers.items():
for cc in compilers:
- FakeCCompilerOpt.fake_info = arch + cc
+ FakeCCompilerOpt.fake_info = (arch, cc, "")
_TestConfFeatures()
if is_standalone:
diff --git a/numpy/distutils/tests/test_system_info.py b/numpy/distutils/tests/test_system_info.py
index ec15126f7..b722281ad 100644
--- a/numpy/distutils/tests/test_system_info.py
+++ b/numpy/distutils/tests/test_system_info.py
@@ -269,7 +269,7 @@ class TestSystemInfoReading:
# But if we copy the values to a '[mkl]' section the value
# is correct
with open(cfg, 'r') as fid:
- mkl = fid.read().replace('ALL', 'mkl')
+ mkl = fid.read().replace('[ALL]', '[mkl]', 1)
with open(cfg, 'w') as fid:
fid.write(mkl)
info = mkl_info()
@@ -277,7 +277,7 @@ class TestSystemInfoReading:
# Also, the values will be taken from a section named '[DEFAULT]'
with open(cfg, 'r') as fid:
- dflt = fid.read().replace('mkl', 'DEFAULT')
+ dflt = fid.read().replace('[mkl]', '[DEFAULT]', 1)
with open(cfg, 'w') as fid:
fid.write(dflt)
info = mkl_info()
diff --git a/numpy/distutils/unixccompiler.py b/numpy/distutils/unixccompiler.py
index 0cd2d243e..fb91f1789 100644
--- a/numpy/distutils/unixccompiler.py
+++ b/numpy/distutils/unixccompiler.py
@@ -54,7 +54,7 @@ def UnixCCompiler__compile(self, obj, src, ext, cc_args, extra_postargs, pp_opts
extra_postargs, display = display)
except DistutilsExecError as e:
msg = str(e)
- raise CompileError(msg)
+ raise CompileError(msg) from None
# add commandline flags to dependency file
if deps:
@@ -131,7 +131,7 @@ def UnixCCompiler_create_static_lib(self, objects, output_libname,
display = display)
except DistutilsExecError as e:
msg = str(e)
- raise LibError(msg)
+ raise LibError(msg) from None
else:
log.debug("skipping %s (up-to-date)", output_filename)
return
diff --git a/numpy/emath.pyi b/numpy/emath.pyi
deleted file mode 100644
index 032ec9505..000000000
--- a/numpy/emath.pyi
+++ /dev/null
@@ -1,11 +0,0 @@
-from typing import Any
-
-sqrt: Any
-log: Any
-log2: Any
-logn: Any
-log10: Any
-power: Any
-arccos: Any
-arcsin: Any
-arctanh: Any
diff --git a/numpy/f2py/__init__.py b/numpy/f2py/__init__.py
index 07ab6cd7d..47354cd9d 100644
--- a/numpy/f2py/__init__.py
+++ b/numpy/f2py/__init__.py
@@ -2,7 +2,7 @@
"""Fortran to Python Interface Generator.
"""
-__all__ = ['run_main', 'compile', 'f2py_testing']
+__all__ = ['run_main', 'compile', 'get_include']
import sys
import subprocess
@@ -122,6 +122,53 @@ def compile(source,
return cp.returncode
+def get_include():
+ """
+ Return the directory that contains the fortranobject.c and .h files.
+
+ .. note::
+
+ This function is not needed when building an extension with
+ `numpy.distutils` directly from ``.f`` and/or ``.pyf`` files
+ in one go.
+
+ Python extension modules built with f2py-generated code need to use
+ ``fortranobject.c`` as a source file, and include the ``fortranobject.h``
+ header. This function can be used to obtain the directory containing
+ both of these files.
+
+ Returns
+ -------
+ include_path : str
+ Absolute path to the directory containing ``fortranobject.c`` and
+ ``fortranobject.h``.
+
+ Notes
+ -----
+ .. versionadded:: 1.22.0
+
+ Unless the build system you are using has specific support for f2py,
+ building a Python extension using a ``.pyf`` signature file is a two-step
+ process. For a module ``mymod``:
+
+ - Step 1: run ``python -m numpy.f2py mymod.pyf --quiet``. This
+ generates ``_mymodmodule.c`` and (if needed)
+ ``_fblas-f2pywrappers.f`` files next to ``mymod.pyf``.
+ - Step 2: build your Python extension module. This requires the
+ following source files:
+
+ - ``_mymodmodule.c``
+ - ``_mymod-f2pywrappers.f`` (if it was generated in step 1)
+ - ``fortranobject.c``
+
+ See Also
+ --------
+ numpy.get_include : function that returns the numpy include directory
+
+ """
+ return os.path.join(os.path.dirname(__file__), 'src')
+
+
if sys.version_info[:2] >= (3, 7):
# module level getattr is only supported in 3.7 onwards
# https://www.python.org/dev/peps/pep-0562/
diff --git a/numpy/f2py/__init__.pyi b/numpy/f2py/__init__.pyi
index 602517957..7d8e092ea 100644
--- a/numpy/f2py/__init__.pyi
+++ b/numpy/f2py/__init__.pyi
@@ -1,5 +1,43 @@
-from typing import Any
+import os
+import subprocess
+from typing import Any, List, Iterable, Dict, overload
+from typing_extensions import TypedDict, Literal as L
-run_main: Any
-compile: Any
-f2py_testing: Any
+from numpy._pytesttester import PytestTester
+
+class _F2PyDictBase(TypedDict):
+ csrc: List[str]
+ h: List[str]
+
+class _F2PyDict(_F2PyDictBase, total=False):
+ fsrc: List[str]
+ ltx: List[str]
+
+__all__: List[str]
+__path__: List[str]
+test: PytestTester
+
+def run_main(comline_list: Iterable[str]) -> Dict[str, _F2PyDict]: ...
+
+@overload
+def compile( # type: ignore[misc]
+ source: str | bytes,
+ modulename: str = ...,
+ extra_args: str | List[str] = ...,
+ verbose: bool = ...,
+ source_fn: None | str | bytes | os.PathLike[Any] = ...,
+ extension: L[".f", ".f90"] = ...,
+ full_output: L[False] = ...,
+) -> int: ...
+@overload
+def compile(
+ source: str | bytes,
+ modulename: str = ...,
+ extra_args: str | List[str] = ...,
+ verbose: bool = ...,
+ source_fn: None | str | bytes | os.PathLike[Any] = ...,
+ extension: L[".f", ".f90"] = ...,
+ full_output: L[True] = ...,
+) -> subprocess.CompletedProcess[bytes]: ...
+
+def get_include() -> str: ...
diff --git a/numpy/f2py/auxfuncs.py b/numpy/f2py/auxfuncs.py
index 80b150655..5250fea84 100644
--- a/numpy/f2py/auxfuncs.py
+++ b/numpy/f2py/auxfuncs.py
@@ -257,6 +257,7 @@ def ismodule(rout):
def isfunction(rout):
return 'block' in rout and 'function' == rout['block']
+
def isfunction_wrap(rout):
if isintent_c(rout):
return 0
@@ -284,6 +285,10 @@ def hasassumedshape(rout):
return False
+def requiresf90wrapper(rout):
+ return ismoduleroutine(rout) or hasassumedshape(rout)
+
+
def isroutine(rout):
return isfunction(rout) or issubroutine(rout)
diff --git a/numpy/f2py/capi_maps.py b/numpy/f2py/capi_maps.py
index 472ddde43..fe0d4a52b 100644
--- a/numpy/f2py/capi_maps.py
+++ b/numpy/f2py/capi_maps.py
@@ -307,7 +307,7 @@ def getstrlength(var):
len = a['*']
elif 'len' in a:
len = a['len']
- if re.match(r'\(\s*([*]|[:])\s*\)', len) or re.match(r'([*]|[:])', len):
+ if re.match(r'\(\s*(\*|:)\s*\)', len) or re.match(r'(\*|:)', len):
if isintent_hide(var):
errmess('getstrlength:intent(hide): expected a string with defined length but got: %s\n' % (
repr(var)))
diff --git a/numpy/f2py/cb_rules.py b/numpy/f2py/cb_rules.py
index 3068dc897..62aa2fca9 100644
--- a/numpy/f2py/cb_rules.py
+++ b/numpy/f2py/cb_rules.py
@@ -70,7 +70,8 @@ static #name#_t *get_active_#name#(void) {
/*typedef #rctype#(*#name#_typedef)(#optargs_td##args_td##strarglens_td##noargs#);*/
#static# #rctype# #callbackname# (#optargs##args##strarglens##noargs#) {
- #name#_t *cb;
+ #name#_t cb_local = { NULL, NULL, 0 };
+ #name#_t *cb = NULL;
PyTupleObject *capi_arglist = NULL;
PyObject *capi_return = NULL;
PyObject *capi_tmp = NULL;
@@ -82,12 +83,17 @@ static #name#_t *get_active_#name#(void) {
f2py_cb_start_clock();
#endif
cb = get_active_#name#();
+ if (cb == NULL) {
+ capi_longjmp_ok = 0;
+ cb = &cb_local;
+ }
capi_arglist = cb->args_capi;
CFUNCSMESS(\"cb:Call-back function #name# (maxnofargs=#maxnofargs#(-#nofoptargs#))\\n\");
CFUNCSMESSPY(\"cb:#name#_capi=\",cb->capi);
if (cb->capi==NULL) {
capi_longjmp_ok = 0;
cb->capi = PyObject_GetAttrString(#modulename#_module,\"#argname#\");
+ CFUNCSMESSPY(\"cb:#name#_capi=\",cb->capi);
}
if (cb->capi==NULL) {
PyErr_SetString(#modulename#_error,\"cb: Callback #argname# not defined (as an argument or module #modulename# attribute).\\n\");
@@ -342,6 +348,7 @@ cb_arg_rules = [
isarray: '#ctype# *',
isstring: '#ctype#'
},
+ 'need': {l_or(isscalar, isarray, isstring): '#ctype#'},
# untested with multiple args
'strarglens': {isstring: ',int #varname_i#_cb_len'},
'strarglens_td': {isstring: ',int'}, # untested with multiple args
diff --git a/numpy/f2py/cfuncs.py b/numpy/f2py/cfuncs.py
index 26b43e7e6..714f9a932 100644
--- a/numpy/f2py/cfuncs.py
+++ b/numpy/f2py/cfuncs.py
@@ -469,7 +469,7 @@ cppmacros['MEMCOPY'] = """\
"""
cppmacros['STRINGMALLOC'] = """\
#define STRINGMALLOC(str,len)\\
- if ((str = (string)malloc(sizeof(char)*(len+1))) == NULL) {\\
+ if ((str = (string)malloc(len+1)) == NULL) {\\
PyErr_SetString(PyExc_MemoryError, \"out of memory\");\\
goto capi_fail;\\
} else {\\
@@ -479,20 +479,41 @@ cppmacros['STRINGMALLOC'] = """\
cppmacros['STRINGFREE'] = """\
#define STRINGFREE(str) do {if (!(str == NULL)) free(str);} while (0)
"""
+needs['STRINGPADN'] = ['string.h']
+cppmacros['STRINGPADN'] = """\
+/*
+STRINGPADN replaces null values with padding values from the right.
+
+`to` must have size of at least N bytes.
+
+If the `to[N-1]` has null value, then replace it and all the
+preceeding nulls with the given padding.
+
+STRINGPADN(to, N, PADDING, NULLVALUE) is an inverse operation.
+*/
+#define STRINGPADN(to, N, NULLVALUE, PADDING) \\
+ do { \\
+ int _m = (N); \\
+ char *_to = (to); \\
+ for (_m -= 1; _m >= 0 && _to[_m] == NULLVALUE; _m--) { \\
+ _to[_m] = PADDING; \\
+ } \\
+ } while (0)
+"""
needs['STRINGCOPYN'] = ['string.h', 'FAILNULL']
cppmacros['STRINGCOPYN'] = """\
-#define STRINGCOPYN(to,from,buf_size) \\
+/*
+STRINGCOPYN copies N bytes.
+
+`to` and `from` buffers must have sizes of at least N bytes.
+*/
+#define STRINGCOPYN(to,from,N) \\
do { \\
- int _m = (buf_size); \\
+ int _m = (N); \\
char *_to = (to); \\
char *_from = (from); \\
FAILNULL(_to); FAILNULL(_from); \\
- (void)strncpy(_to, _from, sizeof(char)*_m); \\
- _to[_m-1] = '\\0'; \\
- /* Padding with spaces instead of nulls */ \\
- for (_m -= 2; _m >= 0 && _to[_m] == '\\0'; _m--) { \\
- _to[_m] = ' '; \\
- } \\
+ (void)strncpy(_to, _from, _m); \\
} while (0)
"""
needs['STRINGCOPY'] = ['string.h', 'FAILNULL']
@@ -545,11 +566,18 @@ cppmacros['OLDPYNUM'] = """\
"""
cppmacros["F2PY_THREAD_LOCAL_DECL"] = """\
#ifndef F2PY_THREAD_LOCAL_DECL
-#if defined(_MSC_VER)
+#if defined(_MSC_VER) \\
+ || defined(_WIN32) || defined(_WIN64) \\
+ || defined(__MINGW32__) || defined(__MINGW64__)
#define F2PY_THREAD_LOCAL_DECL __declspec(thread)
#elif defined(__STDC_VERSION__) \\
&& (__STDC_VERSION__ >= 201112L) \\
- && !defined(__STDC_NO_THREADS__)
+ && !defined(__STDC_NO_THREADS__) \\
+ && (!defined(__GLIBC__) || __GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 12))
+/* __STDC_NO_THREADS__ was first defined in a maintenance release of glibc 2.12,
+ see https://lists.gnu.org/archive/html/commit-hurd/2012-07/msg00180.html,
+ so `!defined(__STDC_NO_THREADS__)` may give false positive for the existence
+ of `threads.h` when using an older release of glibc 2.12 */
#include <threads.h>
#define F2PY_THREAD_LOCAL_DECL thread_local
#elif defined(__GNUC__) \\
@@ -616,71 +644,127 @@ static int *nextforcomb(void) {
}"""
needs['try_pyarr_from_string'] = ['STRINGCOPYN', 'PRINTPYOBJERR', 'string']
cfuncs['try_pyarr_from_string'] = """\
-static int try_pyarr_from_string(PyObject *obj,const string str) {
- PyArrayObject *arr = NULL;
- if (PyArray_Check(obj) && (!((arr = (PyArrayObject *)obj) == NULL)))
- { STRINGCOPYN(PyArray_DATA(arr),str,PyArray_NBYTES(arr)); }
- return 1;
+/*
+ try_pyarr_from_string copies str[:len(obj)] to the data of an `ndarray`.
+
+ If obj is an `ndarray`, it is assumed to be contiguous.
+
+ If the specified len==-1, str must be null-terminated.
+*/
+static int try_pyarr_from_string(PyObject *obj,
+ const string str, const int len) {
+#ifdef DEBUGCFUNCS
+fprintf(stderr, "try_pyarr_from_string(str='%s', len=%d, obj=%p)\\n",
+ (char*)str,len, obj);
+#endif
+ if (PyArray_Check(obj)) {
+ PyArrayObject *arr = (PyArrayObject *)obj;
+ assert(ISCONTIGUOUS(arr));
+ string buf = PyArray_DATA(arr);
+ npy_intp n = len;
+ if (n == -1) {
+ /* Assuming null-terminated str. */
+ n = strlen(str);
+ }
+ if (n > PyArray_NBYTES(arr)) {
+ n = PyArray_NBYTES(arr);
+ }
+ STRINGCOPYN(buf, str, n);
+ return 1;
+ }
capi_fail:
PRINTPYOBJERR(obj);
- PyErr_SetString(#modulename#_error,\"try_pyarr_from_string failed\");
+ PyErr_SetString(#modulename#_error, \"try_pyarr_from_string failed\");
return 0;
}
"""
needs['string_from_pyobj'] = ['string', 'STRINGMALLOC', 'STRINGCOPYN']
cfuncs['string_from_pyobj'] = """\
+/*
+ Create a new string buffer `str` of at most length `len` from a
+ Python string-like object `obj`.
+
+ The string buffer has given size (len) or the size of inistr when len==-1.
+
+ The string buffer is padded with blanks: in Fortran, trailing blanks
+ are insignificant contrary to C nulls.
+ */
static int
-string_from_pyobj(string *str,int *len,const string inistr,PyObject *obj,const char *errmess)
+string_from_pyobj(string *str, int *len, const string inistr, PyObject *obj,
+ const char *errmess)
{
- PyArrayObject *arr = NULL;
PyObject *tmp = NULL;
+ string buf = NULL;
+ npy_intp n = -1;
#ifdef DEBUGCFUNCS
-fprintf(stderr,\"string_from_pyobj(str='%s',len=%d,inistr='%s',obj=%p)\\n\",(char*)str,*len,(char *)inistr,obj);
+fprintf(stderr,\"string_from_pyobj(str='%s',len=%d,inistr='%s',obj=%p)\\n\",
+ (char*)str, *len, (char *)inistr, obj);
#endif
if (obj == Py_None) {
- if (*len == -1)
- *len = strlen(inistr); /* Will this cause problems? */
- STRINGMALLOC(*str,*len);
- STRINGCOPYN(*str,inistr,*len+1);
- return 1;
+ n = strlen(inistr);
+ buf = inistr;
}
- if (PyArray_Check(obj)) {
- if ((arr = (PyArrayObject *)obj) == NULL)
- goto capi_fail;
+ else if (PyArray_Check(obj)) {
+ PyArrayObject *arr = (PyArrayObject *)obj;
if (!ISCONTIGUOUS(arr)) {
- PyErr_SetString(PyExc_ValueError,\"array object is non-contiguous.\");
+ PyErr_SetString(PyExc_ValueError,
+ \"array object is non-contiguous.\");
goto capi_fail;
}
- if (*len == -1)
- *len = (PyArray_ITEMSIZE(arr))*PyArray_SIZE(arr);
- STRINGMALLOC(*str,*len);
- STRINGCOPYN(*str,PyArray_DATA(arr),*len+1);
- return 1;
- }
- if (PyBytes_Check(obj)) {
- tmp = obj;
- Py_INCREF(tmp);
- }
- else if (PyUnicode_Check(obj)) {
- tmp = PyUnicode_AsASCIIString(obj);
+ n = PyArray_NBYTES(arr);
+ buf = PyArray_DATA(arr);
+ n = strnlen(buf, n);
}
else {
- PyObject *tmp2;
- tmp2 = PyObject_Str(obj);
- if (tmp2) {
- tmp = PyUnicode_AsASCIIString(tmp2);
- Py_DECREF(tmp2);
+ if (PyBytes_Check(obj)) {
+ tmp = obj;
+ Py_INCREF(tmp);
+ }
+ else if (PyUnicode_Check(obj)) {
+ tmp = PyUnicode_AsASCIIString(obj);
}
else {
- tmp = NULL;
+ PyObject *tmp2;
+ tmp2 = PyObject_Str(obj);
+ if (tmp2) {
+ tmp = PyUnicode_AsASCIIString(tmp2);
+ Py_DECREF(tmp2);
+ }
+ else {
+ tmp = NULL;
+ }
+ }
+ if (tmp == NULL) goto capi_fail;
+ n = PyBytes_GET_SIZE(tmp);
+ buf = PyBytes_AS_STRING(tmp);
+ }
+ if (*len == -1) {
+ /* TODO: change the type of `len` so that we can remove this */
+ if (n > NPY_MAX_INT) {
+ PyErr_SetString(PyExc_OverflowError,
+ "object too large for a 32-bit int");
+ goto capi_fail;
}
+ *len = n;
}
- if (tmp == NULL) goto capi_fail;
- if (*len == -1)
- *len = PyBytes_GET_SIZE(tmp);
- STRINGMALLOC(*str,*len);
- STRINGCOPYN(*str,PyBytes_AS_STRING(tmp),*len+1);
- Py_DECREF(tmp);
+ else if (*len < n) {
+ /* discard the last (len-n) bytes of input buf */
+ n = *len;
+ }
+ if (n < 0 || *len < 0 || buf == NULL) {
+ goto capi_fail;
+ }
+ STRINGMALLOC(*str, *len); // *str is allocated with size (*len + 1)
+ if (n < *len) {
+ /*
+ Pad fixed-width string with nulls. The caller will replace
+ nulls with blanks when the corresponding argument is not
+ intent(c).
+ */
+ memset(*str + n, '\\0', *len - n);
+ }
+ STRINGCOPYN(*str, buf, n);
+ Py_XDECREF(tmp);
return 1;
capi_fail:
Py_XDECREF(tmp);
@@ -695,7 +779,6 @@ capi_fail:
}
"""
-
needs['char_from_pyobj'] = ['int_from_pyobj']
cfuncs['char_from_pyobj'] = """\
static int
@@ -1018,6 +1101,7 @@ complex_double_from_pyobj(complex_double* v, PyObject *obj, const char *errmess)
}
(*v).r = ((npy_cdouble *)PyArray_DATA(arr))->real;
(*v).i = ((npy_cdouble *)PyArray_DATA(arr))->imag;
+ Py_DECREF(arr);
return 1;
}
/* Python does not provide PyNumber_Complex function :-( */
diff --git a/numpy/f2py/crackfortran.py b/numpy/f2py/crackfortran.py
index 2e95e4596..3ac9b80c8 100755
--- a/numpy/f2py/crackfortran.py
+++ b/numpy/f2py/crackfortran.py
@@ -43,7 +43,8 @@ Usage:
'implicit','externals','interfaced','common','sortvars',
'commonvars','note']}
B['block'] = 'interface' | 'function' | 'subroutine' | 'module' |
- 'program' | 'block data' | 'type' | 'pythonmodule'
+ 'program' | 'block data' | 'type' | 'pythonmodule' |
+ 'abstract interface'
B['body'] --- list containing `subblocks' with the same structure as `blocks'
B['parent_block'] --- dictionary of a parent block:
C['body'][<index>]['parent_block'] is C
@@ -294,10 +295,10 @@ def getextension(name):
return ''
return name[i + 1:]
-is_f_file = re.compile(r'.*[.](for|ftn|f77|f)\Z', re.I).match
-_has_f_header = re.compile(r'-[*]-\s*fortran\s*-[*]-', re.I).search
-_has_f90_header = re.compile(r'-[*]-\s*f90\s*-[*]-', re.I).search
-_has_fix_header = re.compile(r'-[*]-\s*fix\s*-[*]-', re.I).search
+is_f_file = re.compile(r'.*\.(for|ftn|f77|f)\Z', re.I).match
+_has_f_header = re.compile(r'-\*-\s*fortran\s*-\*-', re.I).search
+_has_f90_header = re.compile(r'-\*-\s*f90\s*-\*-', re.I).search
+_has_fix_header = re.compile(r'-\*-\s*fix\s*-\*-', re.I).search
_free_f90_start = re.compile(r'[^c*]\s*[^\s\d\t]', re.I).match
@@ -341,7 +342,9 @@ def readfortrancode(ffile, dowithline=show, istop=1):
if ffile == []:
return
localdolowercase = dolowercase
- cont = 0
+ # cont: set to True when the content of the last line read
+ # indicates statement continuation
+ cont = False
finalline = ''
ll = ''
includeline = re.compile(
@@ -392,14 +395,26 @@ def readfortrancode(ffile, dowithline=show, istop=1):
if rl[:5].lower() == '!f2py': # f2py directive
l, _ = split_by_unquoted(l + 4 * ' ' + rl[5:], '!')
if l.strip() == '': # Skip empty line
- cont = 0
+ if sourcecodeform == 'free':
+ # In free form, a statement continues in the next line
+ # that is not a comment line [3.3.2.4^1], lines with
+ # blanks are comment lines [3.3.2.3^1]. Hence, the
+ # line continuation flag must retain its state.
+ pass
+ else:
+ # In fixed form, statement continuation is determined
+ # by a non-blank character at the 6-th position. Empty
+ # line indicates a start of a new statement
+ # [3.3.3.3^1]. Hence, the line continuation flag must
+ # be reset.
+ cont = False
continue
if sourcecodeform == 'fix':
if l[0] in ['*', 'c', '!', 'C', '#']:
if l[1:5].lower() == 'f2py': # f2py directive
l = ' ' + l[5:]
else: # Skip comment line
- cont = 0
+ cont = False
continue
elif strictf77:
if len(l) > 72:
@@ -553,15 +568,15 @@ groupbegins77 = r'program|block\s*data'
beginpattern77 = re.compile(
beforethisafter % ('', groupbegins77, groupbegins77, '.*'), re.I), 'begin'
groupbegins90 = groupbegins77 + \
- r'|module(?!\s*procedure)|python\s*module|interface|type(?!\s*\()'
+ r'|module(?!\s*procedure)|python\s*module|(abstract|)\s*interface|' + \
+ r'type(?!\s*\()'
beginpattern90 = re.compile(
beforethisafter % ('', groupbegins90, groupbegins90, '.*'), re.I), 'begin'
groupends = (r'end|endprogram|endblockdata|endmodule|endpythonmodule|'
r'endinterface|endsubroutine|endfunction')
endpattern = re.compile(
beforethisafter % ('', groupends, groupends, r'[\w\s]*'), re.I), 'end'
-# endifs='end\s*(if|do|where|select|while|forall)'
-endifs = r'(end\s*(if|do|where|select|while|forall))|(module\s*procedure)'
+endifs = r'(end\s*(if|do|where|select|while|forall|associate|block|critical|enum|team))|(module\s*procedure)'
endifpattern = re.compile(
beforethisafter % (r'[\w]*?', endifs, endifs, r'[\w\s]*'), re.I), 'endif'
#
@@ -636,7 +651,7 @@ def _simplifyargs(argsline):
a.append(n)
return ','.join(a)
-crackline_re_1 = re.compile(r'\s*(?P<result>\b[a-z]+[\w]*\b)\s*[=].*', re.I)
+crackline_re_1 = re.compile(r'\s*(?P<result>\b[a-z]+\w*\b)\s*=.*', re.I)
def crackline(line, reset=0):
@@ -868,7 +883,7 @@ def appenddecl(decl, decl2, force=1):
return decl
selectpattern = re.compile(
- r'\s*(?P<this>(@\(@.*?@\)@|[*][\d*]+|[*]\s*@\(@.*?@\)@|))(?P<after>.*)\Z', re.I)
+ r'\s*(?P<this>(@\(@.*?@\)@|\*[\d*]+|\*\s*@\(@.*?@\)@|))(?P<after>.*)\Z', re.I)
nameargspattern = re.compile(
r'\s*(?P<name>\b[\w$]+\b)\s*(@\(@\s*(?P<args>[\w\s,]*)\s*@\)@|)\s*((result(\s*@\(@\s*(?P<result>\b[\w$]+\b)\s*@\)@|))|(bind\s*@\(@\s*(?P<bind>.*)\s*@\)@))*\s*\Z', re.I)
callnameargspattern = re.compile(
@@ -928,15 +943,17 @@ def analyzeline(m, case, line):
block = block.lower()
if re.match(r'block\s*data', block, re.I):
block = 'block data'
- if re.match(r'python\s*module', block, re.I):
+ elif re.match(r'python\s*module', block, re.I):
block = 'python module'
+ elif re.match(r'abstract\s*interface', block, re.I):
+ block = 'abstract interface'
name, args, result, bind = _resolvenameargspattern(m.group('after'))
if name is None:
if block == 'block data':
name = '_BLOCK_DATA_'
else:
name = ''
- if block not in ['interface', 'block data']:
+ if block not in ['interface', 'block data', 'abstract interface']:
outmess('analyzeline: No name/args pattern found for line.\n')
previous_context = (block, name, groupcounter)
@@ -970,7 +987,7 @@ def analyzeline(m, case, line):
if f77modulename and neededmodule == -1 and groupcounter <= 1:
neededmodule = groupcounter + 2
needmodule = 1
- if block != 'interface':
+ if block not in ['interface', 'abstract interface']:
needinterface = 1
# Create new block(s)
groupcounter = groupcounter + 1
@@ -1010,7 +1027,7 @@ def analyzeline(m, case, line):
groupname[groupcounter] = block
groupcache[groupcounter]['block'] = block
if not name:
- name = 'unknown_' + block
+ name = 'unknown_' + block.replace(' ', '_')
groupcache[groupcounter]['prefix'] = m.group('before')
groupcache[groupcounter]['name'] = rmbadname1(name)
groupcache[groupcounter]['result'] = result
@@ -1389,7 +1406,7 @@ def analyzeline(m, case, line):
previous_context = ('common', bn, groupcounter)
elif case == 'use':
m1 = re.match(
- r'\A\s*(?P<name>\b[\w]+\b)\s*((,(\s*\bonly\b\s*:|(?P<notonly>))\s*(?P<list>.*))|)\s*\Z', m.group('after'), re.I)
+ r'\A\s*(?P<name>\b\w+\b)\s*((,(\s*\bonly\b\s*:|(?P<notonly>))\s*(?P<list>.*))|)\s*\Z', m.group('after'), re.I)
if m1:
mm = m1.groupdict()
if 'use' not in groupcache[groupcounter]:
@@ -1406,7 +1423,7 @@ def analyzeline(m, case, line):
for l in ll:
if '=' in l:
m2 = re.match(
- r'\A\s*(?P<local>\b[\w]+\b)\s*=\s*>\s*(?P<use>\b[\w]+\b)\s*\Z', l, re.I)
+ r'\A\s*(?P<local>\b\w+\b)\s*=\s*>\s*(?P<use>\b\w+\b)\s*\Z', l, re.I)
if m2:
rl[m2.group('local').strip()] = m2.group(
'use').strip()
@@ -1482,15 +1499,15 @@ def cracktypespec0(typespec, ll):
ll = ll[i + 2:]
return typespec, selector, attr, ll
#####
-namepattern = re.compile(r'\s*(?P<name>\b[\w]+\b)\s*(?P<after>.*)\s*\Z', re.I)
+namepattern = re.compile(r'\s*(?P<name>\b\w+\b)\s*(?P<after>.*)\s*\Z', re.I)
kindselector = re.compile(
- r'\s*(\(\s*(kind\s*=)?\s*(?P<kind>.*)\s*\)|[*]\s*(?P<kind2>.*?))\s*\Z', re.I)
+ r'\s*(\(\s*(kind\s*=)?\s*(?P<kind>.*)\s*\)|\*\s*(?P<kind2>.*?))\s*\Z', re.I)
charselector = re.compile(
- r'\s*(\((?P<lenkind>.*)\)|[*]\s*(?P<charlen>.*))\s*\Z', re.I)
+ r'\s*(\((?P<lenkind>.*)\)|\*\s*(?P<charlen>.*))\s*\Z', re.I)
lenkindpattern = re.compile(
r'\s*(kind\s*=\s*(?P<kind>.*?)\s*(@,@\s*len\s*=\s*(?P<len>.*)|)|(len\s*=\s*|)(?P<len2>.*?)\s*(@,@\s*(kind\s*=\s*|)(?P<kind2>.*)|))\s*\Z', re.I)
lenarraypattern = re.compile(
- r'\s*(@\(@\s*(?!/)\s*(?P<array>.*?)\s*@\)@\s*[*]\s*(?P<len>.*?)|([*]\s*(?P<len2>.*?)|)\s*(@\(@\s*(?!/)\s*(?P<array2>.*?)\s*@\)@|))\s*(=\s*(?P<init>.*?)|(@\(@|)/\s*(?P<init2>.*?)\s*/(@\)@|)|)\s*\Z', re.I)
+ r'\s*(@\(@\s*(?!/)\s*(?P<array>.*?)\s*@\)@\s*\*\s*(?P<len>.*?)|(\*\s*(?P<len2>.*?)|)\s*(@\(@\s*(?!/)\s*(?P<array2>.*?)\s*@\)@|))\s*(=\s*(?P<init>.*?)|(@\(@|)/\s*(?P<init2>.*?)\s*/(@\)@|)|)\s*\Z', re.I)
def removespaces(expr):
@@ -1509,27 +1526,40 @@ def removespaces(expr):
def markinnerspaces(line):
- l = ''
- f = 0
- cc = '\''
- cb = ''
+ """
+ The function replace all spaces in the input variable line which are
+ surrounded with quotation marks, with the triplet "@_@".
+
+ For instance, for the input "a 'b c'" the function returns "a 'b@_@c'"
+
+ Parameters
+ ----------
+ line : str
+
+ Returns
+ -------
+ str
+
+ """
+ fragment = ''
+ inside = False
+ current_quote = None
+ escaped = ''
for c in line:
- if cb == '\\' and c in ['\\', '\'', '"']:
- l = l + c
- cb = c
+ if escaped == '\\' and c in ['\\', '\'', '"']:
+ fragment += c
+ escaped = c
continue
- if f == 0 and c in ['\'', '"']:
- cc = c
- if c == cc:
- f = f + 1
- elif c == cc:
- f = f - 1
- elif c == ' ' and f == 1:
- l = l + '@_@'
+ if not inside and c in ['\'', '"']:
+ current_quote = c
+ if c == current_quote:
+ inside = not inside
+ elif c == ' ' and inside:
+ fragment += '@_@'
continue
- l = l + c
- cb = c
- return l
+ fragment += c
+ escaped = c # reset to non-backslash
+ return fragment
def updatevars(typespec, selector, attrspec, entitydecl):
@@ -1611,6 +1641,10 @@ def updatevars(typespec, selector, attrspec, entitydecl):
edecl['charselector'] = copy.copy(charselect)
edecl['typename'] = typename
edecl['attrspec'] = copy.copy(attrspec)
+ if 'external' in (edecl.get('attrspec') or []) and e in groupcache[groupcounter]['args']:
+ if 'externals' not in groupcache[groupcounter]:
+ groupcache[groupcounter]['externals'] = []
+ groupcache[groupcounter]['externals'].append(e)
if m.group('after'):
m1 = lenarraypattern.match(markouterparen(m.group('after')))
if m1:
@@ -2071,7 +2105,7 @@ def analyzebody(block, args, tab=''):
else:
as_ = args
b = postcrack(b, as_, tab=tab + '\t')
- if b['block'] == 'interface' and not b['body']:
+ if b['block'] in ['interface', 'abstract interface'] and not b['body']:
if 'f2pyenhancements' not in b:
continue
if b['block'].replace(' ', '') == 'pythonmodule':
@@ -2530,10 +2564,8 @@ def get_parameters(vars, global_params={}):
v = ''.join(tt)
elif iscomplex(vars[n]):
- # FIXME complex numbers may also have exponents
- if v[0] == '(' and v[-1] == ')':
- # FIXME, unused l looks like potential bug
- l = markoutercomma(v[1:-1]).split('@,@')
+ outmess(f'get_parameters[TODO]: '
+ f'implement evaluation of complex expression {v}')
try:
params[n] = eval(v, g_params, params)
@@ -2605,7 +2637,7 @@ def analyzevars(block):
params = get_parameters(vars, get_useparameters(block))
dep_matches = {}
- name_match = re.compile(r'\w[\w\d_$]*').match
+ name_match = re.compile(r'[A-Za-z][\w$]*').match
for v in list(vars.keys()):
m = name_match(v)
if m:
@@ -2964,7 +2996,7 @@ def expr2name(a, block, args=[]):
def analyzeargs(block):
setmesstext(block)
- implicitrules, attrrules = buildimplicitrules(block)
+ implicitrules, _ = buildimplicitrules(block)
if 'args' not in block:
block['args'] = []
args = []
@@ -2988,10 +3020,10 @@ def analyzeargs(block):
block['vars'][block['result']] = {}
return block
-determineexprtype_re_1 = re.compile(r'\A\(.+?[,].+?\)\Z', re.I)
-determineexprtype_re_2 = re.compile(r'\A[+-]?\d+(_(?P<name>[\w]+)|)\Z', re.I)
+determineexprtype_re_1 = re.compile(r'\A\(.+?,.+?\)\Z', re.I)
+determineexprtype_re_2 = re.compile(r'\A[+-]?\d+(_(?P<name>\w+)|)\Z', re.I)
determineexprtype_re_3 = re.compile(
- r'\A[+-]?[\d.]+[\d+\-de.]*(_(?P<name>[\w]+)|)\Z', re.I)
+ r'\A[+-]?[\d.]+[-\d+de.]*(_(?P<name>\w+)|)\Z', re.I)
determineexprtype_re_4 = re.compile(r'\A\(.*\)\Z', re.I)
determineexprtype_re_5 = re.compile(r'\A(?P<name>\w+)\s*\(.*?\)\s*\Z', re.I)
@@ -3109,7 +3141,7 @@ def crack2fortrangen(block, tab='\n', as_interface=False):
result = ' result (%s)' % block['result']
if block['result'] not in argsl:
argsl.append(block['result'])
- body = crack2fortrangen(block['body'], tab + tabchar)
+ body = crack2fortrangen(block['body'], tab + tabchar, as_interface=as_interface)
vars = vars2fortran(
block, block['vars'], argsl, tab + tabchar, as_interface=as_interface)
mess = ''
@@ -3227,8 +3259,13 @@ def vars2fortran(block, vars, args, tab='', as_interface=False):
show(vars)
outmess('vars2fortran: No definition for argument "%s".\n' % a)
continue
- if a == block['name'] and not block['block'] == 'function':
- continue
+ if a == block['name']:
+ if block['block'] != 'function' or block.get('result'):
+ # 1) skip declaring a variable that name matches with
+ # subroutine name
+ # 2) skip declaring function when its type is
+ # declared via `result` construction
+ continue
if 'typespec' not in vars[a]:
if 'attrspec' in vars[a] and 'external' in vars[a]['attrspec']:
if a in args:
diff --git a/numpy/f2py/f2py2e.py b/numpy/f2py/f2py2e.py
index b45d985aa..a14f068f1 100755
--- a/numpy/f2py/f2py2e.py
+++ b/numpy/f2py/f2py2e.py
@@ -511,14 +511,14 @@ def run_compile():
remove_build_dir = 1
build_dir = tempfile.mkdtemp()
- _reg1 = re.compile(r'[-][-]link[-]')
+ _reg1 = re.compile(r'--link-')
sysinfo_flags = [_m for _m in sys.argv[1:] if _reg1.match(_m)]
sys.argv = [_m for _m in sys.argv if _m not in sysinfo_flags]
if sysinfo_flags:
sysinfo_flags = [f[7:] for f in sysinfo_flags]
_reg2 = re.compile(
- r'[-][-]((no[-]|)(wrap[-]functions|lower)|debug[-]capi|quiet)|[-]include')
+ r'--((no-|)(wrap-functions|lower)|debug-capi|quiet)|-include')
f2py_flags = [_m for _m in sys.argv[1:] if _reg2.match(_m)]
sys.argv = [_m for _m in sys.argv if _m not in f2py_flags]
f2py_flags2 = []
@@ -536,11 +536,11 @@ def run_compile():
sys.argv = [_m for _m in sys.argv if _m not in f2py_flags2]
_reg3 = re.compile(
- r'[-][-]((f(90)?compiler([-]exec|)|compiler)=|help[-]compiler)')
+ r'--((f(90)?compiler(-exec|)|compiler)=|help-compiler)')
flib_flags = [_m for _m in sys.argv[1:] if _reg3.match(_m)]
sys.argv = [_m for _m in sys.argv if _m not in flib_flags]
_reg4 = re.compile(
- r'[-][-]((f(77|90)(flags|exec)|opt|arch)=|(debug|noopt|noarch|help[-]fcompiler))')
+ r'--((f(77|90)(flags|exec)|opt|arch)=|(debug|noopt|noarch|help-fcompiler))')
fc_flags = [_m for _m in sys.argv[1:] if _reg4.match(_m)]
sys.argv = [_m for _m in sys.argv if _m not in fc_flags]
@@ -569,7 +569,7 @@ def run_compile():
del flib_flags[i]
assert len(flib_flags) <= 2, repr(flib_flags)
- _reg5 = re.compile(r'[-][-](verbose)')
+ _reg5 = re.compile(r'--(verbose)')
setup_flags = [_m for _m in sys.argv[1:] if _reg5.match(_m)]
sys.argv = [_m for _m in sys.argv if _m not in setup_flags]
diff --git a/numpy/f2py/f90mod_rules.py b/numpy/f2py/f90mod_rules.py
index 122fa8939..3e1c9674f 100644
--- a/numpy/f2py/f90mod_rules.py
+++ b/numpy/f2py/f90mod_rules.py
@@ -192,7 +192,8 @@ def buildhooks(pymod):
if hasbody(m):
for b in m['body']:
if not isroutine(b):
- print('Skipping', b['block'], b['name'])
+ outmess("f90mod_rules.buildhooks:"
+ f" skipping {b['block']} {b['name']}\n")
continue
modobjs.append('%s()' % (b['name']))
b['modulename'] = m['name']
diff --git a/numpy/f2py/func2subr.py b/numpy/f2py/func2subr.py
index e9976f43c..21d4c009c 100644
--- a/numpy/f2py/func2subr.py
+++ b/numpy/f2py/func2subr.py
@@ -130,7 +130,7 @@ def createfuncwrapper(rout, signature=0):
l = l + ', ' + fortranname
if need_interface:
for line in rout['saved_interface'].split('\n'):
- if line.lstrip().startswith('use '):
+ if line.lstrip().startswith('use ') and '__user__' not in line:
add(line)
args = args[1:]
@@ -222,7 +222,7 @@ def createsubrwrapper(rout, signature=0):
if need_interface:
for line in rout['saved_interface'].split('\n'):
- if line.lstrip().startswith('use '):
+ if line.lstrip().startswith('use ') and '__user__' not in line:
add(line)
dumped_args = []
@@ -247,7 +247,10 @@ def createsubrwrapper(rout, signature=0):
pass
else:
add('interface')
- add(rout['saved_interface'].lstrip())
+ for line in rout['saved_interface'].split('\n'):
+ if line.lstrip().startswith('use ') and '__user__' in line:
+ continue
+ add(line)
add('end interface')
sargs = ', '.join([a for a in args if a not in extra_args])
diff --git a/numpy/f2py/rules.py b/numpy/f2py/rules.py
index f1490527e..587ae2e5f 100755
--- a/numpy/f2py/rules.py
+++ b/numpy/f2py/rules.py
@@ -73,7 +73,7 @@ from .auxfuncs import (
issubroutine, issubroutine_wrap, isthreadsafe, isunsigned,
isunsigned_char, isunsigned_chararray, isunsigned_long_long,
isunsigned_long_longarray, isunsigned_short, isunsigned_shortarray,
- l_and, l_not, l_or, outmess, replace, stripcomma,
+ l_and, l_not, l_or, outmess, replace, stripcomma, requiresf90wrapper
)
from . import capi_maps
@@ -561,7 +561,8 @@ rout_rules = [
'\tint #name#_return_value_len = 0;'],
'callfortran':'#name#_return_value,#name#_return_value_len,',
'callfortranroutine':['\t#name#_return_value_len = #rlength#;',
- '\tif ((#name#_return_value = (string)malloc(sizeof(char)*(#name#_return_value_len+1))) == NULL) {',
+ '\tif ((#name#_return_value = (string)malloc('
+ '#name#_return_value_len+1) == NULL) {',
'\t\tPyErr_SetString(PyExc_MemoryError, \"out of memory\");',
'\t\tf2py_success = 0;',
'\t} else {',
@@ -809,7 +810,7 @@ if (#varname#_cb.capi==Py_None) {
""",
{debugcapi: ["""\
fprintf(stderr,\"debug-capi:Assuming %d arguments; at most #maxnofargs#(-#nofoptargs#) is expected.\\n\",#varname#_cb.nofargs);
- CFUNCSMESSPY(\"for #varname#=\",#cbname#_capi);""",
+ CFUNCSMESSPY(\"for #varname#=\",#varname#_cb.capi);""",
{l_not(isintent_callback): """ fprintf(stderr,\"#vardebugshowvalue# (call-back in C).\\n\",#cbname#);"""}]},
"""\
CFUNCSMESS(\"Saving callback variables for `#varname#`.\\n\");
@@ -942,19 +943,35 @@ if (#varname#_cb.capi==Py_None) {
'\tPyObject *#varname#_capi = Py_None;'],
'callfortran':'#varname#,',
'callfortranappend':'slen(#varname#),',
- 'pyobjfrom':{debugcapi: '\tfprintf(stderr,"#vardebugshowvalue#\\n",slen(#varname#),#varname#);'},
+ 'pyobjfrom':[
+ {debugcapi:
+ '\tfprintf(stderr,'
+ '"#vardebugshowvalue#\\n",slen(#varname#),#varname#);'},
+ # The trailing null value for Fortran is blank.
+ {l_and(isintent_out, l_not(isintent_c)):
+ "\t\tSTRINGPADN(#varname#, slen(#varname#), ' ', '\\0');"},
+ ],
'return': {isintent_out: ',#varname#'},
- 'need': ['len..'], # 'STRINGFREE'],
+ 'need': ['len..',
+ {l_and(isintent_out, l_not(isintent_c)): 'STRINGPADN'}],
'_check':isstring
}, { # Common
- 'frompyobj': """\
+ 'frompyobj': [
+ """\
\tslen(#varname#) = #length#;
-\tf2py_success = #ctype#_from_pyobj(&#varname#,&slen(#varname#),#init#,#varname#_capi,\"#ctype#_from_pyobj failed in converting #nth# `#varname#\' of #pyname# to C #ctype#\");
+\tf2py_success = #ctype#_from_pyobj(&#varname#,&slen(#varname#),#init#,"""
+"""#varname#_capi,\"#ctype#_from_pyobj failed in converting #nth#"""
+"""`#varname#\' of #pyname# to C #ctype#\");
\tif (f2py_success) {""",
+ # The trailing null value for Fortran is blank.
+ {l_not(isintent_c):
+ "\t\tSTRINGPADN(#varname#, slen(#varname#), '\\0', ' ');"},
+ ],
'cleanupfrompyobj': """\
\t\tSTRINGFREE(#varname#);
\t} /*if (f2py_success) of #varname#*/""",
- 'need': ['#ctype#_from_pyobj', 'len..', 'STRINGFREE'],
+ 'need': ['#ctype#_from_pyobj', 'len..', 'STRINGFREE',
+ {l_not(isintent_c): 'STRINGPADN'}],
'_check':isstring,
'_depend':''
}, { # Not hidden
@@ -962,11 +979,16 @@ if (#varname#_cb.capi==Py_None) {
'keyformat': {isoptional: 'O'},
'args_capi': {isrequired: ',&#varname#_capi'},
'keys_capi': {isoptional: ',&#varname#_capi'},
- 'pyobjfrom': {isintent_inout: '''\
-\tf2py_success = try_pyarr_from_#ctype#(#varname#_capi,#varname#);
-\tif (f2py_success) {'''},
+ 'pyobjfrom': [
+ {l_and(isintent_inout, l_not(isintent_c)):
+ "\t\tSTRINGPADN(#varname#, slen(#varname#), ' ', '\\0');"},
+ {isintent_inout: '''\
+\tf2py_success = try_pyarr_from_#ctype#(#varname#_capi, #varname#,
+\t slen(#varname#));
+\tif (f2py_success) {'''}],
'closepyobjfrom': {isintent_inout: '\t} /*if (f2py_success) of #varname# pyobjfrom*/'},
- 'need': {isintent_inout: 'try_pyarr_from_#ctype#'},
+ 'need': {isintent_inout: 'try_pyarr_from_#ctype#',
+ l_and(isintent_inout, l_not(isintent_c)): 'STRINGPADN'},
'_check': l_and(isstring, isintent_nothide)
}, { # Hidden
'_check': l_and(isstring, isintent_hide)
@@ -1163,7 +1185,7 @@ def buildmodule(m, um):
for n in m['interfaced']:
nb = None
for bi in m['body']:
- if not bi['block'] == 'interface':
+ if bi['block'] not in ['interface', 'abstract interface']:
errmess('buildmodule: Expected interface block. Skipping.\n')
continue
for b in bi['body']:
@@ -1184,9 +1206,12 @@ def buildmodule(m, um):
nb1['args'] = a
nb_list.append(nb1)
for nb in nb_list:
+ # requiresf90wrapper must be called before buildapi as it
+ # rewrites assumed shape arrays as automatic arrays.
+ isf90 = requiresf90wrapper(nb)
api, wrap = buildapi(nb)
if wrap:
- if ismoduleroutine(nb):
+ if isf90:
funcwrappers2.append(wrap)
else:
funcwrappers.append(wrap)
@@ -1288,7 +1313,10 @@ def buildmodule(m, um):
'C It contains Fortran 77 wrappers to fortran functions.\n')
lines = []
for l in ('\n\n'.join(funcwrappers) + '\n').split('\n'):
- if l and l[0] == ' ':
+ if 0 <= l.find('!') < 66:
+ # don't split comment lines
+ lines.append(l + '\n')
+ elif l and l[0] == ' ':
while len(l) >= 66:
lines.append(l[:66] + '\n &')
l = l[66:]
@@ -1310,7 +1338,10 @@ def buildmodule(m, um):
'! It contains Fortran 90 wrappers to fortran functions.\n')
lines = []
for l in ('\n\n'.join(funcwrappers2) + '\n').split('\n'):
- if len(l) > 72 and l[0] == ' ':
+ if 0 <= l.find('!') < 72:
+ # don't split comment lines
+ lines.append(l + '\n')
+ elif len(l) > 72 and l[0] == ' ':
lines.append(l[:72] + '&\n &')
l = l[72:]
while len(l) > 66:
diff --git a/numpy/f2py/src/fortranobject.c b/numpy/f2py/src/fortranobject.c
index 3275f90ad..b9ef18701 100644
--- a/numpy/f2py/src/fortranobject.c
+++ b/numpy/f2py/src/fortranobject.c
@@ -799,7 +799,7 @@ PyArrayObject* array_from_pyobj(const int type_num,
&& ARRAY_ISCOMPATIBLE(arr,type_num)
&& F2PY_CHECK_ALIGNMENT(arr, intent)
) {
- if ((intent & F2PY_INTENT_C)?PyArray_ISCARRAY(arr):PyArray_ISFARRAY(arr)) {
+ if ((intent & F2PY_INTENT_C)?PyArray_ISCARRAY_RO(arr):PyArray_ISFARRAY_RO(arr)) {
if ((intent & F2PY_INTENT_OUT)) {
Py_INCREF(arr);
}
@@ -807,9 +807,9 @@ PyArrayObject* array_from_pyobj(const int type_num,
return arr;
}
}
-
if (intent & F2PY_INTENT_INOUT) {
strcpy(mess, "failed to initialize intent(inout) array");
+ /* Must use PyArray_IS*ARRAY because intent(inout) requires writable input */
if ((intent & F2PY_INTENT_C) && !PyArray_ISCARRAY(arr))
strcat(mess, " -- input not contiguous");
if (!(intent & F2PY_INTENT_C) && !PyArray_ISFARRAY(arr))
diff --git a/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c b/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c
index 0411b62e0..fe21d4b9b 100644
--- a/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c
+++ b/numpy/f2py/tests/src/array_from_pyobj/wrapmodule.c
@@ -93,7 +93,7 @@ static PyObject *f2py_rout_wrap_attrs(PyObject *capi_self,
PyObject *strides = NULL;
char s[100];
int i;
- memset(s,0,100*sizeof(char));
+ memset(s,0,100);
if (!PyArg_ParseTuple(capi_args,"O!|:wrap.attrs",
&PyArray_Type,&arr_capi))
return NULL;
diff --git a/numpy/f2py/tests/test_abstract_interface.py b/numpy/f2py/tests/test_abstract_interface.py
new file mode 100644
index 000000000..936c1f7bc
--- /dev/null
+++ b/numpy/f2py/tests/test_abstract_interface.py
@@ -0,0 +1,66 @@
+import textwrap
+from . import util
+from numpy.f2py import crackfortran
+
+
+class TestAbstractInterface(util.F2PyTest):
+ suffix = '.f90'
+
+ skip = ['add1', 'add2']
+
+ code = textwrap.dedent("""
+ module ops_module
+
+ abstract interface
+ subroutine op(x, y, z)
+ integer, intent(in) :: x, y
+ integer, intent(out) :: z
+ end subroutine
+ end interface
+
+ contains
+
+ subroutine foo(x, y, r1, r2)
+ integer, intent(in) :: x, y
+ integer, intent(out) :: r1, r2
+ procedure (op) add1, add2
+ procedure (op), pointer::p
+ p=>add1
+ call p(x, y, r1)
+ p=>add2
+ call p(x, y, r2)
+ end subroutine
+ end module
+
+ subroutine add1(x, y, z)
+ integer, intent(in) :: x, y
+ integer, intent(out) :: z
+ z = x + y
+ end subroutine
+
+ subroutine add2(x, y, z)
+ integer, intent(in) :: x, y
+ integer, intent(out) :: z
+ z = x + 2 * y
+ end subroutine
+ """)
+
+ def test_abstract_interface(self):
+ assert self.module.ops_module.foo(3, 5) == (8, 13)
+
+ def test_parse_abstract_interface(self, tmp_path):
+ # Test gh18403
+ f_path = tmp_path / "gh18403_mod.f90"
+ with f_path.open('w') as ff:
+ ff.write(textwrap.dedent("""\
+ module test
+ abstract interface
+ subroutine foo()
+ end subroutine
+ end interface
+ end module test
+ """))
+ mod = crackfortran.crackfortran([str(f_path)])
+ assert len(mod) == 1
+ assert len(mod[0]['body']) == 1
+ assert mod[0]['body'][0]['block'] == 'abstract interface'
diff --git a/numpy/f2py/tests/test_array_from_pyobj.py b/numpy/f2py/tests/test_array_from_pyobj.py
index b719f2495..649fd1c48 100644
--- a/numpy/f2py/tests/test_array_from_pyobj.py
+++ b/numpy/f2py/tests/test_array_from_pyobj.py
@@ -1,11 +1,11 @@
import os
import sys
import copy
+import platform
import pytest
-from numpy import (
- array, alltrue, ndarray, zeros, dtype, intp, clongdouble
- )
+import numpy as np
+
from numpy.testing import assert_, assert_equal
from numpy.core.multiarray import typeinfo
from . import util
@@ -119,8 +119,11 @@ _cast_dict['CFLOAT'] = _cast_dict['FLOAT'] + ['CFLOAT']
# 16 byte long double types this means the inout intent cannot be satisfied
# and several tests fail as the alignment flag can be randomly true or fals
# when numpy gains an aligned allocator the tests could be enabled again
-if ((intp().dtype.itemsize != 4 or clongdouble().dtype.alignment <= 8) and
- sys.platform != 'win32'):
+#
+# Furthermore, on macOS ARM64, LONGDOUBLE is an alias for DOUBLE.
+if ((np.intp().dtype.itemsize != 4 or np.clongdouble().dtype.alignment <= 8) and
+ sys.platform != 'win32' and
+ (platform.system(), platform.processor()) != ('Darwin', 'arm')):
_type_names.extend(['LONGDOUBLE', 'CDOUBLE', 'CLONGDOUBLE'])
_cast_dict['LONGDOUBLE'] = _cast_dict['LONG'] + \
['ULONG', 'FLOAT', 'DOUBLE', 'LONGDOUBLE']
@@ -133,7 +136,7 @@ class Type:
_type_cache = {}
def __new__(cls, name):
- if isinstance(name, dtype):
+ if isinstance(name, np.dtype):
dtype0 = name
name = None
for n, i in typeinfo.items():
@@ -153,7 +156,8 @@ class Type:
info = typeinfo[self.NAME]
self.type_num = getattr(wrap, 'NPY_' + self.NAME)
assert_equal(self.type_num, info.num)
- self.dtype = info.type
+ self.dtype = np.dtype(info.type)
+ self.type = info.type
self.elsize = info.bits / 8
self.dtypechar = info.char
@@ -202,7 +206,7 @@ class Array:
# arr.dtypechar may be different from typ.dtypechar
self.arr = wrap.call(typ.type_num, dims, intent.flags, obj)
- assert_(isinstance(self.arr, ndarray), repr(type(self.arr)))
+ assert_(isinstance(self.arr, np.ndarray), repr(type(self.arr)))
self.arr_attr = wrap.array_attrs(self.arr)
@@ -225,13 +229,15 @@ class Array:
return
if intent.is_intent('cache'):
- assert_(isinstance(obj, ndarray), repr(type(obj)))
- self.pyarr = array(obj).reshape(*dims).copy()
+ assert_(isinstance(obj, np.ndarray), repr(type(obj)))
+ self.pyarr = np.array(obj).reshape(*dims).copy()
else:
- self.pyarr = array(array(obj, dtype=typ.dtypechar).reshape(*dims),
- order=self.intent.is_intent('c') and 'C' or 'F')
+ self.pyarr = np.array(
+ np.array(obj, dtype=typ.dtypechar).reshape(*dims),
+ order=self.intent.is_intent('c') and 'C' or 'F')
assert_(self.pyarr.dtype == typ,
repr((self.pyarr.dtype, typ)))
+ self.pyarr.setflags(write=self.arr.flags['WRITEABLE'])
assert_(self.pyarr.flags['OWNDATA'], (obj, intent))
self.pyarr_attr = wrap.array_attrs(self.pyarr)
@@ -266,7 +272,7 @@ class Array:
repr((self.arr_attr[5][3], self.type.elsize)))
assert_(self.arr_equal(self.pyarr, self.arr))
- if isinstance(self.obj, ndarray):
+ if isinstance(self.obj, np.ndarray):
if typ.elsize == Type(obj.dtype).elsize:
if not intent.is_intent('copy') and self.arr_attr[1] <= 1:
assert_(self.has_shared_memory())
@@ -274,8 +280,7 @@ class Array:
def arr_equal(self, arr1, arr2):
if arr1.shape != arr2.shape:
return False
- s = arr1 == arr2
- return alltrue(s.flatten())
+ return (arr1 == arr2).all()
def __str__(self):
return str(self.arr)
@@ -285,7 +290,7 @@ class Array:
"""
if self.obj is self.arr:
return True
- if not isinstance(self.obj, ndarray):
+ if not isinstance(self.obj, np.ndarray):
return False
obj_attr = wrap.array_attrs(self.obj)
return obj_attr[0] == self.arr_attr[0]
@@ -318,7 +323,7 @@ class TestSharedMemory:
def test_in_from_2casttype(self):
for t in self.type.cast_types():
- obj = array(self.num2seq, dtype=t.dtype)
+ obj = np.array(self.num2seq, dtype=t.dtype)
a = self.array([len(self.num2seq)], intent.in_, obj)
if t.elsize == self.type.elsize:
assert_(
@@ -326,8 +331,20 @@ class TestSharedMemory:
else:
assert_(not a.has_shared_memory(), repr(t.dtype))
+ @pytest.mark.parametrize('write', ['w', 'ro'])
+ @pytest.mark.parametrize('order', ['C', 'F'])
+ @pytest.mark.parametrize('inp', ['2seq', '23seq'])
+ def test_in_nocopy(self, write, order, inp):
+ """Test if intent(in) array can be passed without copies
+ """
+ seq = getattr(self, 'num' + inp)
+ obj = np.array(seq, dtype=self.type.dtype, order=order)
+ obj.setflags(write=(write == 'w'))
+ a = self.array(obj.shape, ((order=='C' and intent.in_.c) or intent.in_), obj)
+ assert a.has_shared_memory()
+
def test_inout_2seq(self):
- obj = array(self.num2seq, dtype=self.type.dtype)
+ obj = np.array(self.num2seq, dtype=self.type.dtype)
a = self.array([len(self.num2seq)], intent.inout, obj)
assert_(a.has_shared_memory())
@@ -341,12 +358,12 @@ class TestSharedMemory:
raise SystemError('intent(inout) should have failed on sequence')
def test_f_inout_23seq(self):
- obj = array(self.num23seq, dtype=self.type.dtype, order='F')
+ obj = np.array(self.num23seq, dtype=self.type.dtype, order='F')
shape = (len(self.num23seq), len(self.num23seq[0]))
a = self.array(shape, intent.in_.inout, obj)
assert_(a.has_shared_memory())
- obj = array(self.num23seq, dtype=self.type.dtype, order='C')
+ obj = np.array(self.num23seq, dtype=self.type.dtype, order='C')
shape = (len(self.num23seq), len(self.num23seq[0]))
try:
a = self.array(shape, intent.in_.inout, obj)
@@ -359,14 +376,14 @@ class TestSharedMemory:
'intent(inout) should have failed on improper array')
def test_c_inout_23seq(self):
- obj = array(self.num23seq, dtype=self.type.dtype)
+ obj = np.array(self.num23seq, dtype=self.type.dtype)
shape = (len(self.num23seq), len(self.num23seq[0]))
a = self.array(shape, intent.in_.c.inout, obj)
assert_(a.has_shared_memory())
def test_in_copy_from_2casttype(self):
for t in self.type.cast_types():
- obj = array(self.num2seq, dtype=t.dtype)
+ obj = np.array(self.num2seq, dtype=t.dtype)
a = self.array([len(self.num2seq)], intent.in_.copy, obj)
assert_(not a.has_shared_memory(), repr(t.dtype))
@@ -377,14 +394,14 @@ class TestSharedMemory:
def test_in_from_23casttype(self):
for t in self.type.cast_types():
- obj = array(self.num23seq, dtype=t.dtype)
+ obj = np.array(self.num23seq, dtype=t.dtype)
a = self.array([len(self.num23seq), len(self.num23seq[0])],
intent.in_, obj)
assert_(not a.has_shared_memory(), repr(t.dtype))
def test_f_in_from_23casttype(self):
for t in self.type.cast_types():
- obj = array(self.num23seq, dtype=t.dtype, order='F')
+ obj = np.array(self.num23seq, dtype=t.dtype, order='F')
a = self.array([len(self.num23seq), len(self.num23seq[0])],
intent.in_, obj)
if t.elsize == self.type.elsize:
@@ -394,7 +411,7 @@ class TestSharedMemory:
def test_c_in_from_23casttype(self):
for t in self.type.cast_types():
- obj = array(self.num23seq, dtype=t.dtype)
+ obj = np.array(self.num23seq, dtype=t.dtype)
a = self.array([len(self.num23seq), len(self.num23seq[0])],
intent.in_.c, obj)
if t.elsize == self.type.elsize:
@@ -404,14 +421,14 @@ class TestSharedMemory:
def test_f_copy_in_from_23casttype(self):
for t in self.type.cast_types():
- obj = array(self.num23seq, dtype=t.dtype, order='F')
+ obj = np.array(self.num23seq, dtype=t.dtype, order='F')
a = self.array([len(self.num23seq), len(self.num23seq[0])],
intent.in_.copy, obj)
assert_(not a.has_shared_memory(), repr(t.dtype))
def test_c_copy_in_from_23casttype(self):
for t in self.type.cast_types():
- obj = array(self.num23seq, dtype=t.dtype)
+ obj = np.array(self.num23seq, dtype=t.dtype)
a = self.array([len(self.num23seq), len(self.num23seq[0])],
intent.in_.c.copy, obj)
assert_(not a.has_shared_memory(), repr(t.dtype))
@@ -420,7 +437,7 @@ class TestSharedMemory:
for t in self.type.all_types():
if t.elsize != self.type.elsize:
continue
- obj = array(self.num2seq, dtype=t.dtype)
+ obj = np.array(self.num2seq, dtype=t.dtype)
shape = (len(self.num2seq),)
a = self.array(shape, intent.in_.c.cache, obj)
assert_(a.has_shared_memory(), repr(t.dtype))
@@ -428,7 +445,7 @@ class TestSharedMemory:
a = self.array(shape, intent.in_.cache, obj)
assert_(a.has_shared_memory(), repr(t.dtype))
- obj = array(self.num2seq, dtype=t.dtype, order='F')
+ obj = np.array(self.num2seq, dtype=t.dtype, order='F')
a = self.array(shape, intent.in_.c.cache, obj)
assert_(a.has_shared_memory(), repr(t.dtype))
@@ -449,7 +466,7 @@ class TestSharedMemory:
for t in self.type.all_types():
if t.elsize >= self.type.elsize:
continue
- obj = array(self.num2seq, dtype=t.dtype)
+ obj = np.array(self.num2seq, dtype=t.dtype)
shape = (len(self.num2seq),)
try:
self.array(shape, intent.in_.cache, obj) # Should succeed
@@ -485,18 +502,18 @@ class TestSharedMemory:
shape = (2,)
a = self.array(shape, intent.hide, None)
assert_(a.arr.shape == shape)
- assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
+ assert_(a.arr_equal(a.arr, np.zeros(shape, dtype=self.type.dtype)))
shape = (2, 3)
a = self.array(shape, intent.hide, None)
assert_(a.arr.shape == shape)
- assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
+ assert_(a.arr_equal(a.arr, np.zeros(shape, dtype=self.type.dtype)))
assert_(a.arr.flags['FORTRAN'] and not a.arr.flags['CONTIGUOUS'])
shape = (2, 3)
a = self.array(shape, intent.c.hide, None)
assert_(a.arr.shape == shape)
- assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
+ assert_(a.arr_equal(a.arr, np.zeros(shape, dtype=self.type.dtype)))
assert_(not a.arr.flags['FORTRAN'] and a.arr.flags['CONTIGUOUS'])
shape = (-1, 3)
@@ -514,18 +531,18 @@ class TestSharedMemory:
shape = (2,)
a = self.array(shape, intent.optional, None)
assert_(a.arr.shape == shape)
- assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
+ assert_(a.arr_equal(a.arr, np.zeros(shape, dtype=self.type.dtype)))
shape = (2, 3)
a = self.array(shape, intent.optional, None)
assert_(a.arr.shape == shape)
- assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
+ assert_(a.arr_equal(a.arr, np.zeros(shape, dtype=self.type.dtype)))
assert_(a.arr.flags['FORTRAN'] and not a.arr.flags['CONTIGUOUS'])
shape = (2, 3)
a = self.array(shape, intent.c.optional, None)
assert_(a.arr.shape == shape)
- assert_(a.arr_equal(a.arr, zeros(shape, dtype=self.type.dtype)))
+ assert_(a.arr_equal(a.arr, np.zeros(shape, dtype=self.type.dtype)))
assert_(not a.arr.flags['FORTRAN'] and a.arr.flags['CONTIGUOUS'])
def test_optional_from_2seq(self):
@@ -547,14 +564,14 @@ class TestSharedMemory:
assert_(not a.has_shared_memory())
def test_inplace(self):
- obj = array(self.num23seq, dtype=self.type.dtype)
+ obj = np.array(self.num23seq, dtype=self.type.dtype)
assert_(not obj.flags['FORTRAN'] and obj.flags['CONTIGUOUS'])
shape = obj.shape
a = self.array(shape, intent.inplace, obj)
assert_(obj[1][2] == a.arr[1][2], repr((obj, a.arr)))
a.arr[1][2] = 54
assert_(obj[1][2] == a.arr[1][2] ==
- array(54, dtype=self.type.dtype), repr((obj, a.arr)))
+ np.array(54, dtype=self.type.dtype), repr((obj, a.arr)))
assert_(a.arr is obj)
assert_(obj.flags['FORTRAN']) # obj attributes are changed inplace!
assert_(not obj.flags['CONTIGUOUS'])
@@ -563,17 +580,17 @@ class TestSharedMemory:
for t in self.type.cast_types():
if t is self.type:
continue
- obj = array(self.num23seq, dtype=t.dtype)
- assert_(obj.dtype.type == t.dtype)
- assert_(obj.dtype.type is not self.type.dtype)
+ obj = np.array(self.num23seq, dtype=t.dtype)
+ assert_(obj.dtype.type == t.type)
+ assert_(obj.dtype.type is not self.type.type)
assert_(not obj.flags['FORTRAN'] and obj.flags['CONTIGUOUS'])
shape = obj.shape
a = self.array(shape, intent.inplace, obj)
assert_(obj[1][2] == a.arr[1][2], repr((obj, a.arr)))
a.arr[1][2] = 54
assert_(obj[1][2] == a.arr[1][2] ==
- array(54, dtype=self.type.dtype), repr((obj, a.arr)))
+ np.array(54, dtype=self.type.dtype), repr((obj, a.arr)))
assert_(a.arr is obj)
assert_(obj.flags['FORTRAN']) # obj attributes changed inplace!
assert_(not obj.flags['CONTIGUOUS'])
- assert_(obj.dtype.type is self.type.dtype) # obj changed inplace!
+ assert_(obj.dtype.type is self.type.type) # obj changed inplace!
diff --git a/numpy/f2py/tests/test_assumed_shape.py b/numpy/f2py/tests/test_assumed_shape.py
index dfc252660..79e3ad138 100644
--- a/numpy/f2py/tests/test_assumed_shape.py
+++ b/numpy/f2py/tests/test_assumed_shape.py
@@ -47,7 +47,7 @@ class TestF2cmapOption(TestAssumedShapeSumExample):
self.sources.append(self.f2cmap_file.name)
self.options = ["--f2cmap", self.f2cmap_file.name]
- super(TestF2cmapOption, self).setup()
+ super().setup()
def teardown(self):
os.unlink(self.f2cmap_file.name)
diff --git a/numpy/f2py/tests/test_callback.py b/numpy/f2py/tests/test_callback.py
index 81650a819..2cb429ec2 100644
--- a/numpy/f2py/tests/test_callback.py
+++ b/numpy/f2py/tests/test_callback.py
@@ -61,6 +61,21 @@ cf2py intent(out) a
a = callback(cu, lencu)
end
+
+ subroutine hidden_callback(a, r)
+ external global_f
+cf2py intent(callback, hide) global_f
+ integer a, r, global_f
+cf2py intent(out) r
+ r = global_f(a)
+ end
+
+ subroutine hidden_callback2(a, r)
+ external global_f
+ integer a, r, global_f
+cf2py intent(out) r
+ r = global_f(a)
+ end
"""
@pytest.mark.parametrize('name', 't,t2'.split(','))
@@ -204,6 +219,39 @@ cf2py intent(out) a
if errors:
raise AssertionError(errors)
+ def test_hidden_callback(self):
+ try:
+ self.module.hidden_callback(2)
+ except Exception as msg:
+ assert_(str(msg).startswith('Callback global_f not defined'))
+
+ try:
+ self.module.hidden_callback2(2)
+ except Exception as msg:
+ assert_(str(msg).startswith('cb: Callback global_f not defined'))
+
+ self.module.global_f = lambda x: x + 1
+ r = self.module.hidden_callback(2)
+ assert_(r == 3)
+
+ self.module.global_f = lambda x: x + 2
+ r = self.module.hidden_callback(2)
+ assert_(r == 4)
+
+ del self.module.global_f
+ try:
+ self.module.hidden_callback(2)
+ except Exception as msg:
+ assert_(str(msg).startswith('Callback global_f not defined'))
+
+ self.module.global_f = lambda x=0: x + 3
+ r = self.module.hidden_callback(2)
+ assert_(r == 5)
+
+ # reproducer of gh18341
+ r = self.module.hidden_callback2(2)
+ assert_(r == 3)
+
class TestF77CallbackPythonTLS(TestF77Callback):
"""
@@ -211,3 +259,68 @@ class TestF77CallbackPythonTLS(TestF77Callback):
compiler-provided
"""
options = ["-DF2PY_USE_PYTHON_TLS"]
+
+
+class TestF90Callback(util.F2PyTest):
+
+ suffix = '.f90'
+
+ code = textwrap.dedent(
+ """
+ function gh17797(f, y) result(r)
+ external f
+ integer(8) :: r, f
+ integer(8), dimension(:) :: y
+ r = f(0)
+ r = r + sum(y)
+ end function gh17797
+ """)
+
+ def test_gh17797(self):
+
+ def incr(x):
+ return x + 123
+
+ y = np.array([1, 2, 3], dtype=np.int64)
+ r = self.module.gh17797(incr, y)
+ assert r == 123 + 1 + 2 + 3
+
+
+class TestGH18335(util.F2PyTest):
+ """The reproduction of the reported issue requires specific input that
+ extensions may break the issue conditions, so the reproducer is
+ implemented as a separate test class. Do not extend this test with
+ other tests!
+ """
+
+ suffix = '.f90'
+
+ code = textwrap.dedent(
+ """
+ ! When gh18335_workaround is defined as an extension,
+ ! the issue cannot be reproduced.
+ !subroutine gh18335_workaround(f, y)
+ ! implicit none
+ ! external f
+ ! integer(kind=1) :: y(1)
+ ! call f(y)
+ !end subroutine gh18335_workaround
+
+ function gh18335(f) result (r)
+ implicit none
+ external f
+ integer(kind=1) :: y(1), r
+ y(1) = 123
+ call f(y)
+ r = y(1)
+ end function gh18335
+ """)
+
+ def test_gh18335(self):
+
+ def foo(x):
+ x[0] += 1
+
+ y = np.array([1, 2, 3], dtype=np.int8)
+ r = self.module.gh18335(foo)
+ assert r == 123 + 1
diff --git a/numpy/f2py/tests/test_crackfortran.py b/numpy/f2py/tests/test_crackfortran.py
index 735804024..140f42cbc 100644
--- a/numpy/f2py/tests/test_crackfortran.py
+++ b/numpy/f2py/tests/test_crackfortran.py
@@ -1,8 +1,8 @@
import numpy as np
-from numpy.testing import assert_array_equal
+from numpy.testing import assert_array_equal, assert_equal
+from numpy.f2py.crackfortran import markinnerspaces
from . import util
from numpy.f2py import crackfortran
-import tempfile
import textwrap
@@ -37,6 +37,7 @@ class TestNoSpace(util.F2PyTest):
assert_array_equal(k, w + 1)
assert self.module.t0(23) == b'2'
+
class TestPublicPrivate():
def test_defaultPrivate(self, tmp_path):
f_path = tmp_path / "mod.f90"
@@ -86,3 +87,81 @@ class TestPublicPrivate():
assert 'public' not in mod['vars']['a']['attrspec']
assert 'private' not in mod['vars']['seta']['attrspec']
assert 'public' in mod['vars']['seta']['attrspec']
+
+
+class TestExternal(util.F2PyTest):
+ # issue gh-17859: add external attribute support
+ code = """
+ integer(8) function external_as_statement(fcn)
+ implicit none
+ external fcn
+ integer(8) :: fcn
+ external_as_statement = fcn(0)
+ end
+
+ integer(8) function external_as_attribute(fcn)
+ implicit none
+ integer(8), external :: fcn
+ external_as_attribute = fcn(0)
+ end
+ """
+
+ def test_external_as_statement(self):
+ def incr(x):
+ return x + 123
+ r = self.module.external_as_statement(incr)
+ assert r == 123
+
+ def test_external_as_attribute(self):
+ def incr(x):
+ return x + 123
+ r = self.module.external_as_attribute(incr)
+ assert r == 123
+
+
+class TestCrackFortran(util.F2PyTest):
+
+ suffix = '.f90'
+
+ code = textwrap.dedent("""
+ subroutine gh2848( &
+ ! first 2 parameters
+ par1, par2,&
+ ! last 2 parameters
+ par3, par4)
+
+ integer, intent(in) :: par1, par2
+ integer, intent(out) :: par3, par4
+
+ par3 = par1
+ par4 = par2
+
+ end subroutine gh2848
+ """)
+
+ def test_gh2848(self):
+ r = self.module.gh2848(1, 2)
+ assert r == (1, 2)
+
+
+class TestMarkinnerspaces():
+ # issue #14118: markinnerspaces does not handle multiple quotations
+
+ def test_do_not_touch_normal_spaces(self):
+ test_list = ["a ", " a", "a b c", "'abcdefghij'"]
+ for i in test_list:
+ assert_equal(markinnerspaces(i), i)
+
+ def test_one_relevant_space(self):
+ assert_equal(markinnerspaces("a 'b c' \\\' \\\'"), "a 'b@_@c' \\' \\'")
+ assert_equal(markinnerspaces(r'a "b c" \" \"'), r'a "b@_@c" \" \"')
+
+ def test_ignore_inner_quotes(self):
+ assert_equal(markinnerspaces('a \'b c" " d\' e'),
+ "a 'b@_@c\"@_@\"@_@d' e")
+ assert_equal(markinnerspaces('a "b c\' \' d" e'),
+ "a \"b@_@c'@_@'@_@d\" e")
+
+ def test_multiple_relevant_spaces(self):
+ assert_equal(markinnerspaces("a 'b c' 'd e'"), "a 'b@_@c' 'd@_@e'")
+ assert_equal(markinnerspaces(r'a "b c" "d e"'), r'a "b@_@c" "d@_@e"')
diff --git a/numpy/f2py/tests/test_regression.py b/numpy/f2py/tests/test_regression.py
index a1b772069..b91499e4a 100644
--- a/numpy/f2py/tests/test_regression.py
+++ b/numpy/f2py/tests/test_regression.py
@@ -25,23 +25,31 @@ class TestIntentInOut(util.F2PyTest):
x = np.arange(3, dtype=np.float32)
self.module.foo(x)
assert_equal(x, [3, 1, 2])
-
+
class TestNumpyVersionAttribute(util.F2PyTest):
# Check that th attribute __f2py_numpy_version__ is present
# in the compiled module and that has the value np.__version__.
sources = [_path('src', 'regression', 'inout.f90')]
-
+
@pytest.mark.slow
def test_numpy_version_attribute(self):
-
+
# Check that self.module has an attribute named "__f2py_numpy_version__"
- assert_(hasattr(self.module, "__f2py_numpy_version__"),
+ assert_(hasattr(self.module, "__f2py_numpy_version__"),
msg="Fortran module does not have __f2py_numpy_version__")
-
+
# Check that the attribute __f2py_numpy_version__ is a string
assert_(isinstance(self.module.__f2py_numpy_version__, str),
msg="__f2py_numpy_version__ is not a string")
-
+
# Check that __f2py_numpy_version__ has the value numpy.__version__
assert_string_equal(np.__version__, self.module.__f2py_numpy_version__)
+
+
+def test_include_path():
+ incdir = np.f2py.get_include()
+ fnames_in_dir = os.listdir(incdir)
+ for fname in ('fortranobject.c', 'fortranobject.h'):
+ assert fname in fnames_in_dir
+
diff --git a/numpy/f2py/tests/test_return_character.py b/numpy/f2py/tests/test_return_character.py
index 429e69bb4..7d4ced914 100644
--- a/numpy/f2py/tests/test_return_character.py
+++ b/numpy/f2py/tests/test_return_character.py
@@ -21,11 +21,11 @@ class TestReturnCharacter(util.F2PyTest):
#assert_(_raises(ValueError, t, array([77,87])))
#assert_(_raises(ValueError, t, array(77)))
elif tname in ['ts', 'ss']:
- assert_(t(23) == b'23 ', repr(t(23)))
+ assert_(t(23) == b'23', repr(t(23)))
assert_(t('123456789abcdef') == b'123456789a')
elif tname in ['t5', 's5']:
- assert_(t(23) == b'23 ', repr(t(23)))
- assert_(t('ab') == b'ab ', repr(t('ab')))
+ assert_(t(23) == b'23', repr(t(23)))
+ assert_(t('ab') == b'ab', repr(t('ab')))
assert_(t('123456789abcdef') == b'12345')
else:
raise NotImplementedError
diff --git a/numpy/f2py/tests/test_string.py b/numpy/f2py/tests/test_string.py
index e3ec96af9..7b27f8786 100644
--- a/numpy/f2py/tests/test_string.py
+++ b/numpy/f2py/tests/test_string.py
@@ -1,6 +1,6 @@
import os
import pytest
-
+import textwrap
from numpy.testing import assert_array_equal
import numpy as np
from . import util
@@ -9,14 +9,158 @@ from . import util
def _path(*a):
return os.path.join(*((os.path.dirname(__file__),) + a))
+
class TestString(util.F2PyTest):
sources = [_path('src', 'string', 'char.f90')]
@pytest.mark.slow
def test_char(self):
strings = np.array(['ab', 'cd', 'ef'], dtype='c').T
- inp, out = self.module.char_test.change_strings(strings, strings.shape[1])
+ inp, out = self.module.char_test.change_strings(strings,
+ strings.shape[1])
assert_array_equal(inp, strings)
expected = strings.copy()
expected[1, :] = 'AAA'
assert_array_equal(out, expected)
+
+
+class TestDocStringArguments(util.F2PyTest):
+ suffix = '.f'
+
+ code = """
+C FILE: STRING.F
+ SUBROUTINE FOO(A,B,C,D)
+ CHARACTER*5 A, B
+ CHARACTER*(*) C,D
+Cf2py intent(in) a,c
+Cf2py intent(inout) b,d
+ PRINT*, "A=",A
+ PRINT*, "B=",B
+ PRINT*, "C=",C
+ PRINT*, "D=",D
+ PRINT*, "CHANGE A,B,C,D"
+ A(1:1) = 'A'
+ B(1:1) = 'B'
+ C(1:1) = 'C'
+ D(1:1) = 'D'
+ PRINT*, "A=",A
+ PRINT*, "B=",B
+ PRINT*, "C=",C
+ PRINT*, "D=",D
+ END
+C END OF FILE STRING.F
+ """
+
+ def test_example(self):
+ a = np.array(b'123\0\0')
+ b = np.array(b'123\0\0')
+ c = np.array(b'123')
+ d = np.array(b'123')
+
+ self.module.foo(a, b, c, d)
+
+ assert a.tobytes() == b'123\0\0'
+ assert b.tobytes() == b'B23\0\0', (b.tobytes(),)
+ assert c.tobytes() == b'123'
+ assert d.tobytes() == b'D23'
+
+
+class TestFixedString(util.F2PyTest):
+ suffix = '.f90'
+
+ code = textwrap.dedent("""
+ function sint(s) result(i)
+ implicit none
+ character(len=*) :: s
+ integer :: j, i
+ i = 0
+ do j=len(s), 1, -1
+ if (.not.((i.eq.0).and.(s(j:j).eq.' '))) then
+ i = i + ichar(s(j:j)) * 10 ** (j - 1)
+ endif
+ end do
+ return
+ end function sint
+
+ function test_in_bytes4(a) result (i)
+ implicit none
+ integer :: sint
+ character(len=4) :: a
+ integer :: i
+ i = sint(a)
+ a(1:1) = 'A'
+ return
+ end function test_in_bytes4
+
+ function test_inout_bytes4(a) result (i)
+ implicit none
+ integer :: sint
+ character(len=4), intent(inout) :: a
+ integer :: i
+ if (a(1:1).ne.' ') then
+ a(1:1) = 'E'
+ endif
+ i = sint(a)
+ return
+ end function test_inout_bytes4
+ """)
+
+ @staticmethod
+ def _sint(s, start=0, end=None):
+ """Return the content of a string buffer as integer value.
+
+ For example:
+ _sint('1234') -> 4321
+ _sint('123A') -> 17321
+ """
+ if isinstance(s, np.ndarray):
+ s = s.tobytes()
+ elif isinstance(s, str):
+ s = s.encode()
+ assert isinstance(s, bytes)
+ if end is None:
+ end = len(s)
+ i = 0
+ for j in range(start, min(end, len(s))):
+ i += s[j] * 10 ** j
+ return i
+
+ def _get_input(self, intent='in'):
+ if intent in ['in']:
+ yield ''
+ yield '1'
+ yield '1234'
+ yield '12345'
+ yield b''
+ yield b'\0'
+ yield b'1'
+ yield b'\01'
+ yield b'1\0'
+ yield b'1234'
+ yield b'12345'
+ yield np.ndarray((), np.bytes_, buffer=b'') # array(b'', dtype='|S0')
+ yield np.array(b'') # array(b'', dtype='|S1')
+ yield np.array(b'\0')
+ yield np.array(b'1')
+ yield np.array(b'1\0')
+ yield np.array(b'\01')
+ yield np.array(b'1234')
+ yield np.array(b'123\0')
+ yield np.array(b'12345')
+
+ def test_intent_in(self):
+ for s in self._get_input():
+ r = self.module.test_in_bytes4(s)
+ # also checks that s is not changed inplace
+ expected = self._sint(s, end=4)
+ assert r == expected, (s)
+
+ def test_intent_inout(self):
+ for s in self._get_input(intent='inout'):
+ rest = self._sint(s, start=4)
+ r = self.module.test_inout_bytes4(s)
+ expected = self._sint(s, end=4)
+ assert r == expected
+
+ # check that the rest of input string is preserved
+ assert rest == self._sint(s, start=4)
diff --git a/numpy/fft/__init__.py b/numpy/fft/__init__.py
index a86bb3ac0..fd5e47580 100644
--- a/numpy/fft/__init__.py
+++ b/numpy/fft/__init__.py
@@ -200,9 +200,13 @@ For examples, see the various functions.
"""
+from . import _pocketfft, helper
from ._pocketfft import *
from .helper import *
+__all__ = _pocketfft.__all__.copy()
+__all__ += helper.__all__
+
from numpy._pytesttester import PytestTester
test = PytestTester(__name__)
del PytestTester
diff --git a/numpy/fft/__init__.pyi b/numpy/fft/__init__.pyi
index 45190517f..648b0bf79 100644
--- a/numpy/fft/__init__.pyi
+++ b/numpy/fft/__init__.pyi
@@ -1,20 +1,26 @@
-from typing import Any
+from typing import Any, List
-fft: Any
-ifft: Any
-rfft: Any
-irfft: Any
-hfft: Any
-ihfft: Any
-rfftn: Any
-irfftn: Any
-rfft2: Any
-irfft2: Any
-fft2: Any
-ifft2: Any
-fftn: Any
-ifftn: Any
-fftshift: Any
-ifftshift: Any
-fftfreq: Any
-rfftfreq: Any
+from numpy._pytesttester import PytestTester
+
+__all__: List[str]
+__path__: List[str]
+test: PytestTester
+
+def fft(a, n=..., axis=..., norm=...): ...
+def ifft(a, n=..., axis=..., norm=...): ...
+def rfft(a, n=..., axis=..., norm=...): ...
+def irfft(a, n=..., axis=..., norm=...): ...
+def hfft(a, n=..., axis=..., norm=...): ...
+def ihfft(a, n=..., axis=..., norm=...): ...
+def fftn(a, s=..., axes=..., norm=...): ...
+def ifftn(a, s=..., axes=..., norm=...): ...
+def rfftn(a, s=..., axes=..., norm=...): ...
+def irfftn(a, s=..., axes=..., norm=...): ...
+def fft2(a, s=..., axes=..., norm=...): ...
+def ifft2(a, s=..., axes=..., norm=...): ...
+def rfft2(a, s=..., axes=..., norm=...): ...
+def irfft2(a, s=..., axes=..., norm=...): ...
+def fftshift(x, axes=...): ...
+def ifftshift(x, axes=...): ...
+def fftfreq(n, d=...): ...
+def rfftfreq(n, d=...): ...
diff --git a/numpy/fft/_pocketfft.py b/numpy/fft/_pocketfft.py
index 83ac86036..ad69f7c83 100644
--- a/numpy/fft/_pocketfft.py
+++ b/numpy/fft/_pocketfft.py
@@ -112,7 +112,7 @@ def _swap_direction(norm):
return _SWAP_DIRECTION_MAP[norm]
except KeyError:
raise ValueError(f'Invalid norm value {norm}; should be "backward", '
- '"ortho" or "forward".')
+ '"ortho" or "forward".') from None
def _fft_dispatcher(a, n=None, axis=None, norm=None):
@@ -160,7 +160,7 @@ def fft(a, n=None, axis=-1, norm=None):
Raises
------
IndexError
- if `axes` is larger than the last axis of `a`.
+ If `axis` is not a valid axis of `a`.
See Also
--------
@@ -272,7 +272,7 @@ def ifft(a, n=None, axis=-1, norm=None):
Raises
------
IndexError
- If `axes` is larger than the last axis of `a`.
+ If `axis` is not a valid axis of `a`.
See Also
--------
@@ -300,9 +300,11 @@ def ifft(a, n=None, axis=-1, norm=None):
>>> n = np.zeros((400,), dtype=complex)
>>> n[40:60] = np.exp(1j*np.random.uniform(0, 2*np.pi, (20,)))
>>> s = np.fft.ifft(n)
- >>> plt.plot(t, s.real, 'b-', t, s.imag, 'r--')
- [<matplotlib.lines.Line2D object at ...>, <matplotlib.lines.Line2D object at ...>]
- >>> plt.legend(('real', 'imaginary'))
+ >>> plt.plot(t, s.real, label='real')
+ [<matplotlib.lines.Line2D object at ...>]
+ >>> plt.plot(t, s.imag, '--', label='imaginary')
+ [<matplotlib.lines.Line2D object at ...>]
+ >>> plt.legend()
<matplotlib.legend.Legend object at ...>
>>> plt.show()
@@ -358,7 +360,7 @@ def rfft(a, n=None, axis=-1, norm=None):
Raises
------
IndexError
- If `axis` is larger than the last axis of `a`.
+ If `axis` is not a valid axis of `a`.
See Also
--------
@@ -461,7 +463,7 @@ def irfft(a, n=None, axis=-1, norm=None):
Raises
------
IndexError
- If `axis` is larger than the last axis of `a`.
+ If `axis` is not a valid axis of `a`.
See Also
--------
@@ -556,7 +558,7 @@ def hfft(a, n=None, axis=-1, norm=None):
Raises
------
IndexError
- If `axis` is larger than the last axis of `a`.
+ If `axis` is not a valid axis of `a`.
See also
--------
@@ -1242,6 +1244,15 @@ def rfft2(a, s=None, axes=(-2, -1), norm=None):
This is really just `rfftn` with different default behavior.
For more details see `rfftn`.
+ Examples
+ --------
+ >>> a = np.mgrid[:5, :5][0]
+ >>> np.fft.rfft2(a)
+ array([[ 50. +0.j , 0. +0.j , 0. +0.j ],
+ [-12.5+17.20477401j, 0. +0.j , 0. +0.j ],
+ [-12.5 +4.0614962j , 0. +0.j , 0. +0.j ],
+ [-12.5 -4.0614962j , 0. +0.j , 0. +0.j ],
+ [-12.5-17.20477401j, 0. +0.j , 0. +0.j ]])
"""
return rfftn(a, s, axes, norm)
@@ -1399,5 +1410,15 @@ def irfft2(a, s=None, axes=(-2, -1), norm=None):
This is really `irfftn` with different defaults.
For more details see `irfftn`.
+ Examples
+ --------
+ >>> a = np.mgrid[:5, :5][0]
+ >>> A = np.fft.rfft2(a)
+ >>> np.fft.irfft2(A, s=a.shape)
+ array([[0., 0., 0., 0., 0.],
+ [1., 1., 1., 1., 1.],
+ [2., 2., 2., 2., 2.],
+ [3., 3., 3., 3., 3.],
+ [4., 4., 4., 4., 4.]])
"""
return irfftn(a, s, axes, norm)
diff --git a/numpy/lib/__init__.pyi b/numpy/lib/__init__.pyi
index 413e2ae1b..25640ec07 100644
--- a/numpy/lib/__init__.pyi
+++ b/numpy/lib/__init__.pyi
@@ -1,177 +1,246 @@
-from typing import Any
-
-emath: Any
-math: Any
-tracemalloc_domain: Any
-Arrayterator: Any
-iscomplexobj: Any
-isrealobj: Any
-imag: Any
-iscomplex: Any
-isreal: Any
-nan_to_num: Any
-real: Any
-real_if_close: Any
-typename: Any
-asfarray: Any
-mintypecode: Any
-asscalar: Any
-common_type: Any
-ravel_multi_index: Any
-unravel_index: Any
-mgrid: Any
-ogrid: Any
-r_: Any
-c_: Any
-s_: Any
-index_exp: Any
-ix_: Any
-ndenumerate: Any
-ndindex: Any
-fill_diagonal: Any
-diag_indices: Any
-diag_indices_from: Any
-select: Any
-piecewise: Any
-trim_zeros: Any
-copy: Any
-iterable: Any
-percentile: Any
-diff: Any
-gradient: Any
-angle: Any
-unwrap: Any
-sort_complex: Any
-disp: Any
-flip: Any
-rot90: Any
-extract: Any
-place: Any
-vectorize: Any
-asarray_chkfinite: Any
-average: Any
-bincount: Any
-digitize: Any
-cov: Any
-corrcoef: Any
-msort: Any
-median: Any
-sinc: Any
-hamming: Any
-hanning: Any
-bartlett: Any
-blackman: Any
-kaiser: Any
-trapz: Any
-i0: Any
-add_newdoc: Any
-add_docstring: Any
-meshgrid: Any
-delete: Any
-insert: Any
-append: Any
-interp: Any
-add_newdoc_ufunc: Any
-quantile: Any
-column_stack: Any
-row_stack: Any
-dstack: Any
-array_split: Any
-split: Any
-hsplit: Any
-vsplit: Any
-dsplit: Any
-apply_over_axes: Any
-expand_dims: Any
-apply_along_axis: Any
-kron: Any
-tile: Any
-get_array_wrap: Any
-take_along_axis: Any
-put_along_axis: Any
-broadcast_to: Any
-broadcast_arrays: Any
-diag: Any
-diagflat: Any
-eye: Any
-fliplr: Any
-flipud: Any
-tri: Any
-triu: Any
-tril: Any
-vander: Any
-histogram2d: Any
-mask_indices: Any
-tril_indices: Any
-tril_indices_from: Any
-triu_indices: Any
-triu_indices_from: Any
-fix: Any
-isneginf: Any
-isposinf: Any
-pad: Any
-poly: Any
-roots: Any
-polyint: Any
-polyder: Any
-polyadd: Any
-polysub: Any
-polymul: Any
-polydiv: Any
-polyval: Any
-poly1d: Any
-polyfit: Any
-RankWarning: Any
-issubclass_: Any
-issubsctype: Any
-issubdtype: Any
-deprecate: Any
-deprecate_with_doc: Any
-get_include: Any
-info: Any
-source: Any
-who: Any
-lookfor: Any
-byte_bounds: Any
-safe_eval: Any
-ediff1d: Any
-intersect1d: Any
-setxor1d: Any
-union1d: Any
-setdiff1d: Any
-unique: Any
-in1d: Any
-isin: Any
-savetxt: Any
-loadtxt: Any
-genfromtxt: Any
-ndfromtxt: Any
-mafromtxt: Any
-recfromtxt: Any
-recfromcsv: Any
-load: Any
-loads: Any
-save: Any
-savez: Any
-savez_compressed: Any
-packbits: Any
-unpackbits: Any
-fromregex: Any
-DataSource: Any
-nansum: Any
-nanmax: Any
-nanmin: Any
-nanargmax: Any
-nanargmin: Any
-nanmean: Any
-nanmedian: Any
-nanpercentile: Any
-nanvar: Any
-nanstd: Any
-nanprod: Any
-nancumsum: Any
-nancumprod: Any
-nanquantile: Any
-histogram: Any
-histogramdd: Any
-histogram_bin_edges: Any
+import math as math
+from typing import Any, List
+
+from numpy._pytesttester import PytestTester
+
+from numpy import (
+ ndenumerate as ndenumerate,
+ ndindex as ndindex,
+)
+
+from numpy.version import version
+
+from numpy.lib import (
+ format as format,
+ mixins as mixins,
+ scimath as scimath,
+ stride_tricks as stride_stricks,
+)
+
+from numpy.lib._version import (
+ NumpyVersion as NumpyVersion,
+)
+
+from numpy.lib.arraypad import (
+ pad as pad,
+)
+
+from numpy.lib.arraysetops import (
+ ediff1d as ediff1d,
+ intersect1d as intersect1d,
+ setxor1d as setxor1d,
+ union1d as union1d,
+ setdiff1d as setdiff1d,
+ unique as unique,
+ in1d as in1d,
+ isin as isin,
+)
+
+from numpy.lib.arrayterator import (
+ Arrayterator as Arrayterator,
+)
+
+from numpy.lib.function_base import (
+ select as select,
+ piecewise as piecewise,
+ trim_zeros as trim_zeros,
+ copy as copy,
+ iterable as iterable,
+ percentile as percentile,
+ diff as diff,
+ gradient as gradient,
+ angle as angle,
+ unwrap as unwrap,
+ sort_complex as sort_complex,
+ disp as disp,
+ flip as flip,
+ rot90 as rot90,
+ extract as extract,
+ place as place,
+ vectorize as vectorize,
+ asarray_chkfinite as asarray_chkfinite,
+ average as average,
+ bincount as bincount,
+ digitize as digitize,
+ cov as cov,
+ corrcoef as corrcoef,
+ msort as msort,
+ median as median,
+ sinc as sinc,
+ hamming as hamming,
+ hanning as hanning,
+ bartlett as bartlett,
+ blackman as blackman,
+ kaiser as kaiser,
+ trapz as trapz,
+ i0 as i0,
+ add_newdoc as add_newdoc,
+ add_docstring as add_docstring,
+ meshgrid as meshgrid,
+ delete as delete,
+ insert as insert,
+ append as append,
+ interp as interp,
+ add_newdoc_ufunc as add_newdoc_ufunc,
+ quantile as quantile,
+)
+
+from numpy.lib.histograms import (
+ histogram_bin_edges as histogram_bin_edges,
+ histogram as histogram,
+ histogramdd as histogramdd,
+)
+
+from numpy.lib.index_tricks import (
+ ravel_multi_index as ravel_multi_index,
+ unravel_index as unravel_index,
+ mgrid as mgrid,
+ ogrid as ogrid,
+ r_ as r_,
+ c_ as c_,
+ s_ as s_,
+ index_exp as index_exp,
+ ix_ as ix_,
+ fill_diagonal as fill_diagonal,
+ diag_indices as diag_indices,
+ diag_indices_from as diag_indices_from,
+)
+
+from numpy.lib.nanfunctions import (
+ nansum as nansum,
+ nanmax as nanmax,
+ nanmin as nanmin,
+ nanargmax as nanargmax,
+ nanargmin as nanargmin,
+ nanmean as nanmean,
+ nanmedian as nanmedian,
+ nanpercentile as nanpercentile,
+ nanvar as nanvar,
+ nanstd as nanstd,
+ nanprod as nanprod,
+ nancumsum as nancumsum,
+ nancumprod as nancumprod,
+ nanquantile as nanquantile,
+)
+
+from numpy.lib.npyio import (
+ savetxt as savetxt,
+ loadtxt as loadtxt,
+ genfromtxt as genfromtxt,
+ recfromtxt as recfromtxt,
+ recfromcsv as recfromcsv,
+ load as load,
+ loads as loads,
+ save as save,
+ savez as savez,
+ savez_compressed as savez_compressed,
+ packbits as packbits,
+ unpackbits as unpackbits,
+ fromregex as fromregex,
+ DataSource as DataSource,
+)
+
+from numpy.lib.polynomial import (
+ poly as poly,
+ roots as roots,
+ polyint as polyint,
+ polyder as polyder,
+ polyadd as polyadd,
+ polysub as polysub,
+ polymul as polymul,
+ polydiv as polydiv,
+ polyval as polyval,
+ polyfit as polyfit,
+ RankWarning as RankWarning,
+ poly1d as poly1d,
+)
+
+from numpy.lib.shape_base import (
+ column_stack as column_stack,
+ row_stack as row_stack,
+ dstack as dstack,
+ array_split as array_split,
+ split as split,
+ hsplit as hsplit,
+ vsplit as vsplit,
+ dsplit as dsplit,
+ apply_over_axes as apply_over_axes,
+ expand_dims as expand_dims,
+ apply_along_axis as apply_along_axis,
+ kron as kron,
+ tile as tile,
+ get_array_wrap as get_array_wrap,
+ take_along_axis as take_along_axis,
+ put_along_axis as put_along_axis,
+)
+
+from numpy.lib.stride_tricks import (
+ broadcast_to as broadcast_to,
+ broadcast_arrays as broadcast_arrays,
+ broadcast_shapes as broadcast_shapes,
+)
+
+from numpy.lib.twodim_base import (
+ diag as diag,
+ diagflat as diagflat,
+ eye as eye,
+ fliplr as fliplr,
+ flipud as flipud,
+ tri as tri,
+ triu as triu,
+ tril as tril,
+ vander as vander,
+ histogram2d as histogram2d,
+ mask_indices as mask_indices,
+ tril_indices as tril_indices,
+ tril_indices_from as tril_indices_from,
+ triu_indices as triu_indices,
+ triu_indices_from as triu_indices_from,
+)
+
+from numpy.lib.type_check import (
+ mintypecode as mintypecode,
+ asfarray as asfarray,
+ real as real,
+ imag as imag,
+ iscomplex as iscomplex,
+ isreal as isreal,
+ iscomplexobj as iscomplexobj,
+ isrealobj as isrealobj,
+ nan_to_num as nan_to_num,
+ real_if_close as real_if_close,
+ typename as typename,
+ common_type as common_type,
+)
+
+from numpy.lib.ufunclike import (
+ fix as fix,
+ isposinf as isposinf,
+ isneginf as isneginf,
+)
+
+from numpy.lib.utils import (
+ issubclass_ as issubclass_,
+ issubsctype as issubsctype,
+ issubdtype as issubdtype,
+ deprecate as deprecate,
+ deprecate_with_doc as deprecate_with_doc,
+ get_include as get_include,
+ info as info,
+ source as source,
+ who as who,
+ lookfor as lookfor,
+ byte_bounds as byte_bounds,
+ safe_eval as safe_eval,
+)
+
+from numpy.core.multiarray import (
+ tracemalloc_domain as tracemalloc_domain,
+)
+
+__all__: List[str]
+__path__: List[str]
+test: PytestTester
+
+__version__ = version
+emath = scimath
diff --git a/numpy/lib/_datasource.py b/numpy/lib/_datasource.py
index 7a23b1651..c790a6462 100644
--- a/numpy/lib/_datasource.py
+++ b/numpy/lib/_datasource.py
@@ -35,7 +35,6 @@ Example::
"""
import os
-import shutil
import io
from numpy.core.overrides import set_module
@@ -257,6 +256,8 @@ class DataSource:
def __del__(self):
# Remove temp directories
if hasattr(self, '_istmpdest') and self._istmpdest:
+ import shutil
+
shutil.rmtree(self._destpath)
def _iszip(self, filename):
@@ -319,8 +320,9 @@ class DataSource:
Creates a copy of the file in the datasource cache.
"""
- # We import these here because importing urllib is slow and
+ # We import these here because importing them is slow and
# a significant fraction of numpy's total import time.
+ import shutil
from urllib.request import urlopen
from urllib.error import URLError
diff --git a/numpy/lib/_version.py b/numpy/lib/_version.py
index d4098acb5..bfac5f814 100644
--- a/numpy/lib/_version.py
+++ b/numpy/lib/_version.py
@@ -15,7 +15,7 @@ class NumpyVersion():
"""Parse and compare numpy version strings.
NumPy has the following versioning scheme (numbers given are examples; they
- can be > 9) in principle):
+ can be > 9 in principle):
- Released version: '1.8.0', '1.8.1', etc.
- Alpha: '1.8.0a1', '1.8.0a2', etc.
@@ -54,7 +54,7 @@ class NumpyVersion():
def __init__(self, vstring):
self.vstring = vstring
- ver_main = re.match(r'\d[.]\d+[.]\d+', vstring)
+ ver_main = re.match(r'\d+\.\d+\.\d+', vstring)
if not ver_main:
raise ValueError("Not a valid numpy version string")
@@ -151,5 +151,5 @@ class NumpyVersion():
def __ge__(self, other):
return self._compare(other) >= 0
- def __repr(self):
+ def __repr__(self):
return "NumpyVersion(%s)" % self.vstring
diff --git a/numpy/lib/_version.pyi b/numpy/lib/_version.pyi
new file mode 100644
index 000000000..3581d639b
--- /dev/null
+++ b/numpy/lib/_version.pyi
@@ -0,0 +1,19 @@
+from typing import Union, List
+
+__all__: List[str]
+
+class NumpyVersion:
+ vstring: str
+ version: str
+ major: int
+ minor: int
+ bugfix: int
+ pre_release: str
+ is_devversion: bool
+ def __init__(self, vstring: str) -> None: ...
+ def __lt__(self, other: Union[str, NumpyVersion]) -> bool: ...
+ def __le__(self, other: Union[str, NumpyVersion]) -> bool: ...
+ def __eq__(self, other: Union[str, NumpyVersion]) -> bool: ... # type: ignore[override]
+ def __ne__(self, other: Union[str, NumpyVersion]) -> bool: ... # type: ignore[override]
+ def __gt__(self, other: Union[str, NumpyVersion]) -> bool: ...
+ def __ge__(self, other: Union[str, NumpyVersion]) -> bool: ...
diff --git a/numpy/lib/arraypad.pyi b/numpy/lib/arraypad.pyi
new file mode 100644
index 000000000..df9538dd7
--- /dev/null
+++ b/numpy/lib/arraypad.pyi
@@ -0,0 +1,94 @@
+import sys
+from typing import (
+ Any,
+ Dict,
+ List,
+ overload,
+ Tuple,
+ TypeVar,
+)
+
+from numpy import ndarray, dtype, generic
+
+from numpy.typing import (
+ ArrayLike,
+ NDArray,
+ _ArrayLikeInt,
+ _NestedSequence,
+ _SupportsArray,
+)
+
+if sys.version_info >= (3, 8):
+ from typing import Literal as L, Protocol
+else:
+ from typing_extensions import Literal as L, Protocol
+
+_SCT = TypeVar("_SCT", bound=generic)
+
+class _ModeFunc(Protocol):
+ def __call__(
+ self,
+ __vector: NDArray[Any],
+ __iaxis_pad_width: Tuple[int, int],
+ __iaxis: int,
+ __kwargs: Dict[str, Any],
+ ) -> None: ...
+
+_ModeKind = L[
+ "constant",
+ "edge",
+ "linear_ramp",
+ "maximum",
+ "mean",
+ "median",
+ "minimum",
+ "reflect",
+ "symmetric",
+ "wrap",
+ "empty",
+]
+
+_ArrayLike = _NestedSequence[_SupportsArray[dtype[_SCT]]]
+
+__all__: List[str]
+
+# TODO: In practice each keyword argument is exclusive to one or more
+# specific modes. Consider adding more overloads to express this in the future.
+
+# Expand `**kwargs` into explicit keyword-only arguments
+@overload
+def pad(
+ array: _ArrayLike[_SCT],
+ pad_width: _ArrayLikeInt,
+ mode: _ModeKind = ...,
+ *,
+ stat_length: None | _ArrayLikeInt = ...,
+ constant_values: ArrayLike = ...,
+ end_values: ArrayLike = ...,
+ reflect_type: L["odd", "even"] = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def pad(
+ array: ArrayLike,
+ pad_width: _ArrayLikeInt,
+ mode: _ModeKind = ...,
+ *,
+ stat_length: None | _ArrayLikeInt = ...,
+ constant_values: ArrayLike = ...,
+ end_values: ArrayLike = ...,
+ reflect_type: L["odd", "even"] = ...,
+) -> NDArray[Any]: ...
+@overload
+def pad(
+ array: _ArrayLike[_SCT],
+ pad_width: _ArrayLikeInt,
+ mode: _ModeFunc,
+ **kwargs: Any,
+) -> NDArray[_SCT]: ...
+@overload
+def pad(
+ array: ArrayLike,
+ pad_width: _ArrayLikeInt,
+ mode: _ModeFunc,
+ **kwargs: Any,
+) -> NDArray[Any]: ...
diff --git a/numpy/lib/arraysetops.py b/numpy/lib/arraysetops.py
index 6c6c1ff80..bd56b6975 100644
--- a/numpy/lib/arraysetops.py
+++ b/numpy/lib/arraysetops.py
@@ -209,6 +209,16 @@ def unique(ar, return_index=False, return_inverse=False,
flattened subarrays are sorted in lexicographic order starting with the
first element.
+ .. versionchanged: NumPy 1.21
+ If nan values are in the input array, a single nan is put
+ to the end of the sorted unique values.
+
+ Also for complex arrays all NaN values are considered equivalent
+ (no matter whether the NaN is in the real or imaginary part).
+ As the representant for the returned array the smallest one in the
+ lexicographical order is chosen - see np.sort for how the lexicographical
+ order is defined for complex arrays.
+
Examples
--------
>>> np.unique([1, 1, 2, 2, 3, 3])
@@ -324,7 +334,18 @@ def _unique1d(ar, return_index=False, return_inverse=False,
aux = ar
mask = np.empty(aux.shape, dtype=np.bool_)
mask[:1] = True
- mask[1:] = aux[1:] != aux[:-1]
+ if aux.shape[0] > 0 and aux.dtype.kind in "cfmM" and np.isnan(aux[-1]):
+ if aux.dtype.kind == "c": # for complex all NaNs are considered equivalent
+ aux_firstnan = np.searchsorted(np.isnan(aux), True, side='left')
+ else:
+ aux_firstnan = np.searchsorted(aux, aux[-1], side='left')
+ if aux_firstnan > 0:
+ mask[1:aux_firstnan] = (
+ aux[1:aux_firstnan] != aux[:aux_firstnan - 1])
+ mask[aux_firstnan] = True
+ mask[aux_firstnan + 1:] = False
+ else:
+ mask[1:] = aux[1:] != aux[:-1]
ret = (aux[mask],)
if return_index:
@@ -565,6 +586,10 @@ def in1d(ar1, ar2, assume_unique=False, invert=False):
ar1 = np.asarray(ar1).ravel()
ar2 = np.asarray(ar2).ravel()
+ # Ensure that iteration through object arrays yields size-1 arrays
+ if ar2.dtype == object:
+ ar2 = ar2.reshape(-1, 1)
+
# Check if one of the arrays may contain arbitrary objects
contains_object = ar1.dtype.hasobject or ar2.dtype.hasobject
diff --git a/numpy/lib/arraysetops.pyi b/numpy/lib/arraysetops.pyi
new file mode 100644
index 000000000..029aa1474
--- /dev/null
+++ b/numpy/lib/arraysetops.pyi
@@ -0,0 +1,12 @@
+from typing import List
+
+__all__: List[str]
+
+def ediff1d(ary, to_end=..., to_begin=...): ...
+def unique(ar, return_index=..., return_inverse=..., return_counts=..., axis=...): ...
+def intersect1d(ar1, ar2, assume_unique=..., return_indices=...): ...
+def setxor1d(ar1, ar2, assume_unique=...): ...
+def in1d(ar1, ar2, assume_unique=..., invert=...): ...
+def isin(element, test_elements, assume_unique=..., invert=...): ...
+def union1d(ar1, ar2): ...
+def setdiff1d(ar1, ar2, assume_unique=...): ...
diff --git a/numpy/lib/arrayterator.pyi b/numpy/lib/arrayterator.pyi
new file mode 100644
index 000000000..39d6fd843
--- /dev/null
+++ b/numpy/lib/arrayterator.pyi
@@ -0,0 +1,53 @@
+import sys
+from typing import (
+ List,
+ Any,
+ TypeVar,
+ Generator,
+ List,
+ Union,
+ Tuple,
+ overload,
+)
+
+from numpy import ndarray, dtype, generic
+from numpy.typing import DTypeLike
+
+# TODO: Set a shape bound once we've got proper shape support
+_Shape = TypeVar("_Shape", bound=Any)
+_DType = TypeVar("_DType", bound=dtype[Any])
+_ScalarType = TypeVar("_ScalarType", bound=generic)
+
+_Index = Union[
+ Union[ellipsis, int, slice],
+ Tuple[Union[ellipsis, int, slice], ...],
+]
+
+__all__: List[str]
+
+# NOTE: In reality `Arrayterator` does not actually inherit from `ndarray`,
+# but its ``__getattr__` method does wrap around the former and thus has
+# access to all its methods
+
+class Arrayterator(ndarray[_Shape, _DType]):
+ var: ndarray[_Shape, _DType] # type: ignore[assignment]
+ buf_size: None | int
+ start: List[int]
+ stop: List[int]
+ step: List[int]
+
+ @property # type: ignore[misc]
+ def shape(self) -> Tuple[int, ...]: ...
+ @property
+ def flat( # type: ignore[override]
+ self: ndarray[Any, dtype[_ScalarType]]
+ ) -> Generator[_ScalarType, None, None]: ...
+ def __init__(
+ self, var: ndarray[_Shape, _DType], buf_size: None | int = ...
+ ) -> None: ...
+ @overload
+ def __array__(self, dtype: None = ...) -> ndarray[Any, _DType]: ...
+ @overload
+ def __array__(self, dtype: DTypeLike) -> ndarray[Any, dtype[Any]]: ...
+ def __getitem__(self, index: _Index) -> Arrayterator[Any, _DType]: ...
+ def __iter__(self) -> Generator[ndarray[Any, _DType], None, None]: ...
diff --git a/numpy/lib/format.py b/numpy/lib/format.py
index 5d951e262..6ac66c22a 100644
--- a/numpy/lib/format.py
+++ b/numpy/lib/format.py
@@ -44,7 +44,7 @@ Capabilities
read most ``.npy`` files that they have been given without much
documentation.
-- Allows memory-mapping of the data. See `open_memmep`.
+- Allows memory-mapping of the data. See `open_memmap`.
- Can be read from a filelike stream object instead of an actual file.
@@ -173,6 +173,7 @@ from numpy.compat import (
__all__ = []
+EXPECTED_KEYS = {'descr', 'fortran_order', 'shape'}
MAGIC_PREFIX = b'\x93NUMPY'
MAGIC_LEN = len(MAGIC_PREFIX) + 2
ARRAY_ALIGN = 64 # plausible values are powers of 2 between 16 and 4096
@@ -378,7 +379,7 @@ def _wrap_header(header, version):
header_prefix = magic(*version) + struct.pack(fmt, hlen + padlen)
except struct.error:
msg = "Header length {} too big for version={}".format(hlen, version)
- raise ValueError(msg)
+ raise ValueError(msg) from None
# Pad the header with spaces and a final newline such that the magic
# string, the header-length short and the header are aligned on a
@@ -432,7 +433,6 @@ def _write_array_header(fp, d, version=None):
header.append("'%s': %s, " % (key, repr(value)))
header.append("}")
header = "".join(header)
- header = _filter_header(header)
if version is None:
header = _wrap_header_guess_version(header)
else:
@@ -590,23 +590,27 @@ def _read_array_header(fp, version):
# "shape" : tuple of int
# "fortran_order" : bool
# "descr" : dtype.descr
- header = _filter_header(header)
+ # Versions (2, 0) and (1, 0) could have been created by a Python 2
+ # implementation before header filtering was implemented.
+ if version <= (2, 0):
+ header = _filter_header(header)
try:
d = safe_eval(header)
except SyntaxError as e:
- msg = "Cannot parse header: {!r}\nException: {!r}"
- raise ValueError(msg.format(header, e))
+ msg = "Cannot parse header: {!r}"
+ raise ValueError(msg.format(header)) from e
if not isinstance(d, dict):
msg = "Header is not a dictionary: {!r}"
raise ValueError(msg.format(d))
- keys = sorted(d.keys())
- if keys != ['descr', 'fortran_order', 'shape']:
+
+ if EXPECTED_KEYS != d.keys():
+ keys = sorted(d.keys())
msg = "Header does not contain the correct keys: {!r}"
raise ValueError(msg.format(keys))
# Sanity-check the values.
if (not isinstance(d['shape'], tuple) or
- not numpy.all([isinstance(x, int) for x in d['shape']])):
+ not all(isinstance(x, int) for x in d['shape'])):
msg = "shape is not valid: {!r}"
raise ValueError(msg.format(d['shape']))
if not isinstance(d['fortran_order'], bool):
@@ -614,9 +618,9 @@ def _read_array_header(fp, version):
raise ValueError(msg.format(d['fortran_order']))
try:
dtype = descr_to_dtype(d['descr'])
- except TypeError:
+ except TypeError as e:
msg = "descr is not a valid dtype descriptor: {!r}"
- raise ValueError(msg.format(d['descr']))
+ raise ValueError(msg.format(d['descr'])) from e
return d['shape'], d['fortran_order'], dtype
diff --git a/numpy/lib/format.pyi b/numpy/lib/format.pyi
new file mode 100644
index 000000000..4c44d57bf
--- /dev/null
+++ b/numpy/lib/format.pyi
@@ -0,0 +1,28 @@
+import sys
+from typing import Any, List, Set
+
+if sys.version_info >= (3, 8):
+ from typing import Literal, Final
+else:
+ from typing_extensions import Literal, Final
+
+__all__: List[str]
+
+EXPECTED_KEYS: Final[Set[str]]
+MAGIC_PREFIX: Final[bytes]
+MAGIC_LEN: Literal[8]
+ARRAY_ALIGN: Literal[64]
+BUFFER_SIZE: Literal[262144] # 2**18
+
+def magic(major, minor): ...
+def read_magic(fp): ...
+def dtype_to_descr(dtype): ...
+def descr_to_dtype(descr): ...
+def header_data_from_array_1_0(array): ...
+def write_array_header_1_0(fp, d): ...
+def write_array_header_2_0(fp, d): ...
+def read_array_header_1_0(fp): ...
+def read_array_header_2_0(fp): ...
+def write_array(fp, array, version=..., allow_pickle=..., pickle_kwargs=...): ...
+def read_array(fp, allow_pickle=..., pickle_kwargs=...): ...
+def open_memmap(filename, mode=..., dtype=..., shape=..., fortran_order=..., version=...): ...
diff --git a/numpy/lib/function_base.py b/numpy/lib/function_base.py
index 696fe617b..b43a1d666 100644
--- a/numpy/lib/function_base.py
+++ b/numpy/lib/function_base.py
@@ -8,7 +8,7 @@ import numpy as np
import numpy.core.numeric as _nx
from numpy.core import transpose
from numpy.core.numeric import (
- ones, zeros, arange, concatenate, array, asarray, asanyarray, empty,
+ ones, zeros_like, arange, concatenate, array, asarray, asanyarray, empty,
ndarray, around, floor, ceil, take, dot, where, intp,
integer, isscalar, absolute
)
@@ -88,8 +88,11 @@ def rot90(m, k=1, axes=(0, 1)):
Notes
-----
- rot90(m, k=1, axes=(1,0)) is the reverse of rot90(m, k=1, axes=(0,1))
- rot90(m, k=1, axes=(1,0)) is equivalent to rot90(m, k=-1, axes=(0,1))
+ ``rot90(m, k=1, axes=(1,0))`` is the reverse of
+ ``rot90(m, k=1, axes=(0,1))``
+
+ ``rot90(m, k=1, axes=(1,0))`` is equivalent to
+ ``rot90(m, k=-1, axes=(0,1))``
Examples
--------
@@ -593,7 +596,7 @@ def piecewise(x, condlist, funclist, *args, **kw):
not isinstance(condlist[0], (list, ndarray)) and x.ndim != 0):
condlist = [condlist]
- condlist = array(condlist, dtype=bool)
+ condlist = asarray(condlist, dtype=bool)
n = len(condlist)
if n == n2 - 1: # compute the "otherwise" condition.
@@ -606,7 +609,7 @@ def piecewise(x, condlist, funclist, *args, **kw):
.format(n, n, n+1)
)
- y = zeros(x.shape, x.dtype)
+ y = zeros_like(x)
for cond, func in zip(condlist, funclist):
if not isinstance(func, collections.abc.Callable):
y[cond] = func
@@ -671,11 +674,22 @@ def select(condlist, choicelist, default=0):
raise ValueError("select with an empty condition list is not possible")
choicelist = [np.asarray(choice) for choice in choicelist]
- choicelist.append(np.asarray(default))
+
+ try:
+ intermediate_dtype = np.result_type(*choicelist)
+ except TypeError as e:
+ msg = f'Choicelist elements do not have a common dtype: {e}'
+ raise TypeError(msg) from None
+ default_array = np.asarray(default)
+ choicelist.append(default_array)
# need to get the result type before broadcasting for correct scalar
# behaviour
- dtype = np.result_type(*choicelist)
+ try:
+ dtype = np.result_type(intermediate_dtype, default_array)
+ except TypeError as e:
+ msg = f'Choicelists and default value do not have a common dtype: {e}'
+ raise TypeError(msg) from None
# Convert conditions to arrays and broadcast conditions and choices
# as the shape is needed for the result. Doing it separately optimizes
@@ -846,7 +860,7 @@ def gradient(f, *varargs, axis=None, edge_order=1):
Returns
-------
gradient : ndarray or list of ndarray
- A set of ndarrays (or a single ndarray if there is only one dimension)
+ A list of ndarrays (or a single ndarray if there is only one dimension)
corresponding to the derivatives of f with respect to each dimension.
Each derivative has the same shape as f.
@@ -1485,26 +1499,40 @@ def angle(z, deg=False):
return a
-def _unwrap_dispatcher(p, discont=None, axis=None):
+def _unwrap_dispatcher(p, discont=None, axis=None, *, period=None):
return (p,)
@array_function_dispatch(_unwrap_dispatcher)
-def unwrap(p, discont=pi, axis=-1):
- """
- Unwrap by changing deltas between values to 2*pi complement.
+def unwrap(p, discont=None, axis=-1, *, period=2*pi):
+ r"""
+ Unwrap by taking the complement of large deltas with respect to the period.
- Unwrap radian phase `p` by changing absolute jumps greater than
- `discont` to their 2*pi complement along the given axis.
+ This unwraps a signal `p` by changing elements which have an absolute
+ difference from their predecessor of more than ``max(discont, period/2)``
+ to their `period`-complementary values.
+
+ For the default case where `period` is :math:`2\pi` and is `discont` is
+ :math:`\pi`, this unwraps a radian phase `p` such that adjacent differences
+ are never greater than :math:`\pi` by adding :math:`2k\pi` for some
+ integer :math:`k`.
Parameters
----------
p : array_like
Input array.
discont : float, optional
- Maximum discontinuity between values, default is ``pi``.
+ Maximum discontinuity between values, default is ``period/2``.
+ Values below ``period/2`` are treated as if they were ``period/2``.
+ To have an effect different from the default, `discont` should be
+ larger than ``period/2``.
axis : int, optional
Axis along which unwrap will operate, default is the last axis.
+ period: float, optional
+ Size of the range over which the input wraps. By default, it is
+ ``2 pi``.
+
+ .. versionadded:: 1.21.0
Returns
-------
@@ -1517,9 +1545,9 @@ def unwrap(p, discont=pi, axis=-1):
Notes
-----
- If the discontinuity in `p` is smaller than ``pi``, but larger than
- `discont`, no unwrapping is done because taking the 2*pi complement
- would only make the discontinuity larger.
+ If the discontinuity in `p` is smaller than ``period/2``,
+ but larger than `discont`, no unwrapping is done because taking
+ the complement would only make the discontinuity larger.
Examples
--------
@@ -1529,19 +1557,44 @@ def unwrap(p, discont=pi, axis=-1):
array([ 0. , 0.78539816, 1.57079633, 5.49778714, 6.28318531]) # may vary
>>> np.unwrap(phase)
array([ 0. , 0.78539816, 1.57079633, -0.78539816, 0. ]) # may vary
-
+ >>> np.unwrap([0, 1, 2, -1, 0], period=4)
+ array([0, 1, 2, 3, 4])
+ >>> np.unwrap([ 1, 2, 3, 4, 5, 6, 1, 2, 3], period=6)
+ array([1, 2, 3, 4, 5, 6, 7, 8, 9])
+ >>> np.unwrap([2, 3, 4, 5, 2, 3, 4, 5], period=4)
+ array([2, 3, 4, 5, 6, 7, 8, 9])
+ >>> phase_deg = np.mod(np.linspace(0 ,720, 19), 360) - 180
+ >>> np.unwrap(phase_deg, period=360)
+ array([-180., -140., -100., -60., -20., 20., 60., 100., 140.,
+ 180., 220., 260., 300., 340., 380., 420., 460., 500.,
+ 540.])
"""
p = asarray(p)
nd = p.ndim
dd = diff(p, axis=axis)
+ if discont is None:
+ discont = period/2
slice1 = [slice(None, None)]*nd # full slices
slice1[axis] = slice(1, None)
slice1 = tuple(slice1)
- ddmod = mod(dd + pi, 2*pi) - pi
- _nx.copyto(ddmod, pi, where=(ddmod == -pi) & (dd > 0))
+ dtype = np.result_type(dd, period)
+ if _nx.issubdtype(dtype, _nx.integer):
+ interval_high, rem = divmod(period, 2)
+ boundary_ambiguous = rem == 0
+ else:
+ interval_high = period / 2
+ boundary_ambiguous = True
+ interval_low = -interval_high
+ ddmod = mod(dd - interval_low, period) + interval_low
+ if boundary_ambiguous:
+ # for `mask = (abs(dd) == period/2)`, the above line made
+ # `ddmod[mask] == -period/2`. correct these such that
+ # `ddmod[mask] == sign(dd[mask])*period/2`.
+ _nx.copyto(ddmod, interval_high,
+ where=(ddmod == interval_low) & (dd > 0))
ph_correct = ddmod - dd
_nx.copyto(ph_correct, 0, where=abs(dd) < discont)
- up = array(p, copy=True, dtype='d')
+ up = array(p, copy=True, dtype=dtype)
up[slice1] = p[slice1] + ph_correct.cumsum(axis)
return up
@@ -1890,11 +1943,19 @@ def _calculate_shapes(broadcast_shape, dim_sizes, list_of_core_dims):
for core_dims in list_of_core_dims]
-def _create_arrays(broadcast_shape, dim_sizes, list_of_core_dims, dtypes):
+def _create_arrays(broadcast_shape, dim_sizes, list_of_core_dims, dtypes,
+ results=None):
"""Helper for creating output arrays in vectorize."""
shapes = _calculate_shapes(broadcast_shape, dim_sizes, list_of_core_dims)
- arrays = tuple(np.empty(shape, dtype=dtype)
- for shape, dtype in zip(shapes, dtypes))
+ if dtypes is None:
+ dtypes = [None] * len(shapes)
+ if results is None:
+ arrays = tuple(np.empty(shape=shape, dtype=dtype)
+ for shape, dtype in zip(shapes, dtypes))
+ else:
+ arrays = tuple(np.empty_like(result, shape=shape, dtype=dtype)
+ for result, shape, dtype
+ in zip(results, shapes, dtypes))
return arrays
@@ -2191,15 +2252,14 @@ class vectorize:
ufunc, otypes = self._get_ufunc_and_otypes(func=func, args=args)
# Convert args to object arrays first
- inputs = [array(a, copy=False, subok=True, dtype=object)
- for a in args]
+ inputs = [asanyarray(a, dtype=object) for a in args]
outputs = ufunc(*inputs)
if ufunc.nout == 1:
- res = array(outputs, copy=False, subok=True, dtype=otypes[0])
+ res = asanyarray(outputs, dtype=otypes[0])
else:
- res = tuple([array(x, copy=False, subok=True, dtype=t)
+ res = tuple([asanyarray(x, dtype=t)
for x, t in zip(outputs, otypes)])
return res
@@ -2241,11 +2301,8 @@ class vectorize:
for result, core_dims in zip(results, output_core_dims):
_update_dim_sizes(dim_sizes, result, core_dims)
- if otypes is None:
- otypes = [asarray(result).dtype for result in results]
-
outputs = _create_arrays(broadcast_shape, dim_sizes,
- output_core_dims, otypes)
+ output_core_dims, otypes, results)
for output, result in zip(outputs, results):
output[index] = result
@@ -3947,11 +4004,10 @@ def _quantile_is_valid(q):
# avoid expensive reductions, relevant for arrays with < O(1000) elements
if q.ndim == 1 and q.size < 10:
for i in range(q.size):
- if q[i] < 0.0 or q[i] > 1.0:
+ if not (0.0 <= q[i] <= 1.0):
return False
else:
- # faster than any()
- if np.count_nonzero(q < 0.0) or np.count_nonzero(q > 1.0):
+ if not (np.all(0 <= q) and np.all(q <= 1)):
return False
return True
@@ -4080,10 +4136,17 @@ def _trapz_dispatcher(y, x=None, dx=None, axis=None):
@array_function_dispatch(_trapz_dispatcher)
def trapz(y, x=None, dx=1.0, axis=-1):
- """
+ r"""
Integrate along the given axis using the composite trapezoidal rule.
- Integrate `y` (`x`) along given axis.
+ If `x` is provided, the integration happens in sequence along its
+ elements - they are not sorted.
+
+ Integrate `y` (`x`) along each 1d slice on the given axis, compute
+ :math:`\int y(x) dx`.
+ When `x` is specified, this integrates along the parametric curve,
+ computing :math:`\int_t y(t) dt =
+ \int_t y(t) \left.\frac{dx}{dt}\right|_{x=x(t)} dt`.
Parameters
----------
@@ -4100,8 +4163,11 @@ def trapz(y, x=None, dx=1.0, axis=-1):
Returns
-------
- trapz : float
- Definite integral as approximated by trapezoidal rule.
+ trapz : float or ndarray
+ Definite integral of 'y' = n-dimensional array as approximated along
+ a single axis by the trapezoidal rule. If 'y' is a 1-dimensional array,
+ then the result is a float. If 'n' is greater than 1, then the result
+ is an 'n-1' dimensional array.
See Also
--------
@@ -4131,6 +4197,20 @@ def trapz(y, x=None, dx=1.0, axis=-1):
8.0
>>> np.trapz([1,2,3], dx=2)
8.0
+
+ Using a decreasing `x` corresponds to integrating in reverse:
+
+ >>> np.trapz([1,2,3], x=[8,6,4])
+ -8.0
+
+ More generally `x` is used to integrate along a parametric curve.
+ This finds the area of a circle, noting we repeat the sample which closes
+ the curve:
+
+ >>> theta = np.linspace(0, 2 * np.pi, num=1000, endpoint=True)
+ >>> np.trapz(np.cos(theta), x=np.sin(theta))
+ 3.141571941375841
+
>>> a = np.arange(6).reshape(2, 3)
>>> a
array([[0, 1, 2],
@@ -4139,7 +4219,6 @@ def trapz(y, x=None, dx=1.0, axis=-1):
array([1.5, 2.5, 3.5])
>>> np.trapz(a, axis=1)
array([2., 8.])
-
"""
y = asanyarray(y)
if x is None:
@@ -4230,12 +4309,12 @@ def meshgrid(*xi, copy=True, sparse=False, indexing='xy'):
'xy' indexing and (M, N, P) for 'ij' indexing. The difference is
illustrated by the following code snippet::
- xv, yv = np.meshgrid(x, y, sparse=False, indexing='ij')
+ xv, yv = np.meshgrid(x, y, indexing='ij')
for i in range(nx):
for j in range(ny):
# treat xv[i,j], yv[i,j]
- xv, yv = np.meshgrid(x, y, sparse=False, indexing='xy')
+ xv, yv = np.meshgrid(x, y, indexing='xy')
for i in range(nx):
for j in range(ny):
# treat xv[j,i], yv[j,i]
@@ -4245,7 +4324,7 @@ def meshgrid(*xi, copy=True, sparse=False, indexing='xy'):
See Also
--------
mgrid : Construct a multi-dimensional "meshgrid" using indexing notation.
- ogrid : Construct an open multi-dimensional "meshgrid" using indexing
+ ogrid : Construct an open multi-dimensional "meshgrid" using indexing
notation.
Examples
@@ -4274,7 +4353,8 @@ def meshgrid(*xi, copy=True, sparse=False, indexing='xy'):
>>> y = np.arange(-5, 5, 0.1)
>>> xx, yy = np.meshgrid(x, y, sparse=True)
>>> z = np.sin(xx**2 + yy**2) / (xx**2 + yy**2)
- >>> h = plt.contourf(x,y,z)
+ >>> h = plt.contourf(x, y, z)
+ >>> plt.axis('scaled')
>>> plt.show()
"""
diff --git a/numpy/lib/function_base.pyi b/numpy/lib/function_base.pyi
new file mode 100644
index 000000000..69c615c9c
--- /dev/null
+++ b/numpy/lib/function_base.pyi
@@ -0,0 +1,57 @@
+from typing import List
+
+from numpy import (
+ vectorize as vectorize,
+)
+
+from numpy.core.function_base import (
+ add_newdoc as add_newdoc,
+)
+
+from numpy.core.multiarray import (
+ add_docstring as add_docstring,
+ bincount as bincount,
+)
+from numpy.core.umath import _add_newdoc_ufunc
+
+__all__: List[str]
+
+add_newdoc_ufunc = _add_newdoc_ufunc
+
+def rot90(m, k=..., axes = ...): ...
+def flip(m, axis=...): ...
+def iterable(y): ...
+def average(a, axis=..., weights=..., returned=...): ...
+def asarray_chkfinite(a, dtype=..., order=...): ...
+def piecewise(x, condlist, funclist, *args, **kw): ...
+def select(condlist, choicelist, default=...): ...
+def copy(a, order=..., subok=...): ...
+def gradient(f, *varargs, axis=..., edge_order=...): ...
+def diff(a, n=..., axis=..., prepend = ..., append = ...): ...
+def interp(x, xp, fp, left=..., right=..., period=...): ...
+def angle(z, deg=...): ...
+def unwrap(p, discont = ..., axis=..., *, period=...): ...
+def sort_complex(a): ...
+def trim_zeros(filt, trim=...): ...
+def extract(condition, arr): ...
+def place(arr, mask, vals): ...
+def disp(mesg, device=..., linefeed=...): ...
+def cov(m, y=..., rowvar=..., bias=..., ddof=..., fweights=..., aweights=..., *, dtype=...): ...
+def corrcoef(x, y=..., rowvar=..., bias = ..., ddof = ..., *, dtype=...): ...
+def blackman(M): ...
+def bartlett(M): ...
+def hanning(M): ...
+def hamming(M): ...
+def i0(x): ...
+def kaiser(M, beta): ...
+def sinc(x): ...
+def msort(a): ...
+def median(a, axis=..., out=..., overwrite_input=..., keepdims=...): ...
+def percentile(a, q, axis=..., out=..., overwrite_input=..., interpolation=..., keepdims=...): ...
+def quantile(a, q, axis=..., out=..., overwrite_input=..., interpolation=..., keepdims=...): ...
+def trapz(y, x=..., dx=..., axis=...): ...
+def meshgrid(*xi, copy=..., sparse=..., indexing=...): ...
+def delete(arr, obj, axis=...): ...
+def insert(arr, obj, values, axis=...): ...
+def append(arr, values, axis=...): ...
+def digitize(x, bins, right=...): ...
diff --git a/numpy/lib/histograms.py b/numpy/lib/histograms.py
index 1a9b41ced..b6909bc1d 100644
--- a/numpy/lib/histograms.py
+++ b/numpy/lib/histograms.py
@@ -562,7 +562,8 @@ def histogram_bin_edges(a, bins=10, range=None, weights=None):
below, :math:`h` is the binwidth and :math:`n_h` is the number of
bins. All estimators that compute bin counts are recast to bin width
using the `ptp` of the data. The final bin count is obtained from
- ``np.round(np.ceil(range / h))``.
+ ``np.round(np.ceil(range / h))``. The final bin width is often less
+ than what is returned by the estimators below.
'auto' (maximum of the 'sturges' and 'fd' estimators)
A compromise to get a good value. For small datasets the Sturges
@@ -678,7 +679,7 @@ def _histogram_dispatcher(
def histogram(a, bins=10, range=None, normed=None, weights=None,
density=None):
r"""
- Compute the histogram of a set of data.
+ Compute the histogram of a dataset.
Parameters
----------
diff --git a/numpy/lib/histograms.pyi b/numpy/lib/histograms.pyi
new file mode 100644
index 000000000..25a33e3ae
--- /dev/null
+++ b/numpy/lib/histograms.pyi
@@ -0,0 +1,7 @@
+from typing import List
+
+__all__: List[str]
+
+def histogram_bin_edges(a, bins=..., range=..., weights=...): ...
+def histogram(a, bins=..., range=..., normed=..., weights=..., density=...): ...
+def histogramdd(sample, bins=..., range=..., normed=..., weights=..., density=...): ...
diff --git a/numpy/lib/index_tricks.py b/numpy/lib/index_tricks.py
index 9d3de69dd..8d1b6e5be 100644
--- a/numpy/lib/index_tricks.py
+++ b/numpy/lib/index_tricks.py
@@ -6,7 +6,7 @@ import warnings
import numpy.core.numeric as _nx
from numpy.core.numeric import (
asarray, ScalarType, array, alltrue, cumprod, arange, ndim
- )
+)
from numpy.core.numerictypes import find_common_type, issubdtype
import numpy.matrixlib as matrixlib
@@ -25,7 +25,7 @@ __all__ = [
'ravel_multi_index', 'unravel_index', 'mgrid', 'ogrid', 'r_', 'c_',
's_', 'index_exp', 'ix_', 'ndenumerate', 'ndindex', 'fill_diagonal',
'diag_indices', 'diag_indices_from'
- ]
+]
def _ix__dispatcher(*args):
@@ -106,6 +106,7 @@ def ix_(*args):
out.append(new)
return tuple(out)
+
class nd_grid:
"""
Construct a multi-dimensional "meshgrid".
@@ -167,7 +168,7 @@ class nd_grid:
typ = float
if self.sparse:
nn = [_nx.arange(_x, dtype=_t)
- for _x, _t in zip(size, (typ,)*len(size))]
+ for _x, _t in zip(size, (typ,)*len(size))]
else:
nn = _nx.indices(size, typ)
for k in range(len(size)):
@@ -200,7 +201,6 @@ class nd_grid:
length = int(step)
if step != 1:
step = (key.stop-start)/float(step-1)
- stop = key.stop + step
return _nx.arange(0, length, 1, float)*step + start
else:
return _nx.arange(start, stop, step)
@@ -248,11 +248,14 @@ class MGridClass(nd_grid):
array([-1. , -0.5, 0. , 0.5, 1. ])
"""
+
def __init__(self):
- super(MGridClass, self).__init__(sparse=False)
+ super().__init__(sparse=False)
+
mgrid = MGridClass()
+
class OGridClass(nd_grid):
"""
`nd_grid` instance which returns an open multi-dimensional "meshgrid".
@@ -292,8 +295,10 @@ class OGridClass(nd_grid):
[4]]), array([[0, 1, 2, 3, 4]])]
"""
+
def __init__(self):
- super(OGridClass, self).__init__(sparse=True)
+ super().__init__(sparse=True)
+
ogrid = OGridClass()
@@ -357,7 +362,7 @@ class AxisConcatenator:
elif isinstance(item, str):
if k != 0:
raise ValueError("special directives must be the "
- "first entry.")
+ "first entry.")
if item in ('r', 'c'):
matrix = True
col = (item == 'c')
@@ -376,8 +381,8 @@ class AxisConcatenator:
try:
axis = int(item)
continue
- except (ValueError, TypeError):
- raise ValueError("unknown special directive")
+ except (ValueError, TypeError) as e:
+ raise ValueError("unknown special directive") from e
elif type(item) in ScalarType:
newobj = array(item, ndmin=ndmin)
scalars.append(len(objs))
@@ -420,6 +425,7 @@ class AxisConcatenator:
# etc. because otherwise we couldn't get the doc string to come out right
# in help(r_)
+
class RClass(AxisConcatenator):
"""
Translates slice objects to concatenation along the first axis.
@@ -518,8 +524,10 @@ class RClass(AxisConcatenator):
def __init__(self):
AxisConcatenator.__init__(self, 0)
+
r_ = RClass()
+
class CClass(AxisConcatenator):
"""
Translates slice objects to concatenation along the second axis.
@@ -528,7 +536,7 @@ class CClass(AxisConcatenator):
useful because of its common occurrence. In particular, arrays will be
stacked along their last axis after being upgraded to at least 2-D with
1's post-pended to the shape (column vectors made out of 1-D arrays).
-
+
See Also
--------
column_stack : Stack 1-D arrays as columns into a 2-D array.
@@ -622,7 +630,8 @@ class ndindex:
Examples
--------
- # dimensions as individual arguments
+ Dimensions as individual arguments
+
>>> for index in np.ndindex(3, 2, 1):
... print(index)
(0, 0, 0)
@@ -632,7 +641,8 @@ class ndindex:
(2, 0, 0)
(2, 1, 0)
- # same dimensions - but in a tuple (3, 2, 1)
+ Same dimensions - but in a tuple ``(3, 2, 1)``
+
>>> for index in np.ndindex((3, 2, 1)):
... print(index)
(0, 0, 0)
@@ -751,6 +761,7 @@ class IndexExpression:
else:
return item
+
index_exp = IndexExpression(maketuple=True)
s_ = IndexExpression(maketuple=False)
@@ -885,7 +896,7 @@ def fill_diagonal(a, val, wrap=False):
# Explicit, fast formula for the common case. For 2-d arrays, we
# accept rectangular ones.
step = a.shape[1] + 1
- #This is needed to don't have tall matrix have the diagonal wrap.
+ # This is needed to don't have tall matrix have the diagonal wrap.
if not wrap:
end = a.shape[1] * a.shape[1]
else:
diff --git a/numpy/lib/index_tricks.pyi b/numpy/lib/index_tricks.pyi
new file mode 100644
index 000000000..0f9ae94a9
--- /dev/null
+++ b/numpy/lib/index_tricks.pyi
@@ -0,0 +1,171 @@
+import sys
+from typing import (
+ Any,
+ Tuple,
+ TypeVar,
+ Generic,
+ overload,
+ List,
+ Union,
+ Sequence,
+)
+
+from numpy import (
+ # Circumvent a naming conflict with `AxisConcatenator.matrix`
+ matrix as _Matrix,
+ ndenumerate as ndenumerate,
+ ndindex as ndindex,
+ ndarray,
+ dtype,
+ integer,
+ str_,
+ bytes_,
+ bool_,
+ int_,
+ float_,
+ complex_,
+ intp,
+ _OrderCF,
+ _ModeKind,
+)
+from numpy.typing import (
+ # Arrays
+ ArrayLike,
+ _NestedSequence,
+ _RecursiveSequence,
+ NDArray,
+ _ArrayLikeInt,
+
+ # DTypes
+ DTypeLike,
+ _SupportsDType,
+
+ # Shapes
+ _ShapeLike,
+)
+
+from numpy.core.multiarray import (
+ unravel_index as unravel_index,
+ ravel_multi_index as ravel_multi_index,
+)
+
+if sys.version_info >= (3, 8):
+ from typing import Literal, SupportsIndex
+else:
+ from typing_extensions import Literal, SupportsIndex
+
+_T = TypeVar("_T")
+_DType = TypeVar("_DType", bound=dtype[Any])
+_BoolType = TypeVar("_BoolType", Literal[True], Literal[False])
+_TupType = TypeVar("_TupType", bound=Tuple[Any, ...])
+_ArrayType = TypeVar("_ArrayType", bound=ndarray[Any, Any])
+
+__all__: List[str]
+
+@overload
+def ix_(*args: _NestedSequence[_SupportsDType[_DType]]) -> Tuple[ndarray[Any, _DType], ...]: ...
+@overload
+def ix_(*args: _NestedSequence[str]) -> Tuple[NDArray[str_], ...]: ...
+@overload
+def ix_(*args: _NestedSequence[bytes]) -> Tuple[NDArray[bytes_], ...]: ...
+@overload
+def ix_(*args: _NestedSequence[bool]) -> Tuple[NDArray[bool_], ...]: ...
+@overload
+def ix_(*args: _NestedSequence[int]) -> Tuple[NDArray[int_], ...]: ...
+@overload
+def ix_(*args: _NestedSequence[float]) -> Tuple[NDArray[float_], ...]: ...
+@overload
+def ix_(*args: _NestedSequence[complex]) -> Tuple[NDArray[complex_], ...]: ...
+@overload
+def ix_(*args: _RecursiveSequence) -> Tuple[NDArray[Any], ...]: ...
+
+class nd_grid(Generic[_BoolType]):
+ sparse: _BoolType
+ def __init__(self, sparse: _BoolType = ...) -> None: ...
+ @overload
+ def __getitem__(
+ self: nd_grid[Literal[False]],
+ key: Union[slice, Sequence[slice]],
+ ) -> NDArray[Any]: ...
+ @overload
+ def __getitem__(
+ self: nd_grid[Literal[True]],
+ key: Union[slice, Sequence[slice]],
+ ) -> List[NDArray[Any]]: ...
+
+class MGridClass(nd_grid[Literal[False]]):
+ def __init__(self) -> None: ...
+
+mgrid: MGridClass
+
+class OGridClass(nd_grid[Literal[True]]):
+ def __init__(self) -> None: ...
+
+ogrid: OGridClass
+
+class AxisConcatenator:
+ axis: int
+ matrix: bool
+ ndmin: int
+ trans1d: int
+ def __init__(
+ self,
+ axis: int = ...,
+ matrix: bool = ...,
+ ndmin: int = ...,
+ trans1d: int = ...,
+ ) -> None: ...
+ @staticmethod
+ @overload
+ def concatenate( # type: ignore[misc]
+ *a: ArrayLike, axis: SupportsIndex = ..., out: None = ...
+ ) -> NDArray[Any]: ...
+ @staticmethod
+ @overload
+ def concatenate(
+ *a: ArrayLike, axis: SupportsIndex = ..., out: _ArrayType = ...
+ ) -> _ArrayType: ...
+ @staticmethod
+ def makemat(
+ data: ArrayLike, dtype: DTypeLike = ..., copy: bool = ...
+ ) -> _Matrix: ...
+
+ # TODO: Sort out this `__getitem__` method
+ def __getitem__(self, key: Any) -> Any: ...
+
+class RClass(AxisConcatenator):
+ axis: Literal[0]
+ matrix: Literal[False]
+ ndmin: Literal[1]
+ trans1d: Literal[-1]
+ def __init__(self) -> None: ...
+
+r_: RClass
+
+class CClass(AxisConcatenator):
+ axis: Literal[-1]
+ matrix: Literal[False]
+ ndmin: Literal[2]
+ trans1d: Literal[0]
+ def __init__(self) -> None: ...
+
+c_: CClass
+
+class IndexExpression(Generic[_BoolType]):
+ maketuple: _BoolType
+ def __init__(self, maketuple: _BoolType) -> None: ...
+ @overload
+ def __getitem__(self, item: _TupType) -> _TupType: ... # type: ignore[misc]
+ @overload
+ def __getitem__(self: IndexExpression[Literal[True]], item: _T) -> Tuple[_T]: ...
+ @overload
+ def __getitem__(self: IndexExpression[Literal[False]], item: _T) -> _T: ...
+
+index_exp: IndexExpression[Literal[True]]
+s_: IndexExpression[Literal[False]]
+
+def fill_diagonal(a: ndarray[Any, Any], val: Any, wrap: bool = ...) -> None: ...
+def diag_indices(n: int, ndim: int = ...) -> Tuple[NDArray[int_], ...]: ...
+def diag_indices_from(arr: ArrayLike) -> Tuple[NDArray[int_], ...]: ...
+
+# NOTE: see `numpy/__init__.pyi` for `ndenumerate` and `ndindex`
diff --git a/numpy/lib/mixins.pyi b/numpy/lib/mixins.pyi
new file mode 100644
index 000000000..f137bb5bc
--- /dev/null
+++ b/numpy/lib/mixins.pyi
@@ -0,0 +1,62 @@
+from typing import List
+from abc import ABCMeta, abstractmethod
+
+__all__: List[str]
+
+# NOTE: `NDArrayOperatorsMixin` is not formally an abstract baseclass,
+# even though it's reliant on subclasses implementing `__array_ufunc__`
+
+class NDArrayOperatorsMixin(metaclass=ABCMeta):
+ @abstractmethod
+ def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): ...
+ def __lt__(self, other): ...
+ def __le__(self, other): ...
+ def __eq__(self, other): ...
+ def __ne__(self, other): ...
+ def __gt__(self, other): ...
+ def __ge__(self, other): ...
+ def __add__(self, other): ...
+ def __radd__(self, other): ...
+ def __iadd__(self, other): ...
+ def __sub__(self, other): ...
+ def __rsub__(self, other): ...
+ def __isub__(self, other): ...
+ def __mul__(self, other): ...
+ def __rmul__(self, other): ...
+ def __imul__(self, other): ...
+ def __matmul__(self, other): ...
+ def __rmatmul__(self, other): ...
+ def __imatmul__(self, other): ...
+ def __truediv__(self, other): ...
+ def __rtruediv__(self, other): ...
+ def __itruediv__(self, other): ...
+ def __floordiv__(self, other): ...
+ def __rfloordiv__(self, other): ...
+ def __ifloordiv__(self, other): ...
+ def __mod__(self, other): ...
+ def __rmod__(self, other): ...
+ def __imod__(self, other): ...
+ def __divmod__(self, other): ...
+ def __rdivmod__(self, other): ...
+ def __pow__(self, other): ...
+ def __rpow__(self, other): ...
+ def __ipow__(self, other): ...
+ def __lshift__(self, other): ...
+ def __rlshift__(self, other): ...
+ def __ilshift__(self, other): ...
+ def __rshift__(self, other): ...
+ def __rrshift__(self, other): ...
+ def __irshift__(self, other): ...
+ def __and__(self, other): ...
+ def __rand__(self, other): ...
+ def __iand__(self, other): ...
+ def __xor__(self, other): ...
+ def __rxor__(self, other): ...
+ def __ixor__(self, other): ...
+ def __or__(self, other): ...
+ def __ror__(self, other): ...
+ def __ior__(self, other): ...
+ def __neg__(self): ...
+ def __pos__(self): ...
+ def __abs__(self): ...
+ def __invert__(self): ...
diff --git a/numpy/lib/nanfunctions.py b/numpy/lib/nanfunctions.py
index 409016adb..2c2c3435b 100644
--- a/numpy/lib/nanfunctions.py
+++ b/numpy/lib/nanfunctions.py
@@ -613,7 +613,7 @@ def nansum(a, axis=None, dtype=None, out=None, keepdims=np._NoValue):
--------
numpy.sum : Sum across array propagating NaNs.
isnan : Show which elements are NaN.
- isfinite: Show which elements are not NaN or +/-inf.
+ isfinite : Show which elements are not NaN or +/-inf.
Notes
-----
@@ -962,12 +962,16 @@ def _nanmedian1d(arr1d, overwrite_input=False):
Private function for rank 1 arrays. Compute the median ignoring NaNs.
See nanmedian for parameter usage
"""
- arr1d, overwrite_input = _remove_nan_1d(arr1d,
- overwrite_input=overwrite_input)
- if arr1d.size == 0:
- return np.nan
+ arr1d_parsed, overwrite_input = _remove_nan_1d(
+ arr1d, overwrite_input=overwrite_input,
+ )
- return np.median(arr1d, overwrite_input=overwrite_input)
+ if arr1d_parsed.size == 0:
+ # Ensure that a nan-esque scalar of the appropiate type (and unit)
+ # is returned for `timedelta64` and `complexfloating`
+ return arr1d[-1]
+
+ return np.median(arr1d_parsed, overwrite_input=overwrite_input)
def _nanmedian(a, axis=None, out=None, overwrite_input=False):
@@ -1008,10 +1012,12 @@ def _nanmedian_small(a, axis=None, out=None, overwrite_input=False):
for i in range(np.count_nonzero(m.mask.ravel())):
warnings.warn("All-NaN slice encountered", RuntimeWarning,
stacklevel=4)
+
+ fill_value = np.timedelta64("NaT") if m.dtype.kind == "m" else np.nan
if out is not None:
- out[...] = m.filled(np.nan)
+ out[...] = m.filled(fill_value)
return out
- return m.filled(np.nan)
+ return m.filled(fill_value)
def _nanmedian_dispatcher(
diff --git a/numpy/lib/nanfunctions.pyi b/numpy/lib/nanfunctions.pyi
new file mode 100644
index 000000000..447770a54
--- /dev/null
+++ b/numpy/lib/nanfunctions.pyi
@@ -0,0 +1,54 @@
+from typing import List
+
+__all__: List[str]
+
+def nanmin(a, axis=..., out=..., keepdims=...): ...
+def nanmax(a, axis=..., out=..., keepdims=...): ...
+def nanargmin(a, axis=...): ...
+def nanargmax(a, axis=...): ...
+def nansum(a, axis=..., dtype=..., out=..., keepdims=...): ...
+def nanprod(a, axis=..., dtype=..., out=..., keepdims=...): ...
+def nancumsum(a, axis=..., dtype=..., out=...): ...
+def nancumprod(a, axis=..., dtype=..., out=...): ...
+def nanmean(a, axis=..., dtype=..., out=..., keepdims=...): ...
+def nanmedian(
+ a,
+ axis=...,
+ out=...,
+ overwrite_input=...,
+ keepdims=...,
+): ...
+def nanpercentile(
+ a,
+ q,
+ axis=...,
+ out=...,
+ overwrite_input=...,
+ interpolation=...,
+ keepdims=...,
+): ...
+def nanquantile(
+ a,
+ q,
+ axis=...,
+ out=...,
+ overwrite_input=...,
+ interpolation=...,
+ keepdims=...,
+): ...
+def nanvar(
+ a,
+ axis=...,
+ dtype=...,
+ out=...,
+ ddof=...,
+ keepdims=...,
+): ...
+def nanstd(
+ a,
+ axis=...,
+ dtype=...,
+ out=...,
+ ddof=...,
+ keepdims=...,
+): ...
diff --git a/numpy/lib/npyio.py b/numpy/lib/npyio.py
index 3b2de3e61..9ae5d0b59 100644
--- a/numpy/lib/npyio.py
+++ b/numpy/lib/npyio.py
@@ -1,4 +1,3 @@
-import sys
import os
import re
import functools
@@ -15,7 +14,6 @@ from ._datasource import DataSource
from numpy.core import overrides
from numpy.core.multiarray import packbits, unpackbits
from numpy.core.overrides import set_array_function_like_doc, set_module
-from numpy.core._internal import recursive
from ._iotools import (
LineSplitter, NameValidator, StringConverter, ConverterError,
ConverterLockError, ConversionWarning, _is_string_like,
@@ -24,7 +22,7 @@ from ._iotools import (
from numpy.compat import (
asbytes, asstr, asunicode, os_fspath, os_PathLike,
- pickle, contextlib_nullcontext
+ pickle
)
@@ -517,7 +515,7 @@ def save(file, arr, allow_pickle=True, fix_imports=True):
# [1 2] [1 3]
"""
if hasattr(file, 'write'):
- file_ctx = contextlib_nullcontext(file)
+ file_ctx = contextlib.nullcontext(file)
else:
file = os_fspath(file)
if not file.endswith('.npy'):
@@ -539,10 +537,11 @@ def _savez_dispatcher(file, *args, **kwds):
def savez(file, *args, **kwds):
"""Save several arrays into a single file in uncompressed ``.npz`` format.
- If arguments are passed in with no keywords, the corresponding variable
- names, in the ``.npz`` file, are 'arr_0', 'arr_1', etc. If keyword
- arguments are given, the corresponding variable names, in the ``.npz``
- file will match the keyword names.
+ Provide arrays as keyword arguments to store them under the
+ corresponding name in the output file: ``savez(fn, x=x, y=y)``.
+
+ If arrays are specified as positional arguments, i.e., ``savez(fn,
+ x, y)``, their names will be `arr_0`, `arr_1`, etc.
Parameters
----------
@@ -552,13 +551,12 @@ def savez(file, *args, **kwds):
``.npz`` extension will be appended to the filename if it is not
already there.
args : Arguments, optional
- Arrays to save to the file. Since it is not possible for Python to
- know the names of the arrays outside `savez`, the arrays will be saved
- with names "arr_0", "arr_1", and so on. These arguments can be any
- expression.
+ Arrays to save to the file. Please use keyword arguments (see
+ `kwds` below) to assign names to arrays. Arrays specified as
+ args will be named "arr_0", "arr_1", and so on.
kwds : Keyword arguments, optional
- Arrays to save to the file. Arrays will be saved in the file with the
- keyword names.
+ Arrays to save to the file. Each array will be saved to the
+ output file with its corresponding keyword name.
Returns
-------
@@ -582,9 +580,13 @@ def savez(file, *args, **kwds):
its list of arrays (with the ``.files`` attribute), and for the arrays
themselves.
- When saving dictionaries, the dictionary keys become filenames
- inside the ZIP archive. Therefore, keys should be valid filenames.
- E.g., avoid keys that begin with ``/`` or contain ``.``.
+ Keys passed in `kwds` are used as filenames inside the ZIP archive.
+ Therefore, keys should be valid filenames; e.g., avoid keys that begin with
+ ``/`` or contain ``.``.
+
+ When naming variables with keyword arguments, it is not possible to name a
+ variable ``file``, as this would cause the ``file`` argument to be defined
+ twice in the call to ``savez``.
Examples
--------
@@ -613,6 +615,7 @@ def savez(file, *args, **kwds):
['x', 'y']
>>> npzfile['x']
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
+
"""
_savez(file, args, kwds, False)
@@ -627,9 +630,11 @@ def savez_compressed(file, *args, **kwds):
"""
Save several arrays into a single file in compressed ``.npz`` format.
- If keyword arguments are given, then filenames are taken from the keywords.
- If arguments are passed in with no keywords, then stored filenames are
- arr_0, arr_1, etc.
+ Provide arrays as keyword arguments to store them under the
+ corresponding name in the output file: ``savez(fn, x=x, y=y)``.
+
+ If arrays are specified as positional arguments, i.e., ``savez(fn,
+ x, y)``, their names will be `arr_0`, `arr_1`, etc.
Parameters
----------
@@ -639,13 +644,12 @@ def savez_compressed(file, *args, **kwds):
``.npz`` extension will be appended to the filename if it is not
already there.
args : Arguments, optional
- Arrays to save to the file. Since it is not possible for Python to
- know the names of the arrays outside `savez`, the arrays will be saved
- with names "arr_0", "arr_1", and so on. These arguments can be any
- expression.
+ Arrays to save to the file. Please use keyword arguments (see
+ `kwds` below) to assign names to arrays. Arrays specified as
+ args will be named "arr_0", "arr_1", and so on.
kwds : Keyword arguments, optional
- Arrays to save to the file. Arrays will be saved in the file with the
- keyword names.
+ Arrays to save to the file. Each array will be saved to the
+ output file with its corresponding keyword name.
Returns
-------
@@ -756,6 +760,64 @@ def _getconv(dtype):
return asstr
+# _loadtxt_flatten_dtype_internal and _loadtxt_pack_items are loadtxt helpers
+# lifted to the toplevel because recursive inner functions cause either
+# GC-dependent reference loops (because they are closures over loadtxt's
+# internal variables) or large overheads if using a manual trampoline to hide
+# the recursive calls.
+
+
+# not to be confused with the flatten_dtype we import...
+def _loadtxt_flatten_dtype_internal(dt):
+ """Unpack a structured data-type, and produce a packer function."""
+ if dt.names is None:
+ # If the dtype is flattened, return.
+ # If the dtype has a shape, the dtype occurs
+ # in the list more than once.
+ shape = dt.shape
+ if len(shape) == 0:
+ return ([dt.base], None)
+ else:
+ packing = [(shape[-1], list)]
+ if len(shape) > 1:
+ for dim in dt.shape[-2::-1]:
+ packing = [(dim*packing[0][0], packing*dim)]
+ return ([dt.base] * int(np.prod(dt.shape)),
+ functools.partial(_loadtxt_pack_items, packing))
+ else:
+ types = []
+ packing = []
+ for field in dt.names:
+ tp, bytes = dt.fields[field]
+ flat_dt, flat_packer = _loadtxt_flatten_dtype_internal(tp)
+ types.extend(flat_dt)
+ flat_packing = flat_packer.args[0] if flat_packer else None
+ # Avoid extra nesting for subarrays
+ if tp.ndim > 0:
+ packing.extend(flat_packing)
+ else:
+ packing.append((len(flat_dt), flat_packing))
+ return (types, functools.partial(_loadtxt_pack_items, packing))
+
+
+def _loadtxt_pack_items(packing, items):
+ """Pack items into nested lists based on re-packing info."""
+ if packing is None:
+ return items[0]
+ elif packing is tuple:
+ return tuple(items)
+ elif packing is list:
+ return list(items)
+ else:
+ start = 0
+ ret = []
+ for length, subpacking in packing:
+ ret.append(
+ _loadtxt_pack_items(subpacking, items[start:start+length]))
+ start += length
+ return tuple(ret)
+
+
# amount of lines loadtxt reads in one chunk, can be overridden for testing
_loadtxt_chunksize = 50000
@@ -778,10 +840,11 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None,
Parameters
----------
- fname : file, str, or pathlib.Path
- File, filename, or generator to read. If the filename extension is
- ``.gz`` or ``.bz2``, the file is first decompressed. Note that
- generators should return byte strings.
+ fname : file, str, pathlib.Path, list of str, generator
+ File, filename, list, or generator to read. If the filename
+ extension is ``.gz`` or ``.bz2``, the file is first decompressed. Note
+ that generators must return bytes or strings. The strings
+ in a list or produced by a generator are treated as lines.
dtype : data-type, optional
Data-type of the resulting array; default: float. If this is a
structured data-type, the resulting array will be 1-dimensional, and
@@ -910,60 +973,11 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None,
# Nested functions used by loadtxt.
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- # not to be confused with the flatten_dtype we import...
- @recursive
- def flatten_dtype_internal(self, dt):
- """Unpack a structured data-type, and produce re-packing info."""
- if dt.names is None:
- # If the dtype is flattened, return.
- # If the dtype has a shape, the dtype occurs
- # in the list more than once.
- shape = dt.shape
- if len(shape) == 0:
- return ([dt.base], None)
- else:
- packing = [(shape[-1], list)]
- if len(shape) > 1:
- for dim in dt.shape[-2::-1]:
- packing = [(dim*packing[0][0], packing*dim)]
- return ([dt.base] * int(np.prod(dt.shape)), packing)
- else:
- types = []
- packing = []
- for field in dt.names:
- tp, bytes = dt.fields[field]
- flat_dt, flat_packing = self(tp)
- types.extend(flat_dt)
- # Avoid extra nesting for subarrays
- if tp.ndim > 0:
- packing.extend(flat_packing)
- else:
- packing.append((len(flat_dt), flat_packing))
- return (types, packing)
-
- @recursive
- def pack_items(self, items, packing):
- """Pack items into nested lists based on re-packing info."""
- if packing is None:
- return items[0]
- elif packing is tuple:
- return tuple(items)
- elif packing is list:
- return list(items)
- else:
- start = 0
- ret = []
- for length, subpacking in packing:
- ret.append(self(items[start:start+length], subpacking))
- start += length
- return tuple(ret)
-
def split_line(line):
"""Chop off comments, strip, and split at delimiter. """
line = _decode_line(line, encoding=encoding)
-
- if comments is not None:
- line = regex_comments.split(line, maxsplit=1)[0]
+ for comment in comments: # Much faster than using a single regex.
+ line = line.split(comment, 1)[0]
line = line.strip('\r\n')
return line.split(delimiter) if line else []
@@ -997,7 +1011,7 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None,
items = [conv(val) for (conv, val) in zip(converters, vals)]
# Then pack it according to the dtype's nesting
- items = pack_items(items, packing)
+ items = packer(items)
X.append(items)
if len(X) > chunk_size:
yield X
@@ -1018,9 +1032,8 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None,
if isinstance(comments, (str, bytes)):
comments = [comments]
comments = [_decode_line(x) for x in comments]
- # Compile regex for comments beforehand
- comments = (re.escape(comment) for comment in comments)
- regex_comments = re.compile('|'.join(comments))
+ else:
+ comments = []
if delimiter is not None:
delimiter = _decode_line(delimiter)
@@ -1055,7 +1068,7 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None,
dtype = np.dtype(dtype)
defconv = _getconv(dtype)
- dtype_types, packing = flatten_dtype_internal(dtype)
+ dtype_types, packer = _loadtxt_flatten_dtype_internal(dtype)
fown = False
try:
@@ -1071,7 +1084,8 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None,
fencoding = getattr(fname, 'encoding', 'latin1')
except TypeError as e:
raise ValueError(
- 'fname must be a string, file handle, or generator'
+ f"fname must be a string, filehandle, list of strings,\n"
+ f"or generator. Got {type(fname)} instead."
) from e
# input may be a python2 io stream
@@ -1110,10 +1124,13 @@ def loadtxt(fname, dtype=float, comments='#', delimiter=None,
# the dtype matches a column
converters = [_getconv(dt) for dt in dtype_types]
else:
- # All fields have the same dtype
+ # All fields have the same dtype; use specialized packers which are
+ # much faster than those using _loadtxt_pack_items.
converters = [defconv for i in range(N)]
- if N > 1:
- packing = [(N, tuple)]
+ if N == 1:
+ packer = itemgetter(0)
+ else:
+ def packer(row): return row
# By preference, use the converters specified by the user
for i, conv in (user_converters or {}).items():
@@ -1576,8 +1593,8 @@ def genfromtxt(fname, dtype=float, comments='#', delimiter=None,
----------
fname : file, str, pathlib.Path, list of str, generator
File, filename, list, or generator to read. If the filename
- extension is `.gz` or `.bz2`, the file is first decompressed. Note
- that generators must return byte strings. The strings
+ extension is ``.gz`` or ``.bz2``, the file is first decompressed. Note
+ that generators must return bytes or strings. The strings
in a list or produced by a generator are treated as lines.
dtype : dtype, optional
Data type of the resulting array.
@@ -1585,7 +1602,7 @@ def genfromtxt(fname, dtype=float, comments='#', delimiter=None,
column, individually.
comments : str, optional
The character used to indicate the start of a comment.
- All the characters occurring on a line after a comment are discarded
+ All the characters occurring on a line after a comment are discarded.
delimiter : str, int, or sequence, optional
The string used to separate values. By default, any consecutive
whitespaces act as delimiter. An integer or sequence of integers
@@ -1612,15 +1629,15 @@ def genfromtxt(fname, dtype=float, comments='#', delimiter=None,
``usecols = (1, 4, 5)`` will extract the 2nd, 5th and 6th columns.
names : {None, True, str, sequence}, optional
If `names` is True, the field names are read from the first line after
- the first `skip_header` lines. This line can optionally be proceeded
+ the first `skip_header` lines. This line can optionally be preceeded
by a comment delimiter. If `names` is a sequence or a single-string of
comma-separated names, the names will be used to define the field names
in a structured dtype. If `names` is None, the names of the dtype
fields will be used, if any.
excludelist : sequence, optional
A list of names to exclude. This list is appended to the default list
- ['return','file','print']. Excluded names are appended an underscore:
- for example, `file` would become `file_`.
+ ['return','file','print']. Excluded names are appended with an
+ underscore: for example, `file` would become `file_`.
deletechars : str, optional
A string combining invalid characters that must be deleted from the
names.
@@ -1629,7 +1646,7 @@ def genfromtxt(fname, dtype=float, comments='#', delimiter=None,
autostrip : bool, optional
Whether to automatically strip white spaces from the variables.
replace_space : char, optional
- Character(s) used in replacement of white spaces in the variables
+ Character(s) used in replacement of white spaces in the variable
names. By default, use a '_'.
case_sensitive : {True, False, 'upper', 'lower'}, optional
If True, field names are case sensitive.
@@ -1792,12 +1809,13 @@ def genfromtxt(fname, dtype=float, comments='#', delimiter=None,
fid_ctx = contextlib.closing(fid)
else:
fid = fname
- fid_ctx = contextlib_nullcontext(fid)
+ fid_ctx = contextlib.nullcontext(fid)
fhd = iter(fid)
except TypeError as e:
raise TypeError(
- "fname must be a string, filehandle, list of strings, "
- "or generator. Got %s instead." % type(fname)) from e
+ f"fname must be a string, filehandle, list of strings,\n"
+ f"or generator. Got {type(fname)} instead."
+ ) from e
with fid_ctx:
split_line = LineSplitter(delimiter=delimiter, comments=comments,
diff --git a/numpy/lib/npyio.pyi b/numpy/lib/npyio.pyi
new file mode 100644
index 000000000..508357927
--- /dev/null
+++ b/numpy/lib/npyio.pyi
@@ -0,0 +1,104 @@
+from typing import Mapping, List, Any
+
+from numpy import (
+ DataSource as DataSource,
+)
+
+from numpy.core.multiarray import (
+ packbits as packbits,
+ unpackbits as unpackbits,
+)
+
+__all__: List[str]
+
+def loads(*args, **kwargs): ...
+
+class BagObj:
+ def __init__(self, obj): ...
+ def __getattribute__(self, key): ...
+ def __dir__(self): ...
+
+def zipfile_factory(file, *args, **kwargs): ...
+
+class NpzFile(Mapping[Any, Any]):
+ zip: Any
+ fid: Any
+ files: Any
+ allow_pickle: Any
+ pickle_kwargs: Any
+ f: Any
+ def __init__(self, fid, own_fid=..., allow_pickle=..., pickle_kwargs=...): ...
+ def __enter__(self): ...
+ def __exit__(self, exc_type, exc_value, traceback): ...
+ def close(self): ...
+ def __del__(self): ...
+ def __iter__(self): ...
+ def __len__(self): ...
+ def __getitem__(self, key): ...
+ def iteritems(self): ...
+ def iterkeys(self): ...
+
+def load(file, mmap_mode=..., allow_pickle=..., fix_imports=..., encoding=...): ...
+def save(file, arr, allow_pickle=..., fix_imports=...): ...
+def savez(file, *args, **kwds): ...
+def savez_compressed(file, *args, **kwds): ...
+def loadtxt(
+ fname,
+ dtype=...,
+ comments=...,
+ delimiter=...,
+ converters=...,
+ skiprows=...,
+ usecols=...,
+ unpack=...,
+ ndmin=...,
+ encoding=...,
+ max_rows=...,
+ *,
+ like=...,
+): ...
+def savetxt(
+ fname,
+ X,
+ fmt=...,
+ delimiter=...,
+ newline=...,
+ header=...,
+ footer=...,
+ comments=...,
+ encoding=...,
+): ...
+def fromregex(file, regexp, dtype, encoding=...): ...
+def genfromtxt(
+ fname,
+ dtype=...,
+ comments=...,
+ delimiter=...,
+ skip_header=...,
+ skip_footer=...,
+ converters=...,
+ missing_values=...,
+ filling_values=...,
+ usecols=...,
+ names=...,
+ excludelist=...,
+ deletechars=...,
+ replace_space=...,
+ autostrip=...,
+ case_sensitive=...,
+ defaultfmt=...,
+ unpack=...,
+ usemask=...,
+ loose=...,
+ invalid_raise=...,
+ max_rows=...,
+ encoding=...,
+ *,
+ like=...,
+): ...
+def recfromtxt(fname, **kwargs): ...
+def recfromcsv(fname, **kwargs): ...
+
+# NOTE: Deprecated
+# def ndfromtxt(fname, **kwargs): ...
+# def mafromtxt(fname, **kwargs): ...
diff --git a/numpy/lib/polynomial.py b/numpy/lib/polynomial.py
index 0fd9bbd79..23021cafa 100644
--- a/numpy/lib/polynomial.py
+++ b/numpy/lib/polynomial.py
@@ -489,16 +489,19 @@ def polyfit(x, y, deg, rcond=None, full=False, w=None, cov=False):
default) just the coefficients are returned, when True diagnostic
information from the singular value decomposition is also returned.
w : array_like, shape (M,), optional
- Weights to apply to the y-coordinates of the sample points. For
- gaussian uncertainties, use 1/sigma (not 1/sigma**2).
+ Weights. If not None, the weight ``w[i]`` applies to the unsquared
+ residual ``y[i] - y_hat[i]`` at ``x[i]``. Ideally the weights are
+ chosen so that the errors of the products ``w[i]*y[i]`` all have the
+ same variance. When using inverse-variance weighting, use
+ ``w[i] = 1/sigma(y[i])``. The default value is None.
cov : bool or str, optional
If given and not `False`, return not just the estimate but also its
covariance matrix. By default, the covariance are scaled by
- chi2/dof, where dof = M - (deg + 1), i.e., the weights are presumed
- to be unreliable except in a relative sense and everything is scaled
- such that the reduced chi2 is unity. This scaling is omitted if
- ``cov='unscaled'``, as is relevant for the case that the weights are
- 1/sigma**2, with sigma known to be a reliable estimate of the
+ chi2/dof, where dof = M - (deg + 1), i.e., the weights are presumed
+ to be unreliable except in a relative sense and everything is scaled
+ such that the reduced chi2 is unity. This scaling is omitted if
+ ``cov='unscaled'``, as is relevant for the case that the weights are
+ w = 1/sigma, with sigma known to be a reliable estimate of the
uncertainty.
Returns
@@ -708,8 +711,8 @@ def polyval(p, x):
``p[0]*x**(N-1) + p[1]*x**(N-2) + ... + p[N-2]*x + p[N-1]``
- If `x` is a sequence, then `p(x)` is returned for each element of `x`.
- If `x` is another polynomial then the composite polynomial `p(x(t))`
+ If `x` is a sequence, then ``p(x)`` is returned for each element of ``x``.
+ If `x` is another polynomial then the composite polynomial ``p(x(t))``
is returned.
Parameters
@@ -1037,7 +1040,7 @@ def polydiv(u, v):
return poly1d(q), poly1d(r)
return q, r
-_poly_mat = re.compile(r"[*][*]([0-9]*)")
+_poly_mat = re.compile(r"\*\*([0-9]*)")
def _raise_power(astr, wrap=70):
n = 0
line1 = ''
@@ -1394,9 +1397,9 @@ class poly1d:
def __getitem__(self, val):
ind = self.order - val
if val > self.order:
- return 0
+ return self.coeffs.dtype.type(0)
if val < 0:
- return 0
+ return self.coeffs.dtype.type(0)
return self.coeffs[ind]
def __setitem__(self, key, val):
diff --git a/numpy/lib/polynomial.pyi b/numpy/lib/polynomial.pyi
new file mode 100644
index 000000000..7d38658d0
--- /dev/null
+++ b/numpy/lib/polynomial.pyi
@@ -0,0 +1,19 @@
+from typing import List
+
+from numpy import (
+ RankWarning as RankWarning,
+ poly1d as poly1d,
+)
+
+__all__: List[str]
+
+def poly(seq_of_zeros): ...
+def roots(p): ...
+def polyint(p, m=..., k=...): ...
+def polyder(p, m=...): ...
+def polyfit(x, y, deg, rcond=..., full=..., w=..., cov=...): ...
+def polyval(p, x): ...
+def polyadd(a1, a2): ...
+def polysub(a1, a2): ...
+def polymul(a1, a2): ...
+def polydiv(u, v): ...
diff --git a/numpy/lib/scimath.py b/numpy/lib/scimath.py
index 2b0d38c37..ed9ffd295 100644
--- a/numpy/lib/scimath.py
+++ b/numpy/lib/scimath.py
@@ -572,10 +572,10 @@ def arctanh(x):
Compute the inverse hyperbolic tangent of `x`.
Return the "principal value" (for a description of this, see
- `numpy.arctanh`) of `arctanh(x)`. For real `x` such that
- `abs(x) < 1`, this is a real number. If `abs(x) > 1`, or if `x` is
+ `numpy.arctanh`) of ``arctanh(x)``. For real `x` such that
+ ``abs(x) < 1``, this is a real number. If `abs(x) > 1`, or if `x` is
complex, the result is complex. Finally, `x = 1` returns``inf`` and
- `x=-1` returns ``-inf``.
+ ``x=-1`` returns ``-inf``.
Parameters
----------
@@ -597,7 +597,7 @@ def arctanh(x):
-----
For an arctanh() that returns ``NAN`` when real `x` is not in the
interval ``(-1,1)``, use `numpy.arctanh` (this latter, however, does
- return +/-inf for `x = +/-1`).
+ return +/-inf for ``x = +/-1``).
Examples
--------
diff --git a/numpy/lib/scimath.pyi b/numpy/lib/scimath.pyi
new file mode 100644
index 000000000..d0d4af41e
--- /dev/null
+++ b/numpy/lib/scimath.pyi
@@ -0,0 +1,13 @@
+from typing import List
+
+__all__: List[str]
+
+def sqrt(x): ...
+def log(x): ...
+def log10(x): ...
+def logn(n, x): ...
+def log2(x): ...
+def power(x, p): ...
+def arccos(x): ...
+def arcsin(x): ...
+def arctanh(x): ...
diff --git a/numpy/lib/shape_base.py b/numpy/lib/shape_base.py
index cbc4641d8..a3fbee3d5 100644
--- a/numpy/lib/shape_base.py
+++ b/numpy/lib/shape_base.py
@@ -69,13 +69,13 @@ def take_along_axis(arr, indices, axis):
Parameters
----------
- arr: ndarray (Ni..., M, Nk...)
+ arr : ndarray (Ni..., M, Nk...)
Source array
- indices: ndarray (Ni..., J, Nk...)
+ indices : ndarray (Ni..., J, Nk...)
Indices to take along each 1d slice of `arr`. This must match the
dimension of arr, but dimensions Ni and Nj only need to broadcast
against `arr`.
- axis: int
+ axis : int
The axis to take 1d slices along. If axis is None, the input array is
treated as if it had first been flattened to 1d, for consistency with
`sort` and `argsort`.
@@ -190,16 +190,16 @@ def put_along_axis(arr, indices, values, axis):
Parameters
----------
- arr: ndarray (Ni..., M, Nk...)
+ arr : ndarray (Ni..., M, Nk...)
Destination array.
- indices: ndarray (Ni..., J, Nk...)
+ indices : ndarray (Ni..., J, Nk...)
Indices to change along each 1d slice of `arr`. This must match the
dimension of arr, but dimensions in Ni and Nj may be 1 to broadcast
against `arr`.
- values: array_like (Ni..., J, Nk...)
+ values : array_like (Ni..., J, Nk...)
values to insert at those indices. Its shape and dimension are
broadcast to match that of `indices`.
- axis: int
+ axis : int
The axis to take 1d slices along. If axis is None, the destination
array is treated as if a flattened 1d view had been created of it.
@@ -649,7 +649,7 @@ def column_stack(tup):
arrays = []
for v in tup:
- arr = array(v, copy=False, subok=True)
+ arr = asanyarray(v)
if arr.ndim < 2:
arr = array(arr, copy=False, subok=True, ndmin=2).T
arrays.append(arr)
@@ -775,7 +775,7 @@ def array_split(ary, indices_or_sections, axis=0):
# indices_or_sections is a scalar, not an array.
Nsections = int(indices_or_sections)
if Nsections <= 0:
- raise ValueError('number sections must be larger than 0.')
+ raise ValueError('number sections must be larger than 0.') from None
Neach_section, extras = divmod(Ntotal, Nsections)
section_sizes = ([0] +
extras * [Neach_section+1] +
@@ -1088,8 +1088,8 @@ def kron(a, b):
-----
The function assumes that the number of dimensions of `a` and `b`
are the same, if necessary prepending the smallest with ones.
- If `a.shape = (r0,r1,..,rN)` and `b.shape = (s0,s1,...,sN)`,
- the Kronecker product has shape `(r0*s0, r1*s1, ..., rN*SN)`.
+ If ``a.shape = (r0,r1,..,rN)`` and ``b.shape = (s0,s1,...,sN)``,
+ the Kronecker product has shape ``(r0*s0, r1*s1, ..., rN*SN)``.
The elements are products of elements from `a` and `b`, organized
explicitly by::
diff --git a/numpy/lib/shape_base.pyi b/numpy/lib/shape_base.pyi
new file mode 100644
index 000000000..cfb3040b7
--- /dev/null
+++ b/numpy/lib/shape_base.pyi
@@ -0,0 +1,215 @@
+from typing import List, TypeVar, Callable, Sequence, Any, overload, Tuple
+from typing_extensions import SupportsIndex, Protocol
+
+from numpy import (
+ generic,
+ integer,
+ dtype,
+ ufunc,
+ bool_,
+ unsignedinteger,
+ signedinteger,
+ floating,
+ complexfloating,
+ object_,
+)
+
+from numpy.typing import (
+ ArrayLike,
+ NDArray,
+ _ShapeLike,
+ _NestedSequence,
+ _SupportsDType,
+ _ArrayLikeBool_co,
+ _ArrayLikeUInt_co,
+ _ArrayLikeInt_co,
+ _ArrayLikeFloat_co,
+ _ArrayLikeComplex_co,
+ _ArrayLikeObject_co,
+)
+
+from numpy.core.shape_base import vstack
+
+_SCT = TypeVar("_SCT", bound=generic)
+
+_ArrayLike = _NestedSequence[_SupportsDType[dtype[_SCT]]]
+
+# The signatures of `__array_wrap__` and `__array_prepare__` are the same;
+# give them unique names for the sake of clarity
+class _ArrayWrap(Protocol):
+ def __call__(
+ self,
+ __array: NDArray[Any],
+ __context: None | Tuple[ufunc, Tuple[Any, ...], int] = ...,
+ ) -> Any: ...
+
+class _ArrayPrepare(Protocol):
+ def __call__(
+ self,
+ __array: NDArray[Any],
+ __context: None | Tuple[ufunc, Tuple[Any, ...], int] = ...,
+ ) -> Any: ...
+
+class _SupportsArrayWrap(Protocol):
+ @property
+ def __array_wrap__(self) -> _ArrayWrap: ...
+
+class _SupportsArrayPrepare(Protocol):
+ @property
+ def __array_prepare__(self) -> _ArrayPrepare: ...
+
+__all__: List[str]
+
+row_stack = vstack
+
+def take_along_axis(
+ arr: _SCT | NDArray[_SCT],
+ indices: NDArray[integer[Any]],
+ axis: None | int,
+) -> NDArray[_SCT]: ...
+
+def put_along_axis(
+ arr: NDArray[_SCT],
+ indices: NDArray[integer[Any]],
+ values: ArrayLike,
+ axis: None | int,
+) -> None: ...
+
+@overload
+def apply_along_axis(
+ func1d: Callable[..., _ArrayLike[_SCT]],
+ axis: SupportsIndex,
+ arr: ArrayLike,
+ *args: Any,
+ **kwargs: Any,
+) -> NDArray[_SCT]: ...
+@overload
+def apply_along_axis(
+ func1d: Callable[..., ArrayLike],
+ axis: SupportsIndex,
+ arr: ArrayLike,
+ *args: Any,
+ **kwargs: Any,
+) -> NDArray[Any]: ...
+
+def apply_over_axes(
+ func: Callable[[NDArray[Any], int], NDArray[_SCT]],
+ a: ArrayLike,
+ axes: int | Sequence[int],
+) -> NDArray[_SCT]: ...
+
+@overload
+def expand_dims(
+ a: _ArrayLike[_SCT],
+ axis: _ShapeLike,
+) -> NDArray[_SCT]: ...
+@overload
+def expand_dims(
+ a: ArrayLike,
+ axis: _ShapeLike,
+) -> NDArray[Any]: ...
+
+@overload
+def column_stack(tup: Sequence[_ArrayLike[_SCT]]) -> NDArray[_SCT]: ...
+@overload
+def column_stack(tup: Sequence[ArrayLike]) -> NDArray[Any]: ...
+
+@overload
+def dstack(tup: Sequence[_ArrayLike[_SCT]]) -> NDArray[_SCT]: ...
+@overload
+def dstack(tup: Sequence[ArrayLike]) -> NDArray[Any]: ...
+
+@overload
+def array_split(
+ ary: _ArrayLike[_SCT],
+ indices_or_sections: _ShapeLike,
+ axis: SupportsIndex = ...,
+) -> List[NDArray[_SCT]]: ...
+@overload
+def array_split(
+ ary: ArrayLike,
+ indices_or_sections: _ShapeLike,
+ axis: SupportsIndex = ...,
+) -> List[NDArray[Any]]: ...
+
+@overload
+def split(
+ ary: _ArrayLike[_SCT],
+ indices_or_sections: _ShapeLike,
+ axis: SupportsIndex = ...,
+) -> List[NDArray[_SCT]]: ...
+@overload
+def split(
+ ary: ArrayLike,
+ indices_or_sections: _ShapeLike,
+ axis: SupportsIndex = ...,
+) -> List[NDArray[Any]]: ...
+
+@overload
+def hsplit(
+ ary: _ArrayLike[_SCT],
+ indices_or_sections: _ShapeLike,
+) -> List[NDArray[_SCT]]: ...
+@overload
+def hsplit(
+ ary: ArrayLike,
+ indices_or_sections: _ShapeLike,
+) -> List[NDArray[Any]]: ...
+
+@overload
+def vsplit(
+ ary: _ArrayLike[_SCT],
+ indices_or_sections: _ShapeLike,
+) -> List[NDArray[_SCT]]: ...
+@overload
+def vsplit(
+ ary: ArrayLike,
+ indices_or_sections: _ShapeLike,
+) -> List[NDArray[Any]]: ...
+
+@overload
+def dsplit(
+ ary: _ArrayLike[_SCT],
+ indices_or_sections: _ShapeLike,
+) -> List[NDArray[_SCT]]: ...
+@overload
+def dsplit(
+ ary: ArrayLike,
+ indices_or_sections: _ShapeLike,
+) -> List[NDArray[Any]]: ...
+
+@overload
+def get_array_prepare(*args: _SupportsArrayPrepare) -> _ArrayPrepare: ...
+@overload
+def get_array_prepare(*args: object) -> None | _ArrayPrepare: ...
+
+@overload
+def get_array_wrap(*args: _SupportsArrayWrap) -> _ArrayWrap: ...
+@overload
+def get_array_wrap(*args: object) -> None | _ArrayWrap: ...
+
+@overload
+def kron(a: _ArrayLikeBool_co, b: _ArrayLikeBool_co) -> NDArray[bool_]: ... # type: ignore[misc]
+@overload
+def kron(a: _ArrayLikeUInt_co, b: _ArrayLikeUInt_co) -> NDArray[unsignedinteger[Any]]: ... # type: ignore[misc]
+@overload
+def kron(a: _ArrayLikeInt_co, b: _ArrayLikeInt_co) -> NDArray[signedinteger[Any]]: ... # type: ignore[misc]
+@overload
+def kron(a: _ArrayLikeFloat_co, b: _ArrayLikeFloat_co) -> NDArray[floating[Any]]: ... # type: ignore[misc]
+@overload
+def kron(a: _ArrayLikeComplex_co, b: _ArrayLikeComplex_co) -> NDArray[complexfloating[Any, Any]]: ...
+@overload
+def kron(a: _ArrayLikeObject_co, b: Any) -> NDArray[object_]: ...
+@overload
+def kron(a: Any, b: _ArrayLikeObject_co) -> NDArray[object_]: ...
+
+@overload
+def tile(
+ A: _ArrayLike[_SCT],
+ reps: int | Sequence[int],
+) -> NDArray[_SCT]: ...
+@overload
+def tile(
+ A: ArrayLike,
+ reps: int | Sequence[int],
+) -> NDArray[Any]: ...
diff --git a/numpy/lib/stride_tricks.py b/numpy/lib/stride_tricks.py
index 82c8a57c8..5093993a9 100644
--- a/numpy/lib/stride_tricks.py
+++ b/numpy/lib/stride_tricks.py
@@ -371,8 +371,9 @@ def broadcast_to(array, shape, subok=False):
----------
array : array_like
The array to broadcast.
- shape : tuple
- The shape of the desired array.
+ shape : tuple or int
+ The shape of the desired array. A single integer ``i`` is interpreted
+ as ``(i,)``.
subok : bool, optional
If True, then sub-classes will be passed-through, otherwise
the returned array will be forced to be a base-class array (default).
diff --git a/numpy/lib/stride_tricks.pyi b/numpy/lib/stride_tricks.pyi
new file mode 100644
index 000000000..d2e744b5a
--- /dev/null
+++ b/numpy/lib/stride_tricks.pyi
@@ -0,0 +1,16 @@
+from typing import Any, List
+
+from numpy.typing import _ShapeLike, _Shape
+
+__all__: List[str]
+
+class DummyArray:
+ __array_interface__: Any
+ base: Any
+ def __init__(self, interface, base=...): ...
+
+def as_strided(x, shape=..., strides=..., subok=..., writeable=...): ...
+def sliding_window_view(x, window_shape, axis=..., *, subok=..., writeable=...): ...
+def broadcast_to(array, shape, subok=...): ...
+def broadcast_shapes(*args: _ShapeLike) -> _Shape: ...
+def broadcast_arrays(*args, subok=...): ...
diff --git a/numpy/lib/tests/test__version.py b/numpy/lib/tests/test__version.py
index 182504631..e6d41ad93 100644
--- a/numpy/lib/tests/test__version.py
+++ b/numpy/lib/tests/test__version.py
@@ -7,7 +7,7 @@ from numpy.lib import NumpyVersion
def test_main_versions():
assert_(NumpyVersion('1.8.0') == '1.8.0')
- for ver in ['1.9.0', '2.0.0', '1.8.1']:
+ for ver in ['1.9.0', '2.0.0', '1.8.1', '10.0.1']:
assert_(NumpyVersion('1.8.0') < ver)
for ver in ['1.7.0', '1.7.1', '0.9.9']:
diff --git a/numpy/lib/tests/test_arraysetops.py b/numpy/lib/tests/test_arraysetops.py
index 847e6cb8a..13385cd24 100644
--- a/numpy/lib/tests/test_arraysetops.py
+++ b/numpy/lib/tests/test_arraysetops.py
@@ -358,6 +358,39 @@ class TestSetOps:
result = np.in1d(ar1, ar2)
assert_array_equal(result, expected)
+ def test_in1d_with_arrays_containing_tuples(self):
+ ar1 = np.array([(1,), 2], dtype=object)
+ ar2 = np.array([(1,), 2], dtype=object)
+ expected = np.array([True, True])
+ result = np.in1d(ar1, ar2)
+ assert_array_equal(result, expected)
+ result = np.in1d(ar1, ar2, invert=True)
+ assert_array_equal(result, np.invert(expected))
+
+ # An integer is added at the end of the array to make sure
+ # that the array builder will create the array with tuples
+ # and after it's created the integer is removed.
+ # There's a bug in the array constructor that doesn't handle
+ # tuples properly and adding the integer fixes that.
+ ar1 = np.array([(1,), (2, 1), 1], dtype=object)
+ ar1 = ar1[:-1]
+ ar2 = np.array([(1,), (2, 1), 1], dtype=object)
+ ar2 = ar2[:-1]
+ expected = np.array([True, True])
+ result = np.in1d(ar1, ar2)
+ assert_array_equal(result, expected)
+ result = np.in1d(ar1, ar2, invert=True)
+ assert_array_equal(result, np.invert(expected))
+
+ ar1 = np.array([(1,), (2, 3), 1], dtype=object)
+ ar1 = ar1[:-1]
+ ar2 = np.array([(1,), 2], dtype=object)
+ expected = np.array([True, False])
+ result = np.in1d(ar1, ar2)
+ assert_array_equal(result, expected)
+ result = np.in1d(ar1, ar2, invert=True)
+ assert_array_equal(result, np.invert(expected))
+
def test_union1d(self):
a = np.array([5, 4, 7, 1, 2])
b = np.array([2, 4, 3, 3, 2, 1, 5])
@@ -531,6 +564,63 @@ class TestUnique:
assert_equal(a3_idx.dtype, np.intp)
assert_equal(a3_inv.dtype, np.intp)
+ # test for ticket 2111 - float
+ a = [2.0, np.nan, 1.0, np.nan]
+ ua = [1.0, 2.0, np.nan]
+ ua_idx = [2, 0, 1]
+ ua_inv = [1, 2, 0, 2]
+ ua_cnt = [1, 1, 2]
+ assert_equal(np.unique(a), ua)
+ assert_equal(np.unique(a, return_index=True), (ua, ua_idx))
+ assert_equal(np.unique(a, return_inverse=True), (ua, ua_inv))
+ assert_equal(np.unique(a, return_counts=True), (ua, ua_cnt))
+
+ # test for ticket 2111 - complex
+ a = [2.0-1j, np.nan, 1.0+1j, complex(0.0, np.nan), complex(1.0, np.nan)]
+ ua = [1.0+1j, 2.0-1j, complex(0.0, np.nan)]
+ ua_idx = [2, 0, 3]
+ ua_inv = [1, 2, 0, 2, 2]
+ ua_cnt = [1, 1, 3]
+ assert_equal(np.unique(a), ua)
+ assert_equal(np.unique(a, return_index=True), (ua, ua_idx))
+ assert_equal(np.unique(a, return_inverse=True), (ua, ua_inv))
+ assert_equal(np.unique(a, return_counts=True), (ua, ua_cnt))
+
+ # test for ticket 2111 - datetime64
+ nat = np.datetime64('nat')
+ a = [np.datetime64('2020-12-26'), nat, np.datetime64('2020-12-24'), nat]
+ ua = [np.datetime64('2020-12-24'), np.datetime64('2020-12-26'), nat]
+ ua_idx = [2, 0, 1]
+ ua_inv = [1, 2, 0, 2]
+ ua_cnt = [1, 1, 2]
+ assert_equal(np.unique(a), ua)
+ assert_equal(np.unique(a, return_index=True), (ua, ua_idx))
+ assert_equal(np.unique(a, return_inverse=True), (ua, ua_inv))
+ assert_equal(np.unique(a, return_counts=True), (ua, ua_cnt))
+
+ # test for ticket 2111 - timedelta
+ nat = np.timedelta64('nat')
+ a = [np.timedelta64(1, 'D'), nat, np.timedelta64(1, 'h'), nat]
+ ua = [np.timedelta64(1, 'h'), np.timedelta64(1, 'D'), nat]
+ ua_idx = [2, 0, 1]
+ ua_inv = [1, 2, 0, 2]
+ ua_cnt = [1, 1, 2]
+ assert_equal(np.unique(a), ua)
+ assert_equal(np.unique(a, return_index=True), (ua, ua_idx))
+ assert_equal(np.unique(a, return_inverse=True), (ua, ua_inv))
+ assert_equal(np.unique(a, return_counts=True), (ua, ua_cnt))
+
+ # test for gh-19300
+ all_nans = [np.nan] * 4
+ ua = [np.nan]
+ ua_idx = [0]
+ ua_inv = [0, 0, 0, 0]
+ ua_cnt = [4]
+ assert_equal(np.unique(all_nans), ua)
+ assert_equal(np.unique(all_nans, return_index=True), (ua, ua_idx))
+ assert_equal(np.unique(all_nans, return_inverse=True), (ua, ua_inv))
+ assert_equal(np.unique(all_nans, return_counts=True), (ua, ua_cnt))
+
def test_unique_axis_errors(self):
assert_raises(TypeError, self._run_axis_tests, object)
assert_raises(TypeError, self._run_axis_tests,
diff --git a/numpy/lib/tests/test_format.py b/numpy/lib/tests/test_format.py
index bac42fad3..10656a233 100644
--- a/numpy/lib/tests/test_format.py
+++ b/numpy/lib/tests/test_format.py
@@ -402,7 +402,7 @@ class BytesIOSRandomSize(BytesIO):
def read(self, size=None):
import random
size = random.randint(1, size)
- return super(BytesIOSRandomSize, self).read(size)
+ return super().read(size)
def roundtrip(arr):
diff --git a/numpy/lib/tests/test_function_base.py b/numpy/lib/tests/test_function_base.py
index 4c7c0480c..e1b615223 100644
--- a/numpy/lib/tests/test_function_base.py
+++ b/numpy/lib/tests/test_function_base.py
@@ -1665,6 +1665,26 @@ class TestVectorize:
with assert_raises_regex(ValueError, 'new output dimensions'):
f(x)
+ def test_subclasses(self):
+ class subclass(np.ndarray):
+ pass
+
+ m = np.array([[1., 0., 0.],
+ [0., 0., 1.],
+ [0., 1., 0.]]).view(subclass)
+ v = np.array([[1., 2., 3.], [4., 5., 6.], [7., 8., 9.]]).view(subclass)
+ # generalized (gufunc)
+ matvec = np.vectorize(np.matmul, signature='(m,m),(m)->(m)')
+ r = matvec(m, v)
+ assert_equal(type(r), subclass)
+ assert_equal(r, [[1., 3., 2.], [4., 6., 5.], [7., 9., 8.]])
+
+ # element-wise (ufunc)
+ mult = np.vectorize(lambda x, y: x*y)
+ r = mult(m, v)
+ assert_equal(type(r), subclass)
+ assert_equal(r, m * v)
+
class TestLeaks:
class A:
@@ -1799,6 +1819,24 @@ class TestUnwrap:
# check that unwrap maintains continuity
assert_(np.all(diff(unwrap(rand(10) * 100)) < np.pi))
+ def test_period(self):
+ # check that unwrap removes jumps greater that 255
+ assert_array_equal(unwrap([1, 1 + 256], period=255), [1, 2])
+ # check that unwrap maintains continuity
+ assert_(np.all(diff(unwrap(rand(10) * 1000, period=255)) < 255))
+ # check simple case
+ simple_seq = np.array([0, 75, 150, 225, 300])
+ wrap_seq = np.mod(simple_seq, 255)
+ assert_array_equal(unwrap(wrap_seq, period=255), simple_seq)
+ # check custom discont value
+ uneven_seq = np.array([0, 75, 150, 225, 300, 430])
+ wrap_uneven = np.mod(uneven_seq, 250)
+ no_discont = unwrap(wrap_uneven, period=250)
+ assert_array_equal(no_discont, [0, 75, 150, 225, 300, 180])
+ sm_discont = unwrap(wrap_uneven, period=250, discont=140)
+ assert_array_equal(sm_discont, [0, 75, 150, 225, 300, 430])
+ assert sm_discont.dtype == wrap_uneven.dtype
+
class TestFilterwindows:
@@ -2307,6 +2345,27 @@ class TestMeshgrid:
assert_equal(x[0, :], 0)
assert_equal(x[1, :], X)
+ def test_nd_shape(self):
+ a, b, c, d, e = np.meshgrid(*([0] * i for i in range(1, 6)))
+ expected_shape = (2, 1, 3, 4, 5)
+ assert_equal(a.shape, expected_shape)
+ assert_equal(b.shape, expected_shape)
+ assert_equal(c.shape, expected_shape)
+ assert_equal(d.shape, expected_shape)
+ assert_equal(e.shape, expected_shape)
+
+ def test_nd_values(self):
+ a, b, c = np.meshgrid([0], [1, 2], [3, 4, 5])
+ assert_equal(a, [[[0, 0, 0]], [[0, 0, 0]]])
+ assert_equal(b, [[[1, 1, 1]], [[2, 2, 2]]])
+ assert_equal(c, [[[3, 4, 5]], [[3, 4, 5]]])
+
+ def test_nd_indexing(self):
+ a, b, c = np.meshgrid([0], [1, 2], [3, 4, 5], indexing='ij')
+ assert_equal(a, [[[0, 0, 0], [0, 0, 0]]])
+ assert_equal(b, [[[1, 1, 1], [2, 2, 2]]])
+ assert_equal(c, [[[3, 4, 5], [3, 4, 5]]])
+
class TestPiecewise:
@@ -2399,6 +2458,14 @@ class TestPiecewise:
assert_array_equal(y, np.array([[-1., -1., -1.],
[3., 3., 1.]]))
+ def test_subclasses(self):
+ class subclass(np.ndarray):
+ pass
+ x = np.arange(5.).view(subclass)
+ r = piecewise(x, [x<2., x>=4], [-1., 1., 0.])
+ assert_equal(type(r), subclass)
+ assert_equal(r, [-1., -1., 0., 0., 1.])
+
class TestBincount:
@@ -2721,6 +2788,10 @@ class TestPercentile:
assert_equal(p, Fraction(7, 4))
assert_equal(type(p), Fraction)
+ p = np.percentile(x, [Fraction(50)])
+ assert_equal(p, np.array([Fraction(7, 4)]))
+ assert_equal(type(p), np.ndarray)
+
def test_api(self):
d = np.ones(5)
np.percentile(d, 5, None, None, False)
@@ -3115,6 +3186,16 @@ class TestPercentile:
assert_equal(np.percentile(
a, [0.3, 0.6], (0, 2), interpolation='nearest'), b)
+ def test_nan_q(self):
+ # GH18830
+ with pytest.raises(ValueError, match="Percentiles must be in"):
+ np.percentile([1, 2, 3, 4.0], np.nan)
+ with pytest.raises(ValueError, match="Percentiles must be in"):
+ np.percentile([1, 2, 3, 4.0], [np.nan])
+ q = np.linspace(1.0, 99.0, 16)
+ q[0] = np.nan
+ with pytest.raises(ValueError, match="Percentiles must be in"):
+ np.percentile([1, 2, 3, 4.0], q)
class TestQuantile:
# most of this is already tested by TestPercentile
@@ -3151,6 +3232,14 @@ class TestQuantile:
assert_equal(q, Fraction(7, 4))
assert_equal(type(q), Fraction)
+ q = np.quantile(x, [Fraction(1, 2)])
+ assert_equal(q, np.array([Fraction(7, 4)]))
+ assert_equal(type(q), np.ndarray)
+
+ q = np.quantile(x, [[Fraction(1, 2)]])
+ assert_equal(q, np.array([[Fraction(7, 4)]]))
+ assert_equal(type(q), np.ndarray)
+
# repeat with integral input but fractional quantile
x = np.arange(8)
assert_equal(np.quantile(x, Fraction(1, 2)), Fraction(7, 2))
diff --git a/numpy/lib/tests/test_index_tricks.py b/numpy/lib/tests/test_index_tricks.py
index 843e27cef..c21aefd1a 100644
--- a/numpy/lib/tests/test_index_tricks.py
+++ b/numpy/lib/tests/test_index_tricks.py
@@ -16,23 +16,13 @@ class TestRavelUnravelIndex:
def test_basic(self):
assert_equal(np.unravel_index(2, (2, 2)), (1, 0))
- # test backwards compatibility with older dims
- # keyword argument; see Issue #10586
- with assert_warns(DeprecationWarning):
- # we should achieve the correct result
- # AND raise the appropriate warning
- # when using older "dims" kw argument
- assert_equal(np.unravel_index(indices=2,
- dims=(2, 2)),
- (1, 0))
-
# test that new shape argument works properly
assert_equal(np.unravel_index(indices=2,
shape=(2, 2)),
(1, 0))
# test that an invalid second keyword argument
- # is properly handled
+ # is properly handled, including the old name `dims`.
with assert_raises(TypeError):
np.unravel_index(indices=2, hape=(2, 2))
@@ -42,6 +32,9 @@ class TestRavelUnravelIndex:
with assert_raises(TypeError):
np.unravel_index(254, ims=(17, 94))
+ with assert_raises(TypeError):
+ np.unravel_index(254, dims=(17, 94))
+
assert_equal(np.ravel_multi_index((1, 0), (2, 2)), 2)
assert_equal(np.unravel_index(254, (17, 94)), (2, 66))
assert_equal(np.ravel_multi_index((2, 66), (17, 94)), 254)
diff --git a/numpy/lib/tests/test_io.py b/numpy/lib/tests/test_io.py
index aa4499764..534ab683c 100644
--- a/numpy/lib/tests/test_io.py
+++ b/numpy/lib/tests/test_io.py
@@ -580,7 +580,7 @@ class TestSaveTxt:
memoryerror_raised.value = False
try:
# The test takes at least 6GB of memory, writes a file larger
- # than 4GB
+ # than 4GB. This tests the ``allowZip64`` kwarg to ``zipfile``
test_data = np.asarray([np.random.rand(
np.random.randint(50,100),4)
for i in range(800000)], dtype=object)
@@ -599,6 +599,9 @@ class TestSaveTxt:
p.join()
if memoryerror_raised.value:
raise MemoryError("Child process raised a MemoryError exception")
+ # -9 indicates a SIGKILL, probably an OOM.
+ if p.exitcode == -9:
+ pytest.xfail("subprocess got a SIGKILL, apparently free memory was not sufficient")
assert p.exitcode == 0
class LoadTxtBase:
diff --git a/numpy/lib/tests/test_nanfunctions.py b/numpy/lib/tests/test_nanfunctions.py
index e0f723a3c..1f1f5601b 100644
--- a/numpy/lib/tests/test_nanfunctions.py
+++ b/numpy/lib/tests/test_nanfunctions.py
@@ -588,6 +588,15 @@ class TestNanFunctions_MeanVarStd(SharedNanFunctionsTestsMixin):
assert_(len(w) == 0)
+_TIME_UNITS = (
+ "Y", "M", "W", "D", "h", "m", "s", "ms", "us", "ns", "ps", "fs", "as"
+)
+
+# All `inexact` + `timdelta64` type codes
+_TYPE_CODES = list(np.typecodes["AllFloat"])
+_TYPE_CODES += [f"m8[{unit}]" for unit in _TIME_UNITS]
+
+
class TestNanFunctions_Median:
def test_mutation(self):
@@ -662,23 +671,32 @@ class TestNanFunctions_Median:
res = np.nanmedian(_ndat, axis=1)
assert_almost_equal(res, tgt)
- def test_allnans(self):
- mat = np.array([np.nan]*9).reshape(3, 3)
- for axis in [None, 0, 1]:
- with suppress_warnings() as sup:
- sup.record(RuntimeWarning)
+ @pytest.mark.parametrize("axis", [None, 0, 1])
+ @pytest.mark.parametrize("dtype", _TYPE_CODES)
+ def test_allnans(self, dtype, axis):
+ mat = np.full((3, 3), np.nan).astype(dtype)
+ with suppress_warnings() as sup:
+ sup.record(RuntimeWarning)
- assert_(np.isnan(np.nanmedian(mat, axis=axis)).all())
- if axis is None:
- assert_(len(sup.log) == 1)
- else:
- assert_(len(sup.log) == 3)
- # Check scalar
- assert_(np.isnan(np.nanmedian(np.nan)))
- if axis is None:
- assert_(len(sup.log) == 2)
- else:
- assert_(len(sup.log) == 4)
+ output = np.nanmedian(mat, axis=axis)
+ assert output.dtype == mat.dtype
+ assert np.isnan(output).all()
+
+ if axis is None:
+ assert_(len(sup.log) == 1)
+ else:
+ assert_(len(sup.log) == 3)
+
+ # Check scalar
+ scalar = np.array(np.nan).astype(dtype)[()]
+ output_scalar = np.nanmedian(scalar)
+ assert output_scalar.dtype == scalar.dtype
+ assert np.isnan(output_scalar)
+
+ if axis is None:
+ assert_(len(sup.log) == 2)
+ else:
+ assert_(len(sup.log) == 4)
def test_empty(self):
mat = np.zeros((0, 3))
diff --git a/numpy/lib/tests/test_polynomial.py b/numpy/lib/tests/test_polynomial.py
index 6c3e4fa02..3734344d2 100644
--- a/numpy/lib/tests/test_polynomial.py
+++ b/numpy/lib/tests/test_polynomial.py
@@ -4,6 +4,12 @@ from numpy.testing import (
assert_array_almost_equal, assert_raises, assert_allclose
)
+import pytest
+
+# `poly1d` has some support for `bool_` and `timedelta64`,
+# but it is limited and they are therefore excluded here
+TYPE_CODES = np.typecodes["AllInteger"] + np.typecodes["AllFloat"] + "O"
+
class TestPolynomial:
def test_poly1d_str_and_repr(self):
@@ -57,11 +63,26 @@ class TestPolynomial:
assert_equal(np.polydiv(np.poly1d([1, 0, -1]), np.poly1d([1, 1])),
(np.poly1d([1., -1.]), np.poly1d([0.])))
- def test_poly1d_misc(self):
- p = np.poly1d([1., 2, 3])
- assert_equal(np.asarray(p), np.array([1., 2., 3.]))
+ @pytest.mark.parametrize("type_code", TYPE_CODES)
+ def test_poly1d_misc(self, type_code: str) -> None:
+ dtype = np.dtype(type_code)
+ ar = np.array([1, 2, 3], dtype=dtype)
+ p = np.poly1d(ar)
+
+ # `__eq__`
+ assert_equal(np.asarray(p), ar)
+ assert_equal(np.asarray(p).dtype, dtype)
assert_equal(len(p), 2)
- assert_equal((p[0], p[1], p[2], p[3]), (3.0, 2.0, 1.0, 0))
+
+ # `__getitem__`
+ comparison_dct = {-1: 0, 0: 3, 1: 2, 2: 1, 3: 0}
+ for index, ref in comparison_dct.items():
+ scalar = p[index]
+ assert_equal(scalar, ref)
+ if dtype == np.object_:
+ assert isinstance(scalar, int)
+ else:
+ assert_equal(scalar.dtype, dtype)
def test_poly1d_variable_arg(self):
q = np.poly1d([1., 2, 3], variable='y')
@@ -257,7 +278,7 @@ class TestPolynomial:
assert_equal(q.coeffs.dtype, np.complex128)
assert_equal(r.coeffs.dtype, np.complex128)
assert_equal(q*a + r, b)
-
+
c = [1, 2, 3]
d = np.poly1d([1, 2, 3])
s, t = np.polydiv(c, d)
diff --git a/numpy/lib/tests/test_regression.py b/numpy/lib/tests/test_regression.py
index 55df2a675..373226277 100644
--- a/numpy/lib/tests/test_regression.py
+++ b/numpy/lib/tests/test_regression.py
@@ -1,3 +1,5 @@
+import pytest
+
import os
import numpy as np
diff --git a/numpy/lib/tests/test_utils.py b/numpy/lib/tests/test_utils.py
index 33951b92a..8a877ae69 100644
--- a/numpy/lib/tests/test_utils.py
+++ b/numpy/lib/tests/test_utils.py
@@ -4,7 +4,7 @@ import pytest
from numpy.core import arange
from numpy.testing import assert_, assert_equal, assert_raises_regex
-from numpy.lib import deprecate
+from numpy.lib import deprecate, deprecate_with_doc
import numpy.lib.utils as utils
from io import StringIO
@@ -60,6 +60,11 @@ def old_func6(self, x):
new_func6 = deprecate(old_func6)
+@deprecate_with_doc(msg="Rather use new_func7")
+def old_func7(self,x):
+ return x
+
+
def test_deprecate_decorator():
assert_('deprecated' in old_func.__doc__)
@@ -73,6 +78,10 @@ def test_deprecate_fn():
assert_('new_func3' in new_func3.__doc__)
+def test_deprecate_with_doc_decorator_message():
+ assert_('Rather use new_func7' in old_func7.__doc__)
+
+
@pytest.mark.skipif(sys.flags.optimize == 2, reason="-OO discards docstrings")
@pytest.mark.parametrize('old_func, new_func', [
(old_func4, new_func4),
diff --git a/numpy/lib/twodim_base.py b/numpy/lib/twodim_base.py
index 2b4cbdfbb..83c028061 100644
--- a/numpy/lib/twodim_base.py
+++ b/numpy/lib/twodim_base.py
@@ -5,12 +5,13 @@ import functools
from numpy.core.numeric import (
asanyarray, arange, zeros, greater_equal, multiply, ones,
- asarray, where, int8, int16, int32, int64, empty, promote_types, diagonal,
- nonzero
+ asarray, where, int8, int16, int32, int64, intp, empty, promote_types,
+ diagonal, nonzero, indices
)
from numpy.core.overrides import set_array_function_like_doc, set_module
from numpy.core import overrides
from numpy.core import iinfo
+from numpy.lib.stride_tricks import broadcast_to
__all__ = [
@@ -46,10 +47,11 @@ def _flip_dispatcher(m):
@array_function_dispatch(_flip_dispatcher)
def fliplr(m):
"""
- Flip array in the left/right direction.
+ Reverse the order of elements along axis 1 (left/right).
- Flip the entries in each row in the left/right direction.
- Columns are preserved, but appear in a different order than before.
+ For a 2-D array, this flips the entries in each row in the left/right
+ direction. Columns are preserved, but appear in a different order than
+ before.
Parameters
----------
@@ -65,11 +67,13 @@ def fliplr(m):
See Also
--------
flipud : Flip array in the up/down direction.
+ flip : Flip array in one or more dimesions.
rot90 : Rotate array counterclockwise.
Notes
-----
- Equivalent to m[:,::-1]. Requires the array to be at least 2-D.
+ Equivalent to ``m[:,::-1]`` or ``np.flip(m, axis=1)``.
+ Requires the array to be at least 2-D.
Examples
--------
@@ -97,10 +101,10 @@ def fliplr(m):
@array_function_dispatch(_flip_dispatcher)
def flipud(m):
"""
- Flip array in the up/down direction.
+ Reverse the order of elements along axis 0 (up/down).
- Flip the entries in each column in the up/down direction.
- Rows are preserved, but appear in a different order than before.
+ For a 2-D array, this flips the entries in each column in the up/down
+ direction. Rows are preserved, but appear in a different order than before.
Parameters
----------
@@ -116,12 +120,13 @@ def flipud(m):
See Also
--------
fliplr : Flip array in the left/right direction.
+ flip : Flip array in one or more dimesions.
rot90 : Rotate array counterclockwise.
Notes
-----
- Equivalent to ``m[::-1,...]``.
- Does not require the array to be two-dimensional.
+ Equivalent to ``m[::-1, ...]`` or ``np.flip(m, axis=0)``.
+ Requires the array to be at least 1-D.
Examples
--------
@@ -347,10 +352,10 @@ def diagflat(v, k=0):
n = s + abs(k)
res = zeros((n, n), v.dtype)
if (k >= 0):
- i = arange(0, n-k)
+ i = arange(0, n-k, dtype=intp)
fi = i+k+i*n
else:
- i = arange(0, n+k)
+ i = arange(0, n+k, dtype=intp)
fi = i+(i-k)*n
res.flat[fi] = v
if not wrap:
@@ -434,10 +439,12 @@ def tril(m, k=0):
Lower triangle of an array.
Return a copy of an array with elements above the `k`-th diagonal zeroed.
+ For arrays with ``ndim`` exceeding 2, `tril` will apply to the final two
+ axes.
Parameters
----------
- m : array_like, shape (M, N)
+ m : array_like, shape (..., M, N)
Input array.
k : int, optional
Diagonal above which to zero elements. `k = 0` (the default) is the
@@ -445,7 +452,7 @@ def tril(m, k=0):
Returns
-------
- tril : ndarray, shape (M, N)
+ tril : ndarray, shape (..., M, N)
Lower triangle of `m`, of same shape and data-type as `m`.
See Also
@@ -460,6 +467,20 @@ def tril(m, k=0):
[ 7, 8, 0],
[10, 11, 12]])
+ >>> np.tril(np.arange(3*4*5).reshape(3, 4, 5))
+ array([[[ 0, 0, 0, 0, 0],
+ [ 5, 6, 0, 0, 0],
+ [10, 11, 12, 0, 0],
+ [15, 16, 17, 18, 0]],
+ [[20, 0, 0, 0, 0],
+ [25, 26, 0, 0, 0],
+ [30, 31, 32, 0, 0],
+ [35, 36, 37, 38, 0]],
+ [[40, 0, 0, 0, 0],
+ [45, 46, 0, 0, 0],
+ [50, 51, 52, 0, 0],
+ [55, 56, 57, 58, 0]]])
+
"""
m = asanyarray(m)
mask = tri(*m.shape[-2:], k=k, dtype=bool)
@@ -473,7 +494,8 @@ def triu(m, k=0):
Upper triangle of an array.
Return a copy of an array with the elements below the `k`-th diagonal
- zeroed.
+ zeroed. For arrays with ``ndim`` exceeding 2, `triu` will apply to the final
+ two axes.
Please refer to the documentation for `tril` for further details.
@@ -489,6 +511,20 @@ def triu(m, k=0):
[ 0, 8, 9],
[ 0, 0, 12]])
+ >>> np.triu(np.arange(3*4*5).reshape(3, 4, 5))
+ array([[[ 0, 1, 2, 3, 4],
+ [ 0, 6, 7, 8, 9],
+ [ 0, 0, 12, 13, 14],
+ [ 0, 0, 0, 18, 19]],
+ [[20, 21, 22, 23, 24],
+ [ 0, 26, 27, 28, 29],
+ [ 0, 0, 32, 33, 34],
+ [ 0, 0, 0, 38, 39]],
+ [[40, 41, 42, 43, 44],
+ [ 0, 46, 47, 48, 49],
+ [ 0, 0, 52, 53, 54],
+ [ 0, 0, 0, 58, 59]]])
+
"""
m = asanyarray(m)
mask = tri(*m.shape[-2:], k=k-1, dtype=bool)
@@ -700,7 +736,9 @@ def histogram2d(x, y, bins=10, range=None, normed=None, weights=None,
>>> x = np.random.normal(2, 1, 100)
>>> y = np.random.normal(1, 1, 100)
>>> H, xedges, yedges = np.histogram2d(x, y, bins=(xedges, yedges))
- >>> H = H.T # Let each row list bins with common y range.
+ >>> # Histogram does not follow Cartesian convention (see Notes),
+ >>> # therefore transpose H for visualization purposes.
+ >>> H = H.T
:func:`imshow <matplotlib.pyplot.imshow>` can only display square bins:
@@ -730,6 +768,40 @@ def histogram2d(x, y, bins=10, range=None, normed=None, weights=None,
>>> ax.images.append(im)
>>> plt.show()
+ It is also possible to construct a 2-D histogram without specifying bin
+ edges:
+
+ >>> # Generate non-symmetric test data
+ >>> n = 10000
+ >>> x = np.linspace(1, 100, n)
+ >>> y = 2*np.log(x) + np.random.rand(n) - 0.5
+ >>> # Compute 2d histogram. Note the order of x/y and xedges/yedges
+ >>> H, yedges, xedges = np.histogram2d(y, x, bins=20)
+
+ Now we can plot the histogram using
+ :func:`pcolormesh <matplotlib.pyplot.pcolormesh>`, and a
+ :func:`hexbin <matplotlib.pyplot.hexbin>` for comparison.
+
+ >>> # Plot histogram using pcolormesh
+ >>> fig, (ax1, ax2) = plt.subplots(ncols=2, sharey=True)
+ >>> ax1.pcolormesh(xedges, yedges, H, cmap='rainbow')
+ >>> ax1.plot(x, 2*np.log(x), 'k-')
+ >>> ax1.set_xlim(x.min(), x.max())
+ >>> ax1.set_ylim(y.min(), y.max())
+ >>> ax1.set_xlabel('x')
+ >>> ax1.set_ylabel('y')
+ >>> ax1.set_title('histogram2d')
+ >>> ax1.grid()
+
+ >>> # Create hexbin plot for comparison
+ >>> ax2.hexbin(x, y, gridsize=20, cmap='rainbow')
+ >>> ax2.plot(x, 2*np.log(x), 'k-')
+ >>> ax2.set_title('hexbin')
+ >>> ax2.set_xlim(x.min(), x.max())
+ >>> ax2.set_xlabel('x')
+ >>> ax2.grid()
+
+ >>> plt.show()
"""
from numpy import histogramdd
@@ -894,7 +966,10 @@ def tril_indices(n, k=0, m=None):
[-10, -10, -10, -10]])
"""
- return nonzero(tri(n, m, k=k, dtype=bool))
+ tri_ = tri(n, m, k=k, dtype=bool)
+
+ return tuple(broadcast_to(inds, tri_.shape)[tri_]
+ for inds in indices(tri_.shape, sparse=True))
def _trilu_indices_form_dispatcher(arr, k=None):
@@ -1010,7 +1085,10 @@ def triu_indices(n, k=0, m=None):
[ 12, 13, 14, -1]])
"""
- return nonzero(~tri(n, m, k=k-1, dtype=bool))
+ tri_ = ~tri(n, m, k=k - 1, dtype=bool)
+
+ return tuple(broadcast_to(inds, tri_.shape)[tri_]
+ for inds in indices(tri_.shape, sparse=True))
@array_function_dispatch(_trilu_indices_form_dispatcher)
diff --git a/numpy/lib/twodim_base.pyi b/numpy/lib/twodim_base.pyi
new file mode 100644
index 000000000..007338d77
--- /dev/null
+++ b/numpy/lib/twodim_base.pyi
@@ -0,0 +1,255 @@
+from typing import (
+ Any,
+ Callable,
+ List,
+ Sequence,
+ overload,
+ Tuple,
+ Type,
+ TypeVar,
+ Union,
+)
+
+from numpy import (
+ ndarray,
+ dtype,
+ generic,
+ number,
+ bool_,
+ timedelta64,
+ datetime64,
+ int_,
+ intp,
+ float64,
+ signedinteger,
+ floating,
+ complexfloating,
+ object_,
+ _OrderCF,
+)
+
+from numpy.typing import (
+ DTypeLike,
+ _SupportsDType,
+ ArrayLike,
+ NDArray,
+ _NestedSequence,
+ _SupportsArray,
+ _ArrayLikeInt_co,
+ _ArrayLikeFloat_co,
+ _ArrayLikeComplex_co,
+ _ArrayLikeObject_co,
+)
+
+_T = TypeVar("_T")
+_SCT = TypeVar("_SCT", bound=generic)
+
+# The returned arrays dtype must be compatible with `np.equal`
+_MaskFunc = Callable[
+ [NDArray[int_], _T],
+ NDArray[Union[number[Any], bool_, timedelta64, datetime64, object_]],
+]
+
+_DTypeLike = Union[
+ Type[_SCT],
+ dtype[_SCT],
+ _SupportsDType[dtype[_SCT]],
+]
+_ArrayLike = _NestedSequence[_SupportsArray[dtype[_SCT]]]
+
+__all__: List[str]
+
+@overload
+def fliplr(m: _ArrayLike[_SCT]) -> NDArray[_SCT]: ...
+@overload
+def fliplr(m: ArrayLike) -> NDArray[Any]: ...
+
+@overload
+def flipud(m: _ArrayLike[_SCT]) -> NDArray[_SCT]: ...
+@overload
+def flipud(m: ArrayLike) -> NDArray[Any]: ...
+
+@overload
+def eye(
+ N: int,
+ M: None | int = ...,
+ k: int = ...,
+ dtype: None = ...,
+ order: _OrderCF = ...,
+ *,
+ like: None | ArrayLike = ...,
+) -> NDArray[float64]: ...
+@overload
+def eye(
+ N: int,
+ M: None | int = ...,
+ k: int = ...,
+ dtype: _DTypeLike[_SCT] = ...,
+ order: _OrderCF = ...,
+ *,
+ like: None | ArrayLike = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def eye(
+ N: int,
+ M: None | int = ...,
+ k: int = ...,
+ dtype: DTypeLike = ...,
+ order: _OrderCF = ...,
+ *,
+ like: None | ArrayLike = ...,
+) -> NDArray[Any]: ...
+
+@overload
+def diag(v: _ArrayLike[_SCT], k: int = ...) -> NDArray[_SCT]: ...
+@overload
+def diag(v: ArrayLike, k: int = ...) -> NDArray[Any]: ...
+
+@overload
+def diagflat(v: _ArrayLike[_SCT], k: int = ...) -> NDArray[_SCT]: ...
+@overload
+def diagflat(v: ArrayLike, k: int = ...) -> NDArray[Any]: ...
+
+@overload
+def tri(
+ N: int,
+ M: None | int = ...,
+ k: int = ...,
+ dtype: None = ...,
+ *,
+ like: None | ArrayLike = ...
+) -> NDArray[float64]: ...
+@overload
+def tri(
+ N: int,
+ M: None | int = ...,
+ k: int = ...,
+ dtype: _DTypeLike[_SCT] = ...,
+ *,
+ like: None | ArrayLike = ...
+) -> NDArray[_SCT]: ...
+@overload
+def tri(
+ N: int,
+ M: None | int = ...,
+ k: int = ...,
+ dtype: DTypeLike = ...,
+ *,
+ like: None | ArrayLike = ...
+) -> NDArray[Any]: ...
+
+@overload
+def tril(v: _ArrayLike[_SCT], k: int = ...) -> NDArray[_SCT]: ...
+@overload
+def tril(v: ArrayLike, k: int = ...) -> NDArray[Any]: ...
+
+@overload
+def triu(v: _ArrayLike[_SCT], k: int = ...) -> NDArray[_SCT]: ...
+@overload
+def triu(v: ArrayLike, k: int = ...) -> NDArray[Any]: ...
+
+@overload
+def vander( # type: ignore[misc]
+ x: _ArrayLikeInt_co,
+ N: None | int = ...,
+ increasing: bool = ...,
+) -> NDArray[signedinteger[Any]]: ...
+@overload
+def vander( # type: ignore[misc]
+ x: _ArrayLikeFloat_co,
+ N: None | int = ...,
+ increasing: bool = ...,
+) -> NDArray[floating[Any]]: ...
+@overload
+def vander(
+ x: _ArrayLikeComplex_co,
+ N: None | int = ...,
+ increasing: bool = ...,
+) -> NDArray[complexfloating[Any, Any]]: ...
+@overload
+def vander(
+ x: _ArrayLikeObject_co,
+ N: None | int = ...,
+ increasing: bool = ...,
+) -> NDArray[object_]: ...
+
+@overload
+def histogram2d( # type: ignore[misc]
+ x: _ArrayLikeFloat_co,
+ y: _ArrayLikeFloat_co,
+ bins: int | Sequence[int] = ...,
+ range: None | _ArrayLikeFloat_co = ...,
+ normed: None | bool = ...,
+ weights: None | _ArrayLikeFloat_co = ...,
+ density: None | bool = ...,
+) -> Tuple[
+ NDArray[float64],
+ NDArray[floating[Any]],
+ NDArray[floating[Any]],
+]: ...
+@overload
+def histogram2d(
+ x: _ArrayLikeComplex_co,
+ y: _ArrayLikeComplex_co,
+ bins: int | Sequence[int] = ...,
+ range: None | _ArrayLikeFloat_co = ...,
+ normed: None | bool = ...,
+ weights: None | _ArrayLikeFloat_co = ...,
+ density: None | bool = ...,
+) -> Tuple[
+ NDArray[float64],
+ NDArray[complexfloating[Any, Any]],
+ NDArray[complexfloating[Any, Any]],
+]: ...
+@overload # TODO: Sort out `bins`
+def histogram2d(
+ x: _ArrayLikeComplex_co,
+ y: _ArrayLikeComplex_co,
+ bins: Sequence[_ArrayLikeInt_co],
+ range: None | _ArrayLikeFloat_co = ...,
+ normed: None | bool = ...,
+ weights: None | _ArrayLikeFloat_co = ...,
+ density: None | bool = ...,
+) -> Tuple[
+ NDArray[float64],
+ NDArray[Any],
+ NDArray[Any],
+]: ...
+
+# NOTE: we're assuming/demanding here the `mask_func` returns
+# an ndarray of shape `(n, n)`; otherwise there is the possibility
+# of the output tuple having more or less than 2 elements
+@overload
+def mask_indices(
+ n: int,
+ mask_func: _MaskFunc[int],
+ k: int = ...,
+) -> Tuple[NDArray[intp], NDArray[intp]]: ...
+@overload
+def mask_indices(
+ n: int,
+ mask_func: _MaskFunc[_T],
+ k: _T,
+) -> Tuple[NDArray[intp], NDArray[intp]]: ...
+
+def tril_indices(
+ n: int,
+ k: int = ...,
+ m: None | int = ...,
+) -> Tuple[NDArray[int_], NDArray[int_]]: ...
+
+def tril_indices_from(
+ arr: NDArray[Any],
+ k: int = ...,
+) -> Tuple[NDArray[int_], NDArray[int_]]: ...
+
+def triu_indices(
+ n: int,
+ k: int = ...,
+ m: None | int = ...,
+) -> Tuple[NDArray[int_], NDArray[int_]]: ...
+
+def triu_indices_from(
+ arr: NDArray[Any],
+ k: int = ...,
+) -> Tuple[NDArray[int_], NDArray[int_]]: ...
diff --git a/numpy/lib/type_check.py b/numpy/lib/type_check.py
index 2a2982ab3..56afd83ce 100644
--- a/numpy/lib/type_check.py
+++ b/numpy/lib/type_check.py
@@ -262,6 +262,10 @@ def isreal(x):
out : ndarray, bool
Boolean array of same shape as `x`.
+ Notes
+ -----
+ `isreal` may behave unexpectedly for string or object arrays (see examples)
+
See Also
--------
iscomplex
@@ -269,8 +273,28 @@ def isreal(x):
Examples
--------
- >>> np.isreal([1+1j, 1+0j, 4.5, 3, 2, 2j])
+ >>> a = np.array([1+1j, 1+0j, 4.5, 3, 2, 2j], dtype=complex)
+ >>> np.isreal(a)
array([False, True, True, True, True, False])
+
+ The function does not work on string arrays.
+
+ >>> a = np.array([2j, "a"], dtype="U")
+ >>> np.isreal(a) # Warns about non-elementwise comparison
+ False
+
+ Returns True for all elements in input array of ``dtype=object`` even if
+ any of the elements is complex.
+
+ >>> a = np.array([1, "2", 3+4j], dtype=object)
+ >>> np.isreal(a)
+ array([ True, True, True])
+
+ isreal should not be used with object arrays
+
+ >>> a = np.array([1+2j, 2+1j], dtype=object)
+ >>> np.isreal(a)
+ array([ True, True])
"""
return imag(x) == 0
@@ -340,6 +364,19 @@ def isrealobj(x):
--------
iscomplexobj, isreal
+ Notes
+ -----
+ The function is only meant for arrays with numerical values but it
+ accepts all other objects. Since it assumes array input, the return
+ value of other objects may be True.
+
+ >>> np.isrealobj('A string')
+ True
+ >>> np.isrealobj(False)
+ True
+ >>> np.isrealobj(None)
+ True
+
Examples
--------
>>> np.isrealobj(1)
diff --git a/numpy/lib/type_check.pyi b/numpy/lib/type_check.pyi
new file mode 100644
index 000000000..fbe325858
--- /dev/null
+++ b/numpy/lib/type_check.pyi
@@ -0,0 +1,235 @@
+import sys
+from typing import (
+ Any,
+ Container,
+ Iterable,
+ List,
+ overload,
+ Type,
+ TypeVar,
+)
+
+from numpy import (
+ dtype,
+ generic,
+ bool_,
+ floating,
+ float64,
+ complexfloating,
+ integer,
+)
+
+from numpy.typing import (
+ ArrayLike,
+ DTypeLike,
+ NBitBase,
+ NDArray,
+ _64Bit,
+ _SupportsDType,
+ _ScalarLike_co,
+ _NestedSequence,
+ _SupportsArray,
+ _DTypeLikeComplex,
+)
+
+if sys.version_info >= (3, 8):
+ from typing import Protocol, Literal as L
+else:
+ from typing_extensions import Protocol, Literal as L
+
+_T = TypeVar("_T")
+_T_co = TypeVar("_T_co", covariant=True)
+_SCT = TypeVar("_SCT", bound=generic)
+_NBit1 = TypeVar("_NBit1", bound=NBitBase)
+_NBit2 = TypeVar("_NBit2", bound=NBitBase)
+
+_ArrayLike = _NestedSequence[_SupportsArray[dtype[_SCT]]]
+
+class _SupportsReal(Protocol[_T_co]):
+ @property
+ def real(self) -> _T_co: ...
+
+class _SupportsImag(Protocol[_T_co]):
+ @property
+ def imag(self) -> _T_co: ...
+
+__all__: List[str]
+
+def mintypecode(
+ typechars: Iterable[str | ArrayLike],
+ typeset: Container[str] = ...,
+ default: str = ...,
+) -> str: ...
+
+# `asfarray` ignores dtypes if they're not inexact
+
+@overload
+def asfarray(
+ a: object,
+ dtype: None | Type[float] = ...,
+) -> NDArray[float64]: ...
+@overload
+def asfarray( # type: ignore[misc]
+ a: Any,
+ dtype: _DTypeLikeComplex,
+) -> NDArray[complexfloating[Any, Any]]: ...
+@overload
+def asfarray(
+ a: Any,
+ dtype: DTypeLike,
+) -> NDArray[floating[Any]]: ...
+
+@overload
+def real(val: _SupportsReal[_T]) -> _T: ...
+@overload
+def real(val: ArrayLike) -> NDArray[Any]: ...
+
+@overload
+def imag(val: _SupportsImag[_T]) -> _T: ...
+@overload
+def imag(val: ArrayLike) -> NDArray[Any]: ...
+
+@overload
+def iscomplex(x: _ScalarLike_co) -> bool_: ... # type: ignore[misc]
+@overload
+def iscomplex(x: ArrayLike) -> NDArray[bool_]: ...
+
+@overload
+def isreal(x: _ScalarLike_co) -> bool_: ... # type: ignore[misc]
+@overload
+def isreal(x: ArrayLike) -> NDArray[bool_]: ...
+
+def iscomplexobj(x: _SupportsDType[dtype[Any]] | ArrayLike) -> bool: ...
+
+def isrealobj(x: _SupportsDType[dtype[Any]] | ArrayLike) -> bool: ...
+
+@overload
+def nan_to_num( # type: ignore[misc]
+ x: _SCT,
+ copy: bool = ...,
+ nan: float = ...,
+ posinf: None | float = ...,
+ neginf: None | float = ...,
+) -> _SCT: ...
+@overload
+def nan_to_num(
+ x: _ScalarLike_co,
+ copy: bool = ...,
+ nan: float = ...,
+ posinf: None | float = ...,
+ neginf: None | float = ...,
+) -> Any: ...
+@overload
+def nan_to_num(
+ x: _ArrayLike[_SCT],
+ copy: bool = ...,
+ nan: float = ...,
+ posinf: None | float = ...,
+ neginf: None | float = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def nan_to_num(
+ x: ArrayLike,
+ copy: bool = ...,
+ nan: float = ...,
+ posinf: None | float = ...,
+ neginf: None | float = ...,
+) -> NDArray[Any]: ...
+
+# If one passes a complex array to `real_if_close`, then one is reasonably
+# expected to verify the output dtype (so we can return an unsafe union here)
+
+@overload
+def real_if_close( # type: ignore[misc]
+ a: _ArrayLike[complexfloating[_NBit1, _NBit1]],
+ tol: float = ...,
+) -> NDArray[floating[_NBit1]] | NDArray[complexfloating[_NBit1, _NBit1]]: ...
+@overload
+def real_if_close(
+ a: _ArrayLike[_SCT],
+ tol: float = ...,
+) -> NDArray[_SCT]: ...
+@overload
+def real_if_close(
+ a: ArrayLike,
+ tol: float = ...,
+) -> NDArray[Any]: ...
+
+# NOTE: deprecated
+# def asscalar(a): ...
+
+@overload
+def typename(char: L['S1']) -> L['character']: ...
+@overload
+def typename(char: L['?']) -> L['bool']: ...
+@overload
+def typename(char: L['b']) -> L['signed char']: ...
+@overload
+def typename(char: L['B']) -> L['unsigned char']: ...
+@overload
+def typename(char: L['h']) -> L['short']: ...
+@overload
+def typename(char: L['H']) -> L['unsigned short']: ...
+@overload
+def typename(char: L['i']) -> L['integer']: ...
+@overload
+def typename(char: L['I']) -> L['unsigned integer']: ...
+@overload
+def typename(char: L['l']) -> L['long integer']: ...
+@overload
+def typename(char: L['L']) -> L['unsigned long integer']: ...
+@overload
+def typename(char: L['q']) -> L['long long integer']: ...
+@overload
+def typename(char: L['Q']) -> L['unsigned long long integer']: ...
+@overload
+def typename(char: L['f']) -> L['single precision']: ...
+@overload
+def typename(char: L['d']) -> L['double precision']: ...
+@overload
+def typename(char: L['g']) -> L['long precision']: ...
+@overload
+def typename(char: L['F']) -> L['complex single precision']: ...
+@overload
+def typename(char: L['D']) -> L['complex double precision']: ...
+@overload
+def typename(char: L['G']) -> L['complex long double precision']: ...
+@overload
+def typename(char: L['S']) -> L['string']: ...
+@overload
+def typename(char: L['U']) -> L['unicode']: ...
+@overload
+def typename(char: L['V']) -> L['void']: ...
+@overload
+def typename(char: L['O']) -> L['object']: ...
+
+@overload
+def common_type( # type: ignore[misc]
+ *arrays: _SupportsDType[dtype[
+ integer[Any]
+ ]]
+) -> Type[floating[_64Bit]]: ...
+@overload
+def common_type( # type: ignore[misc]
+ *arrays: _SupportsDType[dtype[
+ floating[_NBit1]
+ ]]
+) -> Type[floating[_NBit1]]: ...
+@overload
+def common_type( # type: ignore[misc]
+ *arrays: _SupportsDType[dtype[
+ integer[Any] | floating[_NBit1]
+ ]]
+) -> Type[floating[_NBit1 | _64Bit]]: ...
+@overload
+def common_type( # type: ignore[misc]
+ *arrays: _SupportsDType[dtype[
+ floating[_NBit1] | complexfloating[_NBit2, _NBit2]
+ ]]
+) -> Type[complexfloating[_NBit1 | _NBit2, _NBit1 | _NBit2]]: ...
+@overload
+def common_type(
+ *arrays: _SupportsDType[dtype[
+ integer[Any] | floating[_NBit1] | complexfloating[_NBit2, _NBit2]
+ ]]
+) -> Type[complexfloating[_64Bit | _NBit1 | _NBit2, _64Bit | _NBit1 | _NBit2]]: ...
diff --git a/numpy/lib/ufunclike.py b/numpy/lib/ufunclike.py
index 1f26a1845..a93c4773b 100644
--- a/numpy/lib/ufunclike.py
+++ b/numpy/lib/ufunclike.py
@@ -100,7 +100,7 @@ def fix(x, out=None):
See Also
--------
- trunc, floor, ceil
+ rint, trunc, floor, ceil
around : Round to given number of decimals
Examples
@@ -189,7 +189,8 @@ def isposinf(x, out=None):
try:
signbit = ~nx.signbit(x)
except TypeError as e:
- raise TypeError('This operation is not supported for complex values '
+ dtype = nx.asanyarray(x).dtype
+ raise TypeError(f'This operation is not supported for {dtype} values '
'because it would be ambiguous.') from e
else:
return nx.logical_and(is_inf, signbit, out)
@@ -260,7 +261,8 @@ def isneginf(x, out=None):
try:
signbit = nx.signbit(x)
except TypeError as e:
- raise TypeError('This operation is not supported for complex values '
+ dtype = nx.asanyarray(x).dtype
+ raise TypeError(f'This operation is not supported for {dtype} values '
'because it would be ambiguous.') from e
else:
return nx.logical_and(is_inf, signbit, out)
diff --git a/numpy/lib/ufunclike.pyi b/numpy/lib/ufunclike.pyi
new file mode 100644
index 000000000..03f08ebff
--- /dev/null
+++ b/numpy/lib/ufunclike.pyi
@@ -0,0 +1,66 @@
+from typing import Any, overload, TypeVar, List, Union
+
+from numpy import floating, bool_, object_, ndarray
+from numpy.typing import (
+ NDArray,
+ _FloatLike_co,
+ _ArrayLikeFloat_co,
+ _ArrayLikeObject_co,
+)
+
+_ArrayType = TypeVar("_ArrayType", bound=ndarray[Any, Any])
+
+__all__: List[str]
+
+@overload
+def fix( # type: ignore[misc]
+ x: _FloatLike_co,
+ out: None = ...,
+) -> floating[Any]: ...
+@overload
+def fix(
+ x: _ArrayLikeFloat_co,
+ out: None = ...,
+) -> NDArray[floating[Any]]: ...
+@overload
+def fix(
+ x: _ArrayLikeObject_co,
+ out: None = ...,
+) -> NDArray[object_]: ...
+@overload
+def fix(
+ x: Union[_ArrayLikeFloat_co, _ArrayLikeObject_co],
+ out: _ArrayType,
+) -> _ArrayType: ...
+
+@overload
+def isposinf( # type: ignore[misc]
+ x: _FloatLike_co,
+ out: None = ...,
+) -> bool_: ...
+@overload
+def isposinf(
+ x: _ArrayLikeFloat_co,
+ out: None = ...,
+) -> NDArray[bool_]: ...
+@overload
+def isposinf(
+ x: _ArrayLikeFloat_co,
+ out: _ArrayType,
+) -> _ArrayType: ...
+
+@overload
+def isneginf( # type: ignore[misc]
+ x: _FloatLike_co,
+ out: None = ...,
+) -> bool_: ...
+@overload
+def isneginf(
+ x: _ArrayLikeFloat_co,
+ out: None = ...,
+) -> NDArray[bool_]: ...
+@overload
+def isneginf(
+ x: _ArrayLikeFloat_co,
+ out: _ArrayType,
+) -> _ArrayType: ...
diff --git a/numpy/lib/utils.py b/numpy/lib/utils.py
index 5447608bf..b1a916d4a 100644
--- a/numpy/lib/utils.py
+++ b/numpy/lib/utils.py
@@ -193,7 +193,32 @@ def deprecate(*args, **kwargs):
else:
return _Deprecate(*args, **kwargs)
-deprecate_with_doc = lambda msg: _Deprecate(message=msg)
+
+def deprecate_with_doc(msg):
+ """
+ Deprecates a function and includes the deprecation in its docstring.
+
+ This function is used as a decorator. It returns an object that can be
+ used to issue a DeprecationWarning, by passing the to-be decorated
+ function as argument, this adds warning to the to-be decorated function's
+ docstring and returns the new function object.
+
+ See Also
+ --------
+ deprecate : Decorate a function such that it issues a `DeprecationWarning`
+
+ Parameters
+ ----------
+ msg : str
+ Additional explanation of the deprecation. Displayed in the
+ docstring after the warning.
+
+ Returns
+ -------
+ obj : object
+
+ """
+ return _Deprecate(message=msg)
#--------------------------------------------
@@ -879,7 +904,7 @@ def _lookfor_generate_cache(module, import_modules, regenerate):
sys.stdout = old_stdout
sys.stderr = old_stderr
# Catch SystemExit, too
- except BaseException:
+ except (Exception, SystemExit):
continue
for n, v in _getmembers(item):
@@ -990,10 +1015,11 @@ def _median_nancheck(data, result, axis, out):
Input data to median function
result : Array or MaskedArray
Result of median function
- axis : {int, sequence of int, None}, optional
- Axis or axes along which the median was computed.
+ axis : int
+ Axis along which the median was computed.
out : ndarray, optional
Output array in which to place the result.
+
Returns
-------
median : scalar or ndarray
@@ -1001,8 +1027,7 @@ def _median_nancheck(data, result, axis, out):
"""
if data.size == 0:
return result
- data = np.moveaxis(data, axis, -1)
- n = np.isnan(data[..., -1])
+ n = np.isnan(data.take(-1, axis=axis))
# masked NaN values are ok
if np.ma.isMaskedArray(n):
n = n.filled(False)
@@ -1017,4 +1042,30 @@ def _median_nancheck(data, result, axis, out):
result[n] = np.nan
return result
+def _opt_info():
+ """
+ Returns a string contains the supported CPU features by the current build.
+
+ The string format can be explained as follows:
+ - dispatched features that are supported by the running machine
+ end with `*`.
+ - dispatched features that are "not" supported by the running machine
+ end with `?`.
+ - remained features are representing the baseline.
+ """
+ from numpy.core._multiarray_umath import (
+ __cpu_features__, __cpu_baseline__, __cpu_dispatch__
+ )
+
+ if len(__cpu_baseline__) == 0 and len(__cpu_dispatch__) == 0:
+ return ''
+
+ enabled_features = ' '.join(__cpu_baseline__)
+ for feature in __cpu_dispatch__:
+ if __cpu_features__[feature]:
+ enabled_features += f" {feature}*"
+ else:
+ enabled_features += f" {feature}?"
+
+ return enabled_features
#-----------------------------------------------------------------------------
diff --git a/numpy/lib/utils.pyi b/numpy/lib/utils.pyi
new file mode 100644
index 000000000..0518655c6
--- /dev/null
+++ b/numpy/lib/utils.pyi
@@ -0,0 +1,99 @@
+import sys
+from ast import AST
+from typing import (
+ Any,
+ Callable,
+ List,
+ Mapping,
+ Optional,
+ overload,
+ Sequence,
+ Tuple,
+ TypeVar,
+ Union,
+)
+
+from numpy import ndarray, generic
+
+from numpy.core.numerictypes import (
+ issubclass_ as issubclass_,
+ issubdtype as issubdtype,
+ issubsctype as issubsctype,
+)
+
+if sys.version_info >= (3, 8):
+ from typing import Protocol
+else:
+ from typing_extensions import Protocol
+
+_T_contra = TypeVar("_T_contra", contravariant=True)
+_FuncType = TypeVar("_FuncType", bound=Callable[..., Any])
+
+# A file-like object opened in `w` mode
+class _SupportsWrite(Protocol[_T_contra]):
+ def write(self, __s: _T_contra) -> Any: ...
+
+__all__: List[str]
+
+class _Deprecate:
+ old_name: Optional[str]
+ new_name: Optional[str]
+ message: Optional[str]
+ def __init__(
+ self,
+ old_name: Optional[str] = ...,
+ new_name: Optional[str] = ...,
+ message: Optional[str] = ...,
+ ) -> None: ...
+ # NOTE: `__call__` can in principle take arbitrary `*args` and `**kwargs`,
+ # even though they aren't used for anything
+ def __call__(self, func: _FuncType) -> _FuncType: ...
+
+def get_include() -> str: ...
+
+@overload
+def deprecate(
+ *,
+ old_name: Optional[str] = ...,
+ new_name: Optional[str] = ...,
+ message: Optional[str] = ...,
+) -> _Deprecate: ...
+@overload
+def deprecate(
+ __func: _FuncType,
+ old_name: Optional[str] = ...,
+ new_name: Optional[str] = ...,
+ message: Optional[str] = ...,
+) -> _FuncType: ...
+
+def deprecate_with_doc(msg: Optional[str]) -> _Deprecate: ...
+
+# NOTE: In practice `byte_bounds` can (potentially) take any object
+# implementing the `__array_interface__` protocol. The caveat is
+# that certain keys, marked as optional in the spec, must be present for
+# `byte_bounds`. This concerns `"strides"` and `"data"`.
+def byte_bounds(a: Union[generic, ndarray[Any, Any]]) -> Tuple[int, int]: ...
+
+def who(vardict: Optional[Mapping[str, ndarray[Any, Any]]] = ...) -> None: ...
+
+def info(
+ object: object = ...,
+ maxwidth: int = ...,
+ output: Optional[_SupportsWrite[str]] = ...,
+ toplevel: str = ...,
+) -> None: ...
+
+def source(
+ object: object,
+ output: Optional[_SupportsWrite[str]] = ...,
+) -> None: ...
+
+def lookfor(
+ what: str,
+ module: Union[None, str, Sequence[str]] = ...,
+ import_modules: bool = ...,
+ regenerate: bool = ...,
+ output: Optional[_SupportsWrite[str]] =...,
+) -> None: ...
+
+def safe_eval(source: Union[str, AST]) -> Any: ...
diff --git a/numpy/linalg/__init__.py b/numpy/linalg/__init__.py
index 3a53ac6ec..93943de38 100644
--- a/numpy/linalg/__init__.py
+++ b/numpy/linalg/__init__.py
@@ -70,8 +70,11 @@ Exceptions
"""
# To get sub-modules
+from . import linalg
from .linalg import *
+__all__ = linalg.__all__.copy()
+
from numpy._pytesttester import PytestTester
test = PytestTester(__name__)
del PytestTester
diff --git a/numpy/linalg/__init__.pyi b/numpy/linalg/__init__.pyi
index ffb05bb81..7237d865d 100644
--- a/numpy/linalg/__init__.pyi
+++ b/numpy/linalg/__init__.pyi
@@ -1,23 +1,30 @@
-from typing import Any
+from typing import Any, List
-matrix_power: Any
-solve: Any
-tensorsolve: Any
-tensorinv: Any
-inv: Any
-cholesky: Any
-eigvals: Any
-eigvalsh: Any
-pinv: Any
-slogdet: Any
-det: Any
-svd: Any
-eig: Any
-eigh: Any
-lstsq: Any
-norm: Any
-qr: Any
-cond: Any
-matrix_rank: Any
-LinAlgError: Any
-multi_dot: Any
+from numpy._pytesttester import PytestTester
+
+__all__: List[str]
+__path__: List[str]
+test: PytestTester
+
+class LinAlgError(Exception): ...
+
+def tensorsolve(a, b, axes=...): ...
+def solve(a, b): ...
+def tensorinv(a, ind=...): ...
+def inv(a): ...
+def matrix_power(a, n): ...
+def cholesky(a): ...
+def qr(a, mode=...): ...
+def eigvals(a): ...
+def eigvalsh(a, UPLO=...): ...
+def eig(a): ...
+def eigh(a, UPLO=...): ...
+def svd(a, full_matrices=..., compute_uv=..., hermitian=...): ...
+def cond(x, p=...): ...
+def matrix_rank(A, tol=..., hermitian=...): ...
+def pinv(a, rcond=..., hermitian=...): ...
+def slogdet(a): ...
+def det(a): ...
+def lstsq(a, b, rcond=...): ...
+def norm(x, ord=..., axis=..., keepdims=...): ...
+def multi_dot(arrays, *, out=...): ...
diff --git a/numpy/linalg/lapack_lite/clapack_scrub.py b/numpy/linalg/lapack_lite/clapack_scrub.py
index f3e7d25d2..738fad7fe 100644
--- a/numpy/linalg/lapack_lite/clapack_scrub.py
+++ b/numpy/linalg/lapack_lite/clapack_scrub.py
@@ -224,7 +224,7 @@ def removeHeader(source):
def removeSubroutinePrototypes(source):
expression = re.compile(
- r'/[*] Subroutine [*]/^\s*(?:(?:inline|static)\s+){0,2}(?!else|typedef|return)\w+\s+\*?\s*(\w+)\s*\([^0]+\)\s*;?'
+ r'/\* Subroutine \*/^\s*(?:(?:inline|static)\s+){0,2}(?!else|typedef|return)\w+\s+\*?\s*(\w+)\s*\([^0]+\)\s*;?'
)
lines = LineQueue()
for line in StringIO(source):
diff --git a/numpy/linalg/lapack_lite/fortran.py b/numpy/linalg/lapack_lite/fortran.py
index 3aaefb92f..fc09f0808 100644
--- a/numpy/linalg/lapack_lite/fortran.py
+++ b/numpy/linalg/lapack_lite/fortran.py
@@ -110,7 +110,7 @@ def getDependencies(filename):
for lineno, line in fortranSourceLines(fo):
m = external_pat.match(line)
if m:
- names = line = line[m.end():].strip().split(',')
+ names = line[m.end():].strip().split(',')
names = [n.strip().lower() for n in names]
names = [n for n in names if n]
routines.extend(names)
diff --git a/numpy/linalg/lapack_lite/make_lite.py b/numpy/linalg/lapack_lite/make_lite.py
index cf15b2541..09ffaf840 100755
--- a/numpy/linalg/lapack_lite/make_lite.py
+++ b/numpy/linalg/lapack_lite/make_lite.py
@@ -261,8 +261,8 @@ def runF2C(fortran_filename, output_dir):
subprocess.check_call(
["f2c"] + F2C_ARGS + ['-d', output_dir, fortran_filename]
)
- except subprocess.CalledProcessError:
- raise F2CError
+ except subprocess.CalledProcessError as e:
+ raise F2CError from e
def scrubF2CSource(c_file):
with open(c_file) as fo:
@@ -275,8 +275,8 @@ def scrubF2CSource(c_file):
def ensure_executable(name):
try:
which(name)
- except:
- raise SystemExit(name + ' not found')
+ except Exception as ex:
+ raise SystemExit(name + ' not found') from ex
def create_name_header(output_dir):
routine_re = re.compile(r'^ (subroutine|.* function)\s+(\w+)\(.*$',
diff --git a/numpy/linalg/linalg.py b/numpy/linalg/linalg.py
index 7775e4c32..2b686839a 100644
--- a/numpy/linalg/linalg.py
+++ b/numpy/linalg/linalg.py
@@ -99,6 +99,10 @@ def _raise_linalgerror_svd_nonconvergence(err, flag):
def _raise_linalgerror_lstsq(err, flag):
raise LinAlgError("SVD did not converge in Linear Least Squares")
+def _raise_linalgerror_qr(err, flag):
+ raise LinAlgError("Incorrect argument found while performing "
+ "QR factorization")
+
def get_linalg_error_extobj(callback):
extobj = list(_linalg_error_extobj) # make a copy
extobj[2] = callback
@@ -128,10 +132,6 @@ def _realType(t, default=double):
def _complexType(t, default=cdouble):
return _complex_types_map.get(t, default)
-def _linalgRealType(t):
- """Cast the type t to either double or cdouble."""
- return double
-
def _commonType(*arrays):
# in lite version, use higher precision (always double or cdouble)
result_type = single
@@ -780,15 +780,16 @@ def qr(a, mode='reduced'):
Parameters
----------
- a : array_like, shape (M, N)
- Matrix to be factored.
+ a : array_like, shape (..., M, N)
+ An array-like object with the dimensionality of at least 2.
mode : {'reduced', 'complete', 'r', 'raw'}, optional
If K = min(M, N), then
- * 'reduced' : returns q, r with dimensions (M, K), (K, N) (default)
- * 'complete' : returns q, r with dimensions (M, M), (M, N)
- * 'r' : returns r only with dimensions (K, N)
- * 'raw' : returns h, tau with dimensions (N, M), (K,)
+ * 'reduced' : returns q, r with dimensions
+ (..., M, K), (..., K, N) (default)
+ * 'complete' : returns q, r with dimensions (..., M, M), (..., M, N)
+ * 'r' : returns r only with dimensions (..., K, N)
+ * 'raw' : returns h, tau with dimensions (..., N, M), (..., K,)
The options 'reduced', 'complete, and 'raw' are new in numpy 1.8,
see the notes for more information. The default is 'reduced', and to
@@ -807,9 +808,13 @@ def qr(a, mode='reduced'):
A matrix with orthonormal columns. When mode = 'complete' the
result is an orthogonal/unitary matrix depending on whether or not
a is real/complex. The determinant may be either +/- 1 in that
- case.
+ case. In case the number of dimensions in the input array is
+ greater than 2 then a stack of the matrices with above properties
+ is returned.
r : ndarray of float or complex, optional
- The upper-triangular matrix.
+ The upper-triangular matrix or a stack of upper-triangular
+ matrices if the number of dimensions in the input array is greater
+ than 2.
(h, tau) : ndarrays of np.double or np.cdouble, optional
The array h contains the Householder reflectors that generate q
along with r. The tau array contains scaling factors for the
@@ -857,6 +862,14 @@ def qr(a, mode='reduced'):
>>> r2 = np.linalg.qr(a, mode='r')
>>> np.allclose(r, r2) # mode='r' returns the same r as mode='full'
True
+ >>> a = np.random.normal(size=(3, 2, 2)) # Stack of 2 x 2 matrices as input
+ >>> q, r = np.linalg.qr(a)
+ >>> q.shape
+ (3, 2, 2)
+ >>> r.shape
+ (3, 2, 2)
+ >>> np.allclose(a, np.matmul(q, r))
+ True
Example illustrating a common use of `qr`: solving of least squares
problems
@@ -904,83 +917,58 @@ def qr(a, mode='reduced'):
raise ValueError(f"Unrecognized mode '{mode}'")
a, wrap = _makearray(a)
- _assert_2d(a)
- m, n = a.shape
+ _assert_stacked_2d(a)
+ m, n = a.shape[-2:]
t, result_t = _commonType(a)
- a = _fastCopyAndTranspose(t, a)
+ a = a.astype(t, copy=True)
a = _to_native_byte_order(a)
mn = min(m, n)
- tau = zeros((mn,), t)
- if isComplexType(t):
- lapack_routine = lapack_lite.zgeqrf
- routine_name = 'zgeqrf'
+ if m <= n:
+ gufunc = _umath_linalg.qr_r_raw_m
else:
- lapack_routine = lapack_lite.dgeqrf
- routine_name = 'dgeqrf'
-
- # calculate optimal size of work data 'work'
- lwork = 1
- work = zeros((lwork,), t)
- results = lapack_routine(m, n, a, max(1, m), tau, work, -1, 0)
- if results['info'] != 0:
- raise LinAlgError('%s returns %d' % (routine_name, results['info']))
-
- # do qr decomposition
- lwork = max(1, n, int(abs(work[0])))
- work = zeros((lwork,), t)
- results = lapack_routine(m, n, a, max(1, m), tau, work, lwork, 0)
- if results['info'] != 0:
- raise LinAlgError('%s returns %d' % (routine_name, results['info']))
+ gufunc = _umath_linalg.qr_r_raw_n
+
+ signature = 'D->D' if isComplexType(t) else 'd->d'
+ extobj = get_linalg_error_extobj(_raise_linalgerror_qr)
+ tau = gufunc(a, signature=signature, extobj=extobj)
# handle modes that don't return q
if mode == 'r':
- r = _fastCopyAndTranspose(result_t, a[:, :mn])
- return wrap(triu(r))
+ r = triu(a[..., :mn, :])
+ r = r.astype(result_t, copy=False)
+ return wrap(r)
if mode == 'raw':
- return a, tau
+ q = transpose(a)
+ q = q.astype(result_t, copy=False)
+ tau = tau.astype(result_t, copy=False)
+ return wrap(q), tau
if mode == 'economic':
- if t != result_t :
- a = a.astype(result_t, copy=False)
- return wrap(a.T)
+ a = a.astype(result_t, copy=False)
+ return wrap(a)
- # generate q from a
+ # mc is the number of columns in the resulting q
+ # matrix. If the mode is complete then it is
+ # same as number of rows, and if the mode is reduced,
+ # then it is the minimum of number of rows and columns.
if mode == 'complete' and m > n:
mc = m
- q = empty((m, m), t)
+ gufunc = _umath_linalg.qr_complete
else:
mc = mn
- q = empty((n, m), t)
- q[:n] = a
-
- if isComplexType(t):
- lapack_routine = lapack_lite.zungqr
- routine_name = 'zungqr'
- else:
- lapack_routine = lapack_lite.dorgqr
- routine_name = 'dorgqr'
+ gufunc = _umath_linalg.qr_reduced
- # determine optimal lwork
- lwork = 1
- work = zeros((lwork,), t)
- results = lapack_routine(m, mc, mn, q, max(1, m), tau, work, -1, 0)
- if results['info'] != 0:
- raise LinAlgError('%s returns %d' % (routine_name, results['info']))
-
- # compute q
- lwork = max(1, n, int(abs(work[0])))
- work = zeros((lwork,), t)
- results = lapack_routine(m, mc, mn, q, max(1, m), tau, work, lwork, 0)
- if results['info'] != 0:
- raise LinAlgError('%s returns %d' % (routine_name, results['info']))
-
- q = _fastCopyAndTranspose(result_t, q[:mc])
- r = _fastCopyAndTranspose(result_t, a[:, :mc])
+ signature = 'DD->D' if isComplexType(t) else 'dd->d'
+ extobj = get_linalg_error_extobj(_raise_linalgerror_qr)
+ q = gufunc(a, tau, signature=signature, extobj=extobj)
+ r = triu(a[..., :mc, :])
- return wrap(q), wrap(triu(r))
+ q = q.astype(result_t, copy=False)
+ r = r.astype(result_t, copy=False)
+ return wrap(q), wrap(r)
# Eigenvalues
@@ -1797,12 +1785,12 @@ def cond(x, p=None):
return r
-def _matrix_rank_dispatcher(M, tol=None, hermitian=None):
- return (M,)
+def _matrix_rank_dispatcher(A, tol=None, hermitian=None):
+ return (A,)
@array_function_dispatch(_matrix_rank_dispatcher)
-def matrix_rank(M, tol=None, hermitian=False):
+def matrix_rank(A, tol=None, hermitian=False):
"""
Return matrix rank of array using SVD method
@@ -1814,18 +1802,18 @@ def matrix_rank(M, tol=None, hermitian=False):
Parameters
----------
- M : {(M,), (..., M, N)} array_like
+ A : {(M,), (..., M, N)} array_like
Input vector or stack of matrices.
tol : (...) array_like, float, optional
Threshold below which SVD values are considered zero. If `tol` is
None, and ``S`` is an array with singular values for `M`, and
``eps`` is the epsilon value for datatype of ``S``, then `tol` is
- set to ``S.max() * max(M.shape) * eps``.
+ set to ``S.max() * max(M, N) * eps``.
.. versionchanged:: 1.14
Broadcasted against the stack of matrices
hermitian : bool, optional
- If True, `M` is assumed to be Hermitian (symmetric if real-valued),
+ If True, `A` is assumed to be Hermitian (symmetric if real-valued),
enabling a more efficient method for finding singular values.
Defaults to False.
@@ -1834,39 +1822,39 @@ def matrix_rank(M, tol=None, hermitian=False):
Returns
-------
rank : (...) array_like
- Rank of M.
+ Rank of A.
Notes
-----
The default threshold to detect rank deficiency is a test on the magnitude
- of the singular values of `M`. By default, we identify singular values less
- than ``S.max() * max(M.shape) * eps`` as indicating rank deficiency (with
+ of the singular values of `A`. By default, we identify singular values less
+ than ``S.max() * max(M, N) * eps`` as indicating rank deficiency (with
the symbols defined above). This is the algorithm MATLAB uses [1]. It also
appears in *Numerical recipes* in the discussion of SVD solutions for linear
least squares [2].
This default threshold is designed to detect rank deficiency accounting for
the numerical errors of the SVD computation. Imagine that there is a column
- in `M` that is an exact (in floating point) linear combination of other
- columns in `M`. Computing the SVD on `M` will not produce a singular value
+ in `A` that is an exact (in floating point) linear combination of other
+ columns in `A`. Computing the SVD on `A` will not produce a singular value
exactly equal to 0 in general: any difference of the smallest SVD value from
0 will be caused by numerical imprecision in the calculation of the SVD.
Our threshold for small SVD values takes this numerical imprecision into
account, and the default threshold will detect such numerical rank
- deficiency. The threshold may declare a matrix `M` rank deficient even if
- the linear combination of some columns of `M` is not exactly equal to
- another column of `M` but only numerically very close to another column of
- `M`.
+ deficiency. The threshold may declare a matrix `A` rank deficient even if
+ the linear combination of some columns of `A` is not exactly equal to
+ another column of `A` but only numerically very close to another column of
+ `A`.
We chose our default threshold because it is in wide use. Other thresholds
are possible. For example, elsewhere in the 2007 edition of *Numerical
recipes* there is an alternative threshold of ``S.max() *
- np.finfo(M.dtype).eps / 2. * np.sqrt(m + n + 1.)``. The authors describe
+ np.finfo(A.dtype).eps / 2. * np.sqrt(m + n + 1.)``. The authors describe
this threshold as being based on "expected roundoff error" (p 71).
The thresholds above deal with floating point roundoff error in the
calculation of the SVD. However, you may have more information about the
- sources of error in `M` that would make you consider other tolerance values
+ sources of error in `A` that would make you consider other tolerance values
to detect *effective* rank deficiency. The most useful measure of the
tolerance depends on the operations you intend to use on your matrix. For
example, if your data come from uncertain measurements with uncertainties
@@ -1895,12 +1883,12 @@ def matrix_rank(M, tol=None, hermitian=False):
>>> matrix_rank(np.zeros((4,)))
0
"""
- M = asarray(M)
- if M.ndim < 2:
- return int(not all(M==0))
- S = svd(M, compute_uv=False, hermitian=hermitian)
+ A = asarray(A)
+ if A.ndim < 2:
+ return int(not all(A==0))
+ S = svd(A, compute_uv=False, hermitian=hermitian)
if tol is None:
- tol = S.max(axis=-1, keepdims=True) * max(M.shape[-2:]) * finfo(S.dtype).eps
+ tol = S.max(axis=-1, keepdims=True) * max(A.shape[-2:]) * finfo(S.dtype).eps
else:
tol = asarray(tol)[..., newaxis]
return count_nonzero(S > tol, axis=-1)
@@ -2171,13 +2159,14 @@ def lstsq(a, b, rcond="warn"):
r"""
Return the least-squares solution to a linear matrix equation.
- Computes the vector x that approximatively solves the equation
+ Computes the vector `x` that approximatively solves the equation
``a @ x = b``. The equation may be under-, well-, or over-determined
(i.e., the number of linearly independent rows of `a` can be less than,
equal to, or greater than its number of linearly independent columns).
If `a` is square and of full rank, then `x` (but for round-off error)
is the "exact" solution of the equation. Else, `x` minimizes the
- Euclidean 2-norm :math:`|| b - a x ||`.
+ Euclidean 2-norm :math:`||b - ax||`. If there are multiple minimizing
+ solutions, the one with the smallest 2-norm :math:`||x||` is returned.
Parameters
----------
@@ -2274,8 +2263,6 @@ def lstsq(a, b, rcond="warn"):
raise LinAlgError('Incompatible dimensions')
t, result_t = _commonType(a, b)
- # FIXME: real_t is unused
- real_t = _linalgRealType(t)
result_real_t = _realType(result_t)
# Determine default rcond value
diff --git a/numpy/linalg/setup.py b/numpy/linalg/setup.py
index 5c9f2a4cb..e2944f38c 100644
--- a/numpy/linalg/setup.py
+++ b/numpy/linalg/setup.py
@@ -9,11 +9,6 @@ def configuration(parent_package='', top_path=None):
config.add_subpackage('tests')
- # Accelerate is buggy, disallow it. See also numpy/core/setup.py
- for opt_order in (blas_opt_info.blas_order, lapack_opt_info.lapack_order):
- if 'accelerate' in opt_order:
- opt_order.remove('accelerate')
-
# Configure lapack_lite
src_dir = 'lapack_lite'
diff --git a/numpy/linalg/tests/test_build.py b/numpy/linalg/tests/test_build.py
index 4859226d9..868341ff2 100644
--- a/numpy/linalg/tests/test_build.py
+++ b/numpy/linalg/tests/test_build.py
@@ -15,8 +15,8 @@ class FindDependenciesLdd:
try:
p = Popen(self.cmd, stdout=PIPE, stderr=PIPE)
stdout, stderr = p.communicate()
- except OSError:
- raise RuntimeError(f'command {self.cmd} cannot be run')
+ except OSError as e:
+ raise RuntimeError(f'command {self.cmd} cannot be run') from e
def get_dependencies(self, lfile):
p = Popen(self.cmd + [lfile], stdout=PIPE, stderr=PIPE)
diff --git a/numpy/linalg/tests/test_linalg.py b/numpy/linalg/tests/test_linalg.py
index 21fab58e1..dd059fb63 100644
--- a/numpy/linalg/tests/test_linalg.py
+++ b/numpy/linalg/tests/test_linalg.py
@@ -1,6 +1,7 @@
""" Test functions for linalg module
"""
+from numpy.core.fromnumeric import shape
import os
import sys
import itertools
@@ -11,6 +12,7 @@ import pytest
import numpy as np
from numpy import array, single, double, csingle, cdouble, dot, identity, matmul
+from numpy.core import swapaxes
from numpy import multiply, atleast_2d, inf, asarray
from numpy import linalg
from numpy.linalg import matrix_power, norm, matrix_rank, multi_dot, LinAlgError
@@ -348,10 +350,10 @@ class LinalgTestCase:
try:
case.check(self.do)
- except Exception:
+ except Exception as e:
msg = f'In test case: {case!r}\n\n'
msg += traceback.format_exc()
- raise AssertionError(msg)
+ raise AssertionError(msg) from e
class LinalgSquareTestCase(LinalgTestCase):
@@ -684,7 +686,7 @@ class SVDHermitianCases(HermitianTestCase, HermitianGeneralizedTestCase):
axes = list(range(mat.ndim))
axes[-1], axes[-2] = axes[-2], axes[-1]
return np.conj(np.transpose(mat, axes=axes))
-
+
assert_almost_equal(np.matmul(u, hermitian(u)), np.broadcast_to(np.eye(u.shape[-1]), u.shape))
assert_almost_equal(np.matmul(vt, hermitian(vt)), np.broadcast_to(np.eye(vt.shape[-1]), vt.shape))
assert_equal(np.sort(s)[..., ::-1], s)
@@ -766,6 +768,9 @@ class TestCond(CondCases):
for A, p in itertools.product(As, p_neg):
linalg.cond(A, p)
+ @pytest.mark.xfail(True, run=False,
+ reason="Platform/LAPACK-dependent failure, "
+ "see gh-18914")
def test_nan(self):
# nans should be passed through, not converted to infs
ps = [None, 1, -1, 2, -2, 'fro']
@@ -981,7 +986,7 @@ class TestLstsq(LstsqCases):
linalg.lstsq(A, y, rcond=None)
-@pytest.mark.parametrize('dt', [np.dtype(c) for c in '?bBhHiIqQefdgFDGO'])
+@pytest.mark.parametrize('dt', [np.dtype(c) for c in '?bBhHiIqQefdgFDGO'])
class TestMatrixPower:
rshft_0 = np.eye(4)
@@ -1010,7 +1015,7 @@ class TestMatrixPower:
mz = matrix_power(M, 0)
assert_equal(mz, identity_like_generalized(M))
assert_equal(mz.dtype, M.dtype)
-
+
for mat in self.rshft_all:
tz(mat.astype(dt))
if dt != object:
@@ -1707,6 +1712,66 @@ class TestQR:
self.check_qr(m2)
self.check_qr(m2.T)
+ def check_qr_stacked(self, a):
+ # This test expects the argument `a` to be an ndarray or
+ # a subclass of an ndarray of inexact type.
+ a_type = type(a)
+ a_dtype = a.dtype
+ m, n = a.shape[-2:]
+ k = min(m, n)
+
+ # mode == 'complete'
+ q, r = linalg.qr(a, mode='complete')
+ assert_(q.dtype == a_dtype)
+ assert_(r.dtype == a_dtype)
+ assert_(isinstance(q, a_type))
+ assert_(isinstance(r, a_type))
+ assert_(q.shape[-2:] == (m, m))
+ assert_(r.shape[-2:] == (m, n))
+ assert_almost_equal(matmul(q, r), a)
+ I_mat = np.identity(q.shape[-1])
+ stack_I_mat = np.broadcast_to(I_mat,
+ q.shape[:-2] + (q.shape[-1],)*2)
+ assert_almost_equal(matmul(swapaxes(q, -1, -2).conj(), q), stack_I_mat)
+ assert_almost_equal(np.triu(r[..., :, :]), r)
+
+ # mode == 'reduced'
+ q1, r1 = linalg.qr(a, mode='reduced')
+ assert_(q1.dtype == a_dtype)
+ assert_(r1.dtype == a_dtype)
+ assert_(isinstance(q1, a_type))
+ assert_(isinstance(r1, a_type))
+ assert_(q1.shape[-2:] == (m, k))
+ assert_(r1.shape[-2:] == (k, n))
+ assert_almost_equal(matmul(q1, r1), a)
+ I_mat = np.identity(q1.shape[-1])
+ stack_I_mat = np.broadcast_to(I_mat,
+ q1.shape[:-2] + (q1.shape[-1],)*2)
+ assert_almost_equal(matmul(swapaxes(q1, -1, -2).conj(), q1),
+ stack_I_mat)
+ assert_almost_equal(np.triu(r1[..., :, :]), r1)
+
+ # mode == 'r'
+ r2 = linalg.qr(a, mode='r')
+ assert_(r2.dtype == a_dtype)
+ assert_(isinstance(r2, a_type))
+ assert_almost_equal(r2, r1)
+
+ @pytest.mark.parametrize("size", [
+ (3, 4), (4, 3), (4, 4),
+ (3, 0), (0, 3)])
+ @pytest.mark.parametrize("outer_size", [
+ (2, 2), (2,), (2, 3, 4)])
+ @pytest.mark.parametrize("dt", [
+ np.single, np.double,
+ np.csingle, np.cdouble])
+ def test_stacked_inputs(self, outer_size, size, dt):
+
+ A = np.random.normal(size=outer_size + size).astype(dt)
+ B = np.random.normal(size=outer_size + size).astype(dt)
+ self.check_qr_stacked(A)
+ self.check_qr_stacked(A + 1.j*B)
+
class TestCholesky:
# TODO: are there no other tests for cholesky?
@@ -2048,10 +2113,11 @@ def test_unsupported_commontype():
linalg.cholesky(arr)
-@pytest.mark.slow
-@pytest.mark.xfail(not HAS_LAPACK64, run=False,
- reason="Numpy not compiled with 64-bit BLAS/LAPACK")
-@requires_memory(free_bytes=16e9)
+#@pytest.mark.slow
+#@pytest.mark.xfail(not HAS_LAPACK64, run=False,
+# reason="Numpy not compiled with 64-bit BLAS/LAPACK")
+#@requires_memory(free_bytes=16e9)
+@pytest.mark.skip(reason="Bad memory reports lead to OOM in ci testing")
def test_blas64_dot():
n = 2**32
a = np.zeros([1, n], dtype=np.float32)
diff --git a/numpy/linalg/umath_linalg.c.src b/numpy/linalg/umath_linalg.c.src
index 1807aadcf..a486e9e5b 100644
--- a/numpy/linalg/umath_linalg.c.src
+++ b/numpy/linalg/umath_linalg.c.src
@@ -163,6 +163,24 @@ FNAME(zgelsd)(fortran_int *m, fortran_int *n, fortran_int *nrhs,
fortran_int *info);
extern fortran_int
+FNAME(dgeqrf)(fortran_int *m, fortran_int *n, double a[], fortran_int *lda,
+ double tau[], double work[],
+ fortran_int *lwork, fortran_int *info);
+extern fortran_int
+FNAME(zgeqrf)(fortran_int *m, fortran_int *n, f2c_doublecomplex a[], fortran_int *lda,
+ f2c_doublecomplex tau[], f2c_doublecomplex work[],
+ fortran_int *lwork, fortran_int *info);
+
+extern fortran_int
+FNAME(dorgqr)(fortran_int *m, fortran_int *n, fortran_int *k, double a[], fortran_int *lda,
+ double tau[], double work[],
+ fortran_int *lwork, fortran_int *info);
+extern fortran_int
+FNAME(zungqr)(fortran_int *m, fortran_int *n, fortran_int *k, f2c_doublecomplex a[],
+ fortran_int *lda, f2c_doublecomplex tau[],
+ f2c_doublecomplex work[], fortran_int *lwork, fortran_int *info);
+
+extern fortran_int
FNAME(sgesv)(fortran_int *n, fortran_int *nrhs,
float a[], fortran_int *lda,
fortran_int ipiv[],
@@ -2834,6 +2852,670 @@ static void
/**end repeat**/
+/* -------------------------------------------------------------------------- */
+ /* qr (modes - r, raw) */
+
+typedef struct geqfr_params_struct
+{
+ fortran_int M;
+ fortran_int N;
+ void *A;
+ fortran_int LDA;
+ void* TAU;
+ void *WORK;
+ fortran_int LWORK;
+} GEQRF_PARAMS_t;
+
+
+static inline void
+dump_geqrf_params(const char *name,
+ GEQRF_PARAMS_t *params)
+{
+ TRACE_TXT("\n%s:\n"\
+
+ "%14s: %18p\n"\
+ "%14s: %18p\n"\
+ "%14s: %18p\n"\
+ "%14s: %18d\n"\
+ "%14s: %18d\n"\
+ "%14s: %18d\n"\
+ "%14s: %18d\n",
+
+ name,
+
+ "A", params->A,
+ "TAU", params->TAU,
+ "WORK", params->WORK,
+
+ "M", (int)params->M,
+ "N", (int)params->N,
+ "LDA", (int)params->LDA,
+ "LWORK", (int)params->LWORK);
+}
+
+/**begin repeat
+ #lapack_func=dgeqrf,zgeqrf#
+ */
+
+static inline fortran_int
+call_@lapack_func@(GEQRF_PARAMS_t *params)
+{
+ fortran_int rv;
+ LAPACK(@lapack_func@)(&params->M, &params->N,
+ params->A, &params->LDA,
+ params->TAU,
+ params->WORK, &params->LWORK,
+ &rv);
+ return rv;
+}
+
+/**end repeat**/
+
+/**begin repeat
+ #TYPE=DOUBLE#
+ #lapack_func=dgeqrf#
+ #ftyp=fortran_doublereal#
+ */
+static inline int
+init_@lapack_func@(GEQRF_PARAMS_t *params,
+ fortran_int m,
+ fortran_int n)
+{
+ npy_uint8 *mem_buff = NULL;
+ npy_uint8 *mem_buff2 = NULL;
+ npy_uint8 *a, *tau, *work;
+ fortran_int min_m_n = fortran_int_min(m, n);
+ size_t safe_min_m_n = min_m_n;
+ size_t safe_m = m;
+ size_t safe_n = n;
+
+ size_t a_size = safe_m * safe_n * sizeof(@ftyp@);
+ size_t tau_size = safe_min_m_n * sizeof(@ftyp@);
+
+ fortran_int work_count;
+ size_t work_size;
+ fortran_int lda = fortran_int_max(1, m);
+
+ mem_buff = malloc(a_size + tau_size);
+
+ if (!mem_buff)
+ goto error;
+
+ a = mem_buff;
+ tau = a + a_size;
+ memset(tau, 0, tau_size);
+
+
+ params->M = m;
+ params->N = n;
+ params->A = a;
+ params->TAU = tau;
+ params->LDA = lda;
+
+ {
+ /* compute optimal work size */
+
+ @ftyp@ work_size_query;
+
+ params->WORK = &work_size_query;
+ params->LWORK = -1;
+
+ if (call_@lapack_func@(params) != 0)
+ goto error;
+
+ work_count = (fortran_int) *(@ftyp@*) params->WORK;
+
+ }
+
+ params->LWORK = fortran_int_max(fortran_int_max(1, n), work_count);
+
+ work_size = (size_t) params->LWORK * sizeof(@ftyp@);
+ mem_buff2 = malloc(work_size);
+ if (!mem_buff2)
+ goto error;
+
+ work = mem_buff2;
+
+ params->WORK = work;
+
+ return 1;
+ error:
+ TRACE_TXT("%s failed init\n", __FUNCTION__);
+ free(mem_buff);
+ free(mem_buff2);
+ memset(params, 0, sizeof(*params));
+
+ return 0;
+}
+
+/**end repeat**/
+
+/**begin repeat
+ #TYPE=CDOUBLE#
+ #lapack_func=zgeqrf#
+ #ftyp=fortran_doublecomplex#
+ */
+static inline int
+init_@lapack_func@(GEQRF_PARAMS_t *params,
+ fortran_int m,
+ fortran_int n)
+{
+ npy_uint8 *mem_buff = NULL;
+ npy_uint8 *mem_buff2 = NULL;
+ npy_uint8 *a, *tau, *work;
+ fortran_int min_m_n = fortran_int_min(m, n);
+ size_t safe_min_m_n = min_m_n;
+ size_t safe_m = m;
+ size_t safe_n = n;
+
+ size_t a_size = safe_m * safe_n * sizeof(@ftyp@);
+ size_t tau_size = safe_min_m_n * sizeof(@ftyp@);
+
+ fortran_int work_count;
+ size_t work_size;
+ fortran_int lda = fortran_int_max(1, m);
+
+ mem_buff = malloc(a_size + tau_size);
+
+ if (!mem_buff)
+ goto error;
+
+ a = mem_buff;
+ tau = a + a_size;
+ memset(tau, 0, tau_size);
+
+
+ params->M = m;
+ params->N = n;
+ params->A = a;
+ params->TAU = tau;
+ params->LDA = lda;
+
+ {
+ /* compute optimal work size */
+
+ @ftyp@ work_size_query;
+
+ params->WORK = &work_size_query;
+ params->LWORK = -1;
+
+ if (call_@lapack_func@(params) != 0)
+ goto error;
+
+ work_count = (fortran_int) ((@ftyp@*)params->WORK)->r;
+
+ }
+
+ params->LWORK = fortran_int_max(fortran_int_max(1, n),
+ work_count);
+
+ work_size = (size_t) params->LWORK * sizeof(@ftyp@);
+
+ mem_buff2 = malloc(work_size);
+ if (!mem_buff2)
+ goto error;
+
+ work = mem_buff2;
+
+ params->WORK = work;
+
+ return 1;
+ error:
+ TRACE_TXT("%s failed init\n", __FUNCTION__);
+ free(mem_buff);
+ free(mem_buff2);
+ memset(params, 0, sizeof(*params));
+
+ return 0;
+}
+
+/**end repeat**/
+
+/**begin repeat
+ #lapack_func=dgeqrf,zgeqrf#
+ */
+static inline void
+release_@lapack_func@(GEQRF_PARAMS_t* params)
+{
+ /* A and WORK contain allocated blocks */
+ free(params->A);
+ free(params->WORK);
+ memset(params, 0, sizeof(*params));
+}
+
+/**end repeat**/
+
+/**begin repeat
+ #TYPE=DOUBLE,CDOUBLE#
+ #REALTYPE=DOUBLE,DOUBLE#
+ #lapack_func=dgeqrf,zgeqrf#
+ #typ = npy_double,npy_cdouble#
+ #basetyp = npy_double,npy_double#
+ #ftyp = fortran_doublereal,fortran_doublecomplex#
+ #cmplx = 0, 1#
+ */
+static void
+@TYPE@_qr_r_raw(char **args, npy_intp const *dimensions, npy_intp const *steps,
+ void *NPY_UNUSED(func))
+{
+ GEQRF_PARAMS_t params;
+ int error_occurred = get_fp_invalid_and_clear();
+ fortran_int n, m;
+
+ INIT_OUTER_LOOP_2
+
+ m = (fortran_int)dimensions[0];
+ n = (fortran_int)dimensions[1];
+
+ if (init_@lapack_func@(&params, m, n)) {
+ LINEARIZE_DATA_t a_in, tau_out;
+
+ init_linearize_data(&a_in, n, m, steps[1], steps[0]);
+ init_linearize_data(&tau_out, 1, fortran_int_min(m, n), 1, steps[2]);
+
+ BEGIN_OUTER_LOOP_2
+ int not_ok;
+ linearize_@TYPE@_matrix(params.A, args[0], &a_in);
+ not_ok = call_@lapack_func@(&params);
+ if (!not_ok) {
+ delinearize_@TYPE@_matrix(args[0], params.A, &a_in);
+ delinearize_@TYPE@_matrix(args[1], params.TAU, &tau_out);
+ } else {
+ error_occurred = 1;
+ nan_@TYPE@_matrix(args[1], &tau_out);
+ }
+ END_OUTER_LOOP
+
+ release_@lapack_func@(&params);
+ }
+
+ set_fp_invalid_or_clear(error_occurred);
+}
+
+/**end repeat**/
+
+/* -------------------------------------------------------------------------- */
+ /* qr common code (modes - reduced and complete) */
+
+typedef struct gqr_params_struct
+{
+ fortran_int M;
+ fortran_int MC;
+ fortran_int MN;
+ void* A;
+ void *Q;
+ fortran_int LDA;
+ void* TAU;
+ void *WORK;
+ fortran_int LWORK;
+} GQR_PARAMS_t;
+
+/**begin repeat
+ #lapack_func=dorgqr,zungqr#
+ */
+
+static inline fortran_int
+call_@lapack_func@(GQR_PARAMS_t *params)
+{
+ fortran_int rv;
+ LAPACK(@lapack_func@)(&params->M, &params->MC, &params->MN,
+ params->Q, &params->LDA,
+ params->TAU,
+ params->WORK, &params->LWORK,
+ &rv);
+ return rv;
+}
+
+/**end repeat**/
+
+/**begin repeat
+ #lapack_func=dorgqr#
+ #ftyp=fortran_doublereal#
+ */
+static inline int
+init_@lapack_func@_common(GQR_PARAMS_t *params,
+ fortran_int m,
+ fortran_int n,
+ fortran_int mc)
+{
+ npy_uint8 *mem_buff = NULL;
+ npy_uint8 *mem_buff2 = NULL;
+ npy_uint8 *a, *q, *tau, *work;
+ fortran_int min_m_n = fortran_int_min(m, n);
+ size_t safe_mc = mc;
+ size_t safe_min_m_n = min_m_n;
+ size_t safe_m = m;
+ size_t safe_n = n;
+ size_t a_size = safe_m * safe_n * sizeof(@ftyp@);
+ size_t q_size = safe_m * safe_mc * sizeof(@ftyp@);
+ size_t tau_size = safe_min_m_n * sizeof(@ftyp@);
+
+ fortran_int work_count;
+ size_t work_size;
+ fortran_int lda = fortran_int_max(1, m);
+
+ mem_buff = malloc(q_size + tau_size + a_size);
+
+ if (!mem_buff)
+ goto error;
+
+ q = mem_buff;
+ tau = q + q_size;
+ a = tau + tau_size;
+
+
+ params->M = m;
+ params->MC = mc;
+ params->MN = min_m_n;
+ params->A = a;
+ params->Q = q;
+ params->TAU = tau;
+ params->LDA = lda;
+
+ {
+ /* compute optimal work size */
+ @ftyp@ work_size_query;
+
+ params->WORK = &work_size_query;
+ params->LWORK = -1;
+
+ if (call_@lapack_func@(params) != 0)
+ goto error;
+
+ work_count = (fortran_int) *(@ftyp@*) params->WORK;
+
+ }
+
+ params->LWORK = fortran_int_max(fortran_int_max(1, n), work_count);
+
+ work_size = (size_t) params->LWORK * sizeof(@ftyp@);
+
+ mem_buff2 = malloc(work_size);
+ if (!mem_buff2)
+ goto error;
+
+ work = mem_buff2;
+
+ params->WORK = work;
+
+ return 1;
+ error:
+ TRACE_TXT("%s failed init\n", __FUNCTION__);
+ free(mem_buff);
+ free(mem_buff2);
+ memset(params, 0, sizeof(*params));
+
+ return 0;
+}
+
+/**end repeat**/
+
+/**begin repeat
+ #lapack_func=zungqr#
+ #ftyp=fortran_doublecomplex#
+ */
+static inline int
+init_@lapack_func@_common(GQR_PARAMS_t *params,
+ fortran_int m,
+ fortran_int n,
+ fortran_int mc)
+{
+ npy_uint8 *mem_buff = NULL;
+ npy_uint8 *mem_buff2 = NULL;
+ npy_uint8 *a, *q, *tau, *work;
+ fortran_int min_m_n = fortran_int_min(m, n);
+ size_t safe_mc = mc;
+ size_t safe_min_m_n = min_m_n;
+ size_t safe_m = m;
+ size_t safe_n = n;
+
+ size_t a_size = safe_m * safe_n * sizeof(@ftyp@);
+ size_t q_size = safe_m * safe_mc * sizeof(@ftyp@);
+ size_t tau_size = safe_min_m_n * sizeof(@ftyp@);
+
+ fortran_int work_count;
+ size_t work_size;
+ fortran_int lda = fortran_int_max(1, m);
+
+ mem_buff = malloc(q_size + tau_size + a_size);
+
+ if (!mem_buff)
+ goto error;
+
+ q = mem_buff;
+ tau = q + q_size;
+ a = tau + tau_size;
+
+
+ params->M = m;
+ params->MC = mc;
+ params->MN = min_m_n;
+ params->A = a;
+ params->Q = q;
+ params->TAU = tau;
+ params->LDA = lda;
+
+ {
+ /* compute optimal work size */
+ @ftyp@ work_size_query;
+
+ params->WORK = &work_size_query;
+ params->LWORK = -1;
+
+ if (call_@lapack_func@(params) != 0)
+ goto error;
+
+ work_count = (fortran_int) ((@ftyp@*)params->WORK)->r;
+
+ }
+
+ params->LWORK = fortran_int_max(fortran_int_max(1, n),
+ work_count);
+
+ work_size = (size_t) params->LWORK * sizeof(@ftyp@);
+
+ mem_buff2 = malloc(work_size);
+ if (!mem_buff2)
+ goto error;
+
+ work = mem_buff2;
+
+ params->WORK = work;
+ params->LWORK = work_count;
+
+ return 1;
+ error:
+ TRACE_TXT("%s failed init\n", __FUNCTION__);
+ free(mem_buff);
+ free(mem_buff2);
+ memset(params, 0, sizeof(*params));
+
+ return 0;
+}
+
+/**end repeat**/
+
+/* -------------------------------------------------------------------------- */
+ /* qr (modes - reduced) */
+
+
+static inline void
+dump_gqr_params(const char *name,
+ GQR_PARAMS_t *params)
+{
+ TRACE_TXT("\n%s:\n"\
+
+ "%14s: %18p\n"\
+ "%14s: %18p\n"\
+ "%14s: %18p\n"\
+ "%14s: %18d\n"\
+ "%14s: %18d\n"\
+ "%14s: %18d\n"\
+ "%14s: %18d\n"\
+ "%14s: %18d\n",
+
+ name,
+
+ "Q", params->Q,
+ "TAU", params->TAU,
+ "WORK", params->WORK,
+
+ "M", (int)params->M,
+ "MC", (int)params->MC,
+ "MN", (int)params->MN,
+ "LDA", (int)params->LDA,
+ "LWORK", (int)params->LWORK);
+}
+
+/**begin repeat
+ #lapack_func=dorgqr,zungqr#
+ #ftyp=fortran_doublereal,fortran_doublecomplex#
+ */
+static inline int
+init_@lapack_func@(GQR_PARAMS_t *params,
+ fortran_int m,
+ fortran_int n)
+{
+ return init_@lapack_func@_common(
+ params, m, n,
+ fortran_int_min(m, n));
+}
+
+/**end repeat**/
+
+/**begin repeat
+ #lapack_func=dorgqr,zungqr#
+ */
+static inline void
+release_@lapack_func@(GQR_PARAMS_t* params)
+{
+ /* A and WORK contain allocated blocks */
+ free(params->Q);
+ free(params->WORK);
+ memset(params, 0, sizeof(*params));
+}
+
+/**end repeat**/
+
+/**begin repeat
+ #TYPE=DOUBLE,CDOUBLE#
+ #REALTYPE=DOUBLE,DOUBLE#
+ #lapack_func=dorgqr,zungqr#
+ #typ = npy_double, npy_cdouble#
+ #basetyp = npy_double, npy_double#
+ #ftyp = fortran_doublereal,fortran_doublecomplex#
+ #cmplx = 0, 1#
+ */
+static void
+@TYPE@_qr_reduced(char **args, npy_intp const *dimensions, npy_intp const *steps,
+ void *NPY_UNUSED(func))
+{
+ GQR_PARAMS_t params;
+ int error_occurred = get_fp_invalid_and_clear();
+ fortran_int n, m;
+
+ INIT_OUTER_LOOP_3
+
+ m = (fortran_int)dimensions[0];
+ n = (fortran_int)dimensions[1];
+
+ if (init_@lapack_func@(&params, m, n)) {
+ LINEARIZE_DATA_t a_in, tau_in, q_out;
+
+ init_linearize_data(&a_in, n, m, steps[1], steps[0]);
+ init_linearize_data(&tau_in, 1, fortran_int_min(m, n), 1, steps[2]);
+ init_linearize_data(&q_out, fortran_int_min(m, n), m, steps[4], steps[3]);
+
+ BEGIN_OUTER_LOOP_3
+ int not_ok;
+ linearize_@TYPE@_matrix(params.A, args[0], &a_in);
+ linearize_@TYPE@_matrix(params.Q, args[0], &a_in);
+ linearize_@TYPE@_matrix(params.TAU, args[1], &tau_in);
+ not_ok = call_@lapack_func@(&params);
+ if (!not_ok) {
+ delinearize_@TYPE@_matrix(args[2], params.Q, &q_out);
+ } else {
+ error_occurred = 1;
+ nan_@TYPE@_matrix(args[2], &q_out);
+ }
+ END_OUTER_LOOP
+
+ release_@lapack_func@(&params);
+ }
+
+ set_fp_invalid_or_clear(error_occurred);
+}
+
+/**end repeat**/
+
+/* -------------------------------------------------------------------------- */
+ /* qr (modes - complete) */
+
+/**begin repeat
+ #lapack_func=dorgqr,zungqr#
+ #ftyp=fortran_doublereal,fortran_doublecomplex#
+ */
+static inline int
+init_@lapack_func@_complete(GQR_PARAMS_t *params,
+ fortran_int m,
+ fortran_int n)
+{
+ return init_@lapack_func@_common(params, m, n, m);
+}
+
+/**end repeat**/
+
+/**begin repeat
+ #TYPE=DOUBLE,CDOUBLE#
+ #REALTYPE=DOUBLE,DOUBLE#
+ #lapack_func=dorgqr,zungqr#
+ #typ = npy_double,npy_cdouble#
+ #basetyp = npy_double,npy_double#
+ #ftyp = fortran_doublereal,fortran_doublecomplex#
+ #cmplx = 0, 1#
+ */
+static void
+@TYPE@_qr_complete(char **args, npy_intp const *dimensions, npy_intp const *steps,
+ void *NPY_UNUSED(func))
+{
+ GQR_PARAMS_t params;
+ int error_occurred = get_fp_invalid_and_clear();
+ fortran_int n, m;
+
+ INIT_OUTER_LOOP_3
+
+ m = (fortran_int)dimensions[0];
+ n = (fortran_int)dimensions[1];
+
+
+ if (init_@lapack_func@_complete(&params, m, n)) {
+ LINEARIZE_DATA_t a_in, tau_in, q_out;
+
+ init_linearize_data(&a_in, n, m, steps[1], steps[0]);
+ init_linearize_data(&tau_in, 1, fortran_int_min(m, n), 1, steps[2]);
+ init_linearize_data(&q_out, m, m, steps[4], steps[3]);
+
+ BEGIN_OUTER_LOOP_3
+ int not_ok;
+ linearize_@TYPE@_matrix(params.A, args[0], &a_in);
+ linearize_@TYPE@_matrix(params.Q, args[0], &a_in);
+ linearize_@TYPE@_matrix(params.TAU, args[1], &tau_in);
+ not_ok = call_@lapack_func@(&params);
+ if (!not_ok) {
+ delinearize_@TYPE@_matrix(args[2], params.Q, &q_out);
+ } else {
+ error_occurred = 1;
+ nan_@TYPE@_matrix(args[2], &q_out);
+ }
+ END_OUTER_LOOP
+
+ release_@lapack_func@(&params);
+ }
+
+ set_fp_invalid_or_clear(error_occurred);
+}
+
+/**end repeat**/
/* -------------------------------------------------------------------------- */
/* least squares */
@@ -3291,6 +3973,17 @@ static void *array_of_nulls[] = {
CDOUBLE_ ## NAME \
}
+/* The single precision functions are not used at all,
+ * due to input data being promoted to double precision
+ * in Python, so they are not implemented here.
+ */
+#define GUFUNC_FUNC_ARRAY_QR(NAME) \
+ static PyUFuncGenericFunction \
+ FUNC_ARRAY_NAME(NAME)[] = { \
+ DOUBLE_ ## NAME, \
+ CDOUBLE_ ## NAME \
+ }
+
GUFUNC_FUNC_ARRAY_REAL_COMPLEX(slogdet);
GUFUNC_FUNC_ARRAY_REAL_COMPLEX(det);
@@ -3305,6 +3998,9 @@ GUFUNC_FUNC_ARRAY_REAL_COMPLEX(cholesky_lo);
GUFUNC_FUNC_ARRAY_REAL_COMPLEX(svd_N);
GUFUNC_FUNC_ARRAY_REAL_COMPLEX(svd_S);
GUFUNC_FUNC_ARRAY_REAL_COMPLEX(svd_A);
+GUFUNC_FUNC_ARRAY_QR(qr_r_raw);
+GUFUNC_FUNC_ARRAY_QR(qr_reduced);
+GUFUNC_FUNC_ARRAY_QR(qr_complete);
GUFUNC_FUNC_ARRAY_REAL_COMPLEX(lstsq);
GUFUNC_FUNC_ARRAY_EIG(eig);
GUFUNC_FUNC_ARRAY_EIG(eigvals);
@@ -3371,6 +4067,24 @@ static char svd_1_3_types[] = {
NPY_CDOUBLE, NPY_CDOUBLE, NPY_DOUBLE, NPY_CDOUBLE
};
+/* A, tau */
+static char qr_r_raw_types[] = {
+ NPY_DOUBLE, NPY_DOUBLE,
+ NPY_CDOUBLE, NPY_CDOUBLE,
+};
+
+/* A, tau, q */
+static char qr_reduced_types[] = {
+ NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE,
+ NPY_CDOUBLE, NPY_CDOUBLE, NPY_CDOUBLE,
+};
+
+/* A, tau, q */
+static char qr_complete_types[] = {
+ NPY_DOUBLE, NPY_DOUBLE, NPY_DOUBLE,
+ NPY_CDOUBLE, NPY_CDOUBLE, NPY_CDOUBLE,
+};
+
/* A, b, rcond, x, resid, rank, s, */
static char lstsq_types[] = {
NPY_FLOAT, NPY_FLOAT, NPY_FLOAT, NPY_FLOAT, NPY_FLOAT, NPY_INT, NPY_FLOAT,
@@ -3571,6 +4285,42 @@ GUFUNC_DESCRIPTOR_t gufunc_descriptors [] = {
eigvals_types
},
{
+ "qr_r_raw_m",
+ "(m,n)->(m)",
+ "Compute TAU vector for the last two dimensions \n"\
+ "and broadcast to the rest. For m <= n. \n",
+ 2, 1, 1,
+ FUNC_ARRAY_NAME(qr_r_raw),
+ qr_r_raw_types
+ },
+ {
+ "qr_r_raw_n",
+ "(m,n)->(n)",
+ "Compute TAU vector for the last two dimensions \n"\
+ "and broadcast to the rest. For m > n. \n",
+ 2, 1, 1,
+ FUNC_ARRAY_NAME(qr_r_raw),
+ qr_r_raw_types
+ },
+ {
+ "qr_reduced",
+ "(m,n),(k)->(m,k)",
+ "Compute Q matrix for the last two dimensions \n"\
+ "and broadcast to the rest. \n",
+ 2, 2, 1,
+ FUNC_ARRAY_NAME(qr_reduced),
+ qr_reduced_types
+ },
+ {
+ "qr_complete",
+ "(m,n),(n)->(m,m)",
+ "Compute Q matrix for the last two dimensions \n"\
+ "and broadcast to the rest. For m > n. \n",
+ 2, 2, 1,
+ FUNC_ARRAY_NAME(qr_complete),
+ qr_complete_types
+ },
+ {
"lstsq_m",
"(m,n),(m,nrhs),()->(n,nrhs),(nrhs),(),(m)",
"least squares on the last two dimensions and broadcast to the rest. \n"\
diff --git a/numpy/ma/__init__.pyi b/numpy/ma/__init__.pyi
index d1259abcc..26d44b508 100644
--- a/numpy/ma/__init__.pyi
+++ b/numpy/ma/__init__.pyi
@@ -1,225 +1,236 @@
-from typing import Any
+from typing import Any, List
-core: Any
-extras: Any
-MAError: Any
-MaskError: Any
-MaskType: Any
-MaskedArray: Any
-abs: Any
-absolute: Any
-add: Any
-all: Any
-allclose: Any
-allequal: Any
-alltrue: Any
-amax: Any
-amin: Any
-angle: Any
-anom: Any
-anomalies: Any
-any: Any
-append: Any
-arange: Any
-arccos: Any
-arccosh: Any
-arcsin: Any
-arcsinh: Any
-arctan: Any
-arctan2: Any
-arctanh: Any
-argmax: Any
-argmin: Any
-argsort: Any
-around: Any
-array: Any
-asanyarray: Any
-asarray: Any
-bitwise_and: Any
-bitwise_or: Any
-bitwise_xor: Any
-bool_: Any
-ceil: Any
-choose: Any
-clip: Any
-common_fill_value: Any
-compress: Any
-compressed: Any
-concatenate: Any
-conjugate: Any
-convolve: Any
-copy: Any
-correlate: Any
-cos: Any
-cosh: Any
-count: Any
-cumprod: Any
-cumsum: Any
-default_fill_value: Any
-diag: Any
-diagonal: Any
-diff: Any
-divide: Any
-empty: Any
-empty_like: Any
-equal: Any
-exp: Any
-expand_dims: Any
-fabs: Any
-filled: Any
-fix_invalid: Any
-flatten_mask: Any
-flatten_structured_array: Any
-floor: Any
-floor_divide: Any
-fmod: Any
-frombuffer: Any
-fromflex: Any
-fromfunction: Any
-getdata: Any
-getmask: Any
-getmaskarray: Any
-greater: Any
-greater_equal: Any
-harden_mask: Any
-hypot: Any
-identity: Any
-ids: Any
-indices: Any
-inner: Any
-innerproduct: Any
-isMA: Any
-isMaskedArray: Any
-is_mask: Any
-is_masked: Any
-isarray: Any
-left_shift: Any
-less: Any
-less_equal: Any
-log: Any
-log10: Any
-log2: Any
-logical_and: Any
-logical_not: Any
-logical_or: Any
-logical_xor: Any
-make_mask: Any
-make_mask_descr: Any
-make_mask_none: Any
-mask_or: Any
-masked: Any
-masked_array: Any
-masked_equal: Any
-masked_greater: Any
-masked_greater_equal: Any
-masked_inside: Any
-masked_invalid: Any
-masked_less: Any
-masked_less_equal: Any
-masked_not_equal: Any
-masked_object: Any
-masked_outside: Any
-masked_print_option: Any
-masked_singleton: Any
-masked_values: Any
-masked_where: Any
-max: Any
-maximum: Any
-maximum_fill_value: Any
-mean: Any
-min: Any
-minimum: Any
-minimum_fill_value: Any
-mod: Any
-multiply: Any
-mvoid: Any
-ndim: Any
-negative: Any
-nomask: Any
-nonzero: Any
-not_equal: Any
-ones: Any
-outer: Any
-outerproduct: Any
-power: Any
-prod: Any
-product: Any
-ptp: Any
-put: Any
-putmask: Any
-ravel: Any
-remainder: Any
-repeat: Any
-reshape: Any
-resize: Any
-right_shift: Any
-round: Any
-round_: Any
-set_fill_value: Any
-shape: Any
-sin: Any
-sinh: Any
-size: Any
-soften_mask: Any
-sometrue: Any
-sort: Any
-sqrt: Any
-squeeze: Any
-std: Any
-subtract: Any
-sum: Any
-swapaxes: Any
-take: Any
-tan: Any
-tanh: Any
-trace: Any
-transpose: Any
-true_divide: Any
-var: Any
-where: Any
-zeros: Any
-apply_along_axis: Any
-apply_over_axes: Any
-atleast_1d: Any
-atleast_2d: Any
-atleast_3d: Any
-average: Any
-clump_masked: Any
-clump_unmasked: Any
-column_stack: Any
-compress_cols: Any
-compress_nd: Any
-compress_rowcols: Any
-compress_rows: Any
-count_masked: Any
-corrcoef: Any
-cov: Any
-diagflat: Any
-dot: Any
-dstack: Any
-ediff1d: Any
-flatnotmasked_contiguous: Any
-flatnotmasked_edges: Any
-hsplit: Any
-hstack: Any
-isin: Any
-in1d: Any
-intersect1d: Any
-mask_cols: Any
-mask_rowcols: Any
-mask_rows: Any
-masked_all: Any
-masked_all_like: Any
-median: Any
-mr_: Any
-notmasked_contiguous: Any
-notmasked_edges: Any
-polyfit: Any
-row_stack: Any
-setdiff1d: Any
-setxor1d: Any
-stack: Any
-unique: Any
-union1d: Any
-vander: Any
-vstack: Any
+from numpy._pytesttester import PytestTester
+
+from numpy.ma import extras as extras
+
+from numpy.ma.core import (
+ MAError as MAError,
+ MaskError as MaskError,
+ MaskType as MaskType,
+ MaskedArray as MaskedArray,
+ abs as abs,
+ absolute as absolute,
+ add as add,
+ all as all,
+ allclose as allclose,
+ allequal as allequal,
+ alltrue as alltrue,
+ amax as amax,
+ amin as amin,
+ angle as angle,
+ anom as anom,
+ anomalies as anomalies,
+ any as any,
+ append as append,
+ arange as arange,
+ arccos as arccos,
+ arccosh as arccosh,
+ arcsin as arcsin,
+ arcsinh as arcsinh,
+ arctan as arctan,
+ arctan2 as arctan2,
+ arctanh as arctanh,
+ argmax as argmax,
+ argmin as argmin,
+ argsort as argsort,
+ around as around,
+ array as array,
+ asanyarray as asanyarray,
+ asarray as asarray,
+ bitwise_and as bitwise_and,
+ bitwise_or as bitwise_or,
+ bitwise_xor as bitwise_xor,
+ bool_ as bool_,
+ ceil as ceil,
+ choose as choose,
+ clip as clip,
+ common_fill_value as common_fill_value,
+ compress as compress,
+ compressed as compressed,
+ concatenate as concatenate,
+ conjugate as conjugate,
+ convolve as convolve,
+ copy as copy,
+ correlate as correlate,
+ cos as cos,
+ cosh as cosh,
+ count as count,
+ cumprod as cumprod,
+ cumsum as cumsum,
+ default_fill_value as default_fill_value,
+ diag as diag,
+ diagonal as diagonal,
+ diff as diff,
+ divide as divide,
+ empty as empty,
+ empty_like as empty_like,
+ equal as equal,
+ exp as exp,
+ expand_dims as expand_dims,
+ fabs as fabs,
+ filled as filled,
+ fix_invalid as fix_invalid,
+ flatten_mask as flatten_mask,
+ flatten_structured_array as flatten_structured_array,
+ floor as floor,
+ floor_divide as floor_divide,
+ fmod as fmod,
+ frombuffer as frombuffer,
+ fromflex as fromflex,
+ fromfunction as fromfunction,
+ getdata as getdata,
+ getmask as getmask,
+ getmaskarray as getmaskarray,
+ greater as greater,
+ greater_equal as greater_equal,
+ harden_mask as harden_mask,
+ hypot as hypot,
+ identity as identity,
+ ids as ids,
+ indices as indices,
+ inner as inner,
+ innerproduct as innerproduct,
+ isMA as isMA,
+ isMaskedArray as isMaskedArray,
+ is_mask as is_mask,
+ is_masked as is_masked,
+ isarray as isarray,
+ left_shift as left_shift,
+ less as less,
+ less_equal as less_equal,
+ log as log,
+ log10 as log10,
+ log2 as log2,
+ logical_and as logical_and,
+ logical_not as logical_not,
+ logical_or as logical_or,
+ logical_xor as logical_xor,
+ make_mask as make_mask,
+ make_mask_descr as make_mask_descr,
+ make_mask_none as make_mask_none,
+ mask_or as mask_or,
+ masked as masked,
+ masked_array as masked_array,
+ masked_equal as masked_equal,
+ masked_greater as masked_greater,
+ masked_greater_equal as masked_greater_equal,
+ masked_inside as masked_inside,
+ masked_invalid as masked_invalid,
+ masked_less as masked_less,
+ masked_less_equal as masked_less_equal,
+ masked_not_equal as masked_not_equal,
+ masked_object as masked_object,
+ masked_outside as masked_outside,
+ masked_print_option as masked_print_option,
+ masked_singleton as masked_singleton,
+ masked_values as masked_values,
+ masked_where as masked_where,
+ max as max,
+ maximum as maximum,
+ maximum_fill_value as maximum_fill_value,
+ mean as mean,
+ min as min,
+ minimum as minimum,
+ minimum_fill_value as minimum_fill_value,
+ mod as mod,
+ multiply as multiply,
+ mvoid as mvoid,
+ ndim as ndim,
+ negative as negative,
+ nomask as nomask,
+ nonzero as nonzero,
+ not_equal as not_equal,
+ ones as ones,
+ outer as outer,
+ outerproduct as outerproduct,
+ power as power,
+ prod as prod,
+ product as product,
+ ptp as ptp,
+ put as put,
+ putmask as putmask,
+ ravel as ravel,
+ remainder as remainder,
+ repeat as repeat,
+ reshape as reshape,
+ resize as resize,
+ right_shift as right_shift,
+ round as round,
+ round_ as round_,
+ set_fill_value as set_fill_value,
+ shape as shape,
+ sin as sin,
+ sinh as sinh,
+ size as size,
+ soften_mask as soften_mask,
+ sometrue as sometrue,
+ sort as sort,
+ sqrt as sqrt,
+ squeeze as squeeze,
+ std as std,
+ subtract as subtract,
+ sum as sum,
+ swapaxes as swapaxes,
+ take as take,
+ tan as tan,
+ tanh as tanh,
+ trace as trace,
+ transpose as transpose,
+ true_divide as true_divide,
+ var as var,
+ where as where,
+ zeros as zeros,
+)
+
+from numpy.ma.extras import (
+ apply_along_axis as apply_along_axis,
+ apply_over_axes as apply_over_axes,
+ atleast_1d as atleast_1d,
+ atleast_2d as atleast_2d,
+ atleast_3d as atleast_3d,
+ average as average,
+ clump_masked as clump_masked,
+ clump_unmasked as clump_unmasked,
+ column_stack as column_stack,
+ compress_cols as compress_cols,
+ compress_nd as compress_nd,
+ compress_rowcols as compress_rowcols,
+ compress_rows as compress_rows,
+ count_masked as count_masked,
+ corrcoef as corrcoef,
+ cov as cov,
+ diagflat as diagflat,
+ dot as dot,
+ dstack as dstack,
+ ediff1d as ediff1d,
+ flatnotmasked_contiguous as flatnotmasked_contiguous,
+ flatnotmasked_edges as flatnotmasked_edges,
+ hsplit as hsplit,
+ hstack as hstack,
+ isin as isin,
+ in1d as in1d,
+ intersect1d as intersect1d,
+ mask_cols as mask_cols,
+ mask_rowcols as mask_rowcols,
+ mask_rows as mask_rows,
+ masked_all as masked_all,
+ masked_all_like as masked_all_like,
+ median as median,
+ mr_ as mr_,
+ notmasked_contiguous as notmasked_contiguous,
+ notmasked_edges as notmasked_edges,
+ polyfit as polyfit,
+ row_stack as row_stack,
+ setdiff1d as setdiff1d,
+ setxor1d as setxor1d,
+ stack as stack,
+ unique as unique,
+ union1d as union1d,
+ vander as vander,
+ vstack as vstack,
+)
+
+__all__: List[str]
+__path__: List[str]
+test: PytestTester
diff --git a/numpy/ma/core.py b/numpy/ma/core.py
index 4fb7d8c28..d2150919f 100644
--- a/numpy/ma/core.py
+++ b/numpy/ma/core.py
@@ -39,8 +39,6 @@ from numpy.compat import (
)
from numpy import expand_dims
from numpy.core.numeric import normalize_axis_tuple
-from numpy.core._internal import recursive
-from numpy.compat import pickle
__all__ = [
@@ -399,10 +397,10 @@ def _recursive_set_fill_value(fillvalue, dt):
Parameters
----------
- fillvalue: scalar or array_like
+ fillvalue : scalar or array_like
Scalar or array representing the fill value. If it is of shorter
length than the number of fields in dt, it will be resized.
- dt: dtype
+ dt : dtype
The structured dtype for which to create the fill value.
Returns
@@ -914,7 +912,7 @@ class _MaskedUnaryOperation(_MaskedUFunc):
"""
def __init__(self, mufunc, fill=0, domain=None):
- super(_MaskedUnaryOperation, self).__init__(mufunc)
+ super().__init__(mufunc)
self.fill = fill
self.domain = domain
ufunc_domain[mufunc] = domain
@@ -996,7 +994,7 @@ class _MaskedBinaryOperation(_MaskedUFunc):
abfunc(x, filly) = x for all x to enable reduce.
"""
- super(_MaskedBinaryOperation, self).__init__(mbfunc)
+ super().__init__(mbfunc)
self.fillx = fillx
self.filly = filly
ufunc_domain[mbfunc] = None
@@ -1142,7 +1140,7 @@ class _DomainedBinaryOperation(_MaskedUFunc):
"""abfunc(fillx, filly) must be defined.
abfunc(x, filly) = x for all x to enable reduce.
"""
- super(_DomainedBinaryOperation, self).__init__(dbfunc)
+ super().__init__(dbfunc)
self.domain = domain
self.fillx = fillx
self.filly = filly
@@ -1686,6 +1684,16 @@ def make_mask_none(newshape, dtype=None):
return result
+def _recursive_mask_or(m1, m2, newmask):
+ names = m1.dtype.names
+ for name in names:
+ current1 = m1[name]
+ if current1.dtype.names is not None:
+ _recursive_mask_or(current1, m2[name], newmask[name])
+ else:
+ umath.logical_or(current1, m2[name], newmask[name])
+
+
def mask_or(m1, m2, copy=False, shrink=True):
"""
Combine two masks with the ``logical_or`` operator.
@@ -1723,17 +1731,6 @@ def mask_or(m1, m2, copy=False, shrink=True):
"""
- @recursive
- def _recursive_mask_or(self, m1, m2, newmask):
- names = m1.dtype.names
- for name in names:
- current1 = m1[name]
- if current1.dtype.names is not None:
- self(current1, m2[name], newmask[name])
- else:
- umath.logical_or(current1, m2[name], newmask[name])
- return
-
if (m1 is nomask) or (m1 is False):
dtype = getattr(m2, 'dtype', MaskType)
return make_mask(m2, copy=copy, shrink=shrink, dtype=dtype)
@@ -1936,6 +1933,10 @@ def masked_where(condition, a, copy=True):
result = a.view(cls)
# Assign to *.mask so that structured masks are handled correctly.
result.mask = _shrink_mask(cond)
+ # There is no view of a boolean so when 'a' is a MaskedArray with nomask
+ # the update to the result's mask has no effect.
+ if not copy and hasattr(a, '_mask') and getmask(a) is nomask:
+ a._mask = result._mask.view()
return result
@@ -2836,11 +2837,6 @@ class MaskedArray(ndarray):
_data = ndarray.view(_data, type(data))
else:
_data = ndarray.view(_data, cls)
- # Backwards compatibility w/ numpy.core.ma.
- if hasattr(data, '_mask') and not isinstance(data, ndarray):
- _data._mask = data._mask
- # FIXME _sharedmask is never used.
- _sharedmask = True
# Process mask.
# Type of the mask
mdtype = make_mask_descr(_data.dtype)
@@ -2859,8 +2855,9 @@ class MaskedArray(ndarray):
elif isinstance(data, (tuple, list)):
try:
# If data is a sequence of masked array
- mask = np.array([getmaskarray(np.asanyarray(m, dtype=mdtype))
- for m in data], dtype=mdtype)
+ mask = np.array(
+ [getmaskarray(np.asanyarray(m, dtype=_data.dtype))
+ for m in data], dtype=mdtype)
except ValueError:
# If data is nested
mask = nomask
@@ -3399,7 +3396,7 @@ class MaskedArray(ndarray):
# Define so that we can overwrite the setter.
@property
def dtype(self):
- return super(MaskedArray, self).dtype
+ return super().dtype
@dtype.setter
def dtype(self, dtype):
@@ -3415,7 +3412,7 @@ class MaskedArray(ndarray):
@property
def shape(self):
- return super(MaskedArray, self).shape
+ return super().shape
@shape.setter
def shape(self, shape):
@@ -3894,7 +3891,7 @@ class MaskedArray(ndarray):
# Force the condition to a regular ndarray and forget the missing
# values.
- condition = np.array(condition, copy=False, subok=False)
+ condition = np.asarray(condition)
_new = _data.compress(condition, axis=axis, out=out).view(type(self))
_new._update_from(self)
@@ -4984,8 +4981,8 @@ class MaskedArray(ndarray):
#!!!: implement out + test!
m = self._mask
if m is nomask:
- result = super(MaskedArray, self).trace(offset=offset, axis1=axis1,
- axis2=axis2, out=out)
+ result = super().trace(offset=offset, axis1=axis1, axis2=axis2,
+ out=out)
return result.astype(dtype)
else:
D = self.diagonal(offset=offset, axis1=axis1, axis2=axis2)
@@ -5220,7 +5217,7 @@ class MaskedArray(ndarray):
--------
numpy.ndarray.mean : corresponding function for ndarrays
numpy.mean : Equivalent function
- numpy.ma.average: Weighted average.
+ numpy.ma.average : Weighted average.
Examples
--------
@@ -5236,8 +5233,7 @@ class MaskedArray(ndarray):
kwargs = {} if keepdims is np._NoValue else {'keepdims': keepdims}
if self._mask is nomask:
- result = super(MaskedArray, self).mean(axis=axis,
- dtype=dtype, **kwargs)[()]
+ result = super().mean(axis=axis, dtype=dtype, **kwargs)[()]
else:
dsum = self.sum(axis=axis, dtype=dtype, **kwargs)
cnt = self.count(axis=axis, **kwargs)
@@ -5287,9 +5283,6 @@ class MaskedArray(ndarray):
"""
m = self.mean(axis, dtype)
- if m is masked:
- return m
-
if not axis:
return self - m
else:
@@ -5314,8 +5307,8 @@ class MaskedArray(ndarray):
# Easy case: nomask, business as usual
if self._mask is nomask:
- ret = super(MaskedArray, self).var(axis=axis, dtype=dtype, out=out,
- ddof=ddof, **kwargs)[()]
+ ret = super().var(axis=axis, dtype=dtype, out=out, ddof=ddof,
+ **kwargs)[()]
if out is not None:
if isinstance(out, MaskedArray):
out.__setmask__(nomask)
@@ -5439,7 +5432,7 @@ class MaskedArray(ndarray):
When the array contains unmasked values at the same extremes of the
datatype, the ordering of these values and the masked values is
undefined.
- fill_value : {var}, optional
+ fill_value : scalar or None, optional
Value used internally for the masked values.
If ``fill_value`` is not None, it supersedes ``endwith``.
@@ -5488,7 +5481,8 @@ class MaskedArray(ndarray):
filled = self.filled(fill_value)
return filled.argsort(axis=axis, kind=kind, order=order)
- def argmin(self, axis=None, fill_value=None, out=None):
+ def argmin(self, axis=None, fill_value=None, out=None, *,
+ keepdims=np._NoValue):
"""
Return array of indices to the minimum values along the given axis.
@@ -5497,7 +5491,7 @@ class MaskedArray(ndarray):
axis : {None, integer}
If None, the index is into the flattened array, otherwise along
the specified axis
- fill_value : {var}, optional
+ fill_value : scalar or None, optional
Value used to fill in the masked values. If None, the output of
minimum_fill_value(self._data) is used instead.
out : {None, array}, optional
@@ -5531,9 +5525,11 @@ class MaskedArray(ndarray):
if fill_value is None:
fill_value = minimum_fill_value(self)
d = self.filled(fill_value).view(ndarray)
- return d.argmin(axis, out=out)
+ keepdims = False if keepdims is np._NoValue else bool(keepdims)
+ return d.argmin(axis, out=out, keepdims=keepdims)
- def argmax(self, axis=None, fill_value=None, out=None):
+ def argmax(self, axis=None, fill_value=None, out=None, *,
+ keepdims=np._NoValue):
"""
Returns array of indices of the maximum values along the given axis.
Masked values are treated as if they had the value fill_value.
@@ -5543,7 +5539,7 @@ class MaskedArray(ndarray):
axis : {None, integer}
If None, the index is into the flattened array, otherwise along
the specified axis
- fill_value : {var}, optional
+ fill_value : scalar or None, optional
Value used to fill in the masked values. If None, the output of
maximum_fill_value(self._data) is used instead.
out : {None, array}, optional
@@ -5568,7 +5564,8 @@ class MaskedArray(ndarray):
if fill_value is None:
fill_value = maximum_fill_value(self._data)
d = self.filled(fill_value).view(ndarray)
- return d.argmax(axis, out=out)
+ keepdims = False if keepdims is np._NoValue else bool(keepdims)
+ return d.argmax(axis, out=out, keepdims=keepdims)
def sort(self, axis=-1, kind=None, order=None,
endwith=True, fill_value=None):
@@ -5594,7 +5591,7 @@ class MaskedArray(ndarray):
When the array contains unmasked values sorting at the same extremes of the
datatype, the ordering of these values and the masked values is
undefined.
- fill_value : {var}, optional
+ fill_value : scalar or None, optional
Value used internally for the masked values.
If ``fill_value`` is not None, it supersedes ``endwith``.
@@ -5665,7 +5662,7 @@ class MaskedArray(ndarray):
out : array_like, optional
Alternative output array in which to place the result. Must be of
the same shape and buffer length as the expected output.
- fill_value : {var}, optional
+ fill_value : scalar or None, optional
Value used to fill in the masked values.
If None, use the output of `minimum_fill_value`.
keepdims : bool, optional
@@ -5799,7 +5796,7 @@ class MaskedArray(ndarray):
out : array_like, optional
Alternative output array in which to place the result. Must
be of the same shape and buffer length as the expected output.
- fill_value : {var}, optional
+ fill_value : scalar or None, optional
Value used to fill in the masked values.
If None, use the output of maximum_fill_value().
keepdims : bool, optional
@@ -5876,7 +5873,7 @@ class MaskedArray(ndarray):
Alternative output array in which to place the result. It must
have the same shape and buffer length as the expected output
but the type will be cast if necessary.
- fill_value : {var}, optional
+ fill_value : scalar or None, optional
Value used to fill in the masked values.
keepdims : bool, optional
If this is set to True, the axes which are reduced are left
@@ -5946,13 +5943,13 @@ class MaskedArray(ndarray):
warnings.warn("Warning: 'partition' will ignore the 'mask' "
f"of the {self.__class__.__name__}.",
stacklevel=2)
- return super(MaskedArray, self).partition(*args, **kwargs)
+ return super().partition(*args, **kwargs)
def argpartition(self, *args, **kwargs):
warnings.warn("Warning: 'argpartition' will ignore the 'mask' "
f"of the {self.__class__.__name__}.",
stacklevel=2)
- return super(MaskedArray, self).argpartition(*args, **kwargs)
+ return super().argpartition(*args, **kwargs)
def take(self, indices, axis=None, out=None, mode='raise'):
"""
@@ -6178,7 +6175,7 @@ class MaskedArray(ndarray):
"""
cf = 'CF'[self.flags.fnc]
- data_state = super(MaskedArray, self).__reduce__()[2]
+ data_state = super().__reduce__()[2]
return data_state + (getmaskarray(self).tobytes(cf), self._fill_value)
def __setstate__(self, state):
@@ -6194,7 +6191,7 @@ class MaskedArray(ndarray):
"""
(_, shp, typ, isf, raw, msk, flv) = state
- super(MaskedArray, self).__setstate__((shp, typ, isf, raw))
+ super().__setstate__((shp, typ, isf, raw))
self._mask.__setstate__((shp, make_mask_descr(typ), isf, msk))
self.fill_value = flv
@@ -6255,7 +6252,7 @@ class mvoid(MaskedArray):
@property
def _data(self):
# Make sure that the _data part is a np.void
- return super(mvoid, self)._data[()]
+ return super()._data[()]
def __getitem__(self, indx):
"""
@@ -6292,7 +6289,7 @@ class mvoid(MaskedArray):
return str(self._data)
rdtype = _replace_dtype_fields(self._data.dtype, "O")
- data_arr = super(mvoid, self)._data
+ data_arr = super()._data
res = data_arr.astype(rdtype)
_recursive_printoption(res, self._mask, masked_print_option)
return str(res)
@@ -6454,7 +6451,7 @@ class MaskedConstant(MaskedArray):
if not self.__has_singleton():
# this handles the `.view` in __new__, which we want to copy across
# properties normally
- return super(MaskedConstant, self).__array_finalize__(obj)
+ return super().__array_finalize__(obj)
elif self is self.__singleton:
# not clear how this can happen, play it safe
pass
@@ -6528,14 +6525,14 @@ class MaskedConstant(MaskedArray):
def __setattr__(self, attr, value):
if not self.__has_singleton():
# allow the singleton to be initialized
- return super(MaskedConstant, self).__setattr__(attr, value)
+ return super().__setattr__(attr, value)
elif self is self.__singleton:
raise AttributeError(
f"attributes of {self!r} are not writeable")
else:
# duplicate instance - we can end up here from __array_finalize__,
# where we set the __class__ attribute
- return super(MaskedConstant, self).__setattr__(attr, value)
+ return super().__setattr__(attr, value)
masked = masked_singleton = MaskedConstant()
@@ -6627,7 +6624,7 @@ class _extrema_operation(_MaskedUFunc):
"""
def __init__(self, ufunc, compare, fill_value):
- super(_extrema_operation, self).__init__(ufunc)
+ super().__init__(ufunc)
self.compare = compare
self.fill_value_func = fill_value
@@ -6913,8 +6910,7 @@ def compressed(x):
See Also
--------
- ma.MaskedArray.compressed
- Equivalent method.
+ ma.MaskedArray.compressed : Equivalent method.
"""
return asanyarray(x).compressed()
@@ -7339,16 +7335,16 @@ def where(condition, x=_NoValue, y=_NoValue):
def choose(indices, choices, out=None, mode='raise'):
"""
- Use an index array to construct a new array from a set of choices.
+ Use an index array to construct a new array from a list of choices.
- Given an array of integers and a set of n choice arrays, this method
+ Given an array of integers and a list of n choice arrays, this method
will create a new array that merges each of the choice arrays. Where a
- value in `a` is i, the new array will have the value that choices[i]
+ value in `index` is i, the new array will have the value that choices[i]
contains in the same place.
Parameters
----------
- a : ndarray of ints
+ indices : ndarray of ints
This array must contain integers in ``[0, n-1]``, where n is the
number of choices.
choices : sequence of arrays
@@ -7870,9 +7866,14 @@ def allclose(a, b, masked_equal=True, rtol=1e-5, atol=1e-8):
# make sure y is an inexact type to avoid abs(MIN_INT); will cause
# casting of x later.
- dtype = np.result_type(y, 1.)
- if y.dtype != dtype:
- y = masked_array(y, dtype=dtype, copy=False)
+ # NOTE: We explicitly allow timedelta, which used to work. This could
+ # possibly be deprecated. See also gh-18286.
+ # timedelta works if `atol` is an integer or also a timedelta.
+ # Although, the default tolerances are unlikely to be useful
+ if y.dtype.kind != "m":
+ dtype = np.result_type(y, 1.)
+ if y.dtype != dtype:
+ y = masked_array(y, dtype=dtype, copy=False)
m = mask_or(getmask(x), getmask(y))
xinf = np.isinf(masked_array(x, copy=False, mask=m)).filled(False)
@@ -8087,22 +8088,51 @@ class _convert2ma:
"""
__doc__ = None
- def __init__(self, funcname, params=None):
+ def __init__(self, funcname, np_ret, np_ma_ret, params=None):
self._func = getattr(np, funcname)
- self.__doc__ = self.getdoc()
+ self.__doc__ = self.getdoc(np_ret, np_ma_ret)
self._extras = params or {}
- def getdoc(self):
+ def getdoc(self, np_ret, np_ma_ret):
"Return the doc of the function (from the doc of the method)."
doc = getattr(self._func, '__doc__', None)
sig = get_object_signature(self._func)
if doc:
+ doc = self._replace_return_type(doc, np_ret, np_ma_ret)
# Add the signature of the function at the beginning of the doc
if sig:
sig = "%s%s\n" % (self._func.__name__, sig)
doc = sig + doc
return doc
+ def _replace_return_type(self, doc, np_ret, np_ma_ret):
+ """
+ Replace documentation of ``np`` function's return type.
+
+ Replaces it with the proper type for the ``np.ma`` function.
+
+ Parameters
+ ----------
+ doc : str
+ The documentation of the ``np`` method.
+ np_ret : str
+ The return type string of the ``np`` method that we want to
+ replace. (e.g. "out : ndarray")
+ np_ma_ret : str
+ The return type string of the ``np.ma`` method.
+ (e.g. "out : MaskedArray")
+ """
+ if np_ret not in doc:
+ raise RuntimeError(
+ f"Failed to replace `{np_ret}` with `{np_ma_ret}`. "
+ f"The documentation string for return type, {np_ret}, is not "
+ f"found in the docstring for `np.{self._func.__name__}`. "
+ f"Fix the docstring for `np.{self._func.__name__}` or "
+ "update the expected string for return type."
+ )
+
+ return doc.replace(np_ret, np_ma_ret)
+
def __call__(self, *args, **params):
# Find the common parameters to the call and the definition
_extras = self._extras
@@ -8118,20 +8148,57 @@ class _convert2ma:
result._hardmask = bool(_extras.get("hard_mask", False))
return result
-arange = _convert2ma('arange', params=dict(fill_value=None, hardmask=False))
+
+arange = _convert2ma(
+ 'arange',
+ params=dict(fill_value=None, hardmask=False),
+ np_ret='arange : ndarray',
+ np_ma_ret='arange : MaskedArray',
+)
clip = np.clip
diff = np.diff
-empty = _convert2ma('empty', params=dict(fill_value=None, hardmask=False))
-empty_like = _convert2ma('empty_like')
-frombuffer = _convert2ma('frombuffer')
-fromfunction = _convert2ma('fromfunction')
+empty = _convert2ma(
+ 'empty',
+ params=dict(fill_value=None, hardmask=False),
+ np_ret='out : ndarray',
+ np_ma_ret='out : MaskedArray',
+)
+empty_like = _convert2ma(
+ 'empty_like',
+ np_ret='out : ndarray',
+ np_ma_ret='out : MaskedArray',
+)
+frombuffer = _convert2ma(
+ 'frombuffer',
+ np_ret='out : ndarray',
+ np_ma_ret='out: MaskedArray',
+)
+fromfunction = _convert2ma(
+ 'fromfunction',
+ np_ret='fromfunction : any',
+ np_ma_ret='fromfunction: MaskedArray',
+)
identity = _convert2ma(
- 'identity', params=dict(fill_value=None, hardmask=False))
+ 'identity',
+ params=dict(fill_value=None, hardmask=False),
+ np_ret='out : ndarray',
+ np_ma_ret='out : MaskedArray',
+)
indices = np.indices
-ones = _convert2ma('ones', params=dict(fill_value=None, hardmask=False))
+ones = _convert2ma(
+ 'ones',
+ params=dict(fill_value=None, hardmask=False),
+ np_ret='out : ndarray',
+ np_ma_ret='out : MaskedArray',
+)
ones_like = np.ones_like
squeeze = np.squeeze
-zeros = _convert2ma('zeros', params=dict(fill_value=None, hardmask=False))
+zeros = _convert2ma(
+ 'zeros',
+ params=dict(fill_value=None, hardmask=False),
+ np_ret='out : ndarray',
+ np_ma_ret='out : MaskedArray',
+)
zeros_like = np.zeros_like
diff --git a/numpy/ma/core.pyi b/numpy/ma/core.pyi
new file mode 100644
index 000000000..bc1f45a8d
--- /dev/null
+++ b/numpy/ma/core.pyi
@@ -0,0 +1,468 @@
+from typing import Any, List, TypeVar, Callable
+from numpy import ndarray, dtype, float64
+
+from numpy import (
+ amax as amax,
+ amin as amin,
+ bool_ as bool_,
+ expand_dims as expand_dims,
+ diff as diff,
+ clip as clip,
+ indices as indices,
+ ones_like as ones_like,
+ squeeze as squeeze,
+ zeros_like as zeros_like,
+)
+
+from numpy.lib.function_base import (
+ angle as angle,
+)
+
+# TODO: Set the `bound` to something more suitable once we
+# have proper shape support
+_ShapeType = TypeVar("_ShapeType", bound=Any)
+_DType_co = TypeVar("_DType_co", bound=dtype[Any], covariant=True)
+
+__all__: List[str]
+
+MaskType = bool_
+nomask: bool_
+
+class MaskedArrayFutureWarning(FutureWarning): ...
+class MAError(Exception): ...
+class MaskError(MAError): ...
+
+def default_fill_value(obj): ...
+def minimum_fill_value(obj): ...
+def maximum_fill_value(obj): ...
+def set_fill_value(a, fill_value): ...
+def common_fill_value(a, b): ...
+def filled(a, fill_value=...): ...
+def getdata(a, subok=...): ...
+get_data = getdata
+
+def fix_invalid(a, mask=..., copy=..., fill_value=...): ...
+
+class _MaskedUFunc:
+ f: Any
+ __doc__: Any
+ __name__: Any
+ def __init__(self, ufunc): ...
+
+class _MaskedUnaryOperation(_MaskedUFunc):
+ fill: Any
+ domain: Any
+ def __init__(self, mufunc, fill=..., domain=...): ...
+ def __call__(self, a, *args, **kwargs): ...
+
+class _MaskedBinaryOperation(_MaskedUFunc):
+ fillx: Any
+ filly: Any
+ def __init__(self, mbfunc, fillx=..., filly=...): ...
+ def __call__(self, a, b, *args, **kwargs): ...
+ def reduce(self, target, axis=..., dtype=...): ...
+ def outer(self, a, b): ...
+ def accumulate(self, target, axis=...): ...
+
+class _DomainedBinaryOperation(_MaskedUFunc):
+ domain: Any
+ fillx: Any
+ filly: Any
+ def __init__(self, dbfunc, domain, fillx=..., filly=...): ...
+ def __call__(self, a, b, *args, **kwargs): ...
+
+exp: _MaskedUnaryOperation
+conjugate: _MaskedUnaryOperation
+sin: _MaskedUnaryOperation
+cos: _MaskedUnaryOperation
+arctan: _MaskedUnaryOperation
+arcsinh: _MaskedUnaryOperation
+sinh: _MaskedUnaryOperation
+cosh: _MaskedUnaryOperation
+tanh: _MaskedUnaryOperation
+abs: _MaskedUnaryOperation
+absolute: _MaskedUnaryOperation
+fabs: _MaskedUnaryOperation
+negative: _MaskedUnaryOperation
+floor: _MaskedUnaryOperation
+ceil: _MaskedUnaryOperation
+around: _MaskedUnaryOperation
+logical_not: _MaskedUnaryOperation
+sqrt: _MaskedUnaryOperation
+log: _MaskedUnaryOperation
+log2: _MaskedUnaryOperation
+log10: _MaskedUnaryOperation
+tan: _MaskedUnaryOperation
+arcsin: _MaskedUnaryOperation
+arccos: _MaskedUnaryOperation
+arccosh: _MaskedUnaryOperation
+arctanh: _MaskedUnaryOperation
+
+add: _MaskedBinaryOperation
+subtract: _MaskedBinaryOperation
+multiply: _MaskedBinaryOperation
+arctan2: _MaskedBinaryOperation
+equal: _MaskedBinaryOperation
+not_equal: _MaskedBinaryOperation
+less_equal: _MaskedBinaryOperation
+greater_equal: _MaskedBinaryOperation
+less: _MaskedBinaryOperation
+greater: _MaskedBinaryOperation
+logical_and: _MaskedBinaryOperation
+alltrue: _MaskedBinaryOperation
+logical_or: _MaskedBinaryOperation
+sometrue: Callable[..., Any]
+logical_xor: _MaskedBinaryOperation
+bitwise_and: _MaskedBinaryOperation
+bitwise_or: _MaskedBinaryOperation
+bitwise_xor: _MaskedBinaryOperation
+hypot: _MaskedBinaryOperation
+divide: _MaskedBinaryOperation
+true_divide: _MaskedBinaryOperation
+floor_divide: _MaskedBinaryOperation
+remainder: _MaskedBinaryOperation
+fmod: _MaskedBinaryOperation
+mod: _MaskedBinaryOperation
+
+def make_mask_descr(ndtype): ...
+def getmask(a): ...
+get_mask = getmask
+
+def getmaskarray(arr): ...
+def is_mask(m): ...
+def make_mask(m, copy=..., shrink=..., dtype=...): ...
+def make_mask_none(newshape, dtype=...): ...
+def mask_or(m1, m2, copy=..., shrink=...): ...
+def flatten_mask(mask): ...
+def masked_where(condition, a, copy=...): ...
+def masked_greater(x, value, copy=...): ...
+def masked_greater_equal(x, value, copy=...): ...
+def masked_less(x, value, copy=...): ...
+def masked_less_equal(x, value, copy=...): ...
+def masked_not_equal(x, value, copy=...): ...
+def masked_equal(x, value, copy=...): ...
+def masked_inside(x, v1, v2, copy=...): ...
+def masked_outside(x, v1, v2, copy=...): ...
+def masked_object(x, value, copy=..., shrink=...): ...
+def masked_values(x, value, rtol=..., atol=..., copy=..., shrink=...): ...
+def masked_invalid(a, copy=...): ...
+
+class _MaskedPrintOption:
+ def __init__(self, display): ...
+ def display(self): ...
+ def set_display(self, s): ...
+ def enabled(self): ...
+ def enable(self, shrink=...): ...
+
+masked_print_option: _MaskedPrintOption
+
+def flatten_structured_array(a): ...
+
+class MaskedIterator:
+ ma: Any
+ dataiter: Any
+ maskiter: Any
+ def __init__(self, ma): ...
+ def __iter__(self): ...
+ def __getitem__(self, indx): ...
+ def __setitem__(self, index, value): ...
+ def __next__(self): ...
+
+class MaskedArray(ndarray[_ShapeType, _DType_co]):
+ __array_priority__: Any
+ def __new__(cls, data=..., mask=..., dtype=..., copy=..., subok=..., ndmin=..., fill_value=..., keep_mask=..., hard_mask=..., shrink=..., order=...): ...
+ def __array_finalize__(self, obj): ...
+ def __array_wrap__(self, obj, context=...): ...
+ def view(self, dtype=..., type=..., fill_value=...): ...
+ def __getitem__(self, indx): ...
+ def __setitem__(self, indx, value): ...
+ @property
+ def dtype(self): ...
+ @dtype.setter
+ def dtype(self, dtype): ...
+ @property
+ def shape(self): ...
+ @shape.setter
+ def shape(self, shape): ...
+ def __setmask__(self, mask, copy=...): ...
+ @property
+ def mask(self): ...
+ @mask.setter
+ def mask(self, value): ...
+ @property
+ def recordmask(self): ...
+ @recordmask.setter
+ def recordmask(self, mask): ...
+ def harden_mask(self): ...
+ def soften_mask(self): ...
+ @property
+ def hardmask(self): ...
+ def unshare_mask(self): ...
+ @property
+ def sharedmask(self): ...
+ def shrink_mask(self): ...
+ @property
+ def baseclass(self): ...
+ data: Any
+ @property
+ def flat(self): ...
+ @flat.setter
+ def flat(self, value): ...
+ @property
+ def fill_value(self): ...
+ @fill_value.setter
+ def fill_value(self, value=...): ...
+ get_fill_value: Any
+ set_fill_value: Any
+ def filled(self, fill_value=...): ...
+ def compressed(self): ...
+ def compress(self, condition, axis=..., out=...): ...
+ def __eq__(self, other): ...
+ def __ne__(self, other): ...
+ def __add__(self, other): ...
+ def __radd__(self, other): ...
+ def __sub__(self, other): ...
+ def __rsub__(self, other): ...
+ def __mul__(self, other): ...
+ def __rmul__(self, other): ...
+ def __div__(self, other): ...
+ def __truediv__(self, other): ...
+ def __rtruediv__(self, other): ...
+ def __floordiv__(self, other): ...
+ def __rfloordiv__(self, other): ...
+ def __pow__(self, other): ...
+ def __rpow__(self, other): ...
+ def __iadd__(self, other): ...
+ def __isub__(self, other): ...
+ def __imul__(self, other): ...
+ def __idiv__(self, other): ...
+ def __ifloordiv__(self, other): ...
+ def __itruediv__(self, other): ...
+ def __ipow__(self, other): ...
+ def __float__(self): ...
+ def __int__(self): ...
+ @property # type: ignore[misc]
+ def imag(self): ...
+ get_imag: Any
+ @property # type: ignore[misc]
+ def real(self): ...
+ get_real: Any
+ def count(self, axis=..., keepdims=...): ...
+ def ravel(self, order=...): ...
+ def reshape(self, *s, **kwargs): ...
+ def resize(self, newshape, refcheck=..., order=...): ...
+ def put(self, indices, values, mode=...): ...
+ def ids(self): ...
+ def iscontiguous(self): ...
+ def all(self, axis=..., out=..., keepdims=...): ...
+ def any(self, axis=..., out=..., keepdims=...): ...
+ def nonzero(self): ...
+ def trace(self, offset=..., axis1=..., axis2=..., dtype=..., out=...): ...
+ def dot(self, b, out=..., strict=...): ...
+ def sum(self, axis=..., dtype=..., out=..., keepdims=...): ...
+ def cumsum(self, axis=..., dtype=..., out=...): ...
+ def prod(self, axis=..., dtype=..., out=..., keepdims=...): ...
+ product: Any
+ def cumprod(self, axis=..., dtype=..., out=...): ...
+ def mean(self, axis=..., dtype=..., out=..., keepdims=...): ...
+ def anom(self, axis=..., dtype=...): ...
+ def var(self, axis=..., dtype=..., out=..., ddof=..., keepdims=...): ...
+ def std(self, axis=..., dtype=..., out=..., ddof=..., keepdims=...): ...
+ def round(self, decimals=..., out=...): ...
+ def argsort(self, axis=..., kind=..., order=..., endwith=..., fill_value=...): ...
+ def argmin(self, axis=..., fill_value=..., out=..., *, keepdims=...): ...
+ def argmax(self, axis=..., fill_value=..., out=..., *, keepdims=...): ...
+ def sort(self, axis=..., kind=..., order=..., endwith=..., fill_value=...): ...
+ def min(self, axis=..., out=..., fill_value=..., keepdims=...): ...
+ # NOTE: deprecated
+ # def mini(self, axis=...): ...
+ # def tostring(self, fill_value=..., order=...): ...
+ def max(self, axis=..., out=..., fill_value=..., keepdims=...): ...
+ def ptp(self, axis=..., out=..., fill_value=..., keepdims=...): ...
+ def partition(self, *args, **kwargs): ...
+ def argpartition(self, *args, **kwargs): ...
+ def take(self, indices, axis=..., out=..., mode=...): ...
+ copy: Any
+ diagonal: Any
+ flatten: Any
+ repeat: Any
+ squeeze: Any
+ swapaxes: Any
+ T: Any
+ transpose: Any
+ def tolist(self, fill_value=...): ...
+ def tobytes(self, fill_value=..., order=...): ...
+ def tofile(self, fid, sep=..., format=...): ...
+ def toflex(self): ...
+ torecords: Any
+ def __reduce__(self): ...
+ def __deepcopy__(self, memo=...): ...
+
+class mvoid(MaskedArray[_ShapeType, _DType_co]):
+ def __new__(
+ self,
+ data,
+ mask=...,
+ dtype=...,
+ fill_value=...,
+ hardmask=...,
+ copy=...,
+ subok=...,
+ ): ...
+ def __getitem__(self, indx): ...
+ def __setitem__(self, indx, value): ...
+ def __iter__(self): ...
+ def __len__(self): ...
+ def filled(self, fill_value=...): ...
+ def tolist(self): ...
+
+def isMaskedArray(x): ...
+isarray = isMaskedArray
+isMA = isMaskedArray
+
+# 0D float64 array
+class MaskedConstant(MaskedArray[Any, dtype[float64]]):
+ def __new__(cls): ...
+ __class__: Any
+ def __array_finalize__(self, obj): ...
+ def __array_prepare__(self, obj, context=...): ...
+ def __array_wrap__(self, obj, context=...): ...
+ def __format__(self, format_spec): ...
+ def __reduce__(self): ...
+ def __iop__(self, other): ...
+ __iadd__: Any
+ __isub__: Any
+ __imul__: Any
+ __ifloordiv__: Any
+ __itruediv__: Any
+ __ipow__: Any
+ def copy(self, *args, **kwargs): ...
+ def __copy__(self): ...
+ def __deepcopy__(self, memo): ...
+ def __setattr__(self, attr, value): ...
+
+masked: MaskedConstant
+masked_singleton: MaskedConstant
+masked_array = MaskedArray
+
+def array(
+ data,
+ dtype=...,
+ copy=...,
+ order=...,
+ mask=...,
+ fill_value=...,
+ keep_mask=...,
+ hard_mask=...,
+ shrink=...,
+ subok=...,
+ ndmin=...,
+): ...
+def is_masked(x): ...
+
+class _extrema_operation(_MaskedUFunc):
+ compare: Any
+ fill_value_func: Any
+ def __init__(self, ufunc, compare, fill_value): ...
+ # NOTE: in practice `b` has a default value, but users should
+ # explicitly provide a value here as the default is deprecated
+ def __call__(self, a, b): ...
+ def reduce(self, target, axis=...): ...
+ def outer(self, a, b): ...
+
+def min(obj, axis=..., out=..., fill_value=..., keepdims=...): ...
+def max(obj, axis=..., out=..., fill_value=..., keepdims=...): ...
+def ptp(obj, axis=..., out=..., fill_value=..., keepdims=...): ...
+
+class _frommethod:
+ __name__: Any
+ __doc__: Any
+ reversed: Any
+ def __init__(self, methodname, reversed=...): ...
+ def getdoc(self): ...
+ def __call__(self, a, *args, **params): ...
+
+all: _frommethod
+anomalies: _frommethod
+anom: _frommethod
+any: _frommethod
+compress: _frommethod
+cumprod: _frommethod
+cumsum: _frommethod
+copy: _frommethod
+diagonal: _frommethod
+harden_mask: _frommethod
+ids: _frommethod
+mean: _frommethod
+nonzero: _frommethod
+prod: _frommethod
+product: _frommethod
+ravel: _frommethod
+repeat: _frommethod
+soften_mask: _frommethod
+std: _frommethod
+sum: _frommethod
+swapaxes: _frommethod
+trace: _frommethod
+var: _frommethod
+count: _frommethod
+argmin: _frommethod
+argmax: _frommethod
+
+minimum: _extrema_operation
+maximum: _extrema_operation
+
+def take(a, indices, axis=..., out=..., mode=...): ...
+def power(a, b, third=...): ...
+def argsort(a, axis=..., kind=..., order=..., endwith=..., fill_value=...): ...
+def sort(a, axis=..., kind=..., order=..., endwith=..., fill_value=...): ...
+def compressed(x): ...
+def concatenate(arrays, axis=...): ...
+def diag(v, k=...): ...
+def left_shift(a, n): ...
+def right_shift(a, n): ...
+def put(a, indices, values, mode=...): ...
+def putmask(a, mask, values): ...
+def transpose(a, axes=...): ...
+def reshape(a, new_shape, order=...): ...
+def resize(x, new_shape): ...
+def ndim(obj): ...
+def shape(obj): ...
+def size(obj, axis=...): ...
+def where(condition, x=..., y=...): ...
+def choose(indices, choices, out=..., mode=...): ...
+def round_(a, decimals=..., out=...): ...
+round = round_
+
+def inner(a, b): ...
+innerproduct = inner
+
+def outer(a, b): ...
+outerproduct = outer
+
+def correlate(a, v, mode=..., propagate_mask=...): ...
+def convolve(a, v, mode=..., propagate_mask=...): ...
+def allequal(a, b, fill_value=...): ...
+def allclose(a, b, masked_equal=..., rtol=..., atol=...): ...
+def asarray(a, dtype=..., order=...): ...
+def asanyarray(a, dtype=...): ...
+def fromflex(fxarray): ...
+
+class _convert2ma:
+ __doc__: Any
+ def __init__(self, funcname, params=...): ...
+ def getdoc(self): ...
+ def __call__(self, *args, **params): ...
+
+arange: _convert2ma
+empty: _convert2ma
+empty_like: _convert2ma
+frombuffer: _convert2ma
+fromfunction: _convert2ma
+identity: _convert2ma
+ones: _convert2ma
+zeros: _convert2ma
+
+def append(a, b, axis=...): ...
+def dot(a, b, strict=..., out=...): ...
+def mask_rowcols(a, axis=...): ...
diff --git a/numpy/ma/extras.py b/numpy/ma/extras.py
index 1bf03e966..73abfc296 100644
--- a/numpy/ma/extras.py
+++ b/numpy/ma/extras.py
@@ -33,7 +33,6 @@ from .core import (
import numpy as np
from numpy import ndarray, array as nxarray
-import numpy.core.umath as umath
from numpy.core.multiarray import normalize_axis_index
from numpy.core.numeric import normalize_axis_tuple
from numpy.lib.function_base import _ureduce
@@ -614,7 +613,7 @@ def average(a, axis=None, weights=None, returned=False):
"Length of weights not compatible with specified axis.")
# setup wgt to broadcast along axis
- wgt = np.broadcast_to(wgt, (a.ndim-1)*(1,) + wgt.shape)
+ wgt = np.broadcast_to(wgt, (a.ndim-1)*(1,) + wgt.shape, subok=True)
wgt = wgt.swapaxes(-1, axis)
if m is not nomask:
@@ -744,7 +743,6 @@ def _median(a, axis=None, out=None, overwrite_input=False):
return np.ma.mean(asorted[indexer], axis=axis, out=out)
if asorted.ndim == 1:
- counts = count(asorted)
idx, odd = divmod(count(asorted), 2)
mid = asorted[idx + odd - 1:idx + 1]
if np.issubdtype(asorted.dtype, np.inexact) and asorted.size > 0:
@@ -1217,7 +1215,7 @@ def union1d(ar1, ar2):
The output is always a masked array. See `numpy.union1d` for more details.
- See also
+ See Also
--------
numpy.union1d : Equivalent function for ndarrays.
@@ -1322,7 +1320,7 @@ def cov(x, y=None, rowvar=True, bias=False, allow_masked=True, ddof=None):
observation of all those variables. Also see `rowvar` below.
y : array_like, optional
An additional set of variables and observations. `y` has the same
- form as `x`.
+ shape as `x`.
rowvar : bool, optional
If `rowvar` is True (default), then each row represents a
variable, with observations in the columns. Otherwise, the relationship
@@ -1483,7 +1481,7 @@ class MAxisConcatenator(AxisConcatenator):
# deprecate that class. In preparation, we use the unmasked version
# to construct the matrix (with copy=False for backwards compatibility
# with the .view)
- data = super(MAxisConcatenator, cls).makemat(arr.data, copy=False)
+ data = super().makemat(arr.data, copy=False)
return array(data, mask=arr.mask)
def __getitem__(self, key):
@@ -1491,7 +1489,7 @@ class MAxisConcatenator(AxisConcatenator):
if isinstance(key, str):
raise MAError("Unavailable for masked array.")
- return super(MAxisConcatenator, self).__getitem__(key)
+ return super().__getitem__(key)
class mr_class(MAxisConcatenator):
diff --git a/numpy/ma/extras.pyi b/numpy/ma/extras.pyi
new file mode 100644
index 000000000..e58e43bad
--- /dev/null
+++ b/numpy/ma/extras.pyi
@@ -0,0 +1,84 @@
+from typing import Any, List
+from numpy.lib.index_tricks import AxisConcatenator
+
+from numpy.ma.core import (
+ dot as dot,
+ mask_rowcols as mask_rowcols,
+)
+
+__all__: List[str]
+
+def count_masked(arr, axis=...): ...
+def masked_all(shape, dtype = ...): ...
+def masked_all_like(arr): ...
+
+class _fromnxfunction:
+ __name__: Any
+ __doc__: Any
+ def __init__(self, funcname): ...
+ def getdoc(self): ...
+ def __call__(self, *args, **params): ...
+
+class _fromnxfunction_single(_fromnxfunction):
+ def __call__(self, x, *args, **params): ...
+
+class _fromnxfunction_seq(_fromnxfunction):
+ def __call__(self, x, *args, **params): ...
+
+class _fromnxfunction_allargs(_fromnxfunction):
+ def __call__(self, *args, **params): ...
+
+atleast_1d: _fromnxfunction_allargs
+atleast_2d: _fromnxfunction_allargs
+atleast_3d: _fromnxfunction_allargs
+
+vstack: _fromnxfunction_seq
+row_stack: _fromnxfunction_seq
+hstack: _fromnxfunction_seq
+column_stack: _fromnxfunction_seq
+dstack: _fromnxfunction_seq
+stack: _fromnxfunction_seq
+
+hsplit: _fromnxfunction_single
+diagflat: _fromnxfunction_single
+
+def apply_along_axis(func1d, axis, arr, *args, **kwargs): ...
+def apply_over_axes(func, a, axes): ...
+def average(a, axis=..., weights=..., returned=...): ...
+def median(a, axis=..., out=..., overwrite_input=..., keepdims=...): ...
+def compress_nd(x, axis=...): ...
+def compress_rowcols(x, axis=...): ...
+def compress_rows(a): ...
+def compress_cols(a): ...
+def mask_rows(a, axis = ...): ...
+def mask_cols(a, axis = ...): ...
+def ediff1d(arr, to_end=..., to_begin=...): ...
+def unique(ar1, return_index=..., return_inverse=...): ...
+def intersect1d(ar1, ar2, assume_unique=...): ...
+def setxor1d(ar1, ar2, assume_unique=...): ...
+def in1d(ar1, ar2, assume_unique=..., invert=...): ...
+def isin(element, test_elements, assume_unique=..., invert=...): ...
+def union1d(ar1, ar2): ...
+def setdiff1d(ar1, ar2, assume_unique=...): ...
+def cov(x, y=..., rowvar=..., bias=..., allow_masked=..., ddof=...): ...
+def corrcoef(x, y=..., rowvar=..., bias = ..., allow_masked=..., ddof = ...): ...
+
+class MAxisConcatenator(AxisConcatenator):
+ concatenate: Any
+ @classmethod
+ def makemat(cls, arr): ...
+ def __getitem__(self, key): ...
+
+class mr_class(MAxisConcatenator):
+ def __init__(self): ...
+
+mr_: mr_class
+
+def flatnotmasked_edges(a): ...
+def notmasked_edges(a, axis=...): ...
+def flatnotmasked_contiguous(a): ...
+def notmasked_contiguous(a, axis=...): ...
+def clump_unmasked(a): ...
+def clump_masked(a): ...
+def vander(x, n=...): ...
+def polyfit(x, y, deg, rcond=..., full=..., w=..., cov=...): ...
diff --git a/numpy/ma/mrecords.py b/numpy/ma/mrecords.py
index 70087632e..6814931b0 100644
--- a/numpy/ma/mrecords.py
+++ b/numpy/ma/mrecords.py
@@ -13,23 +13,23 @@ and the masking of individual fields.
# first place, and then rename the invalid fields with a trailing
# underscore. Maybe we could just overload the parser function ?
+from numpy.ma import (
+ MAError, MaskedArray, masked, nomask, masked_array, getdata,
+ getmaskarray, filled
+)
+import numpy.ma as ma
import warnings
import numpy as np
from numpy import (
- bool_, dtype, ndarray, recarray, array as narray
- )
+ bool_, dtype, ndarray, recarray, array as narray
+)
from numpy.core.records import (
- fromarrays as recfromarrays, fromrecords as recfromrecords
- )
+ fromarrays as recfromarrays, fromrecords as recfromrecords
+)
_byteorderconv = np.core.records._byteorderconv
-import numpy.ma as ma
-from numpy.ma import (
- MAError, MaskedArray, masked, nomask, masked_array, getdata,
- getmaskarray, filled
- )
_check_fill_value = ma.core._check_fill_value
@@ -37,7 +37,7 @@ _check_fill_value = ma.core._check_fill_value
__all__ = [
'MaskedRecords', 'mrecarray', 'fromarrays', 'fromrecords',
'fromtextfile', 'addfield',
- ]
+]
reserved_fields = ['_data', '_mask', '_fieldmask', 'dtype']
@@ -129,7 +129,6 @@ class MaskedRecords(MaskedArray):
msg = "Mask and data not compatible: data size is %i, " + \
"mask size is %i."
raise MAError(msg % (nd, nm))
- copy = True
if not keep_mask:
self.__setmask__(mask)
self._sharedmask = True
@@ -199,7 +198,8 @@ class MaskedRecords(MaskedArray):
try:
res = fielddict[attr][:2]
except (TypeError, KeyError) as e:
- raise AttributeError(f'record array has no attribute {attr}') from e
+ raise AttributeError(
+ f'record array has no attribute {attr}') from e
# So far, so good
_localdict = ndarray.__getattribute__(self, '__dict__')
_data = ndarray.view(self, _localdict['_baseclass'])
@@ -273,8 +273,9 @@ class MaskedRecords(MaskedArray):
# Let's try to set the field
try:
res = fielddict[attr][:2]
- except (TypeError, KeyError):
- raise AttributeError(f'record array has no attribute {attr}')
+ except (TypeError, KeyError) as e:
+ raise AttributeError(
+ f'record array has no attribute {attr}') from e
if val is masked:
_fill_value = _localdict['_fill_value']
@@ -355,7 +356,7 @@ class MaskedRecords(MaskedArray):
reprstr = [fmt % (f, getattr(self, f)) for f in self.dtype.names]
reprstr.insert(0, 'masked_records(')
reprstr.extend([fmt % (' fill_value', self.fill_value),
- ' )'])
+ ' )'])
return str("\n".join(reprstr))
def view(self, dtype=None, type=None):
@@ -374,7 +375,6 @@ class MaskedRecords(MaskedArray):
try:
if issubclass(dtype, ndarray):
output = ndarray.view(self, dtype)
- dtype = None
else:
output = ndarray.view(self, dtype)
# OK, there's the change
@@ -483,6 +483,7 @@ class MaskedRecords(MaskedArray):
(self.__class__, self._baseclass, (0,), 'b',),
self.__getstate__())
+
def _mrreconstruct(subtype, baseclass, baseshape, basetype,):
"""
Build a new MaskedArray from the information stored in a pickle.
@@ -492,6 +493,7 @@ def _mrreconstruct(subtype, baseclass, baseshape, basetype,):
_mask = ndarray.__new__(ndarray, baseshape, 'b1')
return subtype.__new__(subtype, _data, mask=_mask, dtype=basetype,)
+
mrecarray = MaskedRecords
@@ -656,8 +658,8 @@ def openfile(fname):
# Try to open the file and guess its type
try:
f = open(fname)
- except IOError:
- raise IOError(f"No such file: '{fname}'")
+ except IOError as e:
+ raise IOError(f"No such file: '{fname}'") from e
if f.readline()[:2] != "\\x":
f.seek(0, 0)
return f
@@ -752,7 +754,7 @@ def addfield(mrecord, newfield, newfieldname=None):
newdata = recarray(_data.shape, newdtype)
# Add the existing field
[newdata.setfield(_data.getfield(*f), *f)
- for f in _data.dtype.fields.values()]
+ for f in _data.dtype.fields.values()]
# Add the new field
newdata.setfield(newfield._data, *newdata.dtype.fields[newfieldname])
newdata = newdata.view(MaskedRecords)
@@ -762,7 +764,7 @@ def addfield(mrecord, newfield, newfieldname=None):
newmask = recarray(_data.shape, newmdtype)
# Add the old masks
[newmask.setfield(_mask.getfield(*f), *f)
- for f in _mask.dtype.fields.values()]
+ for f in _mask.dtype.fields.values()]
# Add the mask of the new field
newmask.setfield(getmaskarray(newfield),
*newmask.dtype.fields[newfieldname])
diff --git a/numpy/ma/mrecords.pyi b/numpy/ma/mrecords.pyi
new file mode 100644
index 000000000..92d5afb89
--- /dev/null
+++ b/numpy/ma/mrecords.pyi
@@ -0,0 +1,88 @@
+from typing import List, Any, TypeVar
+
+from numpy import dtype
+from numpy.ma import MaskedArray
+
+__all__: List[str]
+
+# TODO: Set the `bound` to something more suitable once we
+# have proper shape support
+_ShapeType = TypeVar("_ShapeType", bound=Any)
+_DType_co = TypeVar("_DType_co", bound=dtype[Any], covariant=True)
+
+class MaskedRecords(MaskedArray[_ShapeType, _DType_co]):
+ def __new__(
+ cls,
+ shape,
+ dtype=...,
+ buf=...,
+ offset=...,
+ strides=...,
+ formats=...,
+ names=...,
+ titles=...,
+ byteorder=...,
+ aligned=...,
+ mask=...,
+ hard_mask=...,
+ fill_value=...,
+ keep_mask=...,
+ copy=...,
+ **options,
+ ): ...
+ _mask: Any
+ _fill_value: Any
+ @property
+ def _data(self): ...
+ @property
+ def _fieldmask(self): ...
+ def __array_finalize__(self, obj): ...
+ def __len__(self): ...
+ def __getattribute__(self, attr): ...
+ def __setattr__(self, attr, val): ...
+ def __getitem__(self, indx): ...
+ def __setitem__(self, indx, value): ...
+ def view(self, dtype=..., type=...): ...
+ def harden_mask(self): ...
+ def soften_mask(self): ...
+ def copy(self): ...
+ def tolist(self, fill_value=...): ...
+ def __reduce__(self): ...
+
+mrecarray = MaskedRecords
+
+def fromarrays(
+ arraylist,
+ dtype=...,
+ shape=...,
+ formats=...,
+ names=...,
+ titles=...,
+ aligned=...,
+ byteorder=...,
+ fill_value=...,
+): ...
+
+def fromrecords(
+ reclist,
+ dtype=...,
+ shape=...,
+ formats=...,
+ names=...,
+ titles=...,
+ aligned=...,
+ byteorder=...,
+ fill_value=...,
+ mask=...,
+): ...
+
+def fromtextfile(
+ fname,
+ delimitor=...,
+ commentchar=...,
+ missingchar=...,
+ varnames=...,
+ vartypes=...,
+): ...
+
+def addfield(mrecord, newfield, newfieldname=...): ...
diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py
index 0b2e7303c..2fd353d23 100644
--- a/numpy/ma/tests/test_core.py
+++ b/numpy/ma/tests/test_core.py
@@ -238,6 +238,26 @@ class TestMaskedArray:
assert_equal(data, [[0, 1, 2, 3, 4], [4, 3, 2, 1, 0]])
assert_(data.mask is nomask)
+ def test_creation_with_list_of_maskedarrays_no_bool_cast(self):
+ # Tests the regression in gh-18551
+ masked_str = np.ma.masked_array(['a', 'b'], mask=[True, False])
+ normal_int = np.arange(2)
+ res = np.ma.asarray([masked_str, normal_int], dtype="U21")
+ assert_array_equal(res.mask, [[True, False], [False, False]])
+
+ # The above only failed due a long chain of oddity, try also with
+ # an object array that cannot be converted to bool always:
+ class NotBool():
+ def __bool__(self):
+ raise ValueError("not a bool!")
+ masked_obj = np.ma.masked_array([NotBool(), 'b'], mask=[True, False])
+ # Check that the NotBool actually fails like we would expect:
+ with pytest.raises(ValueError, match="not a bool!"):
+ np.asarray([masked_obj], dtype=bool)
+
+ res = np.ma.asarray([masked_obj, normal_int])
+ assert_array_equal(res.mask, [[True, False], [False, False]])
+
def test_creation_from_ndarray_with_padding(self):
x = np.array([('A', 0)], dtype={'names':['f0','f1'],
'formats':['S4','i8'],
@@ -1297,7 +1317,7 @@ class TestMaskedArrayArithmetic:
dtype=float_dtype)
assert_equal(zm.min(), float_dtype(-np.inf-1j))
assert_equal(zm.max(), float_dtype(np.inf+2j))
-
+
cmax = np.inf - 1j * np.finfo(np.float64).max
assert masked_array([-cmax, 0], mask=[0, 1]).max() == -cmax
assert masked_array([cmax, 0], mask=[0, 1]).min() == cmax
@@ -2833,6 +2853,8 @@ class TestMaskedArrayInPlaceArithmetics:
def test_inplace_floor_division_scalar_type(self):
# Test of inplace division
+ # Check for TypeError in case of unsupported types
+ unsupported = {np.dtype(t).type for t in np.typecodes["Complex"]}
for t in self.othertypes:
with warnings.catch_warnings(record=True) as w:
warnings.filterwarnings("always")
@@ -2840,15 +2862,21 @@ class TestMaskedArrayInPlaceArithmetics:
x = arange(10, dtype=t) * t(2)
xm = arange(10, dtype=t) * t(2)
xm[2] = masked
- x //= t(2)
- xm //= t(2)
- assert_equal(x, y)
- assert_equal(xm, y)
+ try:
+ x //= t(2)
+ xm //= t(2)
+ assert_equal(x, y)
+ assert_equal(xm, y)
- assert_equal(len(w), 0, "Failed on type=%s." % t)
+ assert_equal(len(w), 0, "Failed on type=%s." % t)
+ except TypeError:
+ msg = f"Supported type {t} throwing TypeError"
+ assert t in unsupported, msg
def test_inplace_floor_division_array_type(self):
# Test of inplace division
+ # Check for TypeError in case of unsupported types
+ unsupported = {np.dtype(t).type for t in np.typecodes["Complex"]}
for t in self.othertypes:
with warnings.catch_warnings(record=True) as w:
warnings.filterwarnings("always")
@@ -2856,16 +2884,20 @@ class TestMaskedArrayInPlaceArithmetics:
m = xm.mask
a = arange(10, dtype=t)
a[-1] = masked
- x //= a
- xm //= a
- assert_equal(x, y // a)
- assert_equal(xm, y // a)
- assert_equal(
- xm.mask,
- mask_or(mask_or(m, a.mask), (a == t(0)))
- )
+ try:
+ x //= a
+ xm //= a
+ assert_equal(x, y // a)
+ assert_equal(xm, y // a)
+ assert_equal(
+ xm.mask,
+ mask_or(mask_or(m, a.mask), (a == t(0)))
+ )
- assert_equal(len(w), 0, f'Failed on type={t}.')
+ assert_equal(len(w), 0, f'Failed on type={t}.')
+ except TypeError:
+ msg = f"Supported type {t} throwing TypeError"
+ assert t in unsupported, msg
def test_inplace_division_scalar_type(self):
# Test of inplace division
@@ -3037,6 +3069,13 @@ class TestMaskedArrayMethods:
a = masked_array([np.iinfo(np.int_).min], dtype=np.int_)
assert_(allclose(a, a))
+ def test_allclose_timedelta(self):
+ # Allclose currently works for timedelta64 as long as `atol` is
+ # an integer or also a timedelta64
+ a = np.array([[1, 2, 3, 4]], dtype="m8[ns]")
+ assert allclose(a, a, atol=0)
+ assert allclose(a, a, atol=np.timedelta64(1, "ns"))
+
def test_allany(self):
# Checks the any/all methods/functions.
x = np.array([[0.13, 0.26, 0.90],
@@ -3776,6 +3815,30 @@ class TestMaskedArrayMathMethods:
assert_equal(a.mean(), 2)
assert_equal(a.anom(), [-1, 0, 1])
+ def test_anom_shape(self):
+ a = masked_array([1, 2, 3])
+ assert_equal(a.anom().shape, a.shape)
+ a.mask = True
+ assert_equal(a.anom().shape, a.shape)
+ assert_(np.ma.is_masked(a.anom()))
+
+ def test_anom(self):
+ a = masked_array(np.arange(1, 7).reshape(2, 3))
+ assert_almost_equal(a.anom(),
+ [[-2.5, -1.5, -0.5], [0.5, 1.5, 2.5]])
+ assert_almost_equal(a.anom(axis=0),
+ [[-1.5, -1.5, -1.5], [1.5, 1.5, 1.5]])
+ assert_almost_equal(a.anom(axis=1),
+ [[-1., 0., 1.], [-1., 0., 1.]])
+ a.mask = [[0, 0, 1], [0, 1, 0]]
+ mval = -99
+ assert_almost_equal(a.anom().filled(mval),
+ [[-2.25, -1.25, mval], [0.75, mval, 2.75]])
+ assert_almost_equal(a.anom(axis=0).filled(mval),
+ [[-1.5, 0.0, mval], [1.5, mval, 0.0]])
+ assert_almost_equal(a.anom(axis=1).filled(mval),
+ [[-0.5, 0.5, mval], [-1.0, mval, 1.0]])
+
def test_trace(self):
# Tests trace on MaskedArrays.
(x, X, XX, m, mx, mX, mXX, m2x, m2X, m2XX) = self.d
@@ -5148,6 +5211,16 @@ def test_masked_array():
a = np.ma.array([0, 1, 2, 3], mask=[0, 0, 1, 0])
assert_equal(np.argwhere(a), [[1], [3]])
+def test_masked_array_no_copy():
+ # check nomask array is updated in place
+ a = np.ma.array([1, 2, 3, 4])
+ _ = np.ma.masked_where(a == 3, a, copy=False)
+ assert_array_equal(a.mask, [False, False, True, False])
+ # check masked array is updated in place
+ a = np.ma.array([1, 2, 3, 4], mask=[1, 0, 0, 0])
+ _ = np.ma.masked_where(a == 3, a, copy=False)
+ assert_array_equal(a.mask, [True, False, True, False])
+
def test_append_masked_array():
a = np.ma.masked_equal([1,2,3], value=2)
b = np.ma.masked_equal([4,3,2], value=2)
@@ -5186,7 +5259,6 @@ def test_append_masked_array_along_axis():
assert_array_equal(result.data, expected.data)
assert_array_equal(result.mask, expected.mask)
-
def test_default_fill_value_complex():
# regression test for Python 3, where 'unicode' was not defined
assert_(default_fill_value(1 + 1j) == 1.e20 + 0.0j)
diff --git a/numpy/ma/tests/test_extras.py b/numpy/ma/tests/test_extras.py
index d237829cb..e735b9bc7 100644
--- a/numpy/ma/tests/test_extras.py
+++ b/numpy/ma/tests/test_extras.py
@@ -292,6 +292,23 @@ class TestAverage:
assert_almost_equal(wav1.real, expected1.real)
assert_almost_equal(wav1.imag, expected1.imag)
+ def test_masked_weights(self):
+ # Test with masked weights.
+ # (Regression test for https://github.com/numpy/numpy/issues/10438)
+ a = np.ma.array(np.arange(9).reshape(3, 3),
+ mask=[[1, 0, 0], [1, 0, 0], [0, 0, 0]])
+ weights_unmasked = masked_array([5, 28, 31], mask=False)
+ weights_masked = masked_array([5, 28, 31], mask=[1, 0, 0])
+
+ avg_unmasked = average(a, axis=0,
+ weights=weights_unmasked, returned=False)
+ expected_unmasked = np.array([6.0, 5.21875, 6.21875])
+ assert_almost_equal(avg_unmasked, expected_unmasked)
+
+ avg_masked = average(a, axis=0, weights=weights_masked, returned=False)
+ expected_masked = np.array([6.0, 5.576271186440678, 6.576271186440678])
+ assert_almost_equal(avg_masked, expected_masked)
+
class TestConcatenator:
# Tests for mr_, the equivalent of r_ for masked arrays.
diff --git a/numpy/ma/tests/test_mrecords.py b/numpy/ma/tests/test_mrecords.py
index c2f859273..27df519d2 100644
--- a/numpy/ma/tests/test_mrecords.py
+++ b/numpy/ma/tests/test_mrecords.py
@@ -405,7 +405,7 @@ class TestMRecordsImport:
for (f, l) in zip(('a', 'b', 'c'), (_a, _b, _c)):
assert_equal(getattr(mrec, f)._mask, l._mask)
# One record only
- _x = ma.array([1, 1.1, 'one'], mask=[1, 0, 0],)
+ _x = ma.array([1, 1.1, 'one'], mask=[1, 0, 0], dtype=object)
assert_equal_records(fromarrays(_x, dtype=mrec.dtype), mrec[0])
def test_fromrecords(self):
diff --git a/numpy/ma/tests/test_subclassing.py b/numpy/ma/tests/test_subclassing.py
index f2623406d..1af539625 100644
--- a/numpy/ma/tests/test_subclassing.py
+++ b/numpy/ma/tests/test_subclassing.py
@@ -28,19 +28,18 @@ class SubArray(np.ndarray):
return x
def __array_finalize__(self, obj):
- if callable(getattr(super(SubArray, self),
- '__array_finalize__', None)):
- super(SubArray, self).__array_finalize__(obj)
+ if callable(getattr(super(), '__array_finalize__', None)):
+ super().__array_finalize__(obj)
self.info = getattr(obj, 'info', {}).copy()
return
def __add__(self, other):
- result = super(SubArray, self).__add__(other)
+ result = super().__add__(other)
result.info['added'] = result.info.get('added', 0) + 1
return result
def __iadd__(self, other):
- result = super(SubArray, self).__iadd__(other)
+ result = super().__iadd__(other)
result.info['iadded'] = result.info.get('iadded', 0) + 1
return result
@@ -51,7 +50,7 @@ subarray = SubArray
class SubMaskedArray(MaskedArray):
"""Pure subclass of MaskedArray, keeping some info on subclass."""
def __new__(cls, info=None, **kwargs):
- obj = super(SubMaskedArray, cls).__new__(cls, **kwargs)
+ obj = super().__new__(cls, **kwargs)
obj._optinfo['info'] = info
return obj
@@ -123,12 +122,11 @@ class ComplicatedSubArray(SubArray):
def __setitem__(self, item, value):
# validation ensures direct assignment with ndarray or
# masked_print_option will fail
- super(ComplicatedSubArray, self).__setitem__(
- item, self._validate_input(value))
+ super().__setitem__(item, self._validate_input(value))
def __getitem__(self, item):
# ensure getter returns our own class also for scalars
- value = super(ComplicatedSubArray, self).__getitem__(item)
+ value = super().__getitem__(item)
if not isinstance(value, np.ndarray): # scalar
value = value.__array__().view(ComplicatedSubArray)
return value
@@ -143,7 +141,7 @@ class ComplicatedSubArray(SubArray):
y[:] = value
def __array_wrap__(self, obj, context=None):
- obj = super(ComplicatedSubArray, self).__array_wrap__(obj, context)
+ obj = super().__array_wrap__(obj, context)
if context is not None and context[0] is np.multiply:
obj.info['multiplied'] = obj.info.get('multiplied', 0) + 1
diff --git a/numpy/ma/testutils.py b/numpy/ma/testutils.py
index 8d55e1763..2dd479abe 100644
--- a/numpy/ma/testutils.py
+++ b/numpy/ma/testutils.py
@@ -134,8 +134,8 @@ def assert_equal(actual, desired, err_msg=''):
msg = build_err_msg([actual, desired],
err_msg, header='', names=('x', 'y'))
raise ValueError(msg)
- actual = np.array(actual, copy=False, subok=True)
- desired = np.array(desired, copy=False, subok=True)
+ actual = np.asanyarray(actual)
+ desired = np.asanyarray(desired)
(actual_dtype, desired_dtype) = (actual.dtype, desired.dtype)
if actual_dtype.char == "S" and desired_dtype.char == "S":
return _assert_equal_on_sequences(actual.tolist(),
diff --git a/numpy/ma/timer_comparison.py b/numpy/ma/timer_comparison.py
index aff72f79b..9eb1a23cd 100644
--- a/numpy/ma/timer_comparison.py
+++ b/numpy/ma/timer_comparison.py
@@ -7,12 +7,9 @@ import numpy.core.fromnumeric as fromnumeric
from numpy.testing import build_err_msg
-# Fixme: this does not look right.
-np.seterr(all='ignore')
pi = np.pi
-
class ModuleTester:
def __init__(self, module):
self.module = module
@@ -111,6 +108,7 @@ class ModuleTester:
self.assert_array_compare(self.equal, x, y, err_msg=err_msg,
header='Arrays are not equal')
+ @np.errstate(all='ignore')
def test_0(self):
"""
Tests creation
@@ -121,6 +119,7 @@ class ModuleTester:
xm = self.masked_array(x, mask=m)
xm[0]
+ @np.errstate(all='ignore')
def test_1(self):
"""
Tests creation
@@ -148,6 +147,7 @@ class ModuleTester:
xf.shape = s
assert(self.count(xm) == len(m1) - reduce(lambda x, y:x+y, m1))
+ @np.errstate(all='ignore')
def test_2(self):
"""
Tests conversions and indexing.
@@ -190,6 +190,7 @@ class ModuleTester:
m3 = self.make_mask(m, copy=1)
assert(m is not m3)
+ @np.errstate(all='ignore')
def test_3(self):
"""
Tests resize/repeat
@@ -209,6 +210,7 @@ class ModuleTester:
y8 = x4.repeat(2, 0)
assert self.allequal(y5, y8)
+ @np.errstate(all='ignore')
def test_4(self):
"""
Test of take, transpose, inner, outer products.
@@ -232,6 +234,7 @@ class ModuleTester:
assert t[1] == 2
assert t[2] == 3
+ @np.errstate(all='ignore')
def test_5(self):
"""
Tests inplace w/ scalar
@@ -284,6 +287,7 @@ class ModuleTester:
x += 1.
assert self.allequal(x, y + 1.)
+ @np.errstate(all='ignore')
def test_6(self):
"""
Tests inplace w/ array
@@ -335,6 +339,7 @@ class ModuleTester:
x /= a
xm /= a
+ @np.errstate(all='ignore')
def test_7(self):
"Tests ufunc"
d = (self.array([1.0, 0, -1, pi/2]*2, mask=[0, 1]+[0]*6),
@@ -369,6 +374,7 @@ class ModuleTester:
self.assert_array_equal(ur.filled(0), mr.filled(0), f)
self.assert_array_equal(ur._mask, mr._mask)
+ @np.errstate(all='ignore')
def test_99(self):
# test average
ott = self.array([0., 1., 2., 3.], mask=[1, 0, 0, 0])
@@ -414,6 +420,7 @@ class ModuleTester:
self.assert_array_equal(self.average(z, axis=1), [2.5, 5.0])
self.assert_array_equal(self.average(z, axis=0, weights=w2), [0., 1., 99., 99., 4.0, 10.0])
+ @np.errstate(all='ignore')
def test_A(self):
x = self.arange(24)
x[5:6] = self.masked
diff --git a/numpy/matrixlib/__init__.pyi b/numpy/matrixlib/__init__.pyi
index b240bb327..26453f000 100644
--- a/numpy/matrixlib/__init__.pyi
+++ b/numpy/matrixlib/__init__.pyi
@@ -1,6 +1,15 @@
-from typing import Any
+from typing import Any, List
-matrix: Any
-bmat: Any
-mat: Any
-asmatrix: Any
+from numpy._pytesttester import PytestTester
+
+from numpy import (
+ matrix as matrix,
+)
+
+__all__: List[str]
+__path__: List[str]
+test: PytestTester
+
+def bmat(obj, ldict=..., gdict=...): ...
+def asmatrix(data, dtype=...): ...
+mat = asmatrix
diff --git a/numpy/polynomial/__init__.py b/numpy/polynomial/__init__.py
index c832094e2..4b4361163 100644
--- a/numpy/polynomial/__init__.py
+++ b/numpy/polynomial/__init__.py
@@ -15,37 +15,36 @@ information can be found in the docstring for the module of interest.
This package provides *convenience classes* for each of six different kinds
of polynomials:
- ============ ================
- **Name** **Provides**
- ============ ================
- Polynomial Power series
- Chebyshev Chebyshev series
- Legendre Legendre series
- Laguerre Laguerre series
- Hermite Hermite series
- HermiteE HermiteE series
- ============ ================
+ ======================== ================
+ **Name** **Provides**
+ ======================== ================
+ `~polynomial.Polynomial` Power series
+ `~chebyshev.Chebyshev` Chebyshev series
+ `~legendre.Legendre` Legendre series
+ `~laguerre.Laguerre` Laguerre series
+ `~hermite.Hermite` Hermite series
+ `~hermite_e.HermiteE` HermiteE series
+ ======================== ================
These *convenience classes* provide a consistent interface for creating,
manipulating, and fitting data with polynomials of different bases.
The convenience classes are the preferred interface for the `~numpy.polynomial`
-package, and are available from the `numpy.polynomial` namespace.
-This eliminates the need to
-navigate to the corresponding submodules, e.g. ``np.polynomial.Polynomial``
-or ``np.polynomial.Chebyshev`` instead of
-``np.polynomial.polynomial.Polynomial`` or
+package, and are available from the ``numpy.polynomial`` namespace.
+This eliminates the need to navigate to the corresponding submodules, e.g.
+``np.polynomial.Polynomial`` or ``np.polynomial.Chebyshev`` instead of
+``np.polynomial.polynomial.Polynomial`` or
``np.polynomial.chebyshev.Chebyshev``, respectively.
The classes provide a more consistent and concise interface than the
type-specific functions defined in the submodules for each type of polynomial.
For example, to fit a Chebyshev polynomial with degree ``1`` to data given
-by arrays ``xdata`` and ``ydata``, the
+by arrays ``xdata`` and ``ydata``, the
`~chebyshev.Chebyshev.fit` class method::
>>> from numpy.polynomial import Chebyshev
>>> c = Chebyshev.fit(xdata, ydata, deg=1)
-is preferred over the `chebyshev.chebfit` function from the
-`numpy.polynomial.chebyshev` module::
+is preferred over the `chebyshev.chebfit` function from the
+``np.polynomial.chebyshev`` module::
>>> from numpy.polynomial.chebyshev import chebfit
>>> c = chebfit(xdata, ydata, deg=1)
@@ -58,8 +57,8 @@ Convenience Classes
The following lists the various constants and methods common to all of
the classes representing the various kinds of polynomials. In the following,
the term ``Poly`` represents any one of the convenience classes (e.g.
-``Polynomial``, ``Chebyshev``, ``Hermite``, etc.) while the lowercase ``p``
-represents an **instance** of a polynomial class.
+`~polynomial.Polynomial`, `~chebyshev.Chebyshev`, `~hermite.Hermite`, etc.)
+while the lowercase ``p`` represents an **instance** of a polynomial class.
Constants
---------
@@ -77,7 +76,7 @@ Methods for creating polynomial instances.
- ``Poly.basis(degree)`` -- Basis polynomial of given degree
- ``Poly.identity()`` -- ``p`` where ``p(x) = x`` for all ``x``
-- ``Poly.fit(x, y, deg)`` -- ``p`` of degree ``deg`` with coefficients
+- ``Poly.fit(x, y, deg)`` -- ``p`` of degree ``deg`` with coefficients
determined by the least-squares fit to the data ``x``, ``y``
- ``Poly.fromroots(roots)`` -- ``p`` with specified roots
- ``p.copy()`` -- Create a copy of ``p``
@@ -121,6 +120,16 @@ from .hermite import Hermite
from .hermite_e import HermiteE
from .laguerre import Laguerre
+__all__ = [
+ "set_default_printstyle",
+ "polynomial", "Polynomial",
+ "chebyshev", "Chebyshev",
+ "legendre", "Legendre",
+ "hermite", "Hermite",
+ "hermite_e", "HermiteE",
+ "laguerre", "Laguerre",
+]
+
def set_default_printstyle(style):
"""
diff --git a/numpy/polynomial/__init__.pyi b/numpy/polynomial/__init__.pyi
index 817ba22ac..e0cfedd7a 100644
--- a/numpy/polynomial/__init__.pyi
+++ b/numpy/polynomial/__init__.pyi
@@ -1,9 +1,24 @@
-from typing import Any
-
-Polynomial: Any
-Chebyshev: Any
-Legendre: Any
-Hermite: Any
-HermiteE: Any
-Laguerre: Any
-set_default_printstyle: Any
+from typing import List
+
+from numpy._pytesttester import PytestTester
+
+from numpy.polynomial import (
+ chebyshev as chebyshev,
+ hermite as hermite,
+ hermite_e as hermite_e,
+ laguerre as laguerre,
+ legendre as legendre,
+ polynomial as polynomial,
+)
+from numpy.polynomial.chebyshev import Chebyshev as Chebyshev
+from numpy.polynomial.hermite import Hermite as Hermite
+from numpy.polynomial.hermite_e import HermiteE as HermiteE
+from numpy.polynomial.laguerre import Laguerre as Laguerre
+from numpy.polynomial.legendre import Legendre as Legendre
+from numpy.polynomial.polynomial import Polynomial as Polynomial
+
+__all__: List[str]
+__path__: List[str]
+test: PytestTester
+
+def set_default_printstyle(style): ...
diff --git a/numpy/polynomial/_polybase.py b/numpy/polynomial/_polybase.py
index 59c380f10..5525b232b 100644
--- a/numpy/polynomial/_polybase.py
+++ b/numpy/polynomial/_polybase.py
@@ -694,7 +694,7 @@ class ABCPolyBase(abc.ABC):
Returns
-------
new_series : series
- Contains the new set of coefficients.
+ New instance of series with trimmed coefficients.
"""
coef = pu.trimcoef(self.coef, tol)
@@ -757,9 +757,6 @@ class ABCPolyBase(abc.ABC):
Conversion between domains and class types can result in
numerically ill defined series.
- Examples
- --------
-
"""
if kind is None:
kind = self.__class__
@@ -939,11 +936,11 @@ class ABCPolyBase(abc.ABC):
diagnostic information from the singular value decomposition is
also returned.
w : array_like, shape (M,), optional
- Weights. If not None the contribution of each point
- ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the
- weights are chosen so that the errors of the products
- ``w[i]*y[i]`` all have the same variance. The default value is
- None.
+ Weights. If not None, the weight ``w[i]`` applies to the unsquared
+ residual ``y[i] - y_hat[i]`` at ``x[i]``. Ideally the weights are
+ chosen so that the errors of the products ``w[i]*y[i]`` all have
+ the same variance. When using inverse-variance weighting, use
+ ``w[i] = 1/sigma(y[i])``. The default value is None.
.. versionadded:: 1.5.0
window : {[beg, end]}, optional
diff --git a/numpy/polynomial/_polybase.pyi b/numpy/polynomial/_polybase.pyi
new file mode 100644
index 000000000..c41601469
--- /dev/null
+++ b/numpy/polynomial/_polybase.pyi
@@ -0,0 +1,69 @@
+import abc
+from typing import Any, List, ClassVar
+
+__all__: List[str]
+
+class ABCPolyBase(abc.ABC):
+ __hash__: ClassVar[None] # type: ignore[assignment]
+ __array_ufunc__: ClassVar[None]
+ maxpower: ClassVar[int]
+ coef: Any
+ @property
+ @abc.abstractmethod
+ def domain(self): ...
+ @property
+ @abc.abstractmethod
+ def window(self): ...
+ @property
+ @abc.abstractmethod
+ def basis_name(self): ...
+ def has_samecoef(self, other): ...
+ def has_samedomain(self, other): ...
+ def has_samewindow(self, other): ...
+ def has_sametype(self, other): ...
+ def __init__(self, coef, domain=..., window=...): ...
+ def __format__(self, fmt_str): ...
+ def __call__(self, arg): ...
+ def __iter__(self): ...
+ def __len__(self): ...
+ def __neg__(self): ...
+ def __pos__(self): ...
+ def __add__(self, other): ...
+ def __sub__(self, other): ...
+ def __mul__(self, other): ...
+ def __truediv__(self, other): ...
+ def __floordiv__(self, other): ...
+ def __mod__(self, other): ...
+ def __divmod__(self, other): ...
+ def __pow__(self, other): ...
+ def __radd__(self, other): ...
+ def __rsub__(self, other): ...
+ def __rmul__(self, other): ...
+ def __rdiv__(self, other): ...
+ def __rtruediv__(self, other): ...
+ def __rfloordiv__(self, other): ...
+ def __rmod__(self, other): ...
+ def __rdivmod__(self, other): ...
+ def __eq__(self, other): ...
+ def __ne__(self, other): ...
+ def copy(self): ...
+ def degree(self): ...
+ def cutdeg(self, deg): ...
+ def trim(self, tol=...): ...
+ def truncate(self, size): ...
+ def convert(self, domain=..., kind=..., window=...): ...
+ def mapparms(self): ...
+ def integ(self, m=..., k = ..., lbnd=...): ...
+ def deriv(self, m=...): ...
+ def roots(self): ...
+ def linspace(self, n=..., domain=...): ...
+ @classmethod
+ def fit(cls, x, y, deg, domain=..., rcond=..., full=..., w=..., window=...): ...
+ @classmethod
+ def fromroots(cls, roots, domain = ..., window=...): ...
+ @classmethod
+ def identity(cls, domain=..., window=...): ...
+ @classmethod
+ def basis(cls, deg, domain=..., window=...): ...
+ @classmethod
+ def cast(cls, series, domain=..., window=...): ...
diff --git a/numpy/polynomial/chebyshev.py b/numpy/polynomial/chebyshev.py
index 6745c9371..210000ec4 100644
--- a/numpy/polynomial/chebyshev.py
+++ b/numpy/polynomial/chebyshev.py
@@ -1149,9 +1149,6 @@ def chebval(x, c, tensor=True):
-----
The evaluation uses Clenshaw recursion, aka synthetic division.
- Examples
- --------
-
"""
c = np.array(c, ndmin=1, copy=True)
if c.dtype.char in '?bBhHiIlLqQpP':
@@ -1585,10 +1582,11 @@ def chebfit(x, y, deg, rcond=None, full=False, w=None):
default) just the coefficients are returned, when True diagnostic
information from the singular value decomposition is also returned.
w : array_like, shape (`M`,), optional
- Weights. If not None, the contribution of each point
- ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the
- weights are chosen so that the errors of the products ``w[i]*y[i]``
- all have the same variance. The default value is None.
+ Weights. If not None, the weight ``w[i]`` applies to the unsquared
+ residual ``y[i] - y_hat[i]`` at ``x[i]``. Ideally the weights are
+ chosen so that the errors of the products ``w[i]*y[i]`` all have the
+ same variance. When using inverse-variance weighting, use
+ ``w[i] = 1/sigma(y[i])``. The default value is None.
.. versionadded:: 1.5.0
@@ -1952,8 +1950,8 @@ def chebpts1(npts):
if _npts < 1:
raise ValueError("npts must be >= 1")
- x = np.linspace(-np.pi, 0, _npts, endpoint=False) + np.pi/(2*_npts)
- return np.cos(x)
+ x = 0.5 * np.pi / _npts * np.arange(-_npts+1, _npts+1, 2)
+ return np.sin(x)
def chebpts2(npts):
diff --git a/numpy/polynomial/chebyshev.pyi b/numpy/polynomial/chebyshev.pyi
new file mode 100644
index 000000000..841c0859b
--- /dev/null
+++ b/numpy/polynomial/chebyshev.pyi
@@ -0,0 +1,51 @@
+from typing import Any, List
+
+from numpy import ndarray, dtype, int_
+from numpy.polynomial._polybase import ABCPolyBase
+from numpy.polynomial.polyutils import trimcoef
+
+__all__: List[str]
+
+chebtrim = trimcoef
+
+def poly2cheb(pol): ...
+def cheb2poly(c): ...
+
+chebdomain: ndarray[Any, dtype[int_]]
+chebzero: ndarray[Any, dtype[int_]]
+chebone: ndarray[Any, dtype[int_]]
+chebx: ndarray[Any, dtype[int_]]
+
+def chebline(off, scl): ...
+def chebfromroots(roots): ...
+def chebadd(c1, c2): ...
+def chebsub(c1, c2): ...
+def chebmulx(c): ...
+def chebmul(c1, c2): ...
+def chebdiv(c1, c2): ...
+def chebpow(c, pow, maxpower=...): ...
+def chebder(c, m=..., scl=..., axis=...): ...
+def chebint(c, m=..., k = ..., lbnd=..., scl=..., axis=...): ...
+def chebval(x, c, tensor=...): ...
+def chebval2d(x, y, c): ...
+def chebgrid2d(x, y, c): ...
+def chebval3d(x, y, z, c): ...
+def chebgrid3d(x, y, z, c): ...
+def chebvander(x, deg): ...
+def chebvander2d(x, y, deg): ...
+def chebvander3d(x, y, z, deg): ...
+def chebfit(x, y, deg, rcond=..., full=..., w=...): ...
+def chebcompanion(c): ...
+def chebroots(c): ...
+def chebinterpolate(func, deg, args = ...): ...
+def chebgauss(deg): ...
+def chebweight(x): ...
+def chebpts1(npts): ...
+def chebpts2(npts): ...
+
+class Chebyshev(ABCPolyBase):
+ @classmethod
+ def interpolate(cls, func, deg, domain=..., args = ...): ...
+ domain: Any
+ window: Any
+ basis_name: Any
diff --git a/numpy/polynomial/hermite.py b/numpy/polynomial/hermite.py
index c679c5298..c1b9f71c0 100644
--- a/numpy/polynomial/hermite.py
+++ b/numpy/polynomial/hermite.py
@@ -1310,10 +1310,11 @@ def hermfit(x, y, deg, rcond=None, full=False, w=None):
default) just the coefficients are returned, when True diagnostic
information from the singular value decomposition is also returned.
w : array_like, shape (`M`,), optional
- Weights. If not None, the contribution of each point
- ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the
- weights are chosen so that the errors of the products ``w[i]*y[i]``
- all have the same variance. The default value is None.
+ Weights. If not None, the weight ``w[i]`` applies to the unsquared
+ residual ``y[i] - y_hat[i]`` at ``x[i]``. Ideally the weights are
+ chosen so that the errors of the products ``w[i]*y[i]`` all have the
+ same variance. When using inverse-variance weighting, use
+ ``w[i] = 1/sigma(y[i])``. The default value is None.
Returns
-------
diff --git a/numpy/polynomial/hermite.pyi b/numpy/polynomial/hermite.pyi
new file mode 100644
index 000000000..8364a5b0f
--- /dev/null
+++ b/numpy/polynomial/hermite.pyi
@@ -0,0 +1,46 @@
+from typing import Any, List
+
+from numpy import ndarray, dtype, int_, float_
+from numpy.polynomial._polybase import ABCPolyBase
+from numpy.polynomial.polyutils import trimcoef
+
+__all__: list[str]
+
+hermtrim = trimcoef
+
+def poly2herm(pol): ...
+def herm2poly(c): ...
+
+hermdomain: ndarray[Any, dtype[int_]]
+hermzero: ndarray[Any, dtype[int_]]
+hermone: ndarray[Any, dtype[int_]]
+hermx: ndarray[Any, dtype[float_]]
+
+def hermline(off, scl): ...
+def hermfromroots(roots): ...
+def hermadd(c1, c2): ...
+def hermsub(c1, c2): ...
+def hermmulx(c): ...
+def hermmul(c1, c2): ...
+def hermdiv(c1, c2): ...
+def hermpow(c, pow, maxpower=...): ...
+def hermder(c, m=..., scl=..., axis=...): ...
+def hermint(c, m=..., k = ..., lbnd=..., scl=..., axis=...): ...
+def hermval(x, c, tensor=...): ...
+def hermval2d(x, y, c): ...
+def hermgrid2d(x, y, c): ...
+def hermval3d(x, y, z, c): ...
+def hermgrid3d(x, y, z, c): ...
+def hermvander(x, deg): ...
+def hermvander2d(x, y, deg): ...
+def hermvander3d(x, y, z, deg): ...
+def hermfit(x, y, deg, rcond=..., full=..., w=...): ...
+def hermcompanion(c): ...
+def hermroots(c): ...
+def hermgauss(deg): ...
+def hermweight(x): ...
+
+class Hermite(ABCPolyBase):
+ domain: Any
+ window: Any
+ basis_name: Any
diff --git a/numpy/polynomial/hermite_e.py b/numpy/polynomial/hermite_e.py
index 1ce8ebe04..b7095c910 100644
--- a/numpy/polynomial/hermite_e.py
+++ b/numpy/polynomial/hermite_e.py
@@ -1301,10 +1301,11 @@ def hermefit(x, y, deg, rcond=None, full=False, w=None):
default) just the coefficients are returned, when True diagnostic
information from the singular value decomposition is also returned.
w : array_like, shape (`M`,), optional
- Weights. If not None, the contribution of each point
- ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the
- weights are chosen so that the errors of the products ``w[i]*y[i]``
- all have the same variance. The default value is None.
+ Weights. If not None, the weight ``w[i]`` applies to the unsquared
+ residual ``y[i] - y_hat[i]`` at ``x[i]``. Ideally the weights are
+ chosen so that the errors of the products ``w[i]*y[i]`` all have the
+ same variance. When using inverse-variance weighting, use
+ ``w[i] = 1/sigma(y[i])``. The default value is None.
Returns
-------
diff --git a/numpy/polynomial/hermite_e.pyi b/numpy/polynomial/hermite_e.pyi
new file mode 100644
index 000000000..c029bfda7
--- /dev/null
+++ b/numpy/polynomial/hermite_e.pyi
@@ -0,0 +1,46 @@
+from typing import Any, List
+
+from numpy import ndarray, dtype, int_
+from numpy.polynomial._polybase import ABCPolyBase
+from numpy.polynomial.polyutils import trimcoef
+
+__all__: list[str]
+
+hermetrim = trimcoef
+
+def poly2herme(pol): ...
+def herme2poly(c): ...
+
+hermedomain: ndarray[Any, dtype[int_]]
+hermezero: ndarray[Any, dtype[int_]]
+hermeone: ndarray[Any, dtype[int_]]
+hermex: ndarray[Any, dtype[int_]]
+
+def hermeline(off, scl): ...
+def hermefromroots(roots): ...
+def hermeadd(c1, c2): ...
+def hermesub(c1, c2): ...
+def hermemulx(c): ...
+def hermemul(c1, c2): ...
+def hermediv(c1, c2): ...
+def hermepow(c, pow, maxpower=...): ...
+def hermeder(c, m=..., scl=..., axis=...): ...
+def hermeint(c, m=..., k = ..., lbnd=..., scl=..., axis=...): ...
+def hermeval(x, c, tensor=...): ...
+def hermeval2d(x, y, c): ...
+def hermegrid2d(x, y, c): ...
+def hermeval3d(x, y, z, c): ...
+def hermegrid3d(x, y, z, c): ...
+def hermevander(x, deg): ...
+def hermevander2d(x, y, deg): ...
+def hermevander3d(x, y, z, deg): ...
+def hermefit(x, y, deg, rcond=..., full=..., w=...): ...
+def hermecompanion(c): ...
+def hermeroots(c): ...
+def hermegauss(deg): ...
+def hermeweight(x): ...
+
+class HermiteE(ABCPolyBase):
+ domain: Any
+ window: Any
+ basis_name: Any
diff --git a/numpy/polynomial/laguerre.py b/numpy/polynomial/laguerre.py
index 9cff0b71c..d3b6432dc 100644
--- a/numpy/polynomial/laguerre.py
+++ b/numpy/polynomial/laguerre.py
@@ -1307,10 +1307,11 @@ def lagfit(x, y, deg, rcond=None, full=False, w=None):
default) just the coefficients are returned, when True diagnostic
information from the singular value decomposition is also returned.
w : array_like, shape (`M`,), optional
- Weights. If not None, the contribution of each point
- ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the
- weights are chosen so that the errors of the products ``w[i]*y[i]``
- all have the same variance. The default value is None.
+ Weights. If not None, the weight ``w[i]`` applies to the unsquared
+ residual ``y[i] - y_hat[i]`` at ``x[i]``. Ideally the weights are
+ chosen so that the errors of the products ``w[i]*y[i]`` all have the
+ same variance. When using inverse-variance weighting, use
+ ``w[i] = 1/sigma(y[i])``. The default value is None.
Returns
-------
diff --git a/numpy/polynomial/laguerre.pyi b/numpy/polynomial/laguerre.pyi
new file mode 100644
index 000000000..2b9ab34e0
--- /dev/null
+++ b/numpy/polynomial/laguerre.pyi
@@ -0,0 +1,46 @@
+from typing import Any, List
+
+from numpy import ndarray, dtype, int_
+from numpy.polynomial._polybase import ABCPolyBase
+from numpy.polynomial.polyutils import trimcoef
+
+__all__: list[str]
+
+lagtrim = trimcoef
+
+def poly2lag(pol): ...
+def lag2poly(c): ...
+
+lagdomain: ndarray[Any, dtype[int_]]
+lagzero: ndarray[Any, dtype[int_]]
+lagone: ndarray[Any, dtype[int_]]
+lagx: ndarray[Any, dtype[int_]]
+
+def lagline(off, scl): ...
+def lagfromroots(roots): ...
+def lagadd(c1, c2): ...
+def lagsub(c1, c2): ...
+def lagmulx(c): ...
+def lagmul(c1, c2): ...
+def lagdiv(c1, c2): ...
+def lagpow(c, pow, maxpower=...): ...
+def lagder(c, m=..., scl=..., axis=...): ...
+def lagint(c, m=..., k = ..., lbnd=..., scl=..., axis=...): ...
+def lagval(x, c, tensor=...): ...
+def lagval2d(x, y, c): ...
+def laggrid2d(x, y, c): ...
+def lagval3d(x, y, z, c): ...
+def laggrid3d(x, y, z, c): ...
+def lagvander(x, deg): ...
+def lagvander2d(x, y, deg): ...
+def lagvander3d(x, y, z, deg): ...
+def lagfit(x, y, deg, rcond=..., full=..., w=...): ...
+def lagcompanion(c): ...
+def lagroots(c): ...
+def laggauss(deg): ...
+def lagweight(x): ...
+
+class Laguerre(ABCPolyBase):
+ domain: Any
+ window: Any
+ basis_name: Any
diff --git a/numpy/polynomial/legendre.py b/numpy/polynomial/legendre.py
index 427f9f82f..d4cf4accf 100644
--- a/numpy/polynomial/legendre.py
+++ b/numpy/polynomial/legendre.py
@@ -605,9 +605,6 @@ def legpow(c, pow, maxpower=16):
--------
legadd, legsub, legmulx, legmul, legdiv
- Examples
- --------
-
"""
return pu._pow(legmul, c, pow, maxpower)
@@ -890,9 +887,6 @@ def legval(x, c, tensor=True):
-----
The evaluation uses Clenshaw recursion, aka synthetic division.
- Examples
- --------
-
"""
c = np.array(c, ndmin=1, copy=False)
if c.dtype.char in '?bBhHiIlLqQpP':
@@ -1327,10 +1321,11 @@ def legfit(x, y, deg, rcond=None, full=False, w=None):
default) just the coefficients are returned, when True diagnostic
information from the singular value decomposition is also returned.
w : array_like, shape (`M`,), optional
- Weights. If not None, the contribution of each point
- ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the
- weights are chosen so that the errors of the products ``w[i]*y[i]``
- all have the same variance. The default value is None.
+ Weights. If not None, the weight ``w[i]`` applies to the unsquared
+ residual ``y[i] - y_hat[i]`` at ``x[i]``. Ideally the weights are
+ chosen so that the errors of the products ``w[i]*y[i]`` all have the
+ same variance. When using inverse-variance weighting, use
+ ``w[i] = 1/sigma(y[i])``. The default value is None.
.. versionadded:: 1.5.0
diff --git a/numpy/polynomial/legendre.pyi b/numpy/polynomial/legendre.pyi
new file mode 100644
index 000000000..86aef1793
--- /dev/null
+++ b/numpy/polynomial/legendre.pyi
@@ -0,0 +1,46 @@
+from typing import Any, List
+
+from numpy import ndarray, dtype, int_
+from numpy.polynomial._polybase import ABCPolyBase
+from numpy.polynomial.polyutils import trimcoef
+
+__all__: list[str]
+
+legtrim = trimcoef
+
+def poly2leg(pol): ...
+def leg2poly(c): ...
+
+legdomain: ndarray[Any, dtype[int_]]
+legzero: ndarray[Any, dtype[int_]]
+legone: ndarray[Any, dtype[int_]]
+legx: ndarray[Any, dtype[int_]]
+
+def legline(off, scl): ...
+def legfromroots(roots): ...
+def legadd(c1, c2): ...
+def legsub(c1, c2): ...
+def legmulx(c): ...
+def legmul(c1, c2): ...
+def legdiv(c1, c2): ...
+def legpow(c, pow, maxpower=...): ...
+def legder(c, m=..., scl=..., axis=...): ...
+def legint(c, m=..., k = ..., lbnd=..., scl=..., axis=...): ...
+def legval(x, c, tensor=...): ...
+def legval2d(x, y, c): ...
+def leggrid2d(x, y, c): ...
+def legval3d(x, y, z, c): ...
+def leggrid3d(x, y, z, c): ...
+def legvander(x, deg): ...
+def legvander2d(x, y, deg): ...
+def legvander3d(x, y, z, deg): ...
+def legfit(x, y, deg, rcond=..., full=..., w=...): ...
+def legcompanion(c): ...
+def legroots(c): ...
+def leggauss(deg): ...
+def legweight(x): ...
+
+class Legendre(ABCPolyBase):
+ domain: Any
+ window: Any
+ basis_name: Any
diff --git a/numpy/polynomial/polynomial.py b/numpy/polynomial/polynomial.py
index 1baa7d870..d8a032068 100644
--- a/numpy/polynomial/polynomial.py
+++ b/numpy/polynomial/polynomial.py
@@ -156,7 +156,7 @@ def polyfromroots(roots):
.. math:: p(x) = (x - r_0) * (x - r_1) * ... * (x - r_n),
- where the `r_n` are the roots specified in `roots`. If a zero has
+ where the ``r_n`` are the roots specified in `roots`. If a zero has
multiplicity n, then it must appear in `roots` n times. For instance,
if 2 is a root of multiplicity three and 3 is a root of multiplicity 2,
then `roots` looks something like [2, 2, 2, 3, 3]. The roots can appear
@@ -192,11 +192,11 @@ def polyfromroots(roots):
Notes
-----
The coefficients are determined by multiplying together linear factors
- of the form `(x - r_i)`, i.e.
+ of the form ``(x - r_i)``, i.e.
.. math:: p(x) = (x - r_0) (x - r_1) ... (x - r_n)
- where ``n == len(roots) - 1``; note that this implies that `1` is always
+ where ``n == len(roots) - 1``; note that this implies that ``1`` is always
returned for :math:`a_n`.
Examples
@@ -1252,10 +1252,11 @@ def polyfit(x, y, deg, rcond=None, full=False, w=None):
diagnostic information from the singular value decomposition (used
to solve the fit's matrix equation) is also returned.
w : array_like, shape (`M`,), optional
- Weights. If not None, the contribution of each point
- ``(x[i],y[i])`` to the fit is weighted by `w[i]`. Ideally the
- weights are chosen so that the errors of the products ``w[i]*y[i]``
- all have the same variance. The default value is None.
+ Weights. If not None, the weight ``w[i]`` applies to the unsquared
+ residual ``y[i] - y_hat[i]`` at ``x[i]``. Ideally the weights are
+ chosen so that the errors of the products ``w[i]*y[i]`` all have the
+ same variance. When using inverse-variance weighting, use
+ ``w[i] = 1/sigma(y[i])``. The default value is None.
.. versionadded:: 1.5.0
diff --git a/numpy/polynomial/polynomial.pyi b/numpy/polynomial/polynomial.pyi
new file mode 100644
index 000000000..f779300a9
--- /dev/null
+++ b/numpy/polynomial/polynomial.pyi
@@ -0,0 +1,41 @@
+from typing import Any, List
+
+from numpy import ndarray, dtype, int_
+from numpy.polynomial._polybase import ABCPolyBase
+from numpy.polynomial.polyutils import trimcoef
+
+__all__: list[str]
+
+polytrim = trimcoef
+
+polydomain: ndarray[Any, dtype[int_]]
+polyzero: ndarray[Any, dtype[int_]]
+polyone: ndarray[Any, dtype[int_]]
+polyx: ndarray[Any, dtype[int_]]
+
+def polyline(off, scl): ...
+def polyfromroots(roots): ...
+def polyadd(c1, c2): ...
+def polysub(c1, c2): ...
+def polymulx(c): ...
+def polymul(c1, c2): ...
+def polydiv(c1, c2): ...
+def polypow(c, pow, maxpower=...): ...
+def polyder(c, m=..., scl=..., axis=...): ...
+def polyint(c, m=..., k=..., lbnd=..., scl=..., axis=...): ...
+def polyval(x, c, tensor=...): ...
+def polyvalfromroots(x, r, tensor=...): ...
+def polyval2d(x, y, c): ...
+def polygrid2d(x, y, c): ...
+def polyval3d(x, y, z, c): ...
+def polygrid3d(x, y, z, c): ...
+def polyvander(x, deg): ...
+def polyvander2d(x, y, deg): ...
+def polyvander3d(x, y, z, deg): ...
+def polyfit(x, y, deg, rcond=..., full=..., w=...): ...
+def polyroots(c): ...
+
+class Polynomial(ABCPolyBase):
+ domain: Any
+ window: Any
+ basis_name: Any
diff --git a/numpy/polynomial/polyutils.py b/numpy/polynomial/polyutils.py
index d81ee9754..3b0f0a9e5 100644
--- a/numpy/polynomial/polyutils.py
+++ b/numpy/polynomial/polyutils.py
@@ -4,15 +4,6 @@ Utility classes and functions for the polynomial modules.
This module provides: error and warning objects; a polynomial base class;
and some routines used in both the `polynomial` and `chebyshev` modules.
-Error objects
--------------
-
-.. autosummary::
- :toctree: generated/
-
- PolyError base class for this sub-package's errors.
- PolyDomainError raised when domains are mismatched.
-
Warning objects
---------------
@@ -21,14 +12,6 @@ Warning objects
RankWarning raised in least-squares fit for rank-deficient matrix.
-Base class
-----------
-
-.. autosummary::
- :toctree: generated/
-
- PolyBase Obsolete base class for the polynomial classes. Do not use.
-
Functions
---------
@@ -50,8 +33,8 @@ import warnings
import numpy as np
__all__ = [
- 'RankWarning', 'PolyError', 'PolyDomainError', 'as_series', 'trimseq',
- 'trimcoef', 'getdomain', 'mapdomain', 'mapparms', 'PolyBase']
+ 'RankWarning', 'as_series', 'trimseq',
+ 'trimcoef', 'getdomain', 'mapdomain', 'mapparms']
#
# Warnings and Exceptions
@@ -61,35 +44,6 @@ class RankWarning(UserWarning):
"""Issued by chebfit when the design matrix is rank deficient."""
pass
-class PolyError(Exception):
- """Base class for errors in this module."""
- pass
-
-class PolyDomainError(PolyError):
- """Issued by the generic Poly class when two domains don't match.
-
- This is raised when an binary operation is passed Poly objects with
- different domains.
-
- """
- pass
-
-#
-# Base class for all polynomial types
-#
-
-class PolyBase:
- """
- Base class for all polynomial types.
-
- Deprecated in numpy 1.9.0, use the abstract
- ABCPolyBase class instead. Note that the latter
- requires a number of virtual functions to be
- implemented.
-
- """
- pass
-
#
# Helper functions to convert inputs to 1-D arrays
#
@@ -509,7 +463,7 @@ def _fromroots(line_f, mul_f, roots):
The ``<type>line`` function, such as ``polyline``
mul_f : function(array_like, array_like) -> ndarray
The ``<type>mul`` function, such as ``polymul``
- roots :
+ roots
See the ``<type>fromroots`` functions for more detail
"""
if len(roots) == 0:
@@ -537,7 +491,7 @@ def _valnd(val_f, c, *args):
----------
val_f : function(array_like, array_like, tensor: bool) -> array_like
The ``<type>val`` function, such as ``polyval``
- c, args :
+ c, args
See the ``<type>val<n>d`` functions for more detail
"""
args = [np.asanyarray(a) for a in args]
@@ -567,7 +521,7 @@ def _gridnd(val_f, c, *args):
----------
val_f : function(array_like, array_like, tensor: bool) -> array_like
The ``<type>val`` function, such as ``polyval``
- c, args :
+ c, args
See the ``<type>grid<n>d`` functions for more detail
"""
for xi in args:
@@ -586,7 +540,7 @@ def _div(mul_f, c1, c2):
----------
mul_f : function(array_like, array_like) -> array_like
The ``<type>mul`` function, such as ``polymul``
- c1, c2 :
+ c1, c2
See the ``<type>div`` functions for more detail
"""
# c1, c2 are trimmed copies
@@ -646,7 +600,7 @@ def _fit(vander_f, x, y, deg, rcond=None, full=False, w=None):
----------
vander_f : function(array_like, int) -> ndarray
The 1d vander function, such as ``polyvander``
- c1, c2 :
+ c1, c2
See the ``<type>fit`` functions for more detail
"""
x = np.asarray(x) + 0.0
@@ -732,12 +686,12 @@ def _pow(mul_f, c, pow, maxpower):
Parameters
----------
- vander_f : function(array_like, int) -> ndarray
- The 1d vander function, such as ``polyvander``
- pow, maxpower :
- See the ``<type>pow`` functions for more detail
mul_f : function(array_like, array_like) -> ndarray
The ``<type>mul`` function, such as ``polymul``
+ c : array_like
+ 1-D array of array of series coefficients
+ pow, maxpower
+ See the ``<type>pow`` functions for more detail
"""
# c is a trimmed copy
[c] = as_series([c])
diff --git a/numpy/polynomial/polyutils.pyi b/numpy/polynomial/polyutils.pyi
new file mode 100644
index 000000000..52c9cfc4a
--- /dev/null
+++ b/numpy/polynomial/polyutils.pyi
@@ -0,0 +1,12 @@
+from typing import List
+
+__all__: List[str]
+
+class RankWarning(UserWarning): ...
+
+def trimseq(seq): ...
+def as_series(alist, trim=...): ...
+def trimcoef(c, tol=...): ...
+def getdomain(x): ...
+def mapparms(old, new): ...
+def mapdomain(x, old, new): ...
diff --git a/numpy/polynomial/tests/test_legendre.py b/numpy/polynomial/tests/test_legendre.py
index a2a212c24..92399c160 100644
--- a/numpy/polynomial/tests/test_legendre.py
+++ b/numpy/polynomial/tests/test_legendre.py
@@ -305,6 +305,9 @@ class TestIntegral:
res = leg.legint(c2d, k=3, axis=1)
assert_almost_equal(res, tgt)
+ def test_legint_zerointord(self):
+ assert_equal(leg.legint((1, 2, 3), 0), (1, 2, 3))
+
class TestDerivative:
@@ -345,6 +348,9 @@ class TestDerivative:
res = leg.legder(c2d, axis=1)
assert_almost_equal(res, tgt)
+ def test_legder_orderhigherthancoeff(self):
+ c = (1, 2, 3, 4)
+ assert_equal(leg.legder(c, 4), [0])
class TestVander:
# some random values in [-1, 1)
@@ -393,6 +399,9 @@ class TestVander:
van = leg.legvander3d([x1], [x2], [x3], [1, 2, 3])
assert_(van.shape == (1, 5, 24))
+ def test_legvander_negdeg(self):
+ assert_raises(ValueError, leg.legvander, (1, 2, 3), -1)
+
class TestFitting:
@@ -541,6 +550,9 @@ class TestMisc:
def test_legline(self):
assert_equal(leg.legline(3, 4), [3, 4])
+ def test_legline_zeroscl(self):
+ assert_equal(leg.legline(3, 0), [3])
+
def test_leg2poly(self):
for i in range(10):
assert_almost_equal(leg.leg2poly([0]*i + [1]), Llist[i])
diff --git a/numpy/polynomial/tests/test_polynomial.py b/numpy/polynomial/tests/test_polynomial.py
index 5fd1a82a2..a0a09fcf4 100644
--- a/numpy/polynomial/tests/test_polynomial.py
+++ b/numpy/polynomial/tests/test_polynomial.py
@@ -473,6 +473,10 @@ class TestVander:
van = poly.polyvander3d([x1], [x2], [x3], [1, 2, 3])
assert_(van.shape == (1, 5, 24))
+ def test_polyvandernegdeg(self):
+ x = np.arange(3)
+ assert_raises(ValueError, poly.polyvander, x, -1)
+
class TestCompanion:
@@ -591,3 +595,6 @@ class TestMisc:
def test_polyline(self):
assert_equal(poly.polyline(3, 4), [3, 4])
+
+ def test_polyline_zero(self):
+ assert_equal(poly.polyline(3, 0), [3])
diff --git a/numpy/polynomial/tests/test_polyutils.py b/numpy/polynomial/tests/test_polyutils.py
index 1b27f53b5..cc630790d 100644
--- a/numpy/polynomial/tests/test_polyutils.py
+++ b/numpy/polynomial/tests/test_polyutils.py
@@ -40,6 +40,21 @@ class TestMisc:
assert_equal(pu.trimcoef(coef, 1), coef[:-3])
assert_equal(pu.trimcoef(coef, 2), [0])
+ def test_vander_nd_exception(self):
+ # n_dims != len(points)
+ assert_raises(ValueError, pu._vander_nd, (), (1, 2, 3), [90])
+ # n_dims != len(degrees)
+ assert_raises(ValueError, pu._vander_nd, (), (), [90.65])
+ # n_dims == 0
+ assert_raises(ValueError, pu._vander_nd, (), (), [])
+
+ def test_div_zerodiv(self):
+ # c2[-1] == 0
+ assert_raises(ZeroDivisionError, pu._div, pu._div, (1, 2, 3), [0])
+
+ def test_pow_too_large(self):
+ # power > maxpower
+ assert_raises(ValueError, pu._pow, (), [1, 2, 3], 5, 4)
class TestDomain:
diff --git a/numpy/polynomial/tests/test_printing.py b/numpy/polynomial/tests/test_printing.py
index 27a8ab9f2..4e9902a69 100644
--- a/numpy/polynomial/tests/test_printing.py
+++ b/numpy/polynomial/tests/test_printing.py
@@ -85,7 +85,7 @@ class TestStrUnicodeSuperSubscripts:
class TestStrAscii:
@pytest.fixture(scope='class', autouse=True)
- def use_unicode(self):
+ def use_ascii(self):
poly.set_default_printstyle('ascii')
@pytest.mark.parametrize(('inp', 'tgt'), (
@@ -161,7 +161,10 @@ class TestStrAscii:
class TestLinebreaking:
- poly.set_default_printstyle('ascii')
+
+ @pytest.fixture(scope='class', autouse=True)
+ def use_ascii(self):
+ poly.set_default_printstyle('ascii')
def test_single_line_one_less(self):
# With 'ascii' style, len(str(p)) is default linewidth - 1 (i.e. 74)
@@ -283,19 +286,19 @@ def test_nonnumeric_object_coefficients(coefs, tgt):
class TestFormat:
def test_format_unicode(self):
- poly.Polynomial._use_unicode = False
+ poly.set_default_printstyle('ascii')
p = poly.Polynomial([1, 2, 0, -1])
assert_equal(format(p, 'unicode'), "1.0 + 2.0·x¹ + 0.0·x² - 1.0·x³")
def test_format_ascii(self):
- poly.Polynomial._use_unicode = True
+ poly.set_default_printstyle('unicode')
p = poly.Polynomial([1, 2, 0, -1])
assert_equal(
format(p, 'ascii'), "1.0 + 2.0 x**1 + 0.0 x**2 - 1.0 x**3"
)
def test_empty_formatstr(self):
- poly.Polynomial._use_unicode = False
+ poly.set_default_printstyle('ascii')
p = poly.Polynomial([1, 2, 3])
assert_equal(format(p), "1.0 + 2.0 x**1 + 3.0 x**2")
assert_equal(f"{p}", "1.0 + 2.0 x**1 + 3.0 x**2")
diff --git a/numpy/random/__init__.py b/numpy/random/__init__.py
index 7efa5c07f..2e8f99fe3 100644
--- a/numpy/random/__init__.py
+++ b/numpy/random/__init__.py
@@ -17,6 +17,7 @@ BitGenerator Streams that work with Generator
--------------------------------------------- ---
MT19937
PCG64
+PCG64DXSM
Philox
SFC64
============================================= ===
@@ -183,13 +184,14 @@ from . import _bounded_integers
from ._generator import Generator, default_rng
from .bit_generator import SeedSequence, BitGenerator
from ._mt19937 import MT19937
-from ._pcg64 import PCG64
+from ._pcg64 import PCG64, PCG64DXSM
from ._philox import Philox
from ._sfc64 import SFC64
from .mtrand import *
__all__ += ['Generator', 'RandomState', 'SeedSequence', 'MT19937',
- 'Philox', 'PCG64', 'SFC64', 'default_rng', 'BitGenerator']
+ 'Philox', 'PCG64', 'PCG64DXSM', 'SFC64', 'default_rng',
+ 'BitGenerator']
def __RandomState_ctor():
diff --git a/numpy/random/__init__.pyi b/numpy/random/__init__.pyi
index f7c3cfafe..bf6147697 100644
--- a/numpy/random/__init__.pyi
+++ b/numpy/random/__init__.pyi
@@ -1,61 +1,72 @@
-from typing import Any
+from typing import List
-beta: Any
-binomial: Any
-bytes: Any
-chisquare: Any
-choice: Any
-dirichlet: Any
-exponential: Any
-f: Any
-gamma: Any
-geometric: Any
-get_state: Any
-gumbel: Any
-hypergeometric: Any
-laplace: Any
-logistic: Any
-lognormal: Any
-logseries: Any
-multinomial: Any
-multivariate_normal: Any
-negative_binomial: Any
-noncentral_chisquare: Any
-noncentral_f: Any
-normal: Any
-pareto: Any
-permutation: Any
-poisson: Any
-power: Any
-rand: Any
-randint: Any
-randn: Any
-random: Any
-random_integers: Any
-random_sample: Any
-ranf: Any
-rayleigh: Any
-sample: Any
-seed: Any
-set_state: Any
-shuffle: Any
-standard_cauchy: Any
-standard_exponential: Any
-standard_gamma: Any
-standard_normal: Any
-standard_t: Any
-triangular: Any
-uniform: Any
-vonmises: Any
-wald: Any
-weibull: Any
-zipf: Any
-Generator: Any
-RandomState: Any
-SeedSequence: Any
-MT19937: Any
-Philox: Any
-PCG64: Any
-SFC64: Any
-default_rng: Any
-BitGenerator: Any
+from numpy._pytesttester import PytestTester
+
+from numpy.random._generator import Generator as Generator
+from numpy.random._generator import default_rng as default_rng
+from numpy.random._mt19937 import MT19937 as MT19937
+from numpy.random._pcg64 import (
+ PCG64 as PCG64,
+ PCG64DXSM as PCG64DXSM,
+)
+from numpy.random._philox import Philox as Philox
+from numpy.random._sfc64 import SFC64 as SFC64
+from numpy.random.bit_generator import BitGenerator as BitGenerator
+from numpy.random.bit_generator import SeedSequence as SeedSequence
+from numpy.random.mtrand import (
+ RandomState as RandomState,
+ beta as beta,
+ binomial as binomial,
+ bytes as bytes,
+ chisquare as chisquare,
+ choice as choice,
+ dirichlet as dirichlet,
+ exponential as exponential,
+ f as f,
+ gamma as gamma,
+ geometric as geometric,
+ get_state as get_state,
+ gumbel as gumbel,
+ hypergeometric as hypergeometric,
+ laplace as laplace,
+ logistic as logistic,
+ lognormal as lognormal,
+ logseries as logseries,
+ multinomial as multinomial,
+ multivariate_normal as multivariate_normal,
+ negative_binomial as negative_binomial,
+ noncentral_chisquare as noncentral_chisquare,
+ noncentral_f as noncentral_f,
+ normal as normal,
+ pareto as pareto,
+ permutation as permutation,
+ poisson as poisson,
+ power as power,
+ rand as rand,
+ randint as randint,
+ randn as randn,
+ random as random,
+ random_integers as random_integers,
+ random_sample as random_sample,
+ ranf as ranf,
+ rayleigh as rayleigh,
+ sample as sample,
+ seed as seed,
+ set_state as set_state,
+ shuffle as shuffle,
+ standard_cauchy as standard_cauchy,
+ standard_exponential as standard_exponential,
+ standard_gamma as standard_gamma,
+ standard_normal as standard_normal,
+ standard_t as standard_t,
+ triangular as triangular,
+ uniform as uniform,
+ vonmises as vonmises,
+ wald as wald,
+ weibull as weibull,
+ zipf as zipf,
+)
+
+__all__: List[str]
+__path__: List[str]
+test: PytestTester
diff --git a/numpy/random/_bounded_integers.pyx.in b/numpy/random/_bounded_integers.pyx.in
index 9f46685d3..7eb6aff1e 100644
--- a/numpy/random/_bounded_integers.pyx.in
+++ b/numpy/random/_bounded_integers.pyx.in
@@ -8,6 +8,7 @@ __all__ = []
np.import_array()
+
cdef extern from "numpy/random/distributions.h":
# Generate random numbers in closed interval [off, off + rng].
uint64_t random_bounded_uint64(bitgen_t *bitgen_state,
@@ -51,6 +52,17 @@ cdef extern from "numpy/random/distributions.h":
np.npy_bool *out) nogil
+cdef object format_bounds_error(bint closed, object low):
+ # Special case low == 0 to provide a better exception for users
+ # since low = 0 is the default single-argument case.
+ if not np.any(low):
+ comp = '<' if closed else '<='
+ return f'high {comp} 0'
+ else:
+ comp = '>' if closed else '>='
+ return f'low {comp} high'
+
+
{{
py:
type_info = (('uint32', 'uint32', 'uint64', 'NPY_UINT64', 0, 0, 0, '0X100000000ULL'),
@@ -99,8 +111,7 @@ cdef object _rand_{{nptype}}_broadcast(np.ndarray low, np.ndarray high, object s
if np.any(high_comp(high_arr, {{ub}})):
raise ValueError('high is out of bounds for {{nptype}}')
if np.any(low_high_comp(low_arr, high_arr)):
- comp = '>' if closed else '>='
- raise ValueError('low {comp} high'.format(comp=comp))
+ raise ValueError(format_bounds_error(closed, low_arr))
low_arr = <np.ndarray>np.PyArray_FROM_OTF(low, np.{{npctype}}, np.NPY_ALIGNED | np.NPY_FORCECAST)
high_arr = <np.ndarray>np.PyArray_FROM_OTF(high, np.{{npctype}}, np.NPY_ALIGNED | np.NPY_FORCECAST)
@@ -173,8 +184,7 @@ cdef object _rand_{{nptype}}_broadcast(object low, object high, object size,
# Avoid object dtype path if already an integer
high_lower_comp = np.less if closed else np.less_equal
if np.any(high_lower_comp(high_arr, {{lb}})):
- comp = '>' if closed else '>='
- raise ValueError('low {comp} high'.format(comp=comp))
+ raise ValueError(format_bounds_error(closed, low_arr))
high_m1 = high_arr if closed else high_arr - dt.type(1)
if np.any(np.greater(high_m1, {{ub}})):
raise ValueError('high is out of bounds for {{nptype}}')
@@ -191,13 +201,11 @@ cdef object _rand_{{nptype}}_broadcast(object low, object high, object size,
if closed_upper > {{ub}}:
raise ValueError('high is out of bounds for {{nptype}}')
if closed_upper < {{lb}}:
- comp = '>' if closed else '>='
- raise ValueError('low {comp} high'.format(comp=comp))
+ raise ValueError(format_bounds_error(closed, low_arr))
highm1_data[i] = <{{nptype}}_t>closed_upper
if np.any(np.greater(low_arr, highm1_arr)):
- comp = '>' if closed else '>='
- raise ValueError('low {comp} high'.format(comp=comp))
+ raise ValueError(format_bounds_error(closed, low_arr))
high_arr = highm1_arr
low_arr = <np.ndarray>np.PyArray_FROM_OTF(low, np.{{npctype}}, np.NPY_ALIGNED | np.NPY_FORCECAST)
@@ -316,8 +324,7 @@ cdef object _rand_{{nptype}}(object low, object high, object size,
if high > {{ub}}:
raise ValueError("high is out of bounds for {{nptype}}")
if low > high: # -1 already subtracted, closed interval
- comp = '>' if closed else '>='
- raise ValueError('low {comp} high'.format(comp=comp))
+ raise ValueError(format_bounds_error(closed, low))
rng = <{{utype}}_t>(high - low)
off = <{{utype}}_t>(<{{nptype}}_t>low)
diff --git a/numpy/random/_common.pxd b/numpy/random/_common.pxd
index 4f404b7a1..9f2e8c3ca 100644
--- a/numpy/random/_common.pxd
+++ b/numpy/random/_common.pxd
@@ -39,7 +39,7 @@ cdef extern from "include/aligned_malloc.h":
cdef void *PyArray_calloc_aligned(size_t n, size_t s)
cdef void PyArray_free_aligned(void *p)
-ctypedef double (*random_double_fill)(bitgen_t *state, np.npy_intp count, double* out) nogil
+ctypedef void (*random_double_fill)(bitgen_t *state, np.npy_intp count, double* out) nogil
ctypedef double (*random_double_0)(void *state) nogil
ctypedef double (*random_double_1)(void *state, double a) nogil
ctypedef double (*random_double_2)(void *state, double a, double b) nogil
diff --git a/numpy/random/_common.pyx b/numpy/random/_common.pyx
index 6d77aed03..ad43f2812 100644
--- a/numpy/random/_common.pyx
+++ b/numpy/random/_common.pyx
@@ -25,11 +25,11 @@ cdef uint64_t MAXSIZE = <uint64_t>sys.maxsize
cdef object benchmark(bitgen_t *bitgen, object lock, Py_ssize_t cnt, object method):
"""Benchmark command used by BitGenerator"""
cdef Py_ssize_t i
- if method==u'uint64':
+ if method=='uint64':
with lock, nogil:
for i in range(cnt):
bitgen.next_uint64(bitgen.state)
- elif method==u'double':
+ elif method=='double':
with lock, nogil:
for i in range(cnt):
bitgen.next_double(bitgen.state)
@@ -121,8 +121,8 @@ cdef object prepare_cffi(bitgen_t *bitgen):
"""
try:
import cffi
- except ImportError:
- raise ImportError('cffi cannot be imported.')
+ except ImportError as e:
+ raise ImportError('cffi cannot be imported.') from e
ffi = cffi.FFI()
_cffi = interface(<uintptr_t>bitgen.state,
@@ -219,8 +219,8 @@ cdef np.ndarray int_to_array(object value, object name, object bits, object uint
cdef validate_output_shape(iter_shape, np.ndarray output):
- cdef np.npy_intp *shape
- cdef ndim, i
+ cdef np.npy_intp *dims
+ cdef np.npy_intp ndim, i
cdef bint error
dims = np.PyArray_DIMS(output)
ndim = np.PyArray_NDIM(output)
@@ -232,13 +232,34 @@ cdef validate_output_shape(iter_shape, np.ndarray output):
)
-cdef check_output(object out, object dtype, object size):
+cdef check_output(object out, object dtype, object size, bint require_c_array):
+ """
+ Check user-supplied output array properties and shape
+
+ Parameters
+ ----------
+ out : {ndarray, None}
+ The array to check. If None, returns immediately.
+ dtype : dtype
+ The required dtype of out.
+ size : {None, int, tuple[int]}
+ The size passed. If out is an ndarray, verifies that the shape of out
+ matches size.
+ require_c_array : bool
+ Whether out must be a C-array. If False, out can be either C- or F-
+ ordered. If True, must be C-ordered. In either case, must be
+ contiguous, writable, aligned and in native byte-order.
+ """
if out is None:
return
cdef np.ndarray out_array = <np.ndarray>out
- if not (np.PyArray_CHKFLAGS(out_array, np.NPY_CARRAY) or
- np.PyArray_CHKFLAGS(out_array, np.NPY_FARRAY)):
- raise ValueError('Supplied output array is not contiguous, writable or aligned.')
+ if not (np.PyArray_ISCARRAY(out_array) or
+ (np.PyArray_ISFARRAY(out_array) and not require_c_array)):
+ req = "C-" if require_c_array else ""
+ raise ValueError(
+ f'Supplied output array must be {req}contiguous, writable, '
+ f'aligned, and in machine byte-order.'
+ )
if out_array.dtype != dtype:
raise TypeError('Supplied output array has the wrong type. '
'Expected {0}, got {1}'.format(np.dtype(dtype), out_array.dtype))
@@ -264,7 +285,7 @@ cdef object double_fill(void *func, bitgen_t *state, object size, object lock, o
return out_val
if out is not None:
- check_output(out, np.float64, size)
+ check_output(out, np.float64, size, False)
out_array = <np.ndarray>out
else:
out_array = <np.ndarray>np.empty(size, np.double)
@@ -288,7 +309,7 @@ cdef object float_fill(void *func, bitgen_t *state, object size, object lock, ob
return out_val
if out is not None:
- check_output(out, np.float32, size)
+ check_output(out, np.float32, size, False)
out_array = <np.ndarray>out
else:
out_array = <np.ndarray>np.empty(size, np.float32)
@@ -310,7 +331,7 @@ cdef object float_fill_from_double(void *func, bitgen_t *state, object size, obj
return <float>random_func(state)
if out is not None:
- check_output(out, np.float32, size)
+ check_output(out, np.float32, size, False)
out_array = <np.ndarray>out
else:
out_array = <np.ndarray>np.empty(size, np.float32)
@@ -521,7 +542,7 @@ cdef object cont(void *func, void *state, object size, object lock, int narg,
cdef np.ndarray a_arr, b_arr, c_arr
cdef double _a = 0.0, _b = 0.0, _c = 0.0
cdef bint is_scalar = True
- check_output(out, np.float64, size)
+ check_output(out, np.float64, size, narg > 0)
if narg > 0:
a_arr = <np.ndarray>np.PyArray_FROM_OTF(a, np.NPY_DOUBLE, np.NPY_ALIGNED)
is_scalar = is_scalar and np.PyArray_NDIM(a_arr) == 0
@@ -971,7 +992,7 @@ cdef object cont_f(void *func, bitgen_t *state, object size, object lock,
cdef float _a
cdef bint is_scalar = True
cdef int requirements = np.NPY_ALIGNED | np.NPY_FORCECAST
- check_output(out, np.float32, size)
+ check_output(out, np.float32, size, True)
a_arr = <np.ndarray>np.PyArray_FROMANY(a, np.NPY_FLOAT32, 0, 0, requirements)
is_scalar = np.PyArray_NDIM(a_arr) == 0
diff --git a/numpy/random/_examples/cffi/parse.py b/numpy/random/_examples/cffi/parse.py
index 73d8646c7..daff6bdec 100644
--- a/numpy/random/_examples/cffi/parse.py
+++ b/numpy/random/_examples/cffi/parse.py
@@ -17,11 +17,20 @@ def parse_distributions_h(ffi, inc_dir):
continue
s.append(line)
ffi.cdef('\n'.join(s))
-
+
with open(os.path.join(inc_dir, 'random', 'distributions.h')) as fid:
s = []
in_skip = 0
+ ignoring = False
for line in fid:
+ # check for and remove extern "C" guards
+ if ignoring:
+ if line.strip().startswith('#endif'):
+ ignoring = False
+ continue
+ if line.strip().startswith('#ifdef __cplusplus'):
+ ignoring = True
+
# massage the include file
if line.strip().startswith('#'):
continue
diff --git a/numpy/random/_examples/cython/setup.py b/numpy/random/_examples/cython/setup.py
index 83f06fde8..7e0dd3e05 100644
--- a/numpy/random/_examples/cython/setup.py
+++ b/numpy/random/_examples/cython/setup.py
@@ -4,19 +4,20 @@ Build the Cython demonstrations of low-level access to NumPy random
Usage: python setup.py build_ext -i
"""
+from distutils.core import setup
+from os.path import dirname, join, abspath
import numpy as np
-from distutils.core import setup
from Cython.Build import cythonize
+from numpy.distutils.misc_util import get_info
from setuptools.extension import Extension
-from os.path import join, dirname
path = dirname(__file__)
src_dir = join(dirname(path), '..', 'src')
defs = [('NPY_NO_DEPRECATED_API', 0)]
inc_path = np.get_include()
-# not so nice. We need the random/lib library from numpy
-lib_path = join(np.get_include(), '..', '..', 'random', 'lib')
+lib_path = [abspath(join(np.get_include(), '..', '..', 'random', 'lib'))]
+lib_path += get_info('npymath')['library_dirs']
extending = Extension("extending",
sources=[join('.', 'extending.pyx')],
@@ -29,10 +30,10 @@ extending = Extension("extending",
distributions = Extension("extending_distributions",
sources=[join('.', 'extending_distributions.pyx')],
include_dirs=[inc_path],
- library_dirs=[lib_path],
- libraries=['npyrandom'],
+ library_dirs=lib_path,
+ libraries=['npyrandom', 'npymath'],
define_macros=defs,
- )
+ )
extensions = [extending, distributions]
diff --git a/numpy/random/_examples/numba/extending.py b/numpy/random/_examples/numba/extending.py
index da4d93944..f387db695 100644
--- a/numpy/random/_examples/numba/extending.py
+++ b/numpy/random/_examples/numba/extending.py
@@ -44,7 +44,7 @@ assert r1.shape == (n,)
assert r1.shape == r2.shape
t1 = timeit(numbacall, number=1000)
-+print(f'{t1:.2f} secs for {n} PCG64 (Numba/PCG64) gaussian randoms')
+print(f'{t1:.2f} secs for {n} PCG64 (Numba/PCG64) gaussian randoms')
t2 = timeit(numpycall, number=1000)
print(f'{t2:.2f} secs for {n} PCG64 (NumPy/PCG64) gaussian randoms')
diff --git a/numpy/random/_generator.pyi b/numpy/random/_generator.pyi
new file mode 100644
index 000000000..14dc55131
--- /dev/null
+++ b/numpy/random/_generator.pyi
@@ -0,0 +1,651 @@
+import sys
+from typing import Any, Callable, Dict, Optional, Tuple, Type, Union, overload, TypeVar
+
+from numpy import (
+ bool_,
+ dtype,
+ float32,
+ float64,
+ int8,
+ int16,
+ int32,
+ int64,
+ int_,
+ ndarray,
+ uint,
+ uint8,
+ uint16,
+ uint32,
+ uint64,
+)
+from numpy.random import BitGenerator, SeedSequence
+from numpy.typing import (
+ ArrayLike,
+ _ArrayLikeFloat_co,
+ _ArrayLikeInt_co,
+ _DoubleCodes,
+ _DTypeLikeBool,
+ _DTypeLikeInt,
+ _DTypeLikeUInt,
+ _Float32Codes,
+ _Float64Codes,
+ _Int8Codes,
+ _Int16Codes,
+ _Int32Codes,
+ _Int64Codes,
+ _IntCodes,
+ _ShapeLike,
+ _SingleCodes,
+ _SupportsDType,
+ _UInt8Codes,
+ _UInt16Codes,
+ _UInt32Codes,
+ _UInt64Codes,
+ _UIntCodes,
+)
+
+if sys.version_info >= (3, 8):
+ from typing import Literal
+else:
+ from typing_extensions import Literal
+
+_ArrayType = TypeVar("_ArrayType", bound=ndarray[Any, Any])
+
+_DTypeLikeFloat32 = Union[
+ dtype[float32],
+ _SupportsDType[dtype[float32]],
+ Type[float32],
+ _Float32Codes,
+ _SingleCodes,
+]
+
+_DTypeLikeFloat64 = Union[
+ dtype[float64],
+ _SupportsDType[dtype[float64]],
+ Type[float],
+ Type[float64],
+ _Float64Codes,
+ _DoubleCodes,
+]
+
+class Generator:
+ def __init__(self, bit_generator: BitGenerator) -> None: ...
+ def __repr__(self) -> str: ...
+ def __str__(self) -> str: ...
+ def __getstate__(self) -> Dict[str, Any]: ...
+ def __setstate__(self, state: Dict[str, Any]) -> None: ...
+ def __reduce__(self) -> Tuple[Callable[[str], Generator], Tuple[str], Dict[str, Any]]: ...
+ @property
+ def bit_generator(self) -> BitGenerator: ...
+ def bytes(self, length: int) -> bytes: ...
+ @overload
+ def standard_normal( # type: ignore[misc]
+ self,
+ size: None = ...,
+ dtype: Union[_DTypeLikeFloat32, _DTypeLikeFloat64] = ...,
+ out: None = ...,
+ ) -> float: ...
+ @overload
+ def standard_normal( # type: ignore[misc]
+ self,
+ size: _ShapeLike = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def standard_normal( # type: ignore[misc]
+ self,
+ *,
+ out: ndarray[Any, dtype[float64]] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def standard_normal( # type: ignore[misc]
+ self,
+ size: _ShapeLike = ...,
+ dtype: _DTypeLikeFloat32 = ...,
+ out: Optional[ndarray[Any, dtype[float32]]] = ...,
+ ) -> ndarray[Any, dtype[float32]]: ...
+ @overload
+ def standard_normal( # type: ignore[misc]
+ self,
+ size: _ShapeLike = ...,
+ dtype: _DTypeLikeFloat64 = ...,
+ out: Optional[ndarray[Any, dtype[float64]]] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def permutation(self, x: int, axis: int = ...) -> ndarray[Any, dtype[int64]]: ...
+ @overload
+ def permutation(self, x: ArrayLike, axis: int = ...) -> ndarray[Any, Any]: ...
+ @overload
+ def standard_exponential( # type: ignore[misc]
+ self,
+ size: None = ...,
+ dtype: Union[_DTypeLikeFloat32, _DTypeLikeFloat64] = ...,
+ method: Literal["zig", "inv"] = ...,
+ out: None = ...,
+ ) -> float: ...
+ @overload
+ def standard_exponential(
+ self,
+ size: _ShapeLike = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def standard_exponential(
+ self,
+ *,
+ out: ndarray[Any, dtype[float64]] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def standard_exponential(
+ self,
+ size: _ShapeLike = ...,
+ *,
+ method: Literal["zig", "inv"] = ...,
+ out: Optional[ndarray[Any, dtype[float64]]] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def standard_exponential(
+ self,
+ size: _ShapeLike = ...,
+ dtype: _DTypeLikeFloat32 = ...,
+ method: Literal["zig", "inv"] = ...,
+ out: Optional[ndarray[Any, dtype[float32]]] = ...,
+ ) -> ndarray[Any, dtype[float32]]: ...
+ @overload
+ def standard_exponential(
+ self,
+ size: _ShapeLike = ...,
+ dtype: _DTypeLikeFloat64 = ...,
+ method: Literal["zig", "inv"] = ...,
+ out: Optional[ndarray[Any, dtype[float64]]] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def random( # type: ignore[misc]
+ self,
+ size: None = ...,
+ dtype: Union[_DTypeLikeFloat32, _DTypeLikeFloat64] = ...,
+ out: None = ...,
+ ) -> float: ...
+ @overload
+ def random(
+ self,
+ *,
+ out: ndarray[Any, dtype[float64]] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def random(
+ self,
+ size: _ShapeLike = ...,
+ *,
+ out: Optional[ndarray[Any, dtype[float64]]] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def random(
+ self,
+ size: _ShapeLike = ...,
+ dtype: _DTypeLikeFloat32 = ...,
+ out: Optional[ndarray[Any, dtype[float32]]] = ...,
+ ) -> ndarray[Any, dtype[float32]]: ...
+ @overload
+ def random(
+ self,
+ size: _ShapeLike = ...,
+ dtype: _DTypeLikeFloat64 = ...,
+ out: Optional[ndarray[Any, dtype[float64]]] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def beta(self, a: float, b: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def beta(
+ self, a: _ArrayLikeFloat_co, b: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def exponential(self, scale: float = ..., size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def exponential(
+ self, scale: _ArrayLikeFloat_co = ..., size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def integers( # type: ignore[misc]
+ self,
+ low: int,
+ high: Optional[int] = ...,
+ ) -> int: ...
+ @overload
+ def integers( # type: ignore[misc]
+ self,
+ low: int,
+ high: Optional[int] = ...,
+ size: None = ...,
+ dtype: _DTypeLikeBool = ...,
+ endpoint: bool = ...,
+ ) -> bool: ...
+ @overload
+ def integers( # type: ignore[misc]
+ self,
+ low: int,
+ high: Optional[int] = ...,
+ size: None = ...,
+ dtype: Union[_DTypeLikeInt, _DTypeLikeUInt] = ...,
+ endpoint: bool = ...,
+ ) -> int: ...
+ @overload
+ def integers( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[int64]]: ...
+ @overload
+ def integers( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ dtype: _DTypeLikeBool = ...,
+ endpoint: bool = ...,
+ ) -> ndarray[Any, dtype[bool_]]: ...
+ @overload
+ def integers( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ dtype: Union[dtype[int8], Type[int8], _Int8Codes, _SupportsDType[dtype[int8]]] = ...,
+ endpoint: bool = ...,
+ ) -> ndarray[Any, dtype[int8]]: ...
+ @overload
+ def integers( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ dtype: Union[dtype[int16], Type[int16], _Int16Codes, _SupportsDType[dtype[int16]]] = ...,
+ endpoint: bool = ...,
+ ) -> ndarray[Any, dtype[int16]]: ...
+ @overload
+ def integers( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ dtype: Union[dtype[int32], Type[int32], _Int32Codes, _SupportsDType[dtype[int32]]] = ...,
+ endpoint: bool = ...,
+ ) -> ndarray[Any, dtype[Union[int32]]]: ...
+ @overload
+ def integers( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ dtype: Optional[
+ Union[dtype[int64], Type[int64], _Int64Codes, _SupportsDType[dtype[int64]]]
+ ] = ...,
+ endpoint: bool = ...,
+ ) -> ndarray[Any, dtype[int64]]: ...
+ @overload
+ def integers( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ dtype: Union[dtype[uint8], Type[uint8], _UInt8Codes, _SupportsDType[dtype[uint8]]] = ...,
+ endpoint: bool = ...,
+ ) -> ndarray[Any, dtype[uint8]]: ...
+ @overload
+ def integers( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ dtype: Union[
+ dtype[uint16], Type[uint16], _UInt16Codes, _SupportsDType[dtype[uint16]]
+ ] = ...,
+ endpoint: bool = ...,
+ ) -> ndarray[Any, dtype[Union[uint16]]]: ...
+ @overload
+ def integers( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ dtype: Union[
+ dtype[uint32], Type[uint32], _UInt32Codes, _SupportsDType[dtype[uint32]]
+ ] = ...,
+ endpoint: bool = ...,
+ ) -> ndarray[Any, dtype[uint32]]: ...
+ @overload
+ def integers( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ dtype: Union[
+ dtype[uint64], Type[uint64], _UInt64Codes, _SupportsDType[dtype[uint64]]
+ ] = ...,
+ endpoint: bool = ...,
+ ) -> ndarray[Any, dtype[uint64]]: ...
+ @overload
+ def integers( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ dtype: Union[
+ dtype[int_], Type[int], Type[int_], _IntCodes, _SupportsDType[dtype[int_]]
+ ] = ...,
+ endpoint: bool = ...,
+ ) -> ndarray[Any, dtype[int_]]: ...
+ @overload
+ def integers( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ dtype: Union[dtype[uint], Type[uint], _UIntCodes, _SupportsDType[dtype[uint]]] = ...,
+ endpoint: bool = ...,
+ ) -> ndarray[Any, dtype[uint]]: ...
+ # TODO: Use a TypeVar _T here to get away from Any output? Should be int->ndarray[Any,dtype[int64]], ArrayLike[_T] -> Union[_T, ndarray[Any,Any]]
+ @overload
+ def choice(
+ self,
+ a: int,
+ size: None = ...,
+ replace: bool = ...,
+ p: Optional[_ArrayLikeFloat_co] = ...,
+ axis: int = ...,
+ shuffle: bool = ...,
+ ) -> int: ...
+ @overload
+ def choice(
+ self,
+ a: int,
+ size: _ShapeLike = ...,
+ replace: bool = ...,
+ p: Optional[_ArrayLikeFloat_co] = ...,
+ axis: int = ...,
+ shuffle: bool = ...,
+ ) -> ndarray[Any, dtype[int64]]: ...
+ @overload
+ def choice(
+ self,
+ a: ArrayLike,
+ size: None = ...,
+ replace: bool = ...,
+ p: Optional[_ArrayLikeFloat_co] = ...,
+ axis: int = ...,
+ shuffle: bool = ...,
+ ) -> Any: ...
+ @overload
+ def choice(
+ self,
+ a: ArrayLike,
+ size: _ShapeLike = ...,
+ replace: bool = ...,
+ p: Optional[_ArrayLikeFloat_co] = ...,
+ axis: int = ...,
+ shuffle: bool = ...,
+ ) -> ndarray[Any, Any]: ...
+ @overload
+ def uniform(self, low: float = ..., high: float = ..., size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def uniform(
+ self,
+ low: _ArrayLikeFloat_co = ...,
+ high: _ArrayLikeFloat_co = ...,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def normal(self, loc: float = ..., scale: float = ..., size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def normal(
+ self,
+ loc: _ArrayLikeFloat_co = ...,
+ scale: _ArrayLikeFloat_co = ...,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def standard_gamma( # type: ignore[misc]
+ self,
+ shape: float,
+ size: None = ...,
+ dtype: Union[_DTypeLikeFloat32, _DTypeLikeFloat64] = ...,
+ out: None = ...,
+ ) -> float: ...
+ @overload
+ def standard_gamma(
+ self,
+ shape: _ArrayLikeFloat_co,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def standard_gamma(
+ self,
+ shape: _ArrayLikeFloat_co,
+ *,
+ out: ndarray[Any, dtype[float64]] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def standard_gamma(
+ self,
+ shape: _ArrayLikeFloat_co,
+ size: Optional[_ShapeLike] = ...,
+ dtype: _DTypeLikeFloat32 = ...,
+ out: Optional[ndarray[Any, dtype[float32]]] = ...,
+ ) -> ndarray[Any, dtype[float32]]: ...
+ @overload
+ def standard_gamma(
+ self,
+ shape: _ArrayLikeFloat_co,
+ size: Optional[_ShapeLike] = ...,
+ dtype: _DTypeLikeFloat64 = ...,
+ out: Optional[ndarray[Any, dtype[float64]]] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def gamma(self, shape: float, scale: float = ..., size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def gamma(
+ self,
+ shape: _ArrayLikeFloat_co,
+ scale: _ArrayLikeFloat_co = ...,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def f(self, dfnum: float, dfden: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def f(
+ self, dfnum: _ArrayLikeFloat_co, dfden: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def noncentral_f(self, dfnum: float, dfden: float, nonc: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def noncentral_f(
+ self,
+ dfnum: _ArrayLikeFloat_co,
+ dfden: _ArrayLikeFloat_co,
+ nonc: _ArrayLikeFloat_co,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def chisquare(self, df: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def chisquare(
+ self, df: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def noncentral_chisquare(self, df: float, nonc: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def noncentral_chisquare(
+ self, df: _ArrayLikeFloat_co, nonc: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def standard_t(self, df: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def standard_t(
+ self, df: _ArrayLikeFloat_co, size: None = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def standard_t(
+ self, df: _ArrayLikeFloat_co, size: _ShapeLike = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def vonmises(self, mu: float, kappa: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def vonmises(
+ self, mu: _ArrayLikeFloat_co, kappa: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def pareto(self, a: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def pareto(
+ self, a: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def weibull(self, a: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def weibull(
+ self, a: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def power(self, a: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def power(
+ self, a: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def standard_cauchy(self, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def standard_cauchy(self, size: _ShapeLike = ...) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def laplace(self, loc: float = ..., scale: float = ..., size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def laplace(
+ self,
+ loc: _ArrayLikeFloat_co = ...,
+ scale: _ArrayLikeFloat_co = ...,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def gumbel(self, loc: float = ..., scale: float = ..., size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def gumbel(
+ self,
+ loc: _ArrayLikeFloat_co = ...,
+ scale: _ArrayLikeFloat_co = ...,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def logistic(self, loc: float = ..., scale: float = ..., size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def logistic(
+ self,
+ loc: _ArrayLikeFloat_co = ...,
+ scale: _ArrayLikeFloat_co = ...,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def lognormal(self, mean: float = ..., sigma: float = ..., size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def lognormal(
+ self,
+ mean: _ArrayLikeFloat_co = ...,
+ sigma: _ArrayLikeFloat_co = ...,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def rayleigh(self, scale: float = ..., size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def rayleigh(
+ self, scale: _ArrayLikeFloat_co = ..., size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def wald(self, mean: float, scale: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def wald(
+ self, mean: _ArrayLikeFloat_co, scale: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def triangular(self, left: float, mode: float, right: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def triangular(
+ self,
+ left: _ArrayLikeFloat_co,
+ mode: _ArrayLikeFloat_co,
+ right: _ArrayLikeFloat_co,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def binomial(self, n: int, p: float, size: None = ...) -> int: ... # type: ignore[misc]
+ @overload
+ def binomial(
+ self, n: _ArrayLikeInt_co, p: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[int64]]: ...
+ @overload
+ def negative_binomial(self, n: float, p: float, size: None = ...) -> int: ... # type: ignore[misc]
+ @overload
+ def negative_binomial(
+ self, n: _ArrayLikeFloat_co, p: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[int64]]: ...
+ @overload
+ def poisson(self, lam: float = ..., size: None = ...) -> int: ... # type: ignore[misc]
+ @overload
+ def poisson(
+ self, lam: _ArrayLikeFloat_co = ..., size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[int64]]: ...
+ @overload
+ def zipf(self, a: float, size: None = ...) -> int: ... # type: ignore[misc]
+ @overload
+ def zipf(
+ self, a: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[int64]]: ...
+ @overload
+ def geometric(self, p: float, size: None = ...) -> int: ... # type: ignore[misc]
+ @overload
+ def geometric(
+ self, p: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[int64]]: ...
+ @overload
+ def hypergeometric(self, ngood: int, nbad: int, nsample: int, size: None = ...) -> int: ... # type: ignore[misc]
+ @overload
+ def hypergeometric(
+ self,
+ ngood: _ArrayLikeInt_co,
+ nbad: _ArrayLikeInt_co,
+ nsample: _ArrayLikeInt_co,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[int64]]: ...
+ @overload
+ def logseries(self, p: float, size: None = ...) -> int: ... # type: ignore[misc]
+ @overload
+ def logseries(
+ self, p: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[int64]]: ...
+ def multivariate_normal(
+ self,
+ mean: _ArrayLikeFloat_co,
+ cov: _ArrayLikeFloat_co,
+ size: Optional[_ShapeLike] = ...,
+ check_valid: Literal["warn", "raise", "ignore"] = ...,
+ tol: float = ...,
+ *,
+ method: Literal["svd", "eigh", "cholesky"] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ def multinomial(
+ self, n: _ArrayLikeInt_co, pvals: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[int64]]: ...
+ def multivariate_hypergeometric(
+ self,
+ colors: _ArrayLikeInt_co,
+ nsample: int,
+ size: Optional[_ShapeLike] = ...,
+ method: Literal["marginals", "count"] = ...,
+ ) -> ndarray[Any, dtype[int64]]: ...
+ def dirichlet(
+ self, alpha: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ def permuted(
+ self, x: ArrayLike, *, axis: Optional[int] = ..., out: Optional[ndarray[Any, Any]] = ...
+ ) -> ndarray[Any, Any]: ...
+ def shuffle(self, x: ArrayLike, axis: int = ...) -> None: ...
+
+def default_rng(
+ seed: Union[None, _ArrayLikeInt_co, SeedSequence, BitGenerator, Generator] = ...
+) -> Generator: ...
diff --git a/numpy/random/_generator.pyx b/numpy/random/_generator.pyx
index bff023d7f..e2430d139 100644
--- a/numpy/random/_generator.pyx
+++ b/numpy/random/_generator.pyx
@@ -2,6 +2,7 @@
#cython: wraparound=False, nonecheck=False, boundscheck=False, cdivision=True, language_level=3
import operator
import warnings
+from collections.abc import Sequence
from cpython.pycapsule cimport PyCapsule_IsValid, PyCapsule_GetPointer
from cpython cimport (Py_INCREF, PyFloat_AsDouble)
@@ -175,8 +176,8 @@ cdef class Generator:
Examples
--------
>>> from numpy.random import Generator, PCG64
- >>> rg = Generator(PCG64())
- >>> rg.standard_normal()
+ >>> rng = Generator(PCG64())
+ >>> rng.standard_normal()
-0.203 # random
See Also
@@ -385,7 +386,7 @@ cdef class Generator:
0.0, '', CONS_NONE,
None)
- def standard_exponential(self, size=None, dtype=np.float64, method=u'zig', out=None):
+ def standard_exponential(self, size=None, dtype=np.float64, method='zig', out=None):
"""
standard_exponential(size=None, dtype=np.float64, method='zig', out=None)
@@ -425,12 +426,12 @@ cdef class Generator:
"""
_dtype = np.dtype(dtype)
if _dtype == np.float64:
- if method == u'zig':
+ if method == 'zig':
return double_fill(&random_standard_exponential_fill, &self._bitgen, size, self.lock, out)
else:
return double_fill(&random_standard_exponential_inv_fill, &self._bitgen, size, self.lock, out)
elif _dtype == np.float32:
- if method == u'zig':
+ if method == 'zig':
return float_fill(&random_standard_exponential_fill_f, &self._bitgen, size, self.lock, out)
else:
return float_fill(&random_standard_exponential_inv_fill_f, &self._bitgen, size, self.lock, out)
@@ -578,13 +579,13 @@ cdef class Generator:
Returns
-------
- out : str
+ out : bytes
String of length `length`.
Examples
--------
>>> np.random.default_rng().bytes(10)
- ' eh\\x85\\x022SZ\\xbf\\xa4' #random
+ b'\\xfeC\\x9b\\x86\\x17\\xf2\\xa1\\xafcp' # random
"""
cdef Py_ssize_t n_uint32 = ((length - 1) // 4 + 1)
@@ -598,7 +599,7 @@ cdef class Generator:
"""
choice(a, size=None, replace=True, p=None, axis=0, shuffle=True)
- Generates a random sample from a given 1-D array
+ Generates a random sample from a given array
Parameters
----------
@@ -613,11 +614,12 @@ cdef class Generator:
len(size)``. Default is None, in which case a single value is
returned.
replace : bool, optional
- Whether the sample is with or without replacement
+ Whether the sample is with or without replacement. Default is True,
+ meaning that a value of ``a`` can be selected multiple times.
p : 1-D array_like, optional
The probabilities associated with each entry in a.
- If not given the sample assumes a uniform distribution over all
- entries in a.
+ If not given, the sample assumes a uniform distribution over all
+ entries in ``a``.
axis : int, optional
The axis along which the selection is performed. The default, 0,
selects by row.
@@ -643,6 +645,12 @@ cdef class Generator:
--------
integers, shuffle, permutation
+ Notes
+ -----
+ Setting user-specified probabilities through ``p`` uses a more general but less
+ efficient sampler than the default. The general sampler produces a different sample
+ than the optimized sampler even if each element of ``p`` is 1 / len(a).
+
Examples
--------
Generate a uniform random sample from np.arange(5) of size 3:
@@ -664,6 +672,13 @@ cdef class Generator:
array([3,1,0]) # random
>>> #This is equivalent to rng.permutation(np.arange(5))[:3]
+ Generate a uniform random sample from a 2-D array along the first
+ axis (the default), without replacement:
+
+ >>> rng.choice([[0, 1, 2], [3, 4, 5], [6, 7, 8]], 2, replace=False)
+ array([[3, 4, 5], # random
+ [0, 1, 2]])
+
Generate a non-uniform random sample from np.arange(5) of size
3 without replacement:
@@ -686,20 +701,22 @@ cdef class Generator:
cdef uint64_t set_size, mask
cdef uint64_t[::1] hash_set
# Format and Verify input
+ a_original = a
a = np.array(a, copy=False)
if a.ndim == 0:
try:
# __index__ must return an integer by python rules.
pop_size = operator.index(a.item())
- except TypeError:
- raise ValueError("a must an array or an integer")
+ except TypeError as exc:
+ raise ValueError("a must be a sequence or an integer, "
+ f"not {type(a_original)}") from exc
if pop_size <= 0 and np.prod(size) != 0:
- raise ValueError("a must be a positive integer unless no"
+ raise ValueError("a must be a positive integer unless no "
"samples are taken")
else:
pop_size = a.shape[axis]
if pop_size == 0 and np.prod(size) != 0:
- raise ValueError("a cannot be empty unless no samples are"
+ raise ValueError("a cannot be empty unless no samples are "
"taken")
if p is not None:
@@ -859,7 +876,8 @@ cdef class Generator:
greater than or equal to low. The default value is 0.
high : float or array_like of floats
Upper boundary of the output interval. All values generated will be
- less than high. The default value is 1.0.
+ less than high. high - low must be non-negative. The default value
+ is 1.0.
size : int or tuple of ints, optional
Output shape. If the given shape is, e.g., ``(m, n, k)``, then
``m * n * k`` samples are drawn. If size is ``None`` (default),
@@ -885,10 +903,6 @@ cdef class Generator:
anywhere within the interval ``[a, b)``, and zero elsewhere.
When ``high`` == ``low``, values of ``low`` will be returned.
- If ``high`` < ``low``, the results are officially undefined
- and may eventually raise an error, i.e. do not rely on this
- function to behave when passed arguments satisfying that
- inequality condition.
Examples
--------
@@ -914,7 +928,7 @@ cdef class Generator:
"""
cdef bint is_scalar = True
cdef np.ndarray alow, ahigh, arange
- cdef double _low, _high, range
+ cdef double _low, _high, rng
cdef object temp
alow = <np.ndarray>np.PyArray_FROM_OTF(low, np.NPY_DOUBLE, np.NPY_ALIGNED)
@@ -923,13 +937,13 @@ cdef class Generator:
if np.PyArray_NDIM(alow) == np.PyArray_NDIM(ahigh) == 0:
_low = PyFloat_AsDouble(low)
_high = PyFloat_AsDouble(high)
- range = _high - _low
- if not np.isfinite(range):
- raise OverflowError('Range exceeds valid bounds')
+ rng = _high - _low
+ if not np.isfinite(rng):
+ raise OverflowError('high - low range exceeds valid bounds')
return cont(&random_uniform, &self._bitgen, size, self.lock, 2,
_low, '', CONS_NONE,
- range, '', CONS_NONE,
+ rng, 'high - low', CONS_NON_NEGATIVE,
0.0, '', CONS_NONE,
None)
@@ -943,7 +957,7 @@ cdef class Generator:
raise OverflowError('Range exceeds valid bounds')
return cont(&random_uniform, &self._bitgen, size, self.lock, 2,
alow, '', CONS_NONE,
- arange, '', CONS_NONE,
+ arange, 'high - low', CONS_NON_NEGATIVE,
0.0, '', CONS_NONE,
None)
@@ -984,14 +998,14 @@ cdef class Generator:
-----
For random samples from :math:`N(\\mu, \\sigma^2)`, use one of::
- mu + sigma * gen.standard_normal(size=...)
- gen.normal(mu, sigma, size=...)
+ mu + sigma * rng.standard_normal(size=...)
+ rng.normal(mu, sigma, size=...)
Examples
--------
>>> rng = np.random.default_rng()
>>> rng.standard_normal()
- 2.1923875335537315 #random
+ 2.1923875335537315 # random
>>> s = rng.standard_normal(8000)
>>> s
@@ -1095,7 +1109,7 @@ cdef class Generator:
0.0 # may vary
>>> abs(sigma - np.std(s, ddof=1))
- 0.1 # may vary
+ 0.0 # may vary
Display the histogram of the samples, along with
the probability density function:
@@ -1727,33 +1741,45 @@ cdef class Generator:
... 7515, 8230, 8770])
Does their energy intake deviate systematically from the recommended
- value of 7725 kJ?
-
- We have 10 degrees of freedom, so is the sample mean within 95% of the
- recommended value?
+ value of 7725 kJ? Our null hypothesis will be the absence of deviation,
+ and the alternate hypothesis will be the presence of an effect that could be
+ either positive or negative, hence making our test 2-tailed.
+
+ Because we are estimating the mean and we have N=11 values in our sample,
+ we have N-1=10 degrees of freedom. We set our significance level to 95% and
+ compute the t statistic using the empirical mean and empirical standard
+ deviation of our intake. We use a ddof of 1 to base the computation of our
+ empirical standard deviation on an unbiased estimate of the variance (note:
+ the final estimate is not unbiased due to the concave nature of the square
+ root).
- >>> s = np.random.default_rng().standard_t(10, size=100000)
>>> np.mean(intake)
6753.636363636364
>>> intake.std(ddof=1)
1142.1232221373727
+ >>> t = (np.mean(intake)-7725)/(intake.std(ddof=1)/np.sqrt(len(intake)))
+ >>> t
+ -2.8207540608310198
- Calculate the t statistic, setting the ddof parameter to the unbiased
- value so the divisor in the standard deviation will be degrees of
- freedom, N-1.
+ We draw 1000000 samples from Student's t distribution with the adequate
+ degrees of freedom.
- >>> t = (np.mean(intake)-7725)/(intake.std(ddof=1)/np.sqrt(len(intake)))
>>> import matplotlib.pyplot as plt
+ >>> s = np.random.default_rng().standard_t(10, size=1000000)
>>> h = plt.hist(s, bins=100, density=True)
- For a one-sided t-test, how far out in the distribution does the t
- statistic appear?
+ Does our t statistic land in one of the two critical regions found at
+ both tails of the distribution?
+
+ >>> np.sum(np.abs(t) < np.abs(s)) / float(len(s))
+ 0.018318 #random < 0.05, statistic is in critical region
- >>> np.sum(s<t) / float(len(s))
- 0.0090699999999999999 #random
+ The probability value for this 2-tailed test is about 1.83%, which is
+ lower than the 5% pre-determined significance threshold.
- So the p-value is about 0.009, which says the null hypothesis has a
- probability of about 99% of being true.
+ Therefore, the probability of observing values as extreme as our intake
+ conditionally on the null hypothesis being true is too low, and we reject
+ the null hypothesis of no deviation.
"""
return cont(&random_standard_t, &self._bitgen, size, self.lock, 1,
@@ -3008,8 +3034,9 @@ cdef class Generator:
Parameters
----------
lam : float or array_like of floats
- Expectation of interval, must be >= 0. A sequence of expectation
- intervals must be broadcastable over the requested size.
+ Expected number of events occurring in a fixed-time interval,
+ must be >= 0. A sequence must be broadcastable over the requested
+ size.
size : int or tuple of ints, optional
Output shape. If the given shape is, e.g., ``(m, n, k)``, then
``m * n * k`` samples are drawn. If size is ``None`` (default),
@@ -3191,7 +3218,7 @@ cdef class Generator:
How many trials succeeded after a single run?
>>> (z == 1).sum() / 10000.
- 0.34889999999999999 #random
+ 0.34889999999999999 # random
"""
return disc(&random_geometric, &self._bitgen, size, self.lock, 1, 0,
@@ -3732,7 +3759,20 @@ cdef class Generator:
pix = <double*>np.PyArray_DATA(parr)
check_array_constraint(parr, 'pvals', CONS_BOUNDED_0_1)
if kahan_sum(pix, d-1) > (1.0 + 1e-12):
- raise ValueError("sum(pvals[:-1]) > 1.0")
+ # When floating, but not float dtype, and close, improve the error
+ # 1.0001 works for float16 and float32
+ if (isinstance(pvals, np.ndarray)
+ and np.issubdtype(pvals.dtype, np.floating)
+ and pvals.dtype != float
+ and pvals.sum() < 1.0001):
+ msg = ("sum(pvals[:-1].astype(np.float64)) > 1.0. The pvals "
+ "array is cast to 64-bit floating point prior to "
+ "checking the sum. Precision changes when casting may "
+ "cause problems even if the sum of the original pvals "
+ "is valid.")
+ else:
+ msg = "sum(pvals[:-1]) > 1.0"
+ raise ValueError(msg)
if np.PyArray_NDIM(on) != 0: # vector
check_array_constraint(on, 'n', CONS_NON_NEGATIVE)
@@ -4023,7 +4063,7 @@ cdef class Generator:
The drawn samples, of shape ``(size, k)``.
Raises
- -------
+ ------
ValueError
If any value in ``alpha`` is less than or equal to zero
@@ -4350,14 +4390,14 @@ cdef class Generator:
"""
shuffle(x, axis=0)
- Modify a sequence in-place by shuffling its contents.
+ Modify an array or sequence in-place by shuffling its contents.
The order of sub-arrays is changed but their contents remains the same.
Parameters
----------
- x : array_like
- The array or list to be shuffled.
+ x : ndarray or MutableSequence
+ The array, list or mutable sequence to be shuffled.
axis : int, optional
The axis which `x` is shuffled along. Default is 0.
It is only supported on `ndarray` objects.
@@ -4393,7 +4433,9 @@ cdef class Generator:
char* x_ptr
char* buf_ptr
- axis = normalize_axis_index(axis, np.ndim(x))
+ if isinstance(x, np.ndarray):
+ # Only call ndim on ndarrays, see GH 18142
+ axis = normalize_axis_index(axis, np.ndim(x))
if type(x) is np.ndarray and x.ndim == 1 and x.size:
# Fast, statically typed path: shuffle the underlying buffer.
@@ -4417,7 +4459,11 @@ cdef class Generator:
with self.lock, nogil:
_shuffle_raw_wrap(&self._bitgen, n, 1, itemsize, stride,
x_ptr, buf_ptr)
- elif isinstance(x, np.ndarray) and x.ndim and x.size:
+ elif isinstance(x, np.ndarray):
+ if x.size == 0:
+ # shuffling is a no-op
+ return
+
x = np.swapaxes(x, 0, axis)
buf = np.empty_like(x[0, ...])
with self.lock:
@@ -4426,11 +4472,21 @@ cdef class Generator:
if i == j:
# i == j is not needed and memcpy is undefined.
continue
- buf[...] = x[j]
- x[j] = x[i]
- x[i] = buf
+ buf[...] = x[j, ...]
+ x[j, ...] = x[i, ...]
+ x[i, ...] = buf
else:
# Untyped path.
+ if not isinstance(x, Sequence):
+ # See gh-18206. We may decide to deprecate here in the future.
+ warnings.warn(
+ f"you are shuffling a '{type(x).__name__}' object "
+ "which is not a subclass of 'Sequence'; "
+ "`shuffle` is not guaranteed to behave correctly. "
+ "E.g., non-numpy array/tensor objects with view semantics "
+ "may contain duplicates after shuffling.",
+ UserWarning, stacklevel=1) # Cython does not add a level
+
if axis != 0:
raise NotImplementedError("Axis argument is only supported "
"on ndarray objects")
@@ -4537,7 +4593,7 @@ def default_rng(seed=None):
Examples
--------
- ``default_rng`` is the reccomended constructor for the random number class
+ ``default_rng`` is the recommended constructor for the random number class
``Generator``. Here are several ways we can construct a random
number generator using ``default_rng`` and the ``Generator`` class.
diff --git a/numpy/random/_mt19937.pyi b/numpy/random/_mt19937.pyi
new file mode 100644
index 000000000..1b8bacdae
--- /dev/null
+++ b/numpy/random/_mt19937.pyi
@@ -0,0 +1,28 @@
+import sys
+from typing import Any, Union
+
+from numpy import dtype, ndarray, uint32
+from numpy.random.bit_generator import BitGenerator, SeedSequence
+from numpy.typing import _ArrayLikeInt_co
+
+if sys.version_info >= (3, 8):
+ from typing import TypedDict
+else:
+ from typing_extensions import TypedDict
+
+class _MT19937Internal(TypedDict):
+ key: ndarray[Any, dtype[uint32]]
+ pos: int
+
+class _MT19937State(TypedDict):
+ bit_generator: str
+ state: _MT19937Internal
+
+class MT19937(BitGenerator):
+ def __init__(self, seed: Union[None, _ArrayLikeInt_co, SeedSequence] = ...) -> None: ...
+ def _legacy_seeding(self, seed: _ArrayLikeInt_co) -> None: ...
+ def jumped(self, jumps: int = ...) -> MT19937: ...
+ @property
+ def state(self) -> _MT19937State: ...
+ @state.setter
+ def state(self, value: _MT19937State) -> None: ...
diff --git a/numpy/random/_pcg64.pyi b/numpy/random/_pcg64.pyi
new file mode 100644
index 000000000..25e2fdde6
--- /dev/null
+++ b/numpy/random/_pcg64.pyi
@@ -0,0 +1,48 @@
+import sys
+from typing import Union
+
+from numpy.random.bit_generator import BitGenerator, SeedSequence
+from numpy.typing import _ArrayLikeInt_co
+
+if sys.version_info >= (3, 8):
+ from typing import TypedDict
+else:
+ from typing_extensions import TypedDict
+
+class _PCG64Internal(TypedDict):
+ state: int
+ inc: int
+
+class _PCG64State(TypedDict):
+ bit_generator: str
+ state: _PCG64Internal
+ has_uint32: int
+ uinteger: int
+
+class PCG64(BitGenerator):
+ def __init__(self, seed: Union[None, _ArrayLikeInt_co, SeedSequence] = ...) -> None: ...
+ def jumped(self, jumps: int = ...) -> PCG64: ...
+ @property
+ def state(
+ self,
+ ) -> _PCG64State: ...
+ @state.setter
+ def state(
+ self,
+ value: _PCG64State,
+ ) -> None: ...
+ def advance(self, delta: int) -> PCG64: ...
+
+class PCG64DXSM(BitGenerator):
+ def __init__(self, seed: Union[None, _ArrayLikeInt_co, SeedSequence] = ...) -> None: ...
+ def jumped(self, jumps: int = ...) -> PCG64DXSM: ...
+ @property
+ def state(
+ self,
+ ) -> _PCG64State: ...
+ @state.setter
+ def state(
+ self,
+ value: _PCG64State,
+ ) -> None: ...
+ def advance(self, delta: int) -> PCG64DXSM: ...
diff --git a/numpy/random/_pcg64.pyx b/numpy/random/_pcg64.pyx
index 605aae4bc..c0a10a812 100644
--- a/numpy/random/_pcg64.pyx
+++ b/numpy/random/_pcg64.pyx
@@ -26,6 +26,10 @@ cdef extern from "src/pcg64/pcg64.h":
void pcg64_get_state(pcg64_state *state, uint64_t *state_arr, int *has_uint32, uint32_t *uinteger)
void pcg64_set_state(pcg64_state *state, uint64_t *state_arr, int has_uint32, uint32_t uinteger)
+ uint64_t pcg64_cm_next64(pcg64_state *state) nogil
+ uint32_t pcg64_cm_next32(pcg64_state *state) nogil
+ void pcg64_cm_advance(pcg64_state *state, uint64_t *step)
+
cdef uint64_t pcg64_uint64(void* st) nogil:
return pcg64_next64(<pcg64_state *>st)
@@ -35,6 +39,14 @@ cdef uint32_t pcg64_uint32(void *st) nogil:
cdef double pcg64_double(void* st) nogil:
return uint64_to_double(pcg64_next64(<pcg64_state *>st))
+cdef uint64_t pcg64_cm_uint64(void* st) nogil:
+ return pcg64_cm_next64(<pcg64_state *>st)
+
+cdef uint32_t pcg64_cm_uint32(void *st) nogil:
+ return pcg64_cm_next32(<pcg64_state *> st)
+
+cdef double pcg64_cm_double(void* st) nogil:
+ return uint64_to_double(pcg64_cm_next64(<pcg64_state *>st))
cdef class PCG64(BitGenerator):
"""
@@ -90,7 +102,7 @@ cdef class PCG64(BitGenerator):
**Compatibility Guarantee**
- ``PCG64`` makes a guarantee that a fixed seed and will always produce
+ ``PCG64`` makes a guarantee that a fixed seed will always produce
the same random integer stream.
References
@@ -268,3 +280,239 @@ cdef class PCG64(BitGenerator):
pcg64_advance(&self.rng_state, <uint64_t *>np.PyArray_DATA(d))
self._reset_state_variables()
return self
+
+
+cdef class PCG64DXSM(BitGenerator):
+ """
+ PCG64DXSM(seed=None)
+
+ BitGenerator for the PCG-64 DXSM pseudo-random number generator.
+
+ Parameters
+ ----------
+ seed : {None, int, array_like[ints], SeedSequence}, optional
+ A seed to initialize the `BitGenerator`. If None, then fresh,
+ unpredictable entropy will be pulled from the OS. If an ``int`` or
+ ``array_like[ints]`` is passed, then it will be passed to
+ `SeedSequence` to derive the initial `BitGenerator` state. One may also
+ pass in a `SeedSequence` instance.
+
+ Notes
+ -----
+ PCG-64 DXSM is a 128-bit implementation of O'Neill's permutation congruential
+ generator ([1]_, [2]_). PCG-64 DXSM has a period of :math:`2^{128}` and supports
+ advancing an arbitrary number of steps as well as :math:`2^{127}` streams.
+ The specific member of the PCG family that we use is PCG CM DXSM 128/64. It
+ differs from ``PCG64`` in that it uses the stronger DXSM output function,
+ a 64-bit "cheap multiplier" in the LCG, and outputs from the state before
+ advancing it rather than advance-then-output.
+
+ ``PCG64DXSM`` provides a capsule containing function pointers that produce
+ doubles, and unsigned 32 and 64- bit integers. These are not
+ directly consumable in Python and must be consumed by a ``Generator``
+ or similar object that supports low-level access.
+
+ Supports the method :meth:`advance` to advance the RNG an arbitrary number of
+ steps. The state of the PCG-64 DXSM RNG is represented by 2 128-bit unsigned
+ integers.
+
+ **State and Seeding**
+
+ The ``PCG64DXSM`` state vector consists of 2 unsigned 128-bit values,
+ which are represented externally as Python ints. One is the state of the
+ PRNG, which is advanced by a linear congruential generator (LCG). The
+ second is a fixed odd increment used in the LCG.
+
+ The input seed is processed by `SeedSequence` to generate both values. The
+ increment is not independently settable.
+
+ **Parallel Features**
+
+ The preferred way to use a BitGenerator in parallel applications is to use
+ the `SeedSequence.spawn` method to obtain entropy values, and to use these
+ to generate new BitGenerators:
+
+ >>> from numpy.random import Generator, PCG64DXSM, SeedSequence
+ >>> sg = SeedSequence(1234)
+ >>> rg = [Generator(PCG64DXSM(s)) for s in sg.spawn(10)]
+
+ **Compatibility Guarantee**
+
+ ``PCG64DXSM`` makes a guarantee that a fixed seed will always produce
+ the same random integer stream.
+
+ References
+ ----------
+ .. [1] `"PCG, A Family of Better Random Number Generators"
+ <http://www.pcg-random.org/>`_
+ .. [2] O'Neill, Melissa E. `"PCG: A Family of Simple Fast Space-Efficient
+ Statistically Good Algorithms for Random Number Generation"
+ <https://www.cs.hmc.edu/tr/hmc-cs-2014-0905.pdf>`_
+ """
+ cdef pcg64_state rng_state
+ cdef pcg64_random_t pcg64_random_state
+
+ def __init__(self, seed=None):
+ BitGenerator.__init__(self, seed)
+ self.rng_state.pcg_state = &self.pcg64_random_state
+
+ self._bitgen.state = <void *>&self.rng_state
+ self._bitgen.next_uint64 = &pcg64_cm_uint64
+ self._bitgen.next_uint32 = &pcg64_cm_uint32
+ self._bitgen.next_double = &pcg64_cm_double
+ self._bitgen.next_raw = &pcg64_cm_uint64
+ # Seed the _bitgen
+ val = self._seed_seq.generate_state(4, np.uint64)
+ pcg64_set_seed(&self.rng_state,
+ <uint64_t *>np.PyArray_DATA(val),
+ (<uint64_t *>np.PyArray_DATA(val) + 2))
+ self._reset_state_variables()
+
+ cdef _reset_state_variables(self):
+ self.rng_state.has_uint32 = 0
+ self.rng_state.uinteger = 0
+
+ cdef jump_inplace(self, jumps):
+ """
+ Jump state in-place
+ Not part of public API
+
+ Parameters
+ ----------
+ jumps : integer, positive
+ Number of times to jump the state of the rng.
+
+ Notes
+ -----
+ The step size is phi-1 when multiplied by 2**128 where phi is the
+ golden ratio.
+ """
+ step = 0x9e3779b97f4a7c15f39cc0605cedc835
+ self.advance(step * int(jumps))
+
+ def jumped(self, jumps=1):
+ """
+ jumped(jumps=1)
+
+ Returns a new bit generator with the state jumped.
+
+ Jumps the state as-if jumps * 210306068529402873165736369884012333109
+ random numbers have been generated.
+
+ Parameters
+ ----------
+ jumps : integer, positive
+ Number of times to jump the state of the bit generator returned
+
+ Returns
+ -------
+ bit_generator : PCG64DXSM
+ New instance of generator jumped iter times
+
+ Notes
+ -----
+ The step size is phi-1 when multiplied by 2**128 where phi is the
+ golden ratio.
+ """
+ cdef PCG64DXSM bit_generator
+
+ bit_generator = self.__class__()
+ bit_generator.state = self.state
+ bit_generator.jump_inplace(jumps)
+
+ return bit_generator
+
+ @property
+ def state(self):
+ """
+ Get or set the PRNG state
+
+ Returns
+ -------
+ state : dict
+ Dictionary containing the information required to describe the
+ state of the PRNG
+ """
+ cdef np.ndarray state_vec
+ cdef int has_uint32
+ cdef uint32_t uinteger
+
+ # state_vec is state.high, state.low, inc.high, inc.low
+ state_vec = <np.ndarray>np.empty(4, dtype=np.uint64)
+ pcg64_get_state(&self.rng_state,
+ <uint64_t *>np.PyArray_DATA(state_vec),
+ &has_uint32, &uinteger)
+ state = int(state_vec[0]) * 2**64 + int(state_vec[1])
+ inc = int(state_vec[2]) * 2**64 + int(state_vec[3])
+ return {'bit_generator': self.__class__.__name__,
+ 'state': {'state': state, 'inc': inc},
+ 'has_uint32': has_uint32,
+ 'uinteger': uinteger}
+
+ @state.setter
+ def state(self, value):
+ cdef np.ndarray state_vec
+ cdef int has_uint32
+ cdef uint32_t uinteger
+ if not isinstance(value, dict):
+ raise TypeError('state must be a dict')
+ bitgen = value.get('bit_generator', '')
+ if bitgen != self.__class__.__name__:
+ raise ValueError('state must be for a {0} '
+ 'RNG'.format(self.__class__.__name__))
+ state_vec = <np.ndarray>np.empty(4, dtype=np.uint64)
+ state_vec[0] = value['state']['state'] // 2 ** 64
+ state_vec[1] = value['state']['state'] % 2 ** 64
+ state_vec[2] = value['state']['inc'] // 2 ** 64
+ state_vec[3] = value['state']['inc'] % 2 ** 64
+ has_uint32 = value['has_uint32']
+ uinteger = value['uinteger']
+ pcg64_set_state(&self.rng_state,
+ <uint64_t *>np.PyArray_DATA(state_vec),
+ has_uint32, uinteger)
+
+ def advance(self, delta):
+ """
+ advance(delta)
+
+ Advance the underlying RNG as-if delta draws have occurred.
+
+ Parameters
+ ----------
+ delta : integer, positive
+ Number of draws to advance the RNG. Must be less than the
+ size state variable in the underlying RNG.
+
+ Returns
+ -------
+ self : PCG64
+ RNG advanced delta steps
+
+ Notes
+ -----
+ Advancing a RNG updates the underlying RNG state as-if a given
+ number of calls to the underlying RNG have been made. In general
+ there is not a one-to-one relationship between the number output
+ random values from a particular distribution and the number of
+ draws from the core RNG. This occurs for two reasons:
+
+ * The random values are simulated using a rejection-based method
+ and so, on average, more than one value from the underlying
+ RNG is required to generate an single draw.
+ * The number of bits required to generate a simulated value
+ differs from the number of bits generated by the underlying
+ RNG. For example, two 16-bit integer values can be simulated
+ from a single draw of a 32-bit RNG.
+
+ Advancing the RNG state resets any pre-computed random numbers.
+ This is required to ensure exact reproducibility.
+ """
+ delta = wrap_int(delta, 128)
+
+ cdef np.ndarray d = np.empty(2, dtype=np.uint64)
+ d[0] = delta // 2**64
+ d[1] = delta % 2**64
+ pcg64_cm_advance(&self.rng_state, <uint64_t *>np.PyArray_DATA(d))
+ self._reset_state_variables()
+ return self
+
diff --git a/numpy/random/_philox.pyi b/numpy/random/_philox.pyi
new file mode 100644
index 000000000..f6a5b9b9b
--- /dev/null
+++ b/numpy/random/_philox.pyi
@@ -0,0 +1,42 @@
+import sys
+from typing import Any, Union
+
+from numpy import dtype, ndarray, uint64
+from numpy.random.bit_generator import BitGenerator, SeedSequence
+from numpy.typing import _ArrayLikeInt_co
+
+if sys.version_info >= (3, 8):
+ from typing import TypedDict
+else:
+ from typing_extensions import TypedDict
+
+class _PhiloxInternal(TypedDict):
+ counter: ndarray[Any, dtype[uint64]]
+ key: ndarray[Any, dtype[uint64]]
+
+class _PhiloxState(TypedDict):
+ bit_generator: str
+ state: _PhiloxInternal
+ buffer: ndarray[Any, dtype[uint64]]
+ buffer_pos: int
+ has_uint32: int
+ uinteger: int
+
+class Philox(BitGenerator):
+ def __init__(
+ self,
+ seed: Union[None, _ArrayLikeInt_co, SeedSequence] = ...,
+ counter: Union[None, _ArrayLikeInt_co] = ...,
+ key: Union[None, _ArrayLikeInt_co] = ...,
+ ) -> None: ...
+ @property
+ def state(
+ self,
+ ) -> _PhiloxState: ...
+ @state.setter
+ def state(
+ self,
+ value: _PhiloxState,
+ ) -> None: ...
+ def jumped(self, jumps: int = ...) -> Philox: ...
+ def advance(self, delta: int) -> Philox: ...
diff --git a/numpy/random/_philox.pyx b/numpy/random/_philox.pyx
index 7e8880490..0fe8ebd7c 100644
--- a/numpy/random/_philox.pyx
+++ b/numpy/random/_philox.pyx
@@ -1,10 +1,5 @@
from cpython.pycapsule cimport PyCapsule_New
-try:
- from threading import Lock
-except ImportError:
- from dummy_threading import Lock
-
import numpy as np
cimport numpy as np
diff --git a/numpy/random/_pickle.py b/numpy/random/_pickle.py
index 29ff69644..a32f64f4a 100644
--- a/numpy/random/_pickle.py
+++ b/numpy/random/_pickle.py
@@ -1,6 +1,6 @@
from .mtrand import RandomState
from ._philox import Philox
-from ._pcg64 import PCG64
+from ._pcg64 import PCG64, PCG64DXSM
from ._sfc64 import SFC64
from ._generator import Generator
@@ -8,6 +8,7 @@ from ._mt19937 import MT19937
BitGenerators = {'MT19937': MT19937,
'PCG64': PCG64,
+ 'PCG64DXSM': PCG64DXSM,
'Philox': Philox,
'SFC64': SFC64,
}
@@ -19,7 +20,7 @@ def __generator_ctor(bit_generator_name='MT19937'):
Parameters
----------
- bit_generator_name: str
+ bit_generator_name : str
String containing the core BitGenerator
Returns
@@ -42,7 +43,7 @@ def __bit_generator_ctor(bit_generator_name='MT19937'):
Parameters
----------
- bit_generator_name: str
+ bit_generator_name : str
String containing the name of the BitGenerator
Returns
@@ -65,7 +66,7 @@ def __randomstate_ctor(bit_generator_name='MT19937'):
Parameters
----------
- bit_generator_name: str
+ bit_generator_name : str
String containing the core BitGenerator
Returns
diff --git a/numpy/random/_sfc64.pyi b/numpy/random/_sfc64.pyi
new file mode 100644
index 000000000..72a271c92
--- /dev/null
+++ b/numpy/random/_sfc64.pyi
@@ -0,0 +1,34 @@
+import sys
+from typing import Any, Union
+
+from numpy import dtype as dtype
+from numpy import ndarray as ndarray
+from numpy import uint64
+from numpy.random.bit_generator import BitGenerator, SeedSequence
+from numpy.typing import _ArrayLikeInt_co
+
+if sys.version_info >= (3, 8):
+ from typing import TypedDict
+else:
+ from typing_extensions import TypedDict
+
+class _SFC64Internal(TypedDict):
+ state: ndarray[Any, dtype[uint64]]
+
+class _SFC64State(TypedDict):
+ bit_generator: str
+ state: _SFC64Internal
+ has_uint32: int
+ uinteger: int
+
+class SFC64(BitGenerator):
+ def __init__(self, seed: Union[None, _ArrayLikeInt_co, SeedSequence] = ...) -> None: ...
+ @property
+ def state(
+ self,
+ ) -> _SFC64State: ...
+ @state.setter
+ def state(
+ self,
+ value: _SFC64State,
+ ) -> None: ...
diff --git a/numpy/random/bit_generator.pyi b/numpy/random/bit_generator.pyi
new file mode 100644
index 000000000..5b68dde6c
--- /dev/null
+++ b/numpy/random/bit_generator.pyi
@@ -0,0 +1,121 @@
+import abc
+import sys
+from threading import Lock
+from typing import (
+ Any,
+ Callable,
+ Dict,
+ List,
+ Mapping,
+ NamedTuple,
+ Optional,
+ Sequence,
+ Tuple,
+ Type,
+ TypedDict,
+ TypeVar,
+ Union,
+ overload,
+)
+
+from numpy import dtype, ndarray, uint32, uint64
+from numpy.typing import _ArrayLikeInt_co, _ShapeLike, _SupportsDType, _UInt32Codes, _UInt64Codes
+
+if sys.version_info >= (3, 8):
+ from typing import Literal
+else:
+ from typing_extensions import Literal
+
+_T = TypeVar("_T")
+
+_DTypeLikeUint32 = Union[
+ dtype[uint32],
+ _SupportsDType[dtype[uint32]],
+ Type[uint32],
+ _UInt32Codes,
+]
+_DTypeLikeUint64 = Union[
+ dtype[uint64],
+ _SupportsDType[dtype[uint64]],
+ Type[uint64],
+ _UInt64Codes,
+]
+
+class _SeedSeqState(TypedDict):
+ entropy: Union[None, int, Sequence[int]]
+ spawn_key: Tuple[int, ...]
+ pool_size: int
+ n_children_spawned: int
+
+class _Interface(NamedTuple):
+ state_address: Any
+ state: Any
+ next_uint64: Any
+ next_uint32: Any
+ next_double: Any
+ bit_generator: Any
+
+class ISeedSequence(abc.ABC):
+ @abc.abstractmethod
+ def generate_state(
+ self, n_words: int, dtype: Union[_DTypeLikeUint32, _DTypeLikeUint64] = ...
+ ) -> ndarray[Any, dtype[Union[uint32, uint64]]]: ...
+
+class ISpawnableSeedSequence(ISeedSequence):
+ @abc.abstractmethod
+ def spawn(self: _T, n_children: int) -> List[_T]: ...
+
+class SeedlessSeedSequence(ISpawnableSeedSequence):
+ def generate_state(
+ self, n_words: int, dtype: Union[_DTypeLikeUint32, _DTypeLikeUint64] = ...
+ ) -> ndarray[Any, dtype[Union[uint32, uint64]]]: ...
+ def spawn(self: _T, n_children: int) -> List[_T]: ...
+
+class SeedSequence(ISpawnableSeedSequence):
+ entropy: Union[None, int, Sequence[int]]
+ spawn_key: Tuple[int, ...]
+ pool_size: int
+ n_children_spawned: int
+ pool: ndarray[Any, dtype[uint32]]
+ def __init__(
+ self,
+ entropy: Union[None, int, Sequence[int], _ArrayLikeInt_co] = ...,
+ *,
+ spawn_key: Sequence[int] = ...,
+ pool_size: int = ...,
+ n_children_spawned: int = ...,
+ ) -> None: ...
+ def __repr__(self) -> str: ...
+ @property
+ def state(
+ self,
+ ) -> _SeedSeqState: ...
+ def generate_state(
+ self, n_words: int, dtype: Union[_DTypeLikeUint32, _DTypeLikeUint64] = ...
+ ) -> ndarray[Any, dtype[Union[uint32, uint64]]]: ...
+ def spawn(self, n_children: int) -> List[SeedSequence]: ...
+
+class BitGenerator(abc.ABC):
+ lock: Lock
+ def __init__(self, seed: Union[None, _ArrayLikeInt_co, SeedSequence] = ...) -> None: ...
+ def __getstate__(self) -> Dict[str, Any]: ...
+ def __setstate__(self, state: Dict[str, Any]) -> None: ...
+ def __reduce__(
+ self,
+ ) -> Tuple[Callable[[str], BitGenerator], Tuple[str], Tuple[Dict[str, Any]]]: ...
+ @abc.abstractmethod
+ @property
+ def state(self) -> Mapping[str, Any]: ...
+ @state.setter
+ def state(self, value: Mapping[str, Any]) -> None: ...
+ @overload
+ def random_raw(self, size: None = ..., output: Literal[True] = ...) -> int: ... # type: ignore[misc]
+ @overload
+ def random_raw(self, size: _ShapeLike = ..., output: Literal[True] = ...) -> ndarray[Any, dtype[uint64]]: ... # type: ignore[misc]
+ @overload
+ def random_raw(self, size: Optional[_ShapeLike] = ..., output: Literal[False] = ...) -> None: ... # type: ignore[misc]
+ def _benchmark(self, cnt: int, method: str = ...) -> None: ...
+ @property
+ def ctypes(self) -> _Interface: ...
+ @property
+ def cffi(self) -> _Interface: ...
diff --git a/numpy/random/bit_generator.pyx b/numpy/random/bit_generator.pyx
index 9b0c363ef..123d77b40 100644
--- a/numpy/random/bit_generator.pyx
+++ b/numpy/random/bit_generator.pyx
@@ -43,10 +43,7 @@ except ImportError:
from random import SystemRandom
randbits = SystemRandom().getrandbits
-try:
- from threading import Lock
-except ImportError:
- from dummy_threading import Lock
+from threading import Lock
from cpython.pycapsule cimport PyCapsule_New
@@ -587,8 +584,8 @@ cdef class BitGenerator():
"""
return random_raw(&self._bitgen, self.lock, size, output)
- def _benchmark(self, Py_ssize_t cnt, method=u'uint64'):
- '''Used in tests'''
+ def _benchmark(self, Py_ssize_t cnt, method='uint64'):
+ """Used in tests"""
return benchmark(&self._bitgen, self.lock, cnt, method)
@property
diff --git a/numpy/random/include/legacy-distributions.h b/numpy/random/include/legacy-distributions.h
index b8ba0841c..f6c5cf053 100644
--- a/numpy/random/include/legacy-distributions.h
+++ b/numpy/random/include/legacy-distributions.h
@@ -17,6 +17,7 @@ extern double legacy_weibull(aug_bitgen_t *aug_state, double a);
extern double legacy_power(aug_bitgen_t *aug_state, double a);
extern double legacy_gamma(aug_bitgen_t *aug_state, double shape, double scale);
extern double legacy_chisquare(aug_bitgen_t *aug_state, double df);
+extern double legacy_rayleigh(bitgen_t *bitgen_state, double mode);
extern double legacy_noncentral_chisquare(aug_bitgen_t *aug_state, double df,
double nonc);
extern double legacy_noncentral_f(aug_bitgen_t *aug_state, double dfnum,
@@ -31,6 +32,7 @@ extern double legacy_f(aug_bitgen_t *aug_state, double dfnum, double dfden);
extern double legacy_normal(aug_bitgen_t *aug_state, double loc, double scale);
extern double legacy_standard_gamma(aug_bitgen_t *aug_state, double shape);
extern double legacy_exponential(aug_bitgen_t *aug_state, double scale);
+extern double legacy_vonmises(bitgen_t *bitgen_state, double mu, double kappa);
extern int64_t legacy_random_binomial(bitgen_t *bitgen_state, double p,
int64_t n, binomial_t *binomial);
extern int64_t legacy_negative_binomial(aug_bitgen_t *aug_state, double n,
@@ -38,7 +40,7 @@ extern int64_t legacy_negative_binomial(aug_bitgen_t *aug_state, double n,
extern int64_t legacy_random_hypergeometric(bitgen_t *bitgen_state,
int64_t good, int64_t bad,
int64_t sample);
-extern int64_t legacy_random_logseries(bitgen_t *bitgen_state, double p);
+extern int64_t legacy_logseries(bitgen_t *bitgen_state, double p);
extern int64_t legacy_random_poisson(bitgen_t *bitgen_state, double lam);
extern int64_t legacy_random_zipf(bitgen_t *bitgen_state, double a);
extern int64_t legacy_random_geometric(bitgen_t *bitgen_state, double p);
diff --git a/numpy/random/mtrand.pyi b/numpy/random/mtrand.pyi
new file mode 100644
index 000000000..3137b0a95
--- /dev/null
+++ b/numpy/random/mtrand.pyi
@@ -0,0 +1,579 @@
+import sys
+from typing import Any, Callable, Dict, Optional, Tuple, Type, Union, overload
+
+from numpy import (
+ bool_,
+ dtype,
+ float32,
+ float64,
+ int8,
+ int16,
+ int32,
+ int64,
+ int_,
+ ndarray,
+ uint,
+ uint8,
+ uint16,
+ uint32,
+ uint64,
+)
+from numpy.random.bit_generator import BitGenerator
+from numpy.typing import (
+ ArrayLike,
+ _ArrayLikeFloat_co,
+ _ArrayLikeInt_co,
+ _DoubleCodes,
+ _DTypeLikeBool,
+ _DTypeLikeInt,
+ _DTypeLikeUInt,
+ _Float32Codes,
+ _Float64Codes,
+ _Int8Codes,
+ _Int16Codes,
+ _Int32Codes,
+ _Int64Codes,
+ _IntCodes,
+ _ShapeLike,
+ _SingleCodes,
+ _SupportsDType,
+ _UInt8Codes,
+ _UInt16Codes,
+ _UInt32Codes,
+ _UInt64Codes,
+ _UIntCodes,
+)
+
+if sys.version_info >= (3, 8):
+ from typing import Literal
+else:
+ from typing_extensions import Literal
+
+_DTypeLikeFloat32 = Union[
+ dtype[float32],
+ _SupportsDType[dtype[float32]],
+ Type[float32],
+ _Float32Codes,
+ _SingleCodes,
+]
+
+_DTypeLikeFloat64 = Union[
+ dtype[float64],
+ _SupportsDType[dtype[float64]],
+ Type[float],
+ Type[float64],
+ _Float64Codes,
+ _DoubleCodes,
+]
+
+class RandomState:
+ _bit_generator: BitGenerator
+ def __init__(self, seed: Union[None, _ArrayLikeInt_co, BitGenerator] = ...) -> None: ...
+ def __repr__(self) -> str: ...
+ def __str__(self) -> str: ...
+ def __getstate__(self) -> Dict[str, Any]: ...
+ def __setstate__(self, state: Dict[str, Any]) -> None: ...
+ def __reduce__(self) -> Tuple[Callable[[str], RandomState], Tuple[str], Dict[str, Any]]: ...
+ def seed(self, seed: Optional[_ArrayLikeFloat_co] = ...) -> None: ...
+ @overload
+ def get_state(self, legacy: Literal[False] = ...) -> Dict[str, Any]: ...
+ @overload
+ def get_state(
+ self, legacy: Literal[True] = ...
+ ) -> Union[Dict[str, Any], Tuple[str, ndarray[Any, dtype[uint32]], int, int, float]]: ...
+ def set_state(
+ self, state: Union[Dict[str, Any], Tuple[str, ndarray[Any, dtype[uint32]], int, int, float]]
+ ) -> None: ...
+ @overload
+ def random_sample(self, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def random_sample(self, size: _ShapeLike = ...) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def random(self, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def random(self, size: _ShapeLike = ...) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def beta(self, a: float, b: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def beta(
+ self, a: _ArrayLikeFloat_co, b: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def exponential(self, scale: float = ..., size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def exponential(
+ self, scale: _ArrayLikeFloat_co = ..., size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def standard_exponential(self, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def standard_exponential(self, size: _ShapeLike = ...) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def tomaxint(self, size: None = ...) -> int: ... # type: ignore[misc]
+ @overload
+ def tomaxint(self, size: _ShapeLike = ...) -> ndarray[Any, dtype[int_]]: ...
+ @overload
+ def randint( # type: ignore[misc]
+ self,
+ low: int,
+ high: Optional[int] = ...,
+ ) -> int: ...
+ @overload
+ def randint( # type: ignore[misc]
+ self,
+ low: int,
+ high: Optional[int] = ...,
+ size: None = ...,
+ dtype: _DTypeLikeBool = ...,
+ ) -> bool: ...
+ @overload
+ def randint( # type: ignore[misc]
+ self,
+ low: int,
+ high: Optional[int] = ...,
+ size: None = ...,
+ dtype: Union[_DTypeLikeInt, _DTypeLikeUInt] = ...,
+ ) -> int: ...
+ @overload
+ def randint( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[int_]]: ...
+ @overload
+ def randint( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ dtype: _DTypeLikeBool = ...,
+ ) -> ndarray[Any, dtype[bool_]]: ...
+ @overload
+ def randint( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ dtype: Union[dtype[int8], Type[int8], _Int8Codes, _SupportsDType[dtype[int8]]] = ...,
+ ) -> ndarray[Any, dtype[int8]]: ...
+ @overload
+ def randint( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ dtype: Union[dtype[int16], Type[int16], _Int16Codes, _SupportsDType[dtype[int16]]] = ...,
+ ) -> ndarray[Any, dtype[int16]]: ...
+ @overload
+ def randint( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ dtype: Union[dtype[int32], Type[int32], _Int32Codes, _SupportsDType[dtype[int32]]] = ...,
+ ) -> ndarray[Any, dtype[Union[int32]]]: ...
+ @overload
+ def randint( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ dtype: Optional[
+ Union[dtype[int64], Type[int64], _Int64Codes, _SupportsDType[dtype[int64]]]
+ ] = ...,
+ ) -> ndarray[Any, dtype[int64]]: ...
+ @overload
+ def randint( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ dtype: Union[dtype[uint8], Type[uint8], _UInt8Codes, _SupportsDType[dtype[uint8]]] = ...,
+ ) -> ndarray[Any, dtype[uint8]]: ...
+ @overload
+ def randint( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ dtype: Union[
+ dtype[uint16], Type[uint16], _UInt16Codes, _SupportsDType[dtype[uint16]]
+ ] = ...,
+ ) -> ndarray[Any, dtype[Union[uint16]]]: ...
+ @overload
+ def randint( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ dtype: Union[
+ dtype[uint32], Type[uint32], _UInt32Codes, _SupportsDType[dtype[uint32]]
+ ] = ...,
+ ) -> ndarray[Any, dtype[uint32]]: ...
+ @overload
+ def randint( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ dtype: Union[
+ dtype[uint64], Type[uint64], _UInt64Codes, _SupportsDType[dtype[uint64]]
+ ] = ...,
+ ) -> ndarray[Any, dtype[uint64]]: ...
+ @overload
+ def randint( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ dtype: Union[
+ dtype[int_], Type[int], Type[int_], _IntCodes, _SupportsDType[dtype[int_]]
+ ] = ...,
+ ) -> ndarray[Any, dtype[int_]]: ...
+ @overload
+ def randint( # type: ignore[misc]
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ dtype: Union[dtype[uint], Type[uint], _UIntCodes, _SupportsDType[dtype[uint]]] = ...,
+ ) -> ndarray[Any, dtype[uint]]: ...
+ def bytes(self, length: int) -> bytes: ...
+ @overload
+ def choice(
+ self,
+ a: int,
+ size: None = ...,
+ replace: bool = ...,
+ p: Optional[_ArrayLikeFloat_co] = ...,
+ ) -> int: ...
+ @overload
+ def choice(
+ self,
+ a: int,
+ size: _ShapeLike = ...,
+ replace: bool = ...,
+ p: Optional[_ArrayLikeFloat_co] = ...,
+ ) -> ndarray[Any, dtype[int_]]: ...
+ @overload
+ def choice(
+ self,
+ a: ArrayLike,
+ size: None = ...,
+ replace: bool = ...,
+ p: Optional[_ArrayLikeFloat_co] = ...,
+ ) -> Any: ...
+ @overload
+ def choice(
+ self,
+ a: ArrayLike,
+ size: _ShapeLike = ...,
+ replace: bool = ...,
+ p: Optional[_ArrayLikeFloat_co] = ...,
+ ) -> ndarray[Any, Any]: ...
+ @overload
+ def uniform(self, low: float = ..., high: float = ..., size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def uniform(
+ self,
+ low: _ArrayLikeFloat_co = ...,
+ high: _ArrayLikeFloat_co = ...,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def rand(self) -> float: ...
+ @overload
+ def rand(self, *args: int) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def randn(self) -> float: ...
+ @overload
+ def randn(self, *args: int) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def random_integers(self, low: int, high: Optional[int] = ..., size: None = ...) -> int: ... # type: ignore[misc]
+ @overload
+ def random_integers(
+ self,
+ low: _ArrayLikeInt_co,
+ high: Optional[_ArrayLikeInt_co] = ...,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[int_]]: ...
+ @overload
+ def standard_normal(self, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def standard_normal( # type: ignore[misc]
+ self, size: _ShapeLike = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def normal(self, loc: float = ..., scale: float = ..., size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def normal(
+ self,
+ loc: _ArrayLikeFloat_co = ...,
+ scale: _ArrayLikeFloat_co = ...,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def standard_gamma( # type: ignore[misc]
+ self,
+ shape: float,
+ size: None = ...,
+ ) -> float: ...
+ @overload
+ def standard_gamma(
+ self,
+ shape: _ArrayLikeFloat_co,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def gamma(self, shape: float, scale: float = ..., size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def gamma(
+ self,
+ shape: _ArrayLikeFloat_co,
+ scale: _ArrayLikeFloat_co = ...,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def f(self, dfnum: float, dfden: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def f(
+ self, dfnum: _ArrayLikeFloat_co, dfden: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def noncentral_f(self, dfnum: float, dfden: float, nonc: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def noncentral_f(
+ self,
+ dfnum: _ArrayLikeFloat_co,
+ dfden: _ArrayLikeFloat_co,
+ nonc: _ArrayLikeFloat_co,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def chisquare(self, df: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def chisquare(
+ self, df: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def noncentral_chisquare(self, df: float, nonc: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def noncentral_chisquare(
+ self, df: _ArrayLikeFloat_co, nonc: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def standard_t(self, df: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def standard_t(
+ self, df: _ArrayLikeFloat_co, size: None = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def standard_t(
+ self, df: _ArrayLikeFloat_co, size: _ShapeLike = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def vonmises(self, mu: float, kappa: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def vonmises(
+ self, mu: _ArrayLikeFloat_co, kappa: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def pareto(self, a: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def pareto(
+ self, a: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def weibull(self, a: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def weibull(
+ self, a: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def power(self, a: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def power(
+ self, a: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def standard_cauchy(self, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def standard_cauchy(self, size: _ShapeLike = ...) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def laplace(self, loc: float = ..., scale: float = ..., size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def laplace(
+ self,
+ loc: _ArrayLikeFloat_co = ...,
+ scale: _ArrayLikeFloat_co = ...,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def gumbel(self, loc: float = ..., scale: float = ..., size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def gumbel(
+ self,
+ loc: _ArrayLikeFloat_co = ...,
+ scale: _ArrayLikeFloat_co = ...,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def logistic(self, loc: float = ..., scale: float = ..., size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def logistic(
+ self,
+ loc: _ArrayLikeFloat_co = ...,
+ scale: _ArrayLikeFloat_co = ...,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def lognormal(self, mean: float = ..., sigma: float = ..., size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def lognormal(
+ self,
+ mean: _ArrayLikeFloat_co = ...,
+ sigma: _ArrayLikeFloat_co = ...,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def rayleigh(self, scale: float = ..., size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def rayleigh(
+ self, scale: _ArrayLikeFloat_co = ..., size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def wald(self, mean: float, scale: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def wald(
+ self, mean: _ArrayLikeFloat_co, scale: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def triangular(self, left: float, mode: float, right: float, size: None = ...) -> float: ... # type: ignore[misc]
+ @overload
+ def triangular(
+ self,
+ left: _ArrayLikeFloat_co,
+ mode: _ArrayLikeFloat_co,
+ right: _ArrayLikeFloat_co,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ @overload
+ def binomial(self, n: int, p: float, size: None = ...) -> int: ... # type: ignore[misc]
+ @overload
+ def binomial(
+ self, n: _ArrayLikeInt_co, p: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[int_]]: ...
+ @overload
+ def negative_binomial(self, n: float, p: float, size: None = ...) -> int: ... # type: ignore[misc]
+ @overload
+ def negative_binomial(
+ self, n: _ArrayLikeFloat_co, p: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[int_]]: ...
+ @overload
+ def poisson(self, lam: float = ..., size: None = ...) -> int: ... # type: ignore[misc]
+ @overload
+ def poisson(
+ self, lam: _ArrayLikeFloat_co = ..., size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[int_]]: ...
+ @overload
+ def zipf(self, a: float, size: None = ...) -> int: ... # type: ignore[misc]
+ @overload
+ def zipf(
+ self, a: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[int_]]: ...
+ @overload
+ def geometric(self, p: float, size: None = ...) -> int: ... # type: ignore[misc]
+ @overload
+ def geometric(
+ self, p: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[int_]]: ...
+ @overload
+ def hypergeometric(self, ngood: int, nbad: int, nsample: int, size: None = ...) -> int: ... # type: ignore[misc]
+ @overload
+ def hypergeometric(
+ self,
+ ngood: _ArrayLikeInt_co,
+ nbad: _ArrayLikeInt_co,
+ nsample: _ArrayLikeInt_co,
+ size: Optional[_ShapeLike] = ...,
+ ) -> ndarray[Any, dtype[int_]]: ...
+ @overload
+ def logseries(self, p: float, size: None = ...) -> int: ... # type: ignore[misc]
+ @overload
+ def logseries(
+ self, p: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[int_]]: ...
+ def multivariate_normal(
+ self,
+ mean: _ArrayLikeFloat_co,
+ cov: _ArrayLikeFloat_co,
+ size: Optional[_ShapeLike] = ...,
+ check_valid: Literal["warn", "raise", "ignore"] = ...,
+ tol: float = ...,
+ ) -> ndarray[Any, dtype[float64]]: ...
+ def multinomial(
+ self, n: _ArrayLikeInt_co, pvals: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[int_]]: ...
+ def dirichlet(
+ self, alpha: _ArrayLikeFloat_co, size: Optional[_ShapeLike] = ...
+ ) -> ndarray[Any, dtype[float64]]: ...
+ def shuffle(self, x: ArrayLike) -> None: ...
+ @overload
+ def permutation(self, x: int) -> ndarray[Any, dtype[int_]]: ...
+ @overload
+ def permutation(self, x: ArrayLike) -> ndarray[Any, Any]: ...
+
+_rand: RandomState
+
+beta = _rand.beta
+binomial = _rand.binomial
+bytes = _rand.bytes
+chisquare = _rand.chisquare
+choice = _rand.choice
+dirichlet = _rand.dirichlet
+exponential = _rand.exponential
+f = _rand.f
+gamma = _rand.gamma
+get_state = _rand.get_state
+geometric = _rand.geometric
+gumbel = _rand.gumbel
+hypergeometric = _rand.hypergeometric
+laplace = _rand.laplace
+logistic = _rand.logistic
+lognormal = _rand.lognormal
+logseries = _rand.logseries
+multinomial = _rand.multinomial
+multivariate_normal = _rand.multivariate_normal
+negative_binomial = _rand.negative_binomial
+noncentral_chisquare = _rand.noncentral_chisquare
+noncentral_f = _rand.noncentral_f
+normal = _rand.normal
+pareto = _rand.pareto
+permutation = _rand.permutation
+poisson = _rand.poisson
+power = _rand.power
+rand = _rand.rand
+randint = _rand.randint
+randn = _rand.randn
+random = _rand.random
+random_integers = _rand.random_integers
+random_sample = _rand.random_sample
+rayleigh = _rand.rayleigh
+seed = _rand.seed
+set_state = _rand.set_state
+shuffle = _rand.shuffle
+standard_cauchy = _rand.standard_cauchy
+standard_exponential = _rand.standard_exponential
+standard_gamma = _rand.standard_gamma
+standard_normal = _rand.standard_normal
+standard_t = _rand.standard_t
+triangular = _rand.triangular
+uniform = _rand.uniform
+vonmises = _rand.vonmises
+wald = _rand.wald
+weibull = _rand.weibull
+zipf = _rand.zipf
+# Two legacy that are trivial wrappers around random_sample
+sample = _rand.random_sample
+ranf = _rand.random_sample
diff --git a/numpy/random/mtrand.pyx b/numpy/random/mtrand.pyx
index d43e7f5aa..4f5862faa 100644
--- a/numpy/random/mtrand.pyx
+++ b/numpy/random/mtrand.pyx
@@ -2,6 +2,7 @@
#cython: wraparound=False, nonecheck=False, boundscheck=False, cdivision=True, language_level=3
import operator
import warnings
+from collections.abc import Sequence
import numpy as np
@@ -50,7 +51,6 @@ cdef extern from "numpy/random/distributions.h":
void random_standard_uniform_fill(bitgen_t* bitgen_state, np.npy_intp cnt, double *out) nogil
int64_t random_positive_int(bitgen_t *bitgen_state) nogil
double random_uniform(bitgen_t *bitgen_state, double lower, double range) nogil
- double random_vonmises(bitgen_t *bitgen_state, double mu, double kappa) nogil
double random_laplace(bitgen_t *bitgen_state, double loc, double scale) nogil
double random_gumbel(bitgen_t *bitgen_state, double loc, double scale) nogil
double random_logistic(bitgen_t *bitgen_state, double loc, double scale) nogil
@@ -79,6 +79,7 @@ cdef extern from "include/legacy-distributions.h":
double legacy_gamma(aug_bitgen_t *aug_state, double shape, double scale) nogil
double legacy_power(aug_bitgen_t *aug_state, double a) nogil
double legacy_chisquare(aug_bitgen_t *aug_state, double df) nogil
+ double legacy_rayleigh(aug_bitgen_t *aug_state, double mode) nogil
double legacy_noncentral_chisquare(aug_bitgen_t *aug_state, double df,
double nonc) nogil
double legacy_noncentral_f(aug_bitgen_t *aug_state, double dfnum, double dfden,
@@ -89,7 +90,7 @@ cdef extern from "include/legacy-distributions.h":
int64_t n, binomial_t *binomial) nogil
int64_t legacy_negative_binomial(aug_bitgen_t *aug_state, double n, double p) nogil
int64_t legacy_random_hypergeometric(bitgen_t *bitgen_state, int64_t good, int64_t bad, int64_t sample) nogil
- int64_t legacy_random_logseries(bitgen_t *bitgen_state, double p) nogil
+ int64_t legacy_logseries(bitgen_t *bitgen_state, double p) nogil
int64_t legacy_random_poisson(bitgen_t *bitgen_state, double lam) nogil
int64_t legacy_random_zipf(bitgen_t *bitgen_state, double a) nogil
int64_t legacy_random_geometric(bitgen_t *bitgen_state, double p) nogil
@@ -99,6 +100,7 @@ cdef extern from "include/legacy-distributions.h":
double legacy_f(aug_bitgen_t *aug_state, double dfnum, double dfden) nogil
double legacy_exponential(aug_bitgen_t *aug_state, double scale) nogil
double legacy_power(aug_bitgen_t *state, double a) nogil
+ double legacy_vonmises(bitgen_t *bitgen_state, double mu, double kappa) nogil
np.import_array()
@@ -783,7 +785,7 @@ cdef class RandomState:
Returns
-------
- out : str
+ out : bytes
String of length `length`.
See Also
@@ -793,7 +795,7 @@ cdef class RandomState:
Examples
--------
>>> np.random.bytes(10)
- ' eh\\x85\\x022SZ\\xbf\\xa4' #random
+ b' eh\\x85\\x022SZ\\xbf\\xa4' #random
"""
cdef Py_ssize_t n_uint32 = ((length - 1) // 4 + 1)
# Interpret the uint32s as little-endian to convert them to bytes
@@ -818,17 +820,18 @@ cdef class RandomState:
----------
a : 1-D array-like or int
If an ndarray, a random sample is generated from its elements.
- If an int, the random sample is generated as if a were np.arange(a)
+ If an int, the random sample is generated as if it were ``np.arange(a)``
size : int or tuple of ints, optional
Output shape. If the given shape is, e.g., ``(m, n, k)``, then
``m * n * k`` samples are drawn. Default is None, in which case a
single value is returned.
replace : boolean, optional
- Whether the sample is with or without replacement
+ Whether the sample is with or without replacement. Default is True,
+ meaning that a value of ``a`` can be selected multiple times.
p : 1-D array-like, optional
The probabilities associated with each entry in a.
- If not given the sample assumes a uniform distribution over all
- entries in a.
+ If not given, the sample assumes a uniform distribution over all
+ entries in ``a``.
Returns
-------
@@ -851,6 +854,10 @@ cdef class RandomState:
Notes
-----
+ Setting user-specified probabilities through ``p`` uses a more general but less
+ efficient sampler than the default. The general sampler produces a different sample
+ than the optimized sampler even if each element of ``p`` is 1 / len(a).
+
Sampling random rows from a 2-D array is not possible with this function,
but is possible with `Generator.choice` through its ``axis`` keyword.
@@ -2146,33 +2153,45 @@ cdef class RandomState:
... 7515, 8230, 8770])
Does their energy intake deviate systematically from the recommended
- value of 7725 kJ?
-
- We have 10 degrees of freedom, so is the sample mean within 95% of the
- recommended value?
+ value of 7725 kJ? Our null hypothesis will be the absence of deviation,
+ and the alternate hypothesis will be the presence of an effect that could be
+ either positive or negative, hence making our test 2-tailed.
+
+ Because we are estimating the mean and we have N=11 values in our sample,
+ we have N-1=10 degrees of freedom. We set our significance level to 95% and
+ compute the t statistic using the empirical mean and empirical standard
+ deviation of our intake. We use a ddof of 1 to base the computation of our
+ empirical standard deviation on an unbiased estimate of the variance (note:
+ the final estimate is not unbiased due to the concave nature of the square
+ root).
- >>> s = np.random.standard_t(10, size=100000)
>>> np.mean(intake)
6753.636363636364
>>> intake.std(ddof=1)
1142.1232221373727
+ >>> t = (np.mean(intake)-7725)/(intake.std(ddof=1)/np.sqrt(len(intake)))
+ >>> t
+ -2.8207540608310198
- Calculate the t statistic, setting the ddof parameter to the unbiased
- value so the divisor in the standard deviation will be degrees of
- freedom, N-1.
+ We draw 1000000 samples from Student's t distribution with the adequate
+ degrees of freedom.
- >>> t = (np.mean(intake)-7725)/(intake.std(ddof=1)/np.sqrt(len(intake)))
>>> import matplotlib.pyplot as plt
+ >>> s = np.random.standard_t(10, size=1000000)
>>> h = plt.hist(s, bins=100, density=True)
- For a one-sided t-test, how far out in the distribution does the t
- statistic appear?
+ Does our t statistic land in one of the two critical regions found at
+ both tails of the distribution?
- >>> np.sum(s<t) / float(len(s))
- 0.0090699999999999999 #random
+ >>> np.sum(np.abs(t) < np.abs(s)) / float(len(s))
+ 0.018318 #random < 0.05, statistic is in critical region
- So the p-value is about 0.009, which says the null hypothesis has a
- probability of about 99% of being true.
+ The probability value for this 2-tailed test is about 1.83%, which is
+ lower than the 5% pre-determined significance threshold.
+
+ Therefore, the probability of observing values as extreme as our intake
+ conditionally on the null hypothesis being true is too low, and we reject
+ the null hypothesis of no deviation.
"""
return cont(&legacy_standard_t, &self._aug_state, size, self.lock, 1,
@@ -2264,7 +2283,7 @@ cdef class RandomState:
>>> plt.show()
"""
- return cont(&random_vonmises, &self._bitgen, size, self.lock, 2,
+ return cont(&legacy_vonmises, &self._bitgen, size, self.lock, 2,
mu, 'mu', CONS_NONE,
kappa, 'kappa', CONS_NON_NEGATIVE,
0.0, '', CONS_NONE, None)
@@ -3069,7 +3088,7 @@ cdef class RandomState:
0.087300000000000003 # random
"""
- return cont(&random_rayleigh, &self._bitgen, size, self.lock, 1,
+ return cont(&legacy_rayleigh, &self._bitgen, size, self.lock, 1,
scale, 'scale', CONS_NON_NEGATIVE,
0.0, '', CONS_NONE,
0.0, '', CONS_NONE, None)
@@ -3511,8 +3530,9 @@ cdef class RandomState:
Parameters
----------
lam : float or array_like of floats
- Expectation of interval, must be >= 0. A sequence of expectation
- intervals must be broadcastable over the requested size.
+ Expected number of events occurring in a fixed-time interval,
+ must be >= 0. A sequence must be broadcastable over the requested
+ size.
size : int or tuple of ints, optional
Output shape. If the given shape is, e.g., ``(m, n, k)``, then
``m * n * k`` samples are drawn. If size is ``None`` (default),
@@ -3936,7 +3956,7 @@ cdef class RandomState:
>>> plt.show()
"""
- out = disc(&legacy_random_logseries, &self._bitgen, size, self.lock, 1, 0,
+ out = disc(&legacy_logseries, &self._bitgen, size, self.lock, 1, 0,
p, 'p', CONS_BOUNDED_0_1,
0.0, '', CONS_NONE,
0.0, '', CONS_NONE)
@@ -4214,7 +4234,20 @@ cdef class RandomState:
pix = <double*>np.PyArray_DATA(parr)
check_array_constraint(parr, 'pvals', CONS_BOUNDED_0_1)
if kahan_sum(pix, d-1) > (1.0 + 1e-12):
- raise ValueError("sum(pvals[:-1]) > 1.0")
+ # When floating, but not float dtype, and close, improve the error
+ # 1.0001 works for float16 and float32
+ if (isinstance(pvals, np.ndarray)
+ and np.issubdtype(pvals.dtype, np.floating)
+ and pvals.dtype != float
+ and pvals.sum() < 1.0001):
+ msg = ("sum(pvals[:-1].astype(np.float64)) > 1.0. The pvals "
+ "array is cast to 64-bit floating point prior to "
+ "checking the sum. Precision changes when casting may "
+ "cause problems even if the sum of the original pvals "
+ "is valid.")
+ else:
+ msg = "sum(pvals[:-1]) > 1.0"
+ raise ValueError(msg)
if size is None:
shape = (d,)
@@ -4402,8 +4435,8 @@ cdef class RandomState:
Parameters
----------
- x : array_like
- The array or list to be shuffled.
+ x : ndarray or MutableSequence
+ The array, list or mutable sequence to be shuffled.
Returns
-------
@@ -4456,7 +4489,22 @@ cdef class RandomState:
self._shuffle_raw(n, sizeof(np.npy_intp), stride, x_ptr, buf_ptr)
else:
self._shuffle_raw(n, itemsize, stride, x_ptr, buf_ptr)
- elif isinstance(x, np.ndarray) and x.ndim and x.size:
+ elif isinstance(x, np.ndarray):
+ if x.size == 0:
+ # shuffling is a no-op
+ return
+
+ if x.ndim == 1 and x.dtype.type is np.object_:
+ warnings.warn(
+ "Shuffling a one dimensional array subclass containing "
+ "objects gives incorrect results for most array "
+ "subclasses. "
+ "Please us the new random number API instead: "
+ "https://numpy.org/doc/stable/reference/random/index.html\n"
+ "The new API fixes this issue. This version will not "
+ "be fixed due to stability guarantees of the API.",
+ UserWarning, stacklevel=1) # Cython adds no stacklevel
+
buf = np.empty_like(x[0, ...])
with self.lock:
for i in reversed(range(1, n)):
@@ -4468,6 +4516,16 @@ cdef class RandomState:
x[i] = buf
else:
# Untyped path.
+ if not isinstance(x, Sequence):
+ # See gh-18206. We may decide to deprecate here in the future.
+ warnings.warn(
+ f"you are shuffling a '{type(x).__name__}' object "
+ "which is not a subclass of 'Sequence'; "
+ "`shuffle` is not guaranteed to behave correctly. "
+ "E.g., non-numpy array/tensor objects with view semantics "
+ "may contain duplicates after shuffling.",
+ UserWarning, stacklevel=1) # Cython does not add a level
+
with self.lock:
for i in reversed(range(1, n)):
j = random_interval(&self._bitgen, i)
diff --git a/numpy/random/setup.py b/numpy/random/setup.py
index bfd08e469..dce9a101e 100644
--- a/numpy/random/setup.py
+++ b/numpy/random/setup.py
@@ -23,7 +23,7 @@ def configuration(parent_package='', top_path=None):
# enable unix large file support on 32 bit systems
# (64 bit off_t, lseek -> lseek64 etc.)
- if sys.platform[:3] == "aix":
+ if sys.platform[:3] == 'aix':
defs = [('_LARGE_FILES', None)]
else:
defs = [('_FILE_OFFSET_BITS', '64'),
@@ -116,7 +116,7 @@ def configuration(parent_package='', top_path=None):
# gen.pyx, src/distributions/distributions.c
config.add_extension(gen,
sources=[f'{gen}.c'],
- libraries=EXTRA_LIBRARIES,
+ libraries=EXTRA_LIBRARIES + ['npymath'],
extra_compile_args=EXTRA_COMPILE_ARGS,
include_dirs=['.', 'src'],
extra_link_args=EXTRA_LINK_ARGS,
@@ -124,13 +124,14 @@ def configuration(parent_package='', top_path=None):
define_macros=defs,
)
config.add_data_files('_bounded_integers.pxd')
+ mtrand_libs = ['m', 'npymath'] if os.name != 'nt' else ['npymath']
config.add_extension('mtrand',
sources=['mtrand.c',
'src/legacy/legacy-distributions.c',
'src/distributions/distributions.c',
],
include_dirs=['.', 'src', 'src/legacy'],
- libraries=['m'] if os.name != 'nt' else [],
+ libraries=mtrand_libs,
extra_compile_args=EXTRA_COMPILE_ARGS,
extra_link_args=EXTRA_LINK_ARGS,
depends=depends + ['mtrand.pyx'],
diff --git a/numpy/random/src/distributions/distributions.c b/numpy/random/src/distributions/distributions.c
index 93e0bdc5f..9bdfa9bea 100644
--- a/numpy/random/src/distributions/distributions.c
+++ b/numpy/random/src/distributions/distributions.c
@@ -47,7 +47,7 @@ static double standard_exponential_unlikely(bitgen_t *bitgen_state,
uint8_t idx, double x) {
if (idx == 0) {
/* Switch to 1.0 - U to avoid log(0.0), see GH 13361 */
- return ziggurat_exp_r - log(1.0 - next_double(bitgen_state));
+ return ziggurat_exp_r - npy_log1p(-next_double(bitgen_state));
} else if ((fe_double[idx - 1] - fe_double[idx]) * next_double(bitgen_state) +
fe_double[idx] <
exp(-x)) {
@@ -84,7 +84,7 @@ static float standard_exponential_unlikely_f(bitgen_t *bitgen_state,
uint8_t idx, float x) {
if (idx == 0) {
/* Switch to 1.0 - U to avoid log(0.0), see GH 13361 */
- return ziggurat_exp_r_f - logf(1.0f - next_float(bitgen_state));
+ return ziggurat_exp_r_f - npy_log1pf(-next_float(bitgen_state));
} else if ((fe_float[idx - 1] - fe_float[idx]) * next_float(bitgen_state) +
fe_float[idx] <
expf(-x)) {
@@ -121,7 +121,7 @@ void random_standard_exponential_inv_fill(bitgen_t * bitgen_state, npy_intp cnt,
{
npy_intp i;
for (i = 0; i < cnt; i++) {
- out[i] = -log(1.0 - next_double(bitgen_state));
+ out[i] = -npy_log1p(-next_double(bitgen_state));
}
}
@@ -129,7 +129,7 @@ void random_standard_exponential_inv_fill_f(bitgen_t * bitgen_state, npy_intp cn
{
npy_intp i;
for (i = 0; i < cnt; i++) {
- out[i] = -log(1.0 - next_float(bitgen_state));
+ out[i] = -npy_log1p(-next_float(bitgen_state));
}
}
@@ -155,8 +155,8 @@ double random_standard_normal(bitgen_t *bitgen_state) {
if (idx == 0) {
for (;;) {
/* Switch to 1.0 - U to avoid log(0.0), see GH 13361 */
- xx = -ziggurat_nor_inv_r * log(1.0 - next_double(bitgen_state));
- yy = -log(1.0 - next_double(bitgen_state));
+ xx = -ziggurat_nor_inv_r * npy_log1p(-next_double(bitgen_state));
+ yy = -npy_log1p(-next_double(bitgen_state));
if (yy + yy > xx * xx)
return ((rabs >> 8) & 0x1) ? -(ziggurat_nor_r + xx)
: ziggurat_nor_r + xx;
@@ -196,8 +196,8 @@ float random_standard_normal_f(bitgen_t *bitgen_state) {
if (idx == 0) {
for (;;) {
/* Switch to 1.0 - U to avoid log(0.0), see GH 13361 */
- xx = -ziggurat_nor_inv_r_f * logf(1.0f - next_float(bitgen_state));
- yy = -logf(1.0f - next_float(bitgen_state));
+ xx = -ziggurat_nor_inv_r_f * npy_log1pf(-next_float(bitgen_state));
+ yy = -npy_log1pf(-next_float(bitgen_state));
if (yy + yy > xx * xx)
return ((rabs >> 8) & 0x1) ? -(ziggurat_nor_r_f + xx)
: ziggurat_nor_r_f + xx;
@@ -508,7 +508,7 @@ double random_lognormal(bitgen_t *bitgen_state, double mean, double sigma) {
}
double random_rayleigh(bitgen_t *bitgen_state, double mode) {
- return mode * sqrt(-2.0 * log(1.0 - next_double(bitgen_state)));
+ return mode * sqrt(2.0 * random_standard_exponential(bitgen_state));
}
double random_standard_t(bitgen_t *bitgen_state, double df) {
@@ -843,6 +843,7 @@ double random_vonmises(bitgen_t *bitgen_state, double mu, double kappa) {
return NPY_NAN;
}
if (kappa < 1e-8) {
+ /* Use a uniform for very small values of kappa */
return M_PI * (2 * next_double(bitgen_state) - 1);
} else {
/* with double precision rho is zero until 1.4e-8 */
@@ -853,9 +854,23 @@ double random_vonmises(bitgen_t *bitgen_state, double mu, double kappa) {
*/
s = (1. / kappa + kappa);
} else {
- double r = 1 + sqrt(1 + 4 * kappa * kappa);
- double rho = (r - sqrt(2 * r)) / (2 * kappa);
- s = (1 + rho * rho) / (2 * rho);
+ if (kappa <= 1e6) {
+ /* Path for 1e-5 <= kappa <= 1e6 */
+ double r = 1 + sqrt(1 + 4 * kappa * kappa);
+ double rho = (r - sqrt(2 * r)) / (2 * kappa);
+ s = (1 + rho * rho) / (2 * rho);
+ } else {
+ /* Fallback to wrapped normal distribution for kappa > 1e6 */
+ result = mu + sqrt(1. / kappa) * random_standard_normal(bitgen_state);
+ /* Ensure result is within bounds */
+ if (result < -M_PI) {
+ result += 2*M_PI;
+ }
+ if (result > M_PI) {
+ result -= 2*M_PI;
+ }
+ return result;
+ }
}
while (1) {
@@ -891,17 +906,11 @@ double random_vonmises(bitgen_t *bitgen_state, double mu, double kappa) {
}
}
-/*
- * RAND_INT_TYPE is used to share integer generators with RandomState which
- * used long in place of int64_t. If changing a distribution that uses
- * RAND_INT_TYPE, then the original unmodified copy must be retained for
- * use in RandomState by copying to the legacy distributions source file.
- */
-RAND_INT_TYPE random_logseries(bitgen_t *bitgen_state, double p) {
+int64_t random_logseries(bitgen_t *bitgen_state, double p) {
double q, r, U, V;
- RAND_INT_TYPE result;
+ int64_t result;
- r = log(1.0 - p);
+ r = npy_log1p(-p);
while (1) {
V = next_double(bitgen_state);
@@ -911,7 +920,7 @@ RAND_INT_TYPE random_logseries(bitgen_t *bitgen_state, double p) {
U = next_double(bitgen_state);
q = 1.0 - exp(r * U);
if (V <= q * q) {
- result = (RAND_INT_TYPE)floor(1 + log(V) / log(q));
+ result = (int64_t)floor(1 + log(V) / log(q));
if ((result < 1) || (V == 0.0)) {
continue;
} else {
@@ -925,6 +934,14 @@ RAND_INT_TYPE random_logseries(bitgen_t *bitgen_state, double p) {
}
}
+/*
+ * RAND_INT_TYPE is used to share integer generators with RandomState which
+ * used long in place of int64_t. If changing a distribution that uses
+ * RAND_INT_TYPE, then the original unmodified copy must be retained for
+ * use in RandomState by copying to the legacy distributions source file.
+ */
+
+/* Still used but both generator and mtrand via legacy_random_geometric */
RAND_INT_TYPE random_geometric_search(bitgen_t *bitgen_state, double p) {
double U;
RAND_INT_TYPE X;
@@ -942,11 +959,11 @@ RAND_INT_TYPE random_geometric_search(bitgen_t *bitgen_state, double p) {
return X;
}
-RAND_INT_TYPE random_geometric_inversion(bitgen_t *bitgen_state, double p) {
- return (RAND_INT_TYPE)ceil(log(1.0 - next_double(bitgen_state)) / log(1.0 - p));
+int64_t random_geometric_inversion(bitgen_t *bitgen_state, double p) {
+ return (int64_t)ceil(-random_standard_exponential(bitgen_state) / npy_log1p(-p));
}
-RAND_INT_TYPE random_geometric(bitgen_t *bitgen_state, double p) {
+int64_t random_geometric(bitgen_t *bitgen_state, double p) {
if (p >= 0.333333333333333333333333) {
return random_geometric_search(bitgen_state, p);
} else {
@@ -971,7 +988,7 @@ RAND_INT_TYPE random_zipf(bitgen_t *bitgen_state, double a) {
* just reject this value. This function then models a Zipf
* distribution truncated to sys.maxint.
*/
- if (X > RAND_INT_MAX || X < 1.0) {
+ if (X > (double)RAND_INT_MAX || X < 1.0) {
continue;
}
diff --git a/numpy/random/src/legacy/legacy-distributions.c b/numpy/random/src/legacy/legacy-distributions.c
index fd067fe8d..443c1a4bf 100644
--- a/numpy/random/src/legacy/legacy-distributions.c
+++ b/numpy/random/src/legacy/legacy-distributions.c
@@ -1,3 +1,13 @@
+/*
+ * This file contains generation code for distribution that have been modified
+ * since Generator was introduced. These are preserved using identical code
+ * to what was in NumPy 1.16 so that the stream of values generated by
+ * RandomState is not changed when there are changes that affect Generator.
+ *
+ * These functions should not be changed except if they contain code that
+ * cannot be compiled. They should not be changed for bug fixes, performance
+ * improvements that can change the values produced, or enhancements to precision.
+ */
#include "include/legacy-distributions.h"
@@ -102,6 +112,10 @@ double legacy_chisquare(aug_bitgen_t *aug_state, double df) {
return 2.0 * legacy_standard_gamma(aug_state, df / 2.0);
}
+double legacy_rayleigh(bitgen_t *bitgen_state, double mode) {
+ return mode * sqrt(-2.0 * npy_log1p(-next_double(bitgen_state)));
+}
+
double legacy_noncentral_chisquare(aug_bitgen_t *aug_state, double df,
double nonc) {
double out;
@@ -369,24 +383,115 @@ int64_t legacy_random_hypergeometric(bitgen_t *bitgen_state, int64_t good,
}
-int64_t legacy_random_logseries(bitgen_t *bitgen_state, double p) {
- return (int64_t)random_logseries(bitgen_state, p);
-}
-
- int64_t legacy_random_poisson(bitgen_t *bitgen_state, double lam) {
+int64_t legacy_random_poisson(bitgen_t *bitgen_state, double lam) {
return (int64_t)random_poisson(bitgen_state, lam);
}
- int64_t legacy_random_zipf(bitgen_t *bitgen_state, double a) {
+int64_t legacy_random_zipf(bitgen_t *bitgen_state, double a) {
return (int64_t)random_zipf(bitgen_state, a);
}
- int64_t legacy_random_geometric(bitgen_t *bitgen_state, double p) {
- return (int64_t)random_geometric(bitgen_state, p);
+
+static long legacy_geometric_inversion(bitgen_t *bitgen_state, double p) {
+ return (long)ceil(npy_log1p(-next_double(bitgen_state)) / log(1 - p));
}
- void legacy_random_multinomial(bitgen_t *bitgen_state, RAND_INT_TYPE n,
+int64_t legacy_random_geometric(bitgen_t *bitgen_state, double p) {
+ if (p >= 0.333333333333333333333333) {
+ return (int64_t)random_geometric_search(bitgen_state, p);
+ } else {
+ return (int64_t)legacy_geometric_inversion(bitgen_state, p);
+ }
+}
+
+void legacy_random_multinomial(bitgen_t *bitgen_state, RAND_INT_TYPE n,
RAND_INT_TYPE *mnix, double *pix, npy_intp d,
binomial_t *binomial) {
return random_multinomial(bitgen_state, n, mnix, pix, d, binomial);
}
+
+double legacy_vonmises(bitgen_t *bitgen_state, double mu, double kappa) {
+ double s;
+ double U, V, W, Y, Z;
+ double result, mod;
+ int neg;
+ if (npy_isnan(kappa)) {
+ return NPY_NAN;
+ }
+ if (kappa < 1e-8) {
+ return M_PI * (2 * next_double(bitgen_state) - 1);
+ } else {
+ /* with double precision rho is zero until 1.4e-8 */
+ if (kappa < 1e-5) {
+ /*
+ * second order taylor expansion around kappa = 0
+ * precise until relatively large kappas as second order is 0
+ */
+ s = (1. / kappa + kappa);
+ } else {
+ /* Path for 1e-5 <= kappa <= 1e6 */
+ double r = 1 + sqrt(1 + 4 * kappa * kappa);
+ double rho = (r - sqrt(2 * r)) / (2 * kappa);
+ s = (1 + rho * rho) / (2 * rho);
+ }
+
+ while (1) {
+ U = next_double(bitgen_state);
+ Z = cos(M_PI * U);
+ W = (1 + s * Z) / (s + Z);
+ Y = kappa * (s - W);
+ V = next_double(bitgen_state);
+ /*
+ * V==0.0 is ok here since Y >= 0 always leads
+ * to accept, while Y < 0 always rejects
+ */
+ if ((Y * (2 - Y) - V >= 0) || (log(Y / V) + 1 - Y >= 0)) {
+ break;
+ }
+ }
+
+ U = next_double(bitgen_state);
+
+ result = acos(W);
+ if (U < 0.5) {
+ result = -result;
+ }
+ result += mu;
+ neg = (result < 0);
+ mod = fabs(result);
+ mod = (fmod(mod + M_PI, 2 * M_PI) - M_PI);
+ if (neg) {
+ mod *= -1;
+ }
+
+ return mod;
+ }
+}
+
+int64_t legacy_logseries(bitgen_t *bitgen_state, double p) {
+ double q, r, U, V;
+ long result;
+
+ r = log(1.0 - p);
+
+ while (1) {
+ V = next_double(bitgen_state);
+ if (V >= p) {
+ return 1;
+ }
+ U = next_double(bitgen_state);
+ q = 1.0 - exp(r * U);
+ if (V <= q * q) {
+ result = (long)floor(1 + log(V) / log(q));
+ if ((result < 1) || (V == 0.0)) {
+ continue;
+ } else {
+ return (int64_t)result;
+ }
+ }
+ if (V >= q) {
+ return 1;
+ }
+ return 2;
+ }
+} \ No newline at end of file
diff --git a/numpy/random/src/pcg64/pcg64.c b/numpy/random/src/pcg64/pcg64.c
index b15973aef..c623c809b 100644
--- a/numpy/random/src/pcg64/pcg64.c
+++ b/numpy/random/src/pcg64/pcg64.c
@@ -61,6 +61,10 @@ pcg_setseq_128_xsl_rr_64_boundedrand_r(pcg_state_setseq_128 *rng,
uint64_t bound);
extern inline void pcg_setseq_128_advance_r(pcg_state_setseq_128 *rng,
pcg128_t delta);
+extern inline uint64_t pcg_cm_random_r(pcg_state_setseq_128 *rng);
+extern inline void pcg_cm_step_r(pcg_state_setseq_128 *rng);
+extern inline uint64_t pcg_output_cm_128_64(pcg128_t state);
+extern inline void pcg_cm_srandom_r(pcg_state_setseq_128 *rng, pcg128_t initstate, pcg128_t initseq);
/* Multi-step advance functions (jump-ahead, jump-back)
*
@@ -117,6 +121,9 @@ pcg128_t pcg_advance_lcg_128(pcg128_t state, pcg128_t delta, pcg128_t cur_mult,
extern inline uint64_t pcg64_next64(pcg64_state *state);
extern inline uint32_t pcg64_next32(pcg64_state *state);
+extern inline uint64_t pcg64_cm_next64(pcg64_state *state);
+extern inline uint32_t pcg64_cm_next32(pcg64_state *state);
+
extern void pcg64_advance(pcg64_state *state, uint64_t *step) {
pcg128_t delta;
#ifndef PCG_EMULATED_128BIT_MATH
@@ -128,6 +135,17 @@ extern void pcg64_advance(pcg64_state *state, uint64_t *step) {
pcg64_advance_r(state->pcg_state, delta);
}
+extern void pcg64_cm_advance(pcg64_state *state, uint64_t *step) {
+ pcg128_t delta;
+#ifndef PCG_EMULATED_128BIT_MATH
+ delta = (((pcg128_t)step[0]) << 64) | step[1];
+#else
+ delta.high = step[0];
+ delta.low = step[1];
+#endif
+ pcg_cm_advance_r(state->pcg_state, delta);
+}
+
extern void pcg64_set_seed(pcg64_state *state, uint64_t *seed, uint64_t *inc) {
pcg128_t s, i;
#ifndef PCG_EMULATED_128BIT_MATH
diff --git a/numpy/random/src/pcg64/pcg64.h b/numpy/random/src/pcg64/pcg64.h
index 2a7217dd9..90a83fd5e 100644
--- a/numpy/random/src/pcg64/pcg64.h
+++ b/numpy/random/src/pcg64/pcg64.h
@@ -57,11 +57,11 @@
#define inline __forceinline
#endif
-#if __GNUC_GNU_INLINE__ && !defined(__cplusplus)
+#if defined(__GNUC_GNU_INLINE__) && !defined(__cplusplus)
#error Nonstandard GNU inlining semantics. Compile with -std=c99 or better.
#endif
-#if __cplusplus
+#ifdef __cplusplus
extern "C" {
#endif
@@ -104,6 +104,9 @@ typedef struct {
, PCG_128BIT_CONSTANT(0x0000000000000001ULL, 0xda3e39cb94b95bdbULL) \
}
+#define PCG_CHEAP_MULTIPLIER_128 (0xda942042e4dd58b5ULL)
+
+
static inline uint64_t pcg_rotr_64(uint64_t value, unsigned int rot) {
#ifdef _WIN32
return _rotr64(value, rot);
@@ -198,6 +201,77 @@ pcg_setseq_128_xsl_rr_64_random_r(pcg_state_setseq_128 *rng) {
#endif
}
+static inline pcg128_t pcg128_mult_64(pcg128_t a, uint64_t b) {
+ uint64_t h1;
+ pcg128_t result;
+
+ h1 = a.high * b;
+ _pcg_mult64(a.low, b, &(result.high), &(result.low));
+ result.high += h1;
+ return result;
+}
+
+static inline void pcg_cm_step_r(pcg_state_setseq_128 *rng) {
+#if defined _WIN32 && _MSC_VER >= 1900 && _M_AMD64
+ uint64_t h1;
+ pcg128_t product;
+
+ /* Manually inline the multiplication and addition using intrinsics */
+ h1 = rng->state.high * PCG_CHEAP_MULTIPLIER_128;
+ product.low =
+ _umul128(rng->state.low, PCG_CHEAP_MULTIPLIER_128, &(product.high));
+ product.high += h1;
+ _addcarry_u64(_addcarry_u64(0, product.low, rng->inc.low, &(rng->state.low)),
+ product.high, rng->inc.high, &(rng->state.high));
+#else
+ rng->state = pcg128_add(pcg128_mult_64(rng->state, PCG_CHEAP_MULTIPLIER_128),
+ rng->inc);
+#endif
+}
+
+
+static inline void pcg_cm_srandom_r(pcg_state_setseq_128 *rng, pcg128_t initstate, pcg128_t initseq) {
+ rng->state = PCG_128BIT_CONSTANT(0ULL, 0ULL);
+ rng->inc.high = initseq.high << 1u;
+ rng->inc.high |= initseq.low >> 63u;
+ rng->inc.low = (initseq.low << 1u) | 1u;
+ pcg_cm_step_r(rng);
+ rng->state = pcg128_add(rng->state, initstate);
+ pcg_cm_step_r(rng);
+}
+
+static inline uint64_t pcg_cm_random_r(pcg_state_setseq_128* rng)
+{
+ /* Lots of manual inlining to help out certain compilers to generate
+ * performant code. */
+ uint64_t hi = rng->state.high;
+ uint64_t lo = rng->state.low;
+
+ /* Run the DXSM output function on the pre-iterated state. */
+ lo |= 1;
+ hi ^= hi >> 32;
+ hi *= 0xda942042e4dd58b5ULL;
+ hi ^= hi >> 48;
+ hi *= lo;
+
+ /* Run the CM step. */
+#if defined _WIN32 && _MSC_VER >= 1900 && _M_AMD64
+ uint64_t h1;
+ pcg128_t product;
+
+ /* Manually inline the multiplication and addition using intrinsics */
+ h1 = rng->state.high * PCG_CHEAP_MULTIPLIER_128;
+ product.low =
+ _umul128(rng->state.low, PCG_CHEAP_MULTIPLIER_128, &(product.high));
+ product.high += h1;
+ _addcarry_u64(_addcarry_u64(0, product.low, rng->inc.low, &(rng->state.low)),
+ product.high, rng->inc.high, &(rng->state.high));
+#else
+ rng->state = pcg128_add(pcg128_mult_64(rng->state, PCG_CHEAP_MULTIPLIER_128),
+ rng->inc);
+#endif
+ return hi;
+}
#else /* PCG_EMULATED_128BIT_MATH */
static inline void pcg_setseq_128_step_r(pcg_state_setseq_128 *rng) {
@@ -209,6 +283,37 @@ static inline uint64_t pcg_output_xsl_rr_128_64(pcg128_t state) {
state >> 122u);
}
+static inline void pcg_cm_step_r(pcg_state_setseq_128 *rng) {
+ rng-> state = rng->state * PCG_CHEAP_MULTIPLIER_128 + rng->inc;
+}
+
+static inline uint64_t pcg_output_cm_128_64(pcg128_t state) {
+ uint64_t hi = state >> 64;
+ uint64_t lo = state;
+
+ lo |= 1;
+ hi ^= hi >> 32;
+ hi *= 0xda942042e4dd58b5ULL;
+ hi ^= hi >> 48;
+ hi *= lo;
+ return hi;
+}
+
+static inline void pcg_cm_srandom_r(pcg_state_setseq_128 *rng, pcg128_t initstate, pcg128_t initseq) {
+ rng->state = 0U;
+ rng->inc = (initseq << 1u) | 1u;
+ pcg_cm_step_r(rng);
+ rng->state += initstate;
+ pcg_cm_step_r(rng);
+}
+
+static inline uint64_t pcg_cm_random_r(pcg_state_setseq_128* rng)
+{
+ uint64_t ret = pcg_output_cm_128_64(rng->state);
+ pcg_cm_step_r(rng);
+ return ret;
+}
+
static inline uint64_t
pcg_setseq_128_xsl_rr_64_random_r(pcg_state_setseq_128* rng)
{
@@ -248,6 +353,12 @@ static inline void pcg_setseq_128_advance_r(pcg_state_setseq_128 *rng,
PCG_DEFAULT_MULTIPLIER_128, rng->inc);
}
+static inline void pcg_cm_advance_r(pcg_state_setseq_128 *rng, pcg128_t delta) {
+ rng->state = pcg_advance_lcg_128(rng->state, delta,
+ PCG_128BIT_CONSTANT(0, PCG_CHEAP_MULTIPLIER_128),
+ rng->inc);
+}
+
typedef pcg_state_setseq_128 pcg64_random_t;
#define pcg64_random_r pcg_setseq_128_xsl_rr_64_random_r
#define pcg64_boundedrand_r pcg_setseq_128_xsl_rr_64_boundedrand_r
@@ -255,7 +366,7 @@ typedef pcg_state_setseq_128 pcg64_random_t;
#define pcg64_advance_r pcg_setseq_128_advance_r
#define PCG64_INITIALIZER PCG_STATE_SETSEQ_128_INITIALIZER
-#if __cplusplus
+#ifdef __cplusplus
}
#endif
@@ -281,7 +392,24 @@ static inline uint32_t pcg64_next32(pcg64_state *state) {
return (uint32_t)(next & 0xffffffff);
}
+static inline uint64_t pcg64_cm_next64(pcg64_state *state) {
+ return pcg_cm_random_r(state->pcg_state);
+}
+
+static inline uint32_t pcg64_cm_next32(pcg64_state *state) {
+ uint64_t next;
+ if (state->has_uint32) {
+ state->has_uint32 = 0;
+ return state->uinteger;
+ }
+ next = pcg_cm_random_r(state->pcg_state);
+ state->has_uint32 = 1;
+ state->uinteger = (uint32_t)(next >> 32);
+ return (uint32_t)(next & 0xffffffff);
+}
+
void pcg64_advance(pcg64_state *state, uint64_t *step);
+void pcg64_cm_advance(pcg64_state *state, uint64_t *step);
void pcg64_set_seed(pcg64_state *state, uint64_t *seed, uint64_t *inc);
diff --git a/numpy/random/src/philox/philox.h b/numpy/random/src/philox/philox.h
index c72424a97..8844acc15 100644
--- a/numpy/random/src/philox/philox.h
+++ b/numpy/random/src/philox/philox.h
@@ -33,10 +33,16 @@ static NPY_INLINE uint64_t mulhilo64(uint64_t a, uint64_t b, uint64_t *hip) {
return (uint64_t)product;
}
#else
-#ifdef _WIN32
+#if defined(_WIN32)
#include <intrin.h>
#if defined(_WIN64) && defined(_M_AMD64)
#pragma intrinsic(_umul128)
+#elif defined(_WIN64) && defined(_M_ARM64)
+#pragma intrinsic(__umulh)
+static NPY_INLINE uint64_t _umul128(uint64_t a, uint64_t b, uint64_t *high) {
+ *high = __umulh(a, b);
+ return a * b;
+}
#else
#pragma intrinsic(__emulu)
static NPY_INLINE uint64_t _umul128(uint64_t a, uint64_t b, uint64_t *high) {
diff --git a/numpy/random/tests/data/pcg64dxsm-testset-1.csv b/numpy/random/tests/data/pcg64dxsm-testset-1.csv
new file mode 100644
index 000000000..39cef057f
--- /dev/null
+++ b/numpy/random/tests/data/pcg64dxsm-testset-1.csv
@@ -0,0 +1,1001 @@
+seed, 0xdeadbeaf
+0, 0xdf1ddcf1e22521fe
+1, 0xc71b2f9c706cf151
+2, 0x6922a8cc24ad96b2
+3, 0x82738c549beccc30
+4, 0x5e8415cdb1f17580
+5, 0x64c54ad0c09cb43
+6, 0x361a17a607dce278
+7, 0x4346f6afb7acad68
+8, 0x6e9f14d4f6398d6b
+9, 0xf818d4343f8ed822
+10, 0x6327647daf508ed6
+11, 0xe1d1dbe5496a262a
+12, 0xfc081e619076b2e0
+13, 0x37126563a956ab1
+14, 0x8bb46e155db16b9
+15, 0x56449f006c9f3fb4
+16, 0x34a9273550941803
+17, 0x5b4df62660f99462
+18, 0xb8665cad532e3018
+19, 0x72fc3e5f7f84216a
+20, 0x71d3c47f6fd59939
+21, 0xfd4218afa1de463b
+22, 0xc84054c78e0a9a71
+23, 0xae59034726be61a8
+24, 0xa6a5f21de983654d
+25, 0x3b633acf572009da
+26, 0x6a0884f347ab54c8
+27, 0x7a907ebe9adcab50
+28, 0xbe779be53d7b8d4a
+29, 0xf5976e8c69b9dcd1
+30, 0x1d8302f114699e11
+31, 0x7d37e43042c038a0
+32, 0x2cc1d4edc2a40f35
+33, 0x83e3347bb2d581f1
+34, 0x253f8698651a844d
+35, 0x4312dea0dd4e32f6
+36, 0x10f106439964ea3a
+37, 0x810eb374844868cc
+38, 0x366342a54b1978cc
+39, 0x9fb39b13aaddfb5e
+40, 0xdb91fd0d9482bed7
+41, 0x89f6ea4ca9c68204
+42, 0x146b31ccca461792
+43, 0x203fd9724deb2486
+44, 0x58a84f23748e25cb
+45, 0x2f20eb6aeb94e88
+46, 0x14d3581460e473c
+47, 0xad5bd0d25f37d047
+48, 0x1cf88fa16de258b2
+49, 0x3bcab6485b7a341
+50, 0xb2433b37f227d90c
+51, 0x2cffd7e0a8360cc8
+52, 0x5d2eeff7c9ebc847
+53, 0x6fd7c7ae23f9f64b
+54, 0x381650b2d00f175d
+55, 0x9d93edcedc873cae
+56, 0x56e369a033d4cb49
+57, 0x7547997116a3bac
+58, 0x11debaa897fd4665
+59, 0xdf799d2b73bd6fb8
+60, 0x3747d299c66624d
+61, 0xac9346701afd0cfa
+62, 0xac90e150fa13c7bf
+63, 0x85c56ad2248c2871
+64, 0xdea66bf35c45f195
+65, 0x59cf910ea079fb74
+66, 0x2f841bb782274586
+67, 0x9814df4384d92bd9
+68, 0x15bc70824be09925
+69, 0x16d4d0524c0503a3
+70, 0xf04ea249135c0cc7
+71, 0xa707ab509b7e3032
+72, 0x465459efa869e372
+73, 0x64cbf70a783fab67
+74, 0x36b3541a14ca8ed7
+75, 0x9a4dfae8f4c596bf
+76, 0x11d9a04224281be3
+77, 0xe09bbe6d5e98ec32
+78, 0xa6c60d908973aa0d
+79, 0x7c524c57dd5915c8
+80, 0xa810c170b27f1fdc
+81, 0xce5d409819621583
+82, 0xfe2ee3d5332a3525
+83, 0x162fb7c8b32045eb
+84, 0x4a3327156b0b2d83
+85, 0x808d0282f971064
+86, 0x2e6f04cf5ed27e60
+87, 0xaf6800699cca67a9
+88, 0xc7590aae7244c3bf
+89, 0x7824345f4713f5f9
+90, 0x8f713505f8fd059b
+91, 0x3d5b5b9bb6b1e80e
+92, 0x8674f45e5dc40d79
+93, 0xcb1e36846aa14773
+94, 0xe0ae45b2b9b778c1
+95, 0xd7254ce931eefcfb
+96, 0xef34e15e4f55ac0a
+97, 0xf17cc0ba15a99bc4
+98, 0x77bb0f7ffe7b31f1
+99, 0x6ee86438d2e71d38
+100, 0x584890f86829a455
+101, 0x7baf0d8d30ba70fe
+102, 0xb1ac8f326b8403ae
+103, 0xcc1963435c874ba7
+104, 0x9c483b953d1334ce
+105, 0xc0924bcbf3e10941
+106, 0x21bcc581558717b1
+107, 0x2c5ad1623f8d292b
+108, 0xa8ea110f6124557e
+109, 0x15f24a6c5c4c591
+110, 0x40fe0d9cd7629126
+111, 0xcfe8f2b3b081484d
+112, 0x891383f4b4cac284
+113, 0x76f2fcdef7fa845
+114, 0x4edd12133aed0584
+115, 0xd53c06d12308873d
+116, 0xf7f22882c17f86bf
+117, 0xfbaa4aad72f35e10
+118, 0x627610da2e3c0cc3
+119, 0x582b16a143634d9a
+120, 0x9b4a7f69ed38f4a0
+121, 0x2df694974d1e1cbe
+122, 0xe5be6eaafed5d4b
+123, 0xc48e2a288ad6605e
+124, 0xbcb088149ce27c2b
+125, 0x3cb6a7fb06ceecbe
+126, 0x516735fff3b9e3ac
+127, 0x5cbafc551ee5008d
+128, 0xee27d1ab855c5fd5
+129, 0xc99fb341f6baf846
+130, 0x7ad8891b92058e6d
+131, 0xf50310d03c1ac6c7
+132, 0x947e281d998cbd3e
+133, 0x1d4d94a93824fe80
+134, 0x5568b77289e7ee73
+135, 0x7d82d1b2b41e3c8b
+136, 0x1af462c7abc787b
+137, 0xcfd8dfe80bfae1ef
+138, 0xd314caeb723a63ea
+139, 0x1c63ddcfc1145429
+140, 0x3801b7cc6cbf2437
+141, 0xc327d5b9fdafddd3
+142, 0xe140278430ca3c78
+143, 0x4d0345a685cb6ef8
+144, 0x47640dc86e261ff9
+145, 0xab817f158523ebf4
+146, 0x37c51e35fbe65a6b
+147, 0xab090f475d30a178
+148, 0x4d3ec225bf599fc1
+149, 0xefd517b0041679b1
+150, 0x20ad50bca4da32c5
+151, 0x75e1f7cd07fad86d
+152, 0x348cf781ee655f4b
+153, 0x9375f0e5ffc2d2ec
+154, 0x7689082fd5f7279c
+155, 0x633e56f763561e77
+156, 0x9d1752d70861f9fd
+157, 0xa3c994b4e70b0b0f
+158, 0xabf7276a58701b88
+159, 0xbfa18d1a0540d000
+160, 0xc6a28a2475646d26
+161, 0x7cdf108583f65085
+162, 0x82dcefb9f32104be
+163, 0xc6baadd0adc6b446
+164, 0x7a63cff01075b1b4
+165, 0x67ac62e575c89919
+166, 0x96fa4320a0942035
+167, 0xc4658859385b325f
+168, 0xde22c17ff47808f6
+169, 0xbb952c4d89e2f2ec
+170, 0x638251fbc55bdc37
+171, 0x38918b307a03b3ea
+172, 0xccb60f2cedbb570b
+173, 0x3c06f4086a28f012
+174, 0x4e8d238388986e33
+175, 0x1760b7793514a143
+176, 0xa3f924efe49ee7d6
+177, 0xaf6be2dbaebc0bdf
+178, 0x6782682090dffe09
+179, 0xb63a4d90d848e8ef
+180, 0x5f649c7eaf4c54c5
+181, 0xbe57582426a085ba
+182, 0xb5dd825aa52fb76d
+183, 0x74cb4e6ca4039617
+184, 0x382e578bf0a49588
+185, 0xc043e8ea6e1dcdae
+186, 0xf902addd5c04fa7c
+187, 0xf3337994612528db
+188, 0x4e8fd48d6d15b4e6
+189, 0x7190a509927c07ab
+190, 0x864c2dee5b7108ae
+191, 0xbb9972ddc196f467
+192, 0x1ea02ab3ca10a448
+193, 0xe50a8ffde35ddef9
+194, 0x7bd2f59a67183541
+195, 0x5a940b30d8fcd27a
+196, 0x82b4cea62623d4d3
+197, 0x6fbda76d4afef445
+198, 0x8b1f6880f418328e
+199, 0x8b69a025c72c54b7
+200, 0xb71e0f3986a3835f
+201, 0xa4a7ddb8b9816825
+202, 0x945dcda28228b1d8
+203, 0xb471abf2f8044d72
+204, 0xf07d4af64742b1ba
+205, 0xfca5190bc4dd6a2a
+206, 0xd681497262e11bc5
+207, 0xbe95d5f00c577028
+208, 0x56313439fd8bde19
+209, 0x3f3d9ac9b5ee6522
+210, 0x7b8d457dd2b49bbe
+211, 0xe76b5747885d214b
+212, 0xa8a695b3deb493ea
+213, 0x5292446548c95d71
+214, 0xbf5cdf0d436412df
+215, 0x7936abaed779d28d
+216, 0x659c6e8073b3a06d
+217, 0x86c9ff28f5543b71
+218, 0x6faa748445a99146
+219, 0xdcc1e6ab57904fd7
+220, 0x770bd61233addc5f
+221, 0x16963e041e46d94f
+222, 0x158e6cb2934157ac
+223, 0xb65088a8fd246441
+224, 0x2b12ced6ce8a68c3
+225, 0x59a18d02cd6082b3
+226, 0x4ddbc318cb5488ee
+227, 0x3d4cf520b3ed20a1
+228, 0x7028b3a92e2b292d
+229, 0xf141da264a250e4d
+230, 0x9788d53e86041c37
+231, 0x1bb91238a7c97dbf
+232, 0x81953d0ddb634309
+233, 0xfa39ccfe14d2d46
+234, 0xf7c7861c9b7e8399
+235, 0x18d27ca50d9dc249
+236, 0x258dfdf38510d0d9
+237, 0x9e72d8af910ea76f
+238, 0x4f8ef24b96de50ad
+239, 0xb9d9c12297e03dc9
+240, 0x91994e41b4a1929c
+241, 0x8defa79b2ccc83b9
+242, 0x948566748706dac5
+243, 0x7b0454946e70e4cf
+244, 0x340b7cb298c70ed7
+245, 0x6602005330cebd95
+246, 0xf71cb803aa61f722
+247, 0x4683fb07fc70ae8a
+248, 0xc6db9f0c4de3ed88
+249, 0x3e8dfae2a593cef9
+250, 0x615f7c38e3862b33
+251, 0x676c7996550d857
+252, 0xc6d520d54a5c266a
+253, 0x202b1e8eef14aa2e
+254, 0xa3a84891a27a582
+255, 0x84dbee451658d47f
+256, 0x254c7cd97e777e3a
+257, 0xf50b6e977f0eba50
+258, 0x2898b1d3062a4798
+259, 0x4096f7cbbb019773
+260, 0x9fb8e75548062c50
+261, 0x4647071e5ca318ec
+262, 0x2b4750bdb3b3b01
+263, 0x88ac41cc69a39786
+264, 0x705e25476ef46fa3
+265, 0xc0c1db19884a48a6
+266, 0x1364c0afdbb465e5
+267, 0x58e98534701272a6
+268, 0x746a5ea9701517c0
+269, 0x523a70bc6b300b67
+270, 0x9b1c098eda8564ad
+271, 0xfbaeb28d3637067f
+272, 0xddd9a13551fdba65
+273, 0x56461a670559e832
+274, 0xab4fd79be85570ad
+275, 0xd4b691ecaff8ca55
+276, 0x11a4495939e7f004
+277, 0x40d069d19477eb47
+278, 0xe790783d285cd81e
+279, 0xde8218b16d935bc7
+280, 0x2635e8c65cd4182d
+281, 0xeae402623e3454
+282, 0x9f99c833184e0279
+283, 0x3d0f79a0d52d84e7
+284, 0xc1f8edb10c625b90
+285, 0x9b4546363d1f0489
+286, 0x98d86d0b1212a282
+287, 0x386b53863161200d
+288, 0xbe1165c7fe48a135
+289, 0xb9658b04dbbfdc8c
+290, 0xcea14eddfe84d71a
+291, 0x55d03298be74abe7
+292, 0x5be3b50d961ffd7e
+293, 0xc76b1045dc4b78e1
+294, 0x7830e3ff3f6c3d4c
+295, 0xb617adb36ca3729
+296, 0x4a51bdb194f14aa9
+297, 0x246024e54e6b682a
+298, 0x33d42fc9c6d33083
+299, 0xadccba149f31e1d
+300, 0x5183e66b9002f8b
+301, 0x70eb2416404d51b7
+302, 0x26c25eb225535351
+303, 0xbc2d5b0d23076561
+304, 0x5823019ddead1da
+305, 0x85cfa109fca69f62
+306, 0x26017933e7e1efd9
+307, 0x3ec7be9a32212753
+308, 0x697e8a0697cd6f60
+309, 0x44735f6cca03920f
+310, 0x8cc655eb94ee212e
+311, 0x8b8b74eba84929a0
+312, 0x7708ccedd0c98c80
+313, 0x1b6f21f19777cbe1
+314, 0x363e564bd5fadedb
+315, 0x5921543a641591fe
+316, 0xc390786d68ea8a1b
+317, 0x9b293138dc033fca
+318, 0x45447ca8dc843345
+319, 0xee6ef6755bc49c5e
+320, 0x70a3a1f5163c3be5
+321, 0xf05e25448b6343b0
+322, 0x4739f4f8717b7e69
+323, 0xb006141975bf957
+324, 0x31874a91b707f452
+325, 0x3a07f2c90bae2869
+326, 0xb73dae5499a55c5e
+327, 0x489070893bb51575
+328, 0x7129acf423940575
+329, 0x38c41f4b90130972
+330, 0xc5260ca65f5a84a1
+331, 0x6e76194f39563932
+332, 0x62ca1f9ca3de3ca6
+333, 0xb4a97874e640853f
+334, 0x38ed0f71e311cc02
+335, 0xde183b81099e8f47
+336, 0x9bb8bf8e6694346
+337, 0xd15497b6bf81e0f2
+338, 0xaaae52536c00111
+339, 0x4e4e60d1435aaafd
+340, 0x5a15512e5d6ea721
+341, 0xff0f1ffabfc6664f
+342, 0xba3ffcedc5f97fec
+343, 0xef87f391c0c6bfb6
+344, 0x4a888c5d31eb0f98
+345, 0x559a3fbfd7946e95
+346, 0xe45b44a0db5a9bad
+347, 0x9457898964190af1
+348, 0xd9357dfaab76cd9e
+349, 0xa60e907178d965a1
+350, 0x76b2dc3032dc2f4a
+351, 0x13549b9c2802120
+352, 0x8656b965a66a1800
+353, 0x16802e6e22456a23
+354, 0x23b62edc60efaa9
+355, 0x6832a366e1e4ea3b
+356, 0x46b1b41093ff2b1e
+357, 0x55c857128143f219
+358, 0x7fc35ddf5e138200
+359, 0x790abe78be67467e
+360, 0xa4446fc08babd466
+361, 0xc23d70327999b855
+362, 0x2e019d1597148196
+363, 0xfefd98e560403ab8
+364, 0xbe5f0a33da330d58
+365, 0x3078a4e9d43ca395
+366, 0x511bfedd6f12f2b3
+367, 0x8bc138e335be987c
+368, 0x24640f803465716d
+369, 0xf6530b04d0bd618f
+370, 0x9b7833e5aa782716
+371, 0x778cd35aea5841b1
+372, 0xecea3c458cefbc60
+373, 0x5107ae83fc527f46
+374, 0x278ad83d44bd2d1a
+375, 0x7014a382295aeb16
+376, 0xf326dd762048743f
+377, 0x858633d56279e553
+378, 0x76408154085f01bc
+379, 0x3e77d3364d02e746
+380, 0x2f26cea26cadd50b
+381, 0x6d6846a4ecb84273
+382, 0x4847e96f2df5f76
+383, 0x5a8610f46e13ff61
+384, 0x4e7a7cac403e10dd
+385, 0x754bdf2e20c7bc90
+386, 0x8bdd80e6c51bd0be
+387, 0x61c655fae2b4bc52
+388, 0x60873ef48e3d2f03
+389, 0x9d7d8d3698a0b4a4
+390, 0xdf48e9c355cd5d4b
+391, 0x69ecf03e20be99ac
+392, 0xc1a0c5a339bd1815
+393, 0x2e3263a6a3adccb
+394, 0x23557459719adbdc
+395, 0xd1b709a3b330e5a
+396, 0xade5ab00a5d88b9d
+397, 0x69a6bd644120cfad
+398, 0x40187ecceee92342
+399, 0x1c41964ba1ac78da
+400, 0x9ac5c51cbecabe67
+401, 0xbdc075781cf36d55
+402, 0xeaf5a32246ded56
+403, 0xcda0b67e39c0fb71
+404, 0x4839ee456ef7cc95
+405, 0xf17092fdd41d5658
+406, 0x2b5d422e60ae3253
+407, 0x3effe71102008551
+408, 0x20a47108e83934b7
+409, 0xd02da65fe768a88f
+410, 0xeb046bd56afa4026
+411, 0x70c0509c08e0fbe0
+412, 0x1d35c38d4f8bac6c
+413, 0x9aa8eb6466f392e0
+414, 0x587bd4a430740f30
+415, 0x82978fe4bad4195
+416, 0xdc4ebc4c0feb50ab
+417, 0xd3b7164d0240c06f
+418, 0x6e2ad6e5a5003a63
+419, 0xa24b430e2ee6b59c
+420, 0x2905f49fd5073094
+421, 0x5f209e4de03aa941
+422, 0x57b7da3e0bedb1dc
+423, 0x5e054018875b01f5
+424, 0xb2f2da6145658db3
+425, 0xbd9c94a69a8eb651
+426, 0x9c5f9a07cd6ac749
+427, 0x2296c4af4d529c38
+428, 0x522ed800fafdefab
+429, 0xe2a447ced0c66791
+430, 0x937f10d45e455fef
+431, 0xc882987d9e29a24
+432, 0x4610bfd6a247ee1a
+433, 0x562ba3e50870059
+434, 0x59d8d58793602189
+435, 0xfe9a606e3e34abe
+436, 0x6825f7932a5e9282
+437, 0xe77f7061bab476ad
+438, 0xbf42001da340ace3
+439, 0x9c3e9230f5e47960
+440, 0x2c0f700d96d5ad58
+441, 0x330048b7cd18f1f9
+442, 0xffc08785eca5cca9
+443, 0xb5879046915f07a5
+444, 0xef51fe26f83c988e
+445, 0xfa4c2968e7881a9a
+446, 0xc0a9744455a4aad
+447, 0xbd2ad686d6313928
+448, 0x6b9f0984c127682a
+449, 0xc9aaa00a5da59ed8
+450, 0x762a0c4b98980dbf
+451, 0x52d1a2393d3ca2d1
+452, 0x1e9308f2861db15c
+453, 0xe7b3c74fe4b4a844
+454, 0x485e15704a7fc594
+455, 0x9e7f67ea44c221f6
+456, 0xbab9ad47fde916e0
+457, 0x50e383912b7fc1f4
+458, 0xaad63db8abcef62d
+459, 0xc2f0c5699f47f013
+460, 0xee15b36ada826812
+461, 0x2a1b1cf1e1777142
+462, 0x8adb03ede79e937d
+463, 0xf14105ef65643bf3
+464, 0x752bbaefc374a3c7
+465, 0xa4980a08a5a21d23
+466, 0x418a1c05194b2db7
+467, 0xdd6ff32efe1c3cd6
+468, 0x272473ed1f0d3aa2
+469, 0x1e7fdebadabe6c06
+470, 0xd1baa90c17b3842f
+471, 0xd3d3a778e9c8404a
+472, 0x781ae7fda49fa1a0
+473, 0x61c44fdbdacc672d
+474, 0x6d447d0a1404f257
+475, 0x9303e8bdfbfb894d
+476, 0x3b3482cdec016244
+477, 0xb149bf245d062e7b
+478, 0x96f8d54b14cf992d
+479, 0x4741549a01f8c3d0
+480, 0x48270811b2992af
+481, 0x7b58f175cd25d147
+482, 0x8f19a840b56f4be9
+483, 0x84a77f43c0951a93
+484, 0x34e1a69381f0c374
+485, 0xb158383c9b4040f
+486, 0x372f1abc7cf3a9fa
+487, 0x5439819a84571763
+488, 0xabf8515e9084e2fa
+489, 0xb02312b9387ff99
+490, 0x238a85bb47a68b12
+491, 0x2068cb83857c49bb
+492, 0xc6170e743083664c
+493, 0x745cf8470bcb8467
+494, 0xe3a759a301670300
+495, 0x292c7686ad3e67da
+496, 0x359efedaff192a45
+497, 0x511f2c31a2d8c475
+498, 0x97fd041bf21c20b3
+499, 0x25ef1fe841b7b3f6
+500, 0xbb71739e656f262d
+501, 0x2729b0e989b6b7b8
+502, 0xd2142702ec7dbabf
+503, 0x7008decd2488ee3f
+504, 0x69daa95e303298d7
+505, 0xc35eca4efb8baa5a
+506, 0xf3f16d261cec3b6c
+507, 0x22371c1d75396bd3
+508, 0x7aefa08eccae857e
+509, 0x255b493c5e3c2a2f
+510, 0x779474a077d34241
+511, 0x5199c42686bea241
+512, 0x16c83931e293b8d3
+513, 0xa57fe8db8c0302c7
+514, 0xd7ace619e5312eb1
+515, 0x8740f013306d217c
+516, 0xb6a1ad5e29f4d453
+517, 0x31abf7c964688597
+518, 0xbc3d791daed71e7
+519, 0x31ee4ca67b7056ed
+520, 0x1ab5416bfe290ea3
+521, 0x93db416f6d3b843a
+522, 0xed83bbe5b1dd2fed
+523, 0xece38271470d9b6d
+524, 0x3a620f42663cd8ae
+525, 0x50c87e02acafee5d
+526, 0xcabeb8bedbc6dab5
+527, 0x2880a6d09970c729
+528, 0x4aba5dd3bfc81bc
+529, 0xaba54edf41080cec
+530, 0xb86bb916fc85a169
+531, 0x4c41de87bc79d8ca
+532, 0xcce2a202622945fe
+533, 0x513f086fad94c107
+534, 0x18b3960c11f8cc96
+535, 0x2f0d1cfd1896e236
+536, 0x1702ae3880d79b15
+537, 0x88923749029ae81
+538, 0x84810d4bdec668eb
+539, 0xf85b0a123f4fc68d
+540, 0x93efd68974b6e4d1
+541, 0x5d16d6d993a071c9
+542, 0x94436858f94ca43b
+543, 0xb3dbb9ed0cb180b6
+544, 0x6447030a010b8c99
+545, 0xd7224897c62925d8
+546, 0xb0c13c1d50605d3a
+547, 0xdff02c7cb9d45f30
+548, 0xe8103179f983570d
+549, 0xbc552037d6d0a24e
+550, 0x775e500b01486b0d
+551, 0x2050ac632c694dd6
+552, 0x218910387c4d7ae7
+553, 0xf83e8b68ff885d5d
+554, 0xe3374ec25fca51a3
+555, 0xfa750ffa3a60f3af
+556, 0x29ee40ba6df5592e
+557, 0x70e21a68f48260d2
+558, 0x3805ca72cd40886e
+559, 0x2f23e73f8eabf062
+560, 0x2296f80cdf6531ae
+561, 0x903099ed968db43a
+562, 0xf044445cf9f2929f
+563, 0xcd47fdc2de1b7a1
+564, 0xaab1cbd4f849da99
+565, 0x5fc990688da01acb
+566, 0xa9cee52ea7dab392
+567, 0xecefc3a4349283a8
+568, 0xdd6b572972e3fafc
+569, 0xc1f0b1a2ffb155da
+570, 0xc30d53fc17bd25c8
+571, 0x8afa89c77834db28
+572, 0x5569a596fb32896c
+573, 0x36f207fc8df3e3d4
+574, 0x57c2bd58517d81db
+575, 0xb524693e73d0061c
+576, 0xb69f6eb233f5c48b
+577, 0x4f0fb23cab8dc695
+578, 0x492c1ad0a48df8df
+579, 0xf6dcc348ec8dec1f
+580, 0xa4d8708d6eb2e262
+581, 0x4c2072c2c9766ff1
+582, 0xa9bf27c4304875f0
+583, 0xfc8fb8066d4f9ae2
+584, 0x188095f6235fec3c
+585, 0x1d8227a2938c2864
+586, 0x89ea50c599010378
+587, 0xcac86df0a7c6d56d
+588, 0x47a8c5df84c7d78
+589, 0xe607ae24ea228bfa
+590, 0x36624a7996efe104
+591, 0x5d72881c1227d810
+592, 0x78694a6750374c8
+593, 0x7b9a217d4ab5ff45
+594, 0xd53e5d6f7504becc
+595, 0x197a72d3f4889a0e
+596, 0xfdc70c4755a8df36
+597, 0xd0fda83748c77f74
+598, 0x7ddc919ac9d6dcc9
+599, 0x785c810a6a2dc08b
+600, 0xba4be83e7e36896c
+601, 0x379d6fe80cf2bffe
+602, 0x74cae2dabc429206
+603, 0x1efac32d5d34c917
+604, 0x3cb64e2f98d36e70
+605, 0xc0a7c3cdc3c60aa7
+606, 0x699dfadd38790ebe
+607, 0x4861e61b3ecfbeac
+608, 0x531744826c345baa
+609, 0x5ec26427ad450cba
+610, 0xf2c1741479abdcae
+611, 0xe9328a78b2595458
+612, 0x30cd1bdf087acd7f
+613, 0x7491ced4e009adbe
+614, 0xdcd942df1e2e7023
+615, 0xfe63f01689fee35
+616, 0x80282dfe5eaedc42
+617, 0x6ecdea86495f8427
+618, 0xe0adfdd5e9ed31c3
+619, 0xf32bd2a7418127e
+620, 0x8aabba078db6ee2
+621, 0xa8a8e60499145aca
+622, 0xf76b086ac4e8a0f2
+623, 0x6e55b3c452ff27f8
+624, 0xe18fa7cd025a71bf
+625, 0xeed7b685fde0fa25
+626, 0xba9b6c95867fa721
+627, 0x4c2603bc69de2df2
+628, 0xaac87eee1b58cd66
+629, 0x3c9af6656e01282c
+630, 0x2dfa05ce8ff476b6
+631, 0xeae9143fcf92f23d
+632, 0x3f0699f631be3bc8
+633, 0xa0f5f79f2492bd67
+634, 0x59c47722388131ed
+635, 0x5f6e9d2941cef1de
+636, 0xe9ad915c09788b7b
+637, 0x92c6d37e4f9482f5
+638, 0x57d301b7fdadd911
+639, 0x7e952d23d2a8443
+640, 0xbb2fa5e0704b3871
+641, 0xe5642199be36e2d5
+642, 0x5020b60d54358291
+643, 0xa0b6317ec3f60343
+644, 0xb57b08b99540bc5c
+645, 0x21f1890adc997a88
+646, 0xfcf824200dd9da2d
+647, 0x8146293d83d425d1
+648, 0xdadfbf5fbb99d420
+649, 0x1eb9bbc5e6482b7d
+650, 0xd40ff44f1bbd0f1c
+651, 0xa9f948ba2d08afa5
+652, 0x638cc07c5301e601
+653, 0x1f984baa606e14e8
+654, 0x44e153671081f398
+655, 0xb17882eeb1d77a5d
+656, 0x5fd8dbee995f14c
+657, 0xff3533e87f81b7fe
+658, 0x2f44124293c49795
+659, 0x3bf6b51e9360248
+660, 0x72d615edf1436371
+661, 0x8fc5cf4a38adab9d
+662, 0xfa517e9022078374
+663, 0xf356733f3e26f4d8
+664, 0x20ea099cdc6aad40
+665, 0xe15b977deb37637d
+666, 0xcc85601b89dae88d
+667, 0x5768c62f8dd4905c
+668, 0xa43cc632b4e56ea
+669, 0xc4240cf980e82458
+670, 0xb194e8ffb4b3eeb6
+671, 0xee753cf2219c5fa1
+672, 0xfe2500192181d44d
+673, 0x2d03d7d6493dd821
+674, 0xff0e787bb98e7f9b
+675, 0xa05cf8d3bd810ce7
+676, 0x718d5d6dcbbdcd65
+677, 0x8d0b5343a06931c
+678, 0xae3a00a932e7eaf9
+679, 0x7ed3d8f18f983e18
+680, 0x3bb778ee466dc143
+681, 0x711c685c4e9062c0
+682, 0x104c3af5d7ac9834
+683, 0x17bdbb671fb5d5cf
+684, 0xabf26caead4d2292
+685, 0xa45f02866467c005
+686, 0xf3769a32dc945d2d
+687, 0xe78d0007f6aabb66
+688, 0x34b60be4acbd8d4b
+689, 0x58c0b04b69359084
+690, 0x3a8bb354c212b1
+691, 0x6b82a8f3d70058d5
+692, 0x405bdef80a276a4a
+693, 0xe20ca40ee9195cad
+694, 0xf5dd96ba2446fefd
+695, 0xc1e180c55fe55e3c
+696, 0xa329caf6daa952b3
+697, 0xb4809dd0c84a6b0a
+698, 0xd27f82661070cee7
+699, 0xa7121f15ee2b0d8a
+700, 0x4bdaea70d6b34583
+701, 0xe821dc2f310f7a49
+702, 0x4c00a5a68e76f647
+703, 0x331065b064a2d5ea
+704, 0xac0c2ce3dc04fa37
+705, 0x56b32b37b8229008
+706, 0xe757cdb51534fcfa
+707, 0xd3ff183576b2fad7
+708, 0x179e1f4190f197a7
+709, 0xf874c626a7c9aae5
+710, 0xd58514ffc37c80e4
+711, 0xc65de31d33fa7fd3
+712, 0x6f6637052025769b
+713, 0xca1c6bdadb519cc0
+714, 0xd1f3534cde37828a
+715, 0xc858c339eee4830a
+716, 0x2371eacc215e02f4
+717, 0x84e5022db85bbbe9
+718, 0x5f71c50bba48610e
+719, 0xe420192dad9c323f
+720, 0x2889342721fca003
+721, 0x83e64f63334f501d
+722, 0xac2617172953f2c
+723, 0xfa1f78d8433938ff
+724, 0x5578382760051462
+725, 0x375d7a2e3b90af16
+726, 0xb93ff44e6c07552d
+727, 0xded1d5ad811e818c
+728, 0x7cf256b3b29e3a8c
+729, 0x78d581b8e7bf95e8
+730, 0x5b69192f2caa6ad3
+731, 0xa9e25855a52de3ce
+732, 0x69d8e8fc45cc188d
+733, 0x5dd012c139ad347d
+734, 0xfcb01c07b77db606
+735, 0x56253e36ab3d1cce
+736, 0x1181edbb3ea2192
+737, 0x325bef47ff19a08d
+738, 0xd3e231ceb27e5f7
+739, 0x8e819dd2de7956d2
+740, 0x34a9689fe6f84a51
+741, 0x3e4eeb719a9c2927
+742, 0x5c3b3440581d0aaf
+743, 0x57caf51897d7c920
+744, 0xec6a458130464b40
+745, 0xe98f044e0da40e9b
+746, 0xbe38662020eeb8e7
+747, 0x7b8c407c632724ae
+748, 0x16c7cfa97b33a544
+749, 0xd23359e2e978ae5a
+750, 0x4fdba458250933dd
+751, 0x3c9e0713cfe616ba
+752, 0x6f0df87b13163b42
+753, 0xc460902cb852cc97
+754, 0x289df8fefd6b0bce
+755, 0x4ac2a2a1c3fb8029
+756, 0x2fc3e24d8b68eef7
+757, 0x34564386a59aab9a
+758, 0x31047391ebd67ce4
+759, 0x6c23d070a0564d41
+760, 0xba6387b2b72545f7
+761, 0xcdcf1008058387af
+762, 0xc9308fa98db05192
+763, 0xdbdbb5abd01a9d84
+764, 0x937088275c7804ab
+765, 0x6f6accfefe34ee81
+766, 0x5c33c74c49cfdb2c
+767, 0x5e1a771edfb92bd3
+768, 0x6e89b009069ecae7
+769, 0x34d64e17ec0e8968
+770, 0x841203d0cde0c330
+771, 0x7642cc9d7eb9e9cb
+772, 0xca01d2e8c128b97e
+773, 0x5b8390617b3304ab
+774, 0x52ec4ed10de1eb2d
+775, 0xb90f288b9616f237
+776, 0x5bd43cd49617b2e2
+777, 0x1a53e21d25230596
+778, 0x36ccd15207a21cd6
+779, 0xc8263d780618fd3c
+780, 0x6eb520598c6ce1cb
+781, 0x493c99a3b341564f
+782, 0xab999e9c5aa8764f
+783, 0xab2fa4ceaba84b
+784, 0xbbd2f17e5cb2331b
+785, 0xc8b4d377c0cc4e81
+786, 0x31f71a6e165c4b1e
+787, 0xd1011e55fb3addaa
+788, 0x5f7ec34728dfa59
+789, 0x2aef59e60a84eb0f
+790, 0x5dde6f09aec9ad5f
+791, 0x968c6cdbc0ef0438
+792, 0x1957133afa15b13a
+793, 0xbaf28f27573a64c2
+794, 0xc6f6ddd543ebf862
+795, 0xdd7534315ec9ae1e
+796, 0xd2b80cd2758dd3b
+797, 0xa38c3da00cc81538
+798, 0x15c95b82d3f9b0f9
+799, 0x6704930287ce2571
+800, 0x9c40cc2f6f4ecb0c
+801, 0xc8de91f50b22e94e
+802, 0x39272e8fddbfdf0a
+803, 0x879e0aa810a117d
+804, 0xa312fff4e9e5f3bd
+805, 0x10dd747f2835dfec
+806, 0xeb8466db7171cdae
+807, 0xaa808d87b9ad040a
+808, 0xab4d2229a329243a
+809, 0x7c622f70d46f789c
+810, 0x5d41cef5965b2a8e
+811, 0xce97ec4702410d99
+812, 0x5beba2812c91211b
+813, 0xf134b46c93a3fec7
+814, 0x76401d5630127226
+815, 0xc55fc9d9eacd4ec1
+816, 0xaec8cefaa12f813f
+817, 0x2f845dcfd7b00722
+818, 0x3380ab4c20885921
+819, 0xdb68ad2597691b74
+820, 0x8a7e4951455f563f
+821, 0x2372d007ed761c53
+822, 0xcab691907714c4f1
+823, 0x16bc31d6f3abec1a
+824, 0x7dff639fbcf1824
+825, 0x6666985fbcff543d
+826, 0xb618948e3d8e6d0c
+827, 0x77b87837c794e068
+828, 0xcd48288d54fcb5a8
+829, 0x47a773ed6ae30dc3
+830, 0xba85ae44e203c942
+831, 0xa7a7b21791a25b2d
+832, 0x4029dd92e63f19e0
+833, 0xc2ad66ab85e7d5aa
+834, 0xa0f237c96fdab0db
+835, 0xffefb0ab1ca18ed
+836, 0x90cb4500785fd7d5
+837, 0xa7dd3120f4876435
+838, 0x53f7872624694300
+839, 0xea111326ff0040d9
+840, 0x5f83cb4cce40c83b
+841, 0x918e04936c3b504d
+842, 0x87a8db4c0e15e87c
+843, 0x7cff39da6a0dedd0
+844, 0x36f7de2037f85381
+845, 0xd1d8d94022a1e9a7
+846, 0x2c9930127dc33ec9
+847, 0x6cb4719dcd0101c6
+848, 0xc01868cde76935f7
+849, 0x6b86f2ec1ab50143
+850, 0x68af607d8d94ae61
+851, 0xe216c5b95feedf34
+852, 0x4b866bd91efe2e4b
+853, 0x4bff79df08f92c99
+854, 0x6ff664ea806acfd1
+855, 0x7fce0b3f9ece39bc
+856, 0x29bc90b59cb3db97
+857, 0x833c4b419198607d
+858, 0xf3573e36ca4d4768
+859, 0x50d71c0a3c2a3fa8
+860, 0xd754591aea2017e7
+861, 0x3f9126f1ee1ebf3
+862, 0xe775d7f4b1e43de8
+863, 0xe93d51628c263060
+864, 0x83e77f6fb32d6d82
+865, 0x43dd7eef823408e4
+866, 0x1c843c2c90180662
+867, 0xe924dafb9a16066b
+868, 0x6af3ee96e7b7fbd9
+869, 0x94d5c4f37befcd1f
+870, 0x40ffb04bedef4236
+871, 0x71c17bbc20e553e
+872, 0x101f7a0a6208729f
+873, 0x5ca34570cf923548
+874, 0x8e3139db2e96e814
+875, 0x3ab96d96263d048d
+876, 0x97f3c0bbc6755c3c
+877, 0x31fc72daedaef3dc
+878, 0x71f8d7855d10789b
+879, 0xce6dc97b4662333b
+880, 0xfddc2aabd342bc61
+881, 0xefbd4007ff8c7d2e
+882, 0xf72cd6c689ef8758
+883, 0x932c8b0c0e755137
+884, 0x94cc4dedd58ff69
+885, 0xde4dfd6890535979
+886, 0xdb00dcd2dcb4a50a
+887, 0xb0466240b4548107
+888, 0x9cb9264c7b90d1a3
+889, 0x357e378e9be5766b
+890, 0x6e0316ef03367bbf
+891, 0x201ea18839544ca
+892, 0x803ff3406be5f338
+893, 0xf9d5e82fd4144bb2
+894, 0x1b6b88ca701e9f47
+895, 0xd1fe5ab8e1f89cc0
+896, 0x14171fe176c4bece
+897, 0x887948bdef78beaa
+898, 0x80449ddc3eb9b977
+899, 0x5f4e1f900fb4bcf3
+900, 0xbe30f8701909f8e2
+901, 0xd1f2a2fb5503306d
+902, 0x6b1c77238dc23803
+903, 0x102156a6c9860f66
+904, 0x4cd446e099edf4c1
+905, 0xc79ac6cbc911f33b
+906, 0x3ee096ffe3384f1c
+907, 0xb58f83b18a306dc7
+908, 0x9f76582141de56b2
+909, 0x9ddfa85e02c13866
+910, 0x4d9a19d4ce90a543
+911, 0xbf81ab39fd17d376
+912, 0x5327e5054c6a74f1
+913, 0xd5062dd31db1a9b7
+914, 0x645853735527edc
+915, 0x485393967f91af08
+916, 0xeff9667dcf77ca68
+917, 0xd012313f5fbec464
+918, 0xbeae35bdfae55144
+919, 0x302c41ebac8444a0
+920, 0x9ccdb6c2fe58fba8
+921, 0x567753af68ed23f8
+922, 0xff90f790e43efec3
+923, 0x970cc756fb799696
+924, 0xe59239d1c44915
+925, 0x4d2d189fb3941f05
+926, 0x96f23085db165a9c
+927, 0xa1202dec7a37b1a5
+928, 0xc0c1ee74bcd7dc1a
+929, 0x9edcf2048b30333a
+930, 0xd848588ba7e865fb
+931, 0x8d9f0897317cab40
+932, 0x67b96f15e25924fb
+933, 0xefc8d8536619ee42
+934, 0xf3f621d22bdde0c2
+935, 0x68610a0de862ae32
+936, 0xa22ca5142de24cbd
+937, 0x8815452f4e6b4801
+938, 0x4e9c1b607b2750e5
+939, 0x19b3c09ba6fc9b25
+940, 0x9b2543c8836780ac
+941, 0xe702b8f950e56431
+942, 0xb357cc329cac3917
+943, 0x387bf86a17a31e08
+944, 0x9940b983d331b163
+945, 0xf5d89d7fe9095e18
+946, 0x4362682329e5c4d1
+947, 0xd2132573f6ae7b42
+948, 0xc0a5849e23a61606
+949, 0xdadbddf47265bc02
+950, 0x1b96f00339a705f7
+951, 0x94e6642329288913
+952, 0x825ab3f10e6d330b
+953, 0x1a1c31ac9d883ea0
+954, 0xb49076b7155c6f47
+955, 0x920cf3085dfe3ccb
+956, 0x9743407c9f28e825
+957, 0x6ce8a28622402719
+958, 0xce2fe67e06baf8a6
+959, 0x3a16b34784ecf5e6
+960, 0x140467cc1d162a0c
+961, 0x32d4772692ab625
+962, 0xa4f4b28562f43336
+963, 0x885b4335457bd84a
+964, 0x499d3ed26c87ad8a
+965, 0xc7328bcedb9a545e
+966, 0xc6dd76a6cbf5d2b2
+967, 0xba9c22be404ee1aa
+968, 0x70e6aee45f23521d
+969, 0x61e03a798593c177
+970, 0x171671f809c68213
+971, 0x28d54872fc1d914c
+972, 0x43c2fcd9bd098b53
+973, 0x172ad4c4a98b9d37
+974, 0x330860c9460f2516
+975, 0x49547f472df984f4
+976, 0x873b2436d3f0e114
+977, 0x6f99accf4ea050b6
+978, 0x5968ac874ed51613
+979, 0x4939d70d29a3c611
+980, 0x11f381ed28738d3d
+981, 0xa97430d36ab3a869
+982, 0xe6fa880801129e22
+983, 0xf84decbd8f48c913
+984, 0x4425c0ed1e9a82a5
+985, 0x7a1f9485e9929d5a
+986, 0xc7c51f155dfce1c6
+987, 0x9619a39501d74f2b
+988, 0x7c7035955dbf4c1b
+989, 0xc61ee569cf57c2c9
+990, 0x3eaf7c5b0df734e1
+991, 0xe71cb4064d1ede05
+992, 0x356e3cec80e418b2
+993, 0xca04306243a15be6
+994, 0x941cf3881fa18896
+995, 0x30dbb0e819d644e0
+996, 0xaae22c0bef02859a
+997, 0x7bd30917bbaa8a94
+998, 0x2672547bc8d7d329
+999, 0x4955c92aaa231578
diff --git a/numpy/random/tests/data/pcg64dxsm-testset-2.csv b/numpy/random/tests/data/pcg64dxsm-testset-2.csv
new file mode 100644
index 000000000..878c5ea7c
--- /dev/null
+++ b/numpy/random/tests/data/pcg64dxsm-testset-2.csv
@@ -0,0 +1,1001 @@
+seed, 0x0
+0, 0xd97e4a147f788a70
+1, 0x8dfa7bce56e3a253
+2, 0x13556ed9f53d3c10
+3, 0x55dbf1c241341e98
+4, 0xa2cd98f722eb0e0a
+5, 0x83dfc407203ade8
+6, 0xeaa083df518f030d
+7, 0x44968c87e432852b
+8, 0x573107b9cb8d9ecc
+9, 0x9eedd1da50b9daca
+10, 0xb33a6735ca451e3c
+11, 0x72830d2b39677262
+12, 0x9da8c512fd0207e8
+13, 0x1fc5c91954a2672b
+14, 0xd33479437116e08
+15, 0x9ccdd9390cee46f3
+16, 0x1fd39bb01acd9e76
+17, 0xedc1869a42ff7fe5
+18, 0xbd68ca0b42a6e7e9
+19, 0x620b67df09621b1f
+20, 0xfa11d51bd6950221
+21, 0xc8c45b36e7d28d08
+22, 0xe9c91272fbaad777
+23, 0x2dc87a143f220e90
+24, 0x6376a7c82361f49d
+25, 0x552c5e434232fe75
+26, 0x468f7f872ac195bc
+27, 0x32bed6858125cf89
+28, 0xe4f06111494d09d3
+29, 0xa5c166ffea248b80
+30, 0x4e26605b97064a3f
+31, 0xceafd9f6fc5569d
+32, 0xb772f2f9eed9e106
+33, 0x672c65e6a93534e2
+34, 0xcdc5e1a28d1bd6a0
+35, 0x1ed9c96daeebd3e3
+36, 0x4d189dcfc0c93c3f
+37, 0x50df5a95c62f4b43
+38, 0xcccf4949fa65bbb8
+39, 0x19b8073d53cdc984
+40, 0x6fb40bba35483703
+41, 0xb02de4aef86b515a
+42, 0x4d90c63655350310
+43, 0xea44e4089825b16c
+44, 0x8d676958b1f9da2b
+45, 0x6d313940917ae195
+46, 0x1b1d35a4c1dd19f4
+47, 0x117720f8397337ef
+48, 0xcc073cf3ac11eeaa
+49, 0x8331ec58a9ff8acb
+50, 0xf3dc2a308b6b866f
+51, 0x7eba1202663382b6
+52, 0x8269839debeb4e5a
+53, 0x87fd3dc0f9181a8e
+54, 0xabe62ddd3c925f03
+55, 0x7f56f146944fe8d4
+56, 0xc535972150852068
+57, 0x60b252d453bd3a68
+58, 0x4251f0134634490a
+59, 0x338950da210dfeb2
+60, 0xcadfe932971c9471
+61, 0xfb7049457fab470e
+62, 0x9bfb8145a4459dff
+63, 0x4a89dda3898f9d8a
+64, 0x88cc560151483929
+65, 0x277dc820f4b6796e
+66, 0x3524bd07ea0afb88
+67, 0x92eb6ffb2bf14311
+68, 0xf6559be0783f3fe9
+69, 0xf0844f9af54af00d
+70, 0xdd5e0b59adcef8a
+71, 0x4ff7e4f2ab18554c
+72, 0x3fa22c8a02634587
+73, 0x1db8e1a9442fe300
+74, 0x40cf15953ad3d3e7
+75, 0x92af15fe1a9f6f0a
+76, 0xab4a0e466fb0cfd
+77, 0x944f1555a06cca82
+78, 0x10cf48412f1f6066
+79, 0x7f51f9a455f9e8e1
+80, 0x47ee93530f024c7e
+81, 0x36cf2f0413e0f6f2
+82, 0xa315e23731969407
+83, 0xd8e2796327cf5f87
+84, 0xa86072696a555c34
+85, 0xee3f0b8804feaab7
+86, 0x41e80dc858f8360b
+87, 0x31ec2e9b78f5b29
+88, 0xd397fb9b8561344c
+89, 0x28081e724e649b74
+90, 0x5c135fc3fc672348
+91, 0x9a276ca70ce9caa0
+92, 0x9216da059229050a
+93, 0xcf7d375ed68007b0
+94, 0xa68ad1963724a770
+95, 0xd4350de8d3b6787c
+96, 0xee7d2c2cc275b6d2
+97, 0x71645ec738749735
+98, 0x45abdf8c68d33dbb
+99, 0xe71cadb692c705ea
+100, 0x60af6f061fd90622
+101, 0x1eabe2072632c99d
+102, 0x947dda995a402cb6
+103, 0xbb19f49a3454f3b
+104, 0xe6e43e907407758c
+105, 0xfe2b67016bd6873a
+106, 0x7fdb4dd8ab30a722
+107, 0x39d3265b0ff1a45b
+108, 0xed24c0e4fce8d0c2
+109, 0xf6e074f86faf669d
+110, 0x9142040df8dc2a79
+111, 0x9682ab16bc939a9c
+112, 0x6a4e80c378d971c8
+113, 0x31309c2c7fc2d3d6
+114, 0xb7237ec682993339
+115, 0x6a30c06bb83dccd9
+116, 0x21c8e9b6d8e7c382
+117, 0x258a24ae6f086a19
+118, 0xb76edb5be7df5c35
+119, 0x3c11d7d5c16e7175
+120, 0xbdfc34c31eff66e1
+121, 0x8af66e44be8bf3a2
+122, 0x3053292e193dec28
+123, 0xd0cc44545b454995
+124, 0x408ac01a9289d56
+125, 0x4e02d34318ec2e85
+126, 0x9413ff3777c6eb6b
+127, 0xa3a301f8e37eb3df
+128, 0x14e6306bd8d8f9f9
+129, 0xd3ea06ce16c4a653
+130, 0x170abe5429122982
+131, 0x7f9e6fddc6cacb85
+132, 0xa41b93e10a10a4c8
+133, 0x239216f9d5b6d0b5
+134, 0x985fcb6cb4190d98
+135, 0xb45e3e7c68f480c6
+136, 0xc1b2fc2e0446211c
+137, 0x4596adb28858c498
+138, 0x2dd706f3458ddc75
+139, 0x29c988c86f75464
+140, 0xac33a65aa679a60
+141, 0xa28fef762d39d938
+142, 0x541e6fa48647f53
+143, 0x27838d56b2649735
+144, 0x8e143d318a796212
+145, 0xaea6097745f586b8
+146, 0x636143330f8ee2e6
+147, 0xc2d05fd8b945b172
+148, 0x6e355f9eb4353055
+149, 0xeb64ca42e8bf282e
+150, 0xe8202dfd9da0fe5
+151, 0x7305689c9d790cba
+152, 0xf122f8b1bef32970
+153, 0x9562887e38c32ba5
+154, 0xf9cd9be121b738d
+155, 0x6238e0c398307913
+156, 0x5f2e79bb07c30f47
+157, 0x8ce8e45c465006e
+158, 0x39281fe1e99e2441
+159, 0xafb10c2ca2874fea
+160, 0x6e52f91633f83cf
+161, 0x8ff12c1ac73c4494
+162, 0xe48608a09365af59
+163, 0xefd9bbc7e76e6a33
+164, 0xbe16a39d5c38ec92
+165, 0x6a6ffbcaf5a2330f
+166, 0xdd5d6ac7d998d43d
+167, 0x207bf978226d4f11
+168, 0xf8eec56bd2a0f62e
+169, 0xa5bccf05dce0d975
+170, 0x93cf3ec1afe457a6
+171, 0x38651466d201f736
+172, 0x3ad21473985c9184
+173, 0xc6407a3bd38c92a6
+174, 0xb1ec42c7afa90a25
+175, 0xbdeca984df8b7dd3
+176, 0xb6926b1d00aa6c55
+177, 0x86141d0022352d49
+178, 0x169316256135ee09
+179, 0xffb1c7767af02a5c
+180, 0x502af38ad19f5c91
+181, 0xfbf6cbc080086658
+182, 0x33cf9b219edae501
+183, 0x46e69bebd77b8862
+184, 0xf11e0cc91125d041
+185, 0xb4cd1649f85e078f
+186, 0xb49be408db4e952
+187, 0xb0b8db46140cce3c
+188, 0xba647f2174012be7
+189, 0x4f0a09e406970ac9
+190, 0xf868c7aec9890a5c
+191, 0xde4c8fa7498ea090
+192, 0x872ceb197978c1d4
+193, 0x1eb5cd9c3269b258
+194, 0x3ea189f91724f014
+195, 0x41379656f7746f2c
+196, 0x7bd18493aca60e51
+197, 0x5380c23b0cbbf15e
+198, 0x920b72835f88246b
+199, 0x24d7f734a4548b8e
+200, 0x9944edb57e5aa145
+201, 0x4628e136ebb8afe1
+202, 0xb4ee6a776356e2a7
+203, 0x481cbe9744ccf7d7
+204, 0x7e8d67e8b0b995d9
+205, 0xeeacde100af7b47e
+206, 0x103da08f2487dab7
+207, 0x6b9890a91d831459
+208, 0xd0c5beae37b572c7
+209, 0xfdccc371ee73fcc
+210, 0x65438f0a367a2003
+211, 0x5d23b2c818a7e943
+212, 0x9a8ed45ac04b58b3
+213, 0xdaf3c3f1695dce10
+214, 0x5960eec706fa2bc0
+215, 0x98ca652facb80d40
+216, 0x72970ae5e2194143
+217, 0x18c6374d878c5c94
+218, 0x20fa51f997381900
+219, 0x3af253dba26d6e1d
+220, 0x1b23d65db15c7f78
+221, 0x9f53ae976259b0e3
+222, 0x9a6addb28dc92d49
+223, 0x1e085c4accd0a7d7
+224, 0xe9d3f4cc9bad6ce5
+225, 0xe018fad78b5b1059
+226, 0x5ef7682232b4b95
+227, 0xb2242aa649f5de80
+228, 0x8f3e6d8dd99b9e4e
+229, 0xb9be6cc22949d62a
+230, 0xecbdc7beaa5ff1fe
+231, 0xd388db43a855bdf0
+232, 0xd71ee3238852568d
+233, 0x85ab3056304c04b5
+234, 0x2ed7ae7ad3cfc3cb
+235, 0x781d1b03d40b6c48
+236, 0x7d3c740886657e6d
+237, 0x982cfa6828daa6b0
+238, 0x278579599c529464
+239, 0x773adecfae9f0e08
+240, 0x63a243ea4b85c5d7
+241, 0x59940074fc3709e1
+242, 0xc914a2eed58a6363
+243, 0x2602b04274dd724c
+244, 0xdf636eb7636c2c42
+245, 0x891a334d0d26c547
+246, 0xde8cd586d499e22d
+247, 0x3ea1aa4d9b7035b6
+248, 0xd085cff6f9501523
+249, 0xe82a872f374959e
+250, 0x55cb495bbd42cc53
+251, 0x5f42b3226e56ca97
+252, 0xea463f6f203493a3
+253, 0xeef3718e57731737
+254, 0x1bd4f9d62b7f9f3c
+255, 0x19284f5e74817511
+256, 0xaf6e842c7450ca87
+257, 0x1d27d2b08a6b3600
+258, 0xfb4b912b396a52e3
+259, 0x30804d4c5c710121
+260, 0x4907e82564e36338
+261, 0x6441cf3b2900ddb7
+262, 0xd76de6f51988dc66
+263, 0x4f298ef96fd5e6d2
+264, 0x65432960c009f83d
+265, 0x65ebed07e1d2e3df
+266, 0xf83ee8078febca20
+267, 0x7bb18e9d74fc5b29
+268, 0x597b5fbc2261d91
+269, 0xea4f8ed0732b15b2
+270, 0xba2267f74f458268
+271, 0x3f304acabd746bbb
+272, 0x7bd187af85659a82
+273, 0x88e20dbdb7a08ea3
+274, 0x2a2dc948c772fcb4
+275, 0x87784fec2993c867
+276, 0x89163933cd362d4e
+277, 0xfd7b24f04302f957
+278, 0x9bdd544405dfb153
+279, 0xddee0fac58ffc611
+280, 0xa8e8993417e71ec1
+281, 0x55e0ab46ff7757af
+282, 0x53e7645f08d3d7df
+283, 0xbf78e563bc656ba2
+284, 0x1d162253b45ee2de
+285, 0x15e2bfefedf29eb4
+286, 0x4e2a4584aa394702
+287, 0xa89fb12b01525897
+288, 0x825bd98f0544e4df
+289, 0xfc6c50da6750700
+290, 0xc24aaabde7d28423
+291, 0x79d6f4660fcb19e5
+292, 0xee7d4fb40c8d659f
+293, 0x70bc281b462e811d
+294, 0x23ed4dc9636519a7
+295, 0xcb7c3f5a5711b935
+296, 0xe73090e0508c5d9d
+297, 0xb25a331f375952a6
+298, 0xa64c86e0c04740f6
+299, 0xb8f3ffc8d56ac124
+300, 0x2479266fc5ee6b15
+301, 0x8d5792d27f5ffbcb
+302, 0xb064298be946cd52
+303, 0xf0934a98912ffe26
+304, 0xbe805682c6634d98
+305, 0xe0e6e2c010012b4f
+306, 0x58c47d475f75976
+307, 0x358c9a6e646b2b4a
+308, 0x7e7c4ffca5b17ba7
+309, 0x43585c8c9a24a04c
+310, 0x5154ddbcd68d5c2c
+311, 0x4a2b062d3742a5e
+312, 0xca5691191da2b946
+313, 0x696a542109457466
+314, 0x9eb5d658a5022ba5
+315, 0x8158cf6b599ab8dc
+316, 0x1b95391eaa4af4a6
+317, 0x9953e79bd0fc3107
+318, 0x8639690086748123
+319, 0x2d35781c287c6842
+320, 0x393ef0001cd7bc8f
+321, 0xe3a61be8c5f2c22a
+322, 0x5e4ff21b847cc29b
+323, 0x4c9c9389a370eb84
+324, 0xd43a25a8fc3635fa
+325, 0xf6790e4a85385508
+326, 0x37edf0c81cb95e1d
+327, 0x52db00d6e6e79af8
+328, 0x3b202bceeb7f096
+329, 0x2a164a1c776136bb
+330, 0x73e03ee3fd80fd1b
+331, 0xd2c58c0746b8d858
+332, 0x2ed2cb0038153d22
+333, 0x98996d0fc8ceeacc
+334, 0xa4ed0589936b37f
+335, 0x5f61cf41a6d2c172
+336, 0xa6d4afb538c110d7
+337, 0xe85834541baadf1a
+338, 0x4c8967107fd49212
+339, 0x49bafb762ab1a8c1
+340, 0x45d540e2a834bf17
+341, 0x1c0ec8b4ed671dac
+342, 0x3d503ce2c83fe883
+343, 0x437bfffd95f42022
+344, 0xc82d1e3d5c2bc8d2
+345, 0x7a0a9cbfcb0d3f24
+346, 0xc0a4f00251b7a3be
+347, 0xb5be24e74bb6a1c6
+348, 0xa3104b94b57545b1
+349, 0x86de7d0c4b97b361
+350, 0x879c1483f26538a6
+351, 0xd74c87557f6accfb
+352, 0x2f9be40dbf0fe8a1
+353, 0x445a93398f608d89
+354, 0x7b3cb8a7211d7fdc
+355, 0xe86cc51290d031e7
+356, 0x33ef3594052ad79f
+357, 0xc61911d241dbb590
+358, 0x37cccb0c0e3de461
+359, 0xb75259124080b48b
+360, 0xd81e8961beb4abe5
+361, 0xf4542deb84a754e
+362, 0x6ea036d00385f02e
+363, 0xa7b60b0ac3b88681
+364, 0x108a6c36ca30baf5
+365, 0x4a2adc5bbfe2bf07
+366, 0x4079501f892a5342
+367, 0x55e113963c5448f0
+368, 0x8019ff4903b37242
+369, 0x109c6dcdb7ec6618
+370, 0x1239ac50944da450
+371, 0xe1399c7f94c651c1
+372, 0x5a6bbbae388d365a
+373, 0x4d72be57b8810929
+374, 0x3f067df24384e1fb
+375, 0x4f8b9e0f7f6c7be
+376, 0x202492c342a3b08
+377, 0x250753192af93a3
+378, 0xfba1159d9de2cb8e
+379, 0xba964497ab05505c
+380, 0x1329ec5d8a709dca
+381, 0x32927cacb6cd22bb
+382, 0x6b4d7db904187d56
+383, 0xe76adccf8e841e02
+384, 0x8c4bf4b6a788202
+385, 0x3013a3b409831651
+386, 0x7427d125c475412f
+387, 0x84dcc4bb2bf43202
+388, 0x117526f1101372a5
+389, 0xfe95d64b8984bd72
+390, 0x524e129934cc55c1
+391, 0xc3db4b0418c36d30
+392, 0xe1cb2047e9c19f7a
+393, 0xea43d6c8d8982795
+394, 0xe80ac8a37df89ed
+395, 0xfecc2104329ed306
+396, 0xa5c38aac9c1d51ea
+397, 0x3abe5d1c01e4fe17
+398, 0x717a805d97fcc7ac
+399, 0x94441f8207a1fb78
+400, 0x22d7869c5f002607
+401, 0x349e899f28c3a1b9
+402, 0x5639950cdea92b75
+403, 0x7e08450497c375b
+404, 0x94bf898b475d211d
+405, 0x75c761a402375104
+406, 0x1930920ec9d2a1e7
+407, 0xb774ba1bc6f6e4e2
+408, 0xf715602412e5d900
+409, 0x87bb995f4a13f0ba
+410, 0xa3c787868dfa9c8d
+411, 0xa17fd42a5a4f0987
+412, 0x4a9f7d435242b86
+413, 0x240364aff88f8aef
+414, 0xe7cd4cf4bf39f144
+415, 0xd030f313ca4c2692
+416, 0xc46696f4e03ec1e9
+417, 0x22c60f1ec21060b3
+418, 0x16c88058fd68986f
+419, 0x69ca448e8e6bde3f
+420, 0x3466c2cdec218abd
+421, 0x837ac4d05e6b117d
+422, 0x911210e154690191
+423, 0x9ece851d6fa358b7
+424, 0x42f79cb0c45e7897
+425, 0xbf7583babd7c499b
+426, 0x2059fe8031c6e0b9
+427, 0xabbec8fc00f7e51d
+428, 0x88809d86a3a256e1
+429, 0xd36056df829fdcb5
+430, 0x515632b6cb914c64
+431, 0xba76d06c2558874
+432, 0x632c54ca4214d253
+433, 0xadec487adf2cb215
+434, 0x521e663e1940513d
+435, 0xb1b638b548806694
+436, 0xbe2d5bfbe57d2c72
+437, 0x8b89e7719db02f7
+438, 0x90ba5281c1d56e63
+439, 0x899e1b92fceea102
+440, 0xf90d918e15182fa6
+441, 0x94a489ce96c948c4
+442, 0xad34db453517fcd4
+443, 0xc5264eb2de15930f
+444, 0x101b4e6603a21cee
+445, 0xef9b6258d6e85fff
+446, 0x6075c7d6c048bd7a
+447, 0x6f03232c64e438aa
+448, 0x18c983d7105ee469
+449, 0x3ffc23f5c1375879
+450, 0xbc1b4a00afb1f9f
+451, 0x5afa6b2bb8c6b46e
+452, 0xe7fce4af2f2c152a
+453, 0x5b00ab5c4b3982c7
+454, 0x2d4b0c9c0eb4bd0c
+455, 0x61d926270642f1f2
+456, 0x7219c485c23a2377
+457, 0x7e471c752fecd895
+458, 0x23c4d30a4d17ba1f
+459, 0x65cb277fe565ca22
+460, 0xcbb56ed9c701363b
+461, 0xfd04ab3a6eba8282
+462, 0x19c9e5c8bab38500
+463, 0xea4c15227676b65b
+464, 0x20f3412606c8da6f
+465, 0xb06782d3bf61a239
+466, 0xf96e02d5276a9a31
+467, 0x835d256b42aa52a6
+468, 0x25b09151747f39c1
+469, 0x64507386e1103eda
+470, 0x51cbc05716ef88e4
+471, 0x998cd9b7989e81cc
+472, 0x9d7115416bec28d1
+473, 0xc992ca39de97906b
+474, 0xd571e6f7ca598214
+475, 0xafc7fb6ccd9abbf8
+476, 0x88ef456febff7bf4
+477, 0xdbe87ccc55b157d2
+478, 0xaab95e405f8a4f6d
+479, 0xad586a385e74af4f
+480, 0x23cd15225c8485aa
+481, 0x370940bf47900ac7
+482, 0xefd6afda1a4b0ead
+483, 0x9cb1a4c90993dd7a
+484, 0xff7893e8b2f70b11
+485, 0xb09e1807c0638e8e
+486, 0xb10915dcb4978f74
+487, 0x88212ab0051a85eb
+488, 0x7af41b76e1ec793f
+489, 0x2e5c486406d3fefd
+490, 0xebe54eff67f513cc
+491, 0xab6c90d0876a79b8
+492, 0x224df82f93fe9089
+493, 0xc51c1ce053dc9cd2
+494, 0x5ef35a4d8a633ee7
+495, 0x4aca033459c2585f
+496, 0xd066932c6eefb23d
+497, 0x5309768aab9a7591
+498, 0xa2a3e33823df37f9
+499, 0xcec77ff6a359ee9
+500, 0x784dc62d999d3483
+501, 0x84e789fb8acc985d
+502, 0xd590237e86aa60f
+503, 0x737e2ffe1c8ad600
+504, 0xc019c3a39a99eab8
+505, 0x6a39e9836964c516
+506, 0xe0fe43129535d9da
+507, 0xdfc5f603d639d4de
+508, 0x7b9a7d048a9c03b6
+509, 0xbb5aa520faa27fdd
+510, 0x2a09b4200f398fa2
+511, 0x38cc88107904064e
+512, 0xa9a90d0b2d92bb25
+513, 0x9419762f87e987e3
+514, 0x1a52c525153dedcd
+515, 0xc26d9973dd65ae99
+516, 0x8e89bd9d0dc6e6a1
+517, 0x2f30868dc01bfb53
+518, 0x20f09d99b46501c4
+519, 0x78b468a563b8f1e9
+520, 0xcccf34b0b6c380c7
+521, 0xf554e7dc815297e6
+522, 0x332a585cfb4a50ef
+523, 0xa9fb64a2b6da41d7
+524, 0xdcd2a5a337391ce0
+525, 0x8a9bd3e324c6463d
+526, 0x9f4487d725503bdd
+527, 0xf72282d82f1d0ff
+528, 0x308f4160abb72d42
+529, 0x648de1db3a601b08
+530, 0x36cab5192e7ebd39
+531, 0x7975fbe4ab6a1c66
+532, 0xd515b4d72243864e
+533, 0x43a568f8b915e895
+534, 0x15fa9f2057bdb91d
+535, 0x7a43858ef7a222dc
+536, 0x17b4a9175ac074fe
+537, 0xa932c833b8d0f8f8
+538, 0x1d2db93a9a587678
+539, 0x98abd1d146124d27
+540, 0xf0ab0431671740aa
+541, 0xa9d182467540ad33
+542, 0x41c8a6cfc331b7fc
+543, 0xa52c6bd0fcd1d228
+544, 0x2773c29a34dc6fa3
+545, 0x3098230746fc1f37
+546, 0xd63311bb4f23fabe
+547, 0x6712bf530cd2faec
+548, 0x342e8f342e42c4dd
+549, 0xfbd83331851cdcad
+550, 0xe903be1361bbc34d
+551, 0xd94372e5077e3ef9
+552, 0x95aaa234f194bd8
+553, 0x20c0c8fb11e27538
+554, 0xfaf47dc90462b30b
+555, 0x8ddc6d144147682a
+556, 0xf626833fd926af55
+557, 0x5df93c34290d1793
+558, 0xb06a903e6e9fca5e
+559, 0x10c792dc851d77ca
+560, 0xd9b1b817b18e56cb
+561, 0x3a81730c408eb408
+562, 0x65052c04a8d4b63c
+563, 0x3328546598e33742
+564, 0xeca44a13f62d156d
+565, 0x69f83d1d86b20170
+566, 0x937764200412027d
+567, 0xc57eb1b58df0f191
+568, 0xa1c7d67dce81bc41
+569, 0x8e709c59a6a579ce
+570, 0x776a2f5155d46c70
+571, 0xd92906fbbc373aa5
+572, 0xe97ad478a2a98bf6
+573, 0xc296c8819ac815f
+574, 0x613ede67ba70e93e
+575, 0xe145222498f99cde
+576, 0xafcdfa7a3c1cf9bf
+577, 0x1c89252176db670d
+578, 0xad245eda5c0865ff
+579, 0x249463d3053eb917
+580, 0xc9be16d337517c0b
+581, 0xefcc82bf67b8f731
+582, 0x1e01577d029e0d00
+583, 0xad9c24b2a4f3d418
+584, 0xed2cceb510db4d0f
+585, 0xbddadcdb92400c70
+586, 0x67d6b0476ef82186
+587, 0xbc7662ff7bf19f73
+588, 0x9d94452a729e6e92
+589, 0x6b278d8594f55428
+590, 0x6c4b31cceb1b2109
+591, 0xccc6c3a726701e9
+592, 0x6bc28ece07df8925
+593, 0xc0422b7bf150ccc4
+594, 0xab7158f044e73479
+595, 0xdf3347546d9ed83f
+596, 0x3b3235a02c70dff4
+597, 0x2551c49c14ea8d77
+598, 0xee2f7f5bb3cc228e
+599, 0x39b87bfe8c882d39
+600, 0x7dd420fad380b51c
+601, 0xffe64976af093f96
+602, 0x4a4f48dc6e7eaa5f
+603, 0x85f2514d32fdc8cc
+604, 0x1ab1215fd7f94801
+605, 0x4cd1200fc795b774
+606, 0xcf8af463a38942ee
+607, 0x319caa7ce3022721
+608, 0x8cd9798a76d1aea4
+609, 0x2bd3933ac7afd34e
+610, 0x85d4c323403cf811
+611, 0xd7b956d3064efa30
+612, 0x67a078dbf1f13068
+613, 0x665fa6c83e87c290
+614, 0x9333ac2416d2469b
+615, 0xdfb1fd21a0094977
+616, 0xa1962a6e2c25f8ff
+617, 0x1f3b10a7ed5287cf
+618, 0x70641efb3d362713
+619, 0xe527a2cf85d00918
+620, 0x9741e45d3f9890a3
+621, 0x6cb74b5d4d36db4b
+622, 0xf24734d622bd2209
+623, 0xadd6d94f78e9d378
+624, 0xc3bbdb59225cca7f
+625, 0x5ad36614275b30cd
+626, 0x495568dd74eea434
+627, 0xf35de47e0ffe1f2d
+628, 0xefa209dca719ab18
+629, 0x844ddcaeb5b99ae8
+630, 0x37449670a1dc7b19
+631, 0x5a4612c166f845c1
+632, 0xe70f7782f2087947
+633, 0x98d484deac365721
+634, 0x705302198cf52457
+635, 0x7135ae0f5b77df41
+636, 0x342ac6e44a9b6fc3
+637, 0x2713fd2a59af5826
+638, 0x6e1a3f90f84efa75
+639, 0x9fb3b4dd446ca040
+640, 0x530044ae91e6bd49
+641, 0xe984c4183974dc3e
+642, 0x40c1fa961997d066
+643, 0xb7868250d8c21559
+644, 0x8bc929fa085fd1de
+645, 0x7bdb63288dc8733e
+646, 0xac4faad24326a468
+647, 0x1c6e799833aea0b1
+648, 0xcc8a749e94f20f36
+649, 0x4e7abfd0443547c5
+650, 0xb661c73bb8caa358
+651, 0x4a800f5728ff2351
+652, 0x8c15e15189b9f7ed
+653, 0xab367846b811362c
+654, 0x4ba7508f0851ca2a
+655, 0xe9af891acbafc356
+656, 0xbdebe183989601f8
+657, 0x4c665ea496afc061
+658, 0x3ca1d14a5f2ed7c
+659, 0xfbdff10a1027dd21
+660, 0xdfd28f77c8cff968
+661, 0xc4fbaadf8a3e9c77
+662, 0xdac7e448b218c589
+663, 0xb26390b5befd19e2
+664, 0xd2ef14916c66dba9
+665, 0xfab600284b0ff86b
+666, 0xf04a1c229b58dabb
+667, 0xc21c45637e452476
+668, 0xd1435966f75e0791
+669, 0xc1f28522eda4a2d0
+670, 0x52332ae8f1222185
+671, 0x81c6c0790c0bf47e
+672, 0xfebd215e7d8ffb86
+673, 0x68c5dce55dbe962b
+674, 0x231d09cb0d2531d1
+675, 0x3218fba199dbbc6b
+676, 0x8f23c535f8ea0bf6
+677, 0x6c228963e1df8bd9
+678, 0x9843c7722ed153e3
+679, 0xd032d99e419bddec
+680, 0xe2dca88aa7814cab
+681, 0x4d53fb8c6a59cdc2
+682, 0x8fb3abc46157b68b
+683, 0xa3e733087e09b8e
+684, 0x6bdc1aee029d6b96
+685, 0x4089667a8906d65b
+686, 0x8f3026a52d39dd03
+687, 0x6d2e0ccb567bae84
+688, 0x74bad450199e464
+689, 0xf114fb68a8f300d5
+690, 0xc7a5cc7b374c7d10
+691, 0xf0e93da639b279d1
+692, 0xb9943841ad493166
+693, 0x77a69290455a3664
+694, 0x41530da2ebea054b
+695, 0xe8f9fab03ea24abf
+696, 0xaa931f0c9f55a57a
+697, 0xb4d68a75d56f97ae
+698, 0x3d58ff898b6ba297
+699, 0x49d81e08faf5a3f5
+700, 0xfc5207b9f3697f3b
+701, 0xa25911abb3cf19b7
+702, 0x6b8908eb67c3a41
+703, 0xd63ef402e2e3fa33
+704, 0x728e75d3f33b14c5
+705, 0x248cb1b8bc6f379a
+706, 0x3aa3d6d2b8c72996
+707, 0x49cc50bd2d3d2860
+708, 0xb4e1387647c72075
+709, 0x435a1630a4a81ed3
+710, 0xa5ea13005d2460cf
+711, 0xc7a613df37d159ec
+712, 0x95721ccc218b857e
+713, 0xd4b70d8c86b124d3
+714, 0x2b82bcc4b612d494
+715, 0xaf13062885276050
+716, 0xcbd8fcf571a33d9c
+717, 0x3f7f67ca1125fc15
+718, 0xddf4bb45aac81b4c
+719, 0x23606da62de9c040
+720, 0xa3a172375666b636
+721, 0x292f87387a6c6c3c
+722, 0xd1d10d00c5496fe1
+723, 0x86b0411ce8a25550
+724, 0x38e0487872e33976
+725, 0x363e49f88ddfd42c
+726, 0x45bdf1e9f6b66b0a
+727, 0x8a6fff3de394f9b5
+728, 0x8502158bb03f6209
+729, 0x22e24d16dba42907
+730, 0x3fe3ba427cc2b779
+731, 0x77144793f66b3d7e
+732, 0xcf8912ccb29b8af9
+733, 0xdc856caff2abd670
+734, 0xe6d3ae0b0d9d4c8b
+735, 0xb8f5d40e454c539f
+736, 0x79ca953114fbc6b7
+737, 0x478d6f4bbfa38837
+738, 0x9babae1a3ffdc340
+739, 0x40edd56802bae613
+740, 0x97a56c2dcccf0641
+741, 0xafc250257f027f8e
+742, 0x8da41ef1edf69125
+743, 0x6574b0280ff9d309
+744, 0x197c776151b8f820
+745, 0x6b03e077c9dac3b6
+746, 0x24a40ebbc5c341c5
+747, 0x50e585169a6a1c4b
+748, 0x37783a5a6a3e4e02
+749, 0xb3de81ee6fbad647
+750, 0xf4f292f57ca4591e
+751, 0x6214e9e7d44d30a
+752, 0x5920190c56d21c12
+753, 0x9ac163419b5e0c9b
+754, 0xfc2328761ae8ed93
+755, 0xc68f945b545508c6
+756, 0x687c49a17ce0a5e2
+757, 0x276d8f53d30d4ab4
+758, 0x8201804970343ce1
+759, 0x1b5d323cc2e7fb7e
+760, 0x6f351ef04fd904b
+761, 0x6c793a7d455d5198
+762, 0x46f5d108430ae91f
+763, 0xac16a15b2a0cf77f
+764, 0xa0d479d9e4122b9d
+765, 0x3afd94604307f19
+766, 0x2573ed6d39d38dbf
+767, 0xa58e14ba60b4294b
+768, 0xe69c1aed5840d156
+769, 0x4cf6fda7f04855c2
+770, 0x2fb65a56ef5f22da
+771, 0xf95819434d5dc220
+772, 0x29c65133623dafba
+773, 0x8e997bd018467523
+774, 0xfd08ba9d498461a7
+775, 0xdd52243bc78a5592
+776, 0x39c30108f6db88b3
+777, 0x38af8e1894f259b9
+778, 0x97eedf3b4ae5f6de
+779, 0x757825add80c5ece
+780, 0xf0fdd90ac14edb14
+781, 0xbbb19d4cc8cac6d4
+782, 0x9a82234edfae05e3
+783, 0x704401c61d1edf1c
+784, 0x8b0eb481fb3a1fb2
+785, 0xef6f36e7cc06c002
+786, 0x7a208b17e04b8cd7
+787, 0xf20e33d498838fe9
+788, 0xc2bdb22117058326
+789, 0x6ec31939eb4ca543
+790, 0x6f1654838f507a21
+791, 0xc65ab81a955d2b93
+792, 0x40b1420fdd9531b8
+793, 0xe31f221cab9f4f40
+794, 0x798cdd414c1deb7a
+795, 0x9c84e9c7d41cd983
+796, 0x63d6b1ae3b60b7fa
+797, 0xb42bfdd1a2f78ffa
+798, 0x37e431eaccaaa8e9
+799, 0x7508142a0f73eac9
+800, 0x91662a023df5893a
+801, 0x59782070e2fe3031
+802, 0xb2acd589a8ce7961
+803, 0xa224743fa877b292
+804, 0xaa5362aa27e6ed9e
+805, 0xa394a4e520c0c1c7
+806, 0xe49b16d2018ffb6f
+807, 0xb8074b9f2f1e762b
+808, 0xcf5f86143d5c23a7
+809, 0xfd838785db987087
+810, 0x31b1889df389aff8
+811, 0x30aaca876a4383b
+812, 0x1731bb71c4c38d4f
+813, 0x9a83a65395e05458
+814, 0x99cd0c8d67c8f4fc
+815, 0xfbd9fdc849b761a5
+816, 0x82c04834fc466889
+817, 0xdeef9d6e715e8c97
+818, 0x549c281c16da6078
+819, 0x2d70661254ad599d
+820, 0x57995793a72acac
+821, 0xf1727005116183ba
+822, 0xa22bb38945285de3
+823, 0x4f2d687fe45131ff
+824, 0x5666c87ddbbc981f
+825, 0xbcb4b2d4e7a517d0
+826, 0x5e794dd2e20b785d
+827, 0x449ad020149e093c
+828, 0x7704ee0412d106f5
+829, 0x83cbdf257b072ac1
+830, 0xae5c4fc9f638b0da
+831, 0x7b9e5a64e372ed47
+832, 0x7eddbbb22c2cdf57
+833, 0x3f19ebfa155b08e
+834, 0x91d991154dfd7177
+835, 0x611ae74b952d387f
+836, 0x3fdf7a335bda36ee
+837, 0xdf182433fc7a7c05
+838, 0x62c78598d1f8db0a
+839, 0xc3750c69d2c5c1f0
+840, 0xf1318024709efdee
+841, 0xaa3fd360d224dc29
+842, 0x62af53b2f307c19
+843, 0xdf527683c58120c2
+844, 0x3281deecc496f93d
+845, 0x4f704ad31527ef08
+846, 0x127a14a5e07cfdfc
+847, 0x90d0b1f549255c92
+848, 0xbc3406b212c5e1fc
+849, 0x4e89f39379dba91d
+850, 0x1290ef43c4998e6e
+851, 0xecfeb1a1cb1c6e1b
+852, 0x2067e90403003bf1
+853, 0x38ae04be30bdbeba
+854, 0x8a3537f298baedda
+855, 0xd07f3b825cdb2936
+856, 0xea020b5aebae8b45
+857, 0xfcd614ab031132b0
+858, 0x5fb682a4ff2268f5
+859, 0xd1c4662ce65596f4
+860, 0x7026b8270dd0b8dc
+861, 0x8101ec4b4beae45a
+862, 0xa0e9dc87940610a6
+863, 0x83ec33679d83165b
+864, 0x981847ca82e86d41
+865, 0xda84c188a304a0b7
+866, 0x3c37529c5a5bbbb8
+867, 0x34a8491ce3e19a5a
+868, 0xd36ad716a2fa6cb8
+869, 0xfd1d1d6a5189a15c
+870, 0x9716eb47851e8d8d
+871, 0x7dfb13ea3b15c5aa
+872, 0xbdf6e707f45113a5
+873, 0xb8118261b04bd097
+874, 0x6191f9895881bec6
+875, 0x7aac257ae11acf9b
+876, 0x35a491e1537ff120
+877, 0xe078943432efa71c
+878, 0xb3338485dd3dc2b9
+879, 0x456060975d2bb3b5
+880, 0xaddc4c451bdfc44c
+881, 0x18bfa7beacf96430
+882, 0x8802ebcaf0f67498
+883, 0xad922a5a825bd780
+884, 0x9fb4587d748f4efa
+885, 0xdb2a445136cd5e7
+886, 0xb98b3676ea8e96ac
+887, 0xb02d8d244d784878
+888, 0xa1a8442b18860abb
+889, 0x6a3029ba1361e5d1
+890, 0xf426d5fac161eb1
+891, 0xfa5ac2b87acecb23
+892, 0xaa659896e50535df
+893, 0xf40dd7a3d3c5c8ed
+894, 0x3f8367abecb705bc
+895, 0x2d60e7525873358f
+896, 0xc4a9d3948a0c3937
+897, 0x5ecc04fef6003909
+898, 0x7a865004918cba2
+899, 0x47ae110a678ec10b
+900, 0xa0f02f629d91aa67
+901, 0x4848b99e7fac9347
+902, 0xaa858346d63b80ac
+903, 0xeb5bf42ee161eeef
+904, 0x4d35d723d3c6ba37
+905, 0xdf22ca6ca93b64a7
+906, 0x9d198520f97b25b1
+907, 0x3068415350778efe
+908, 0xf3709f2e8793c2fe
+909, 0xd1517bac8dd9f16f
+910, 0xfb99bccaa15861dc
+911, 0xa9ad607d796a2521
+912, 0x55d3793d36bd22e4
+913, 0xf99270d891ff7401
+914, 0x401750a5c4aa8238
+915, 0xd84b3003e6f28309
+916, 0x8a23798b5fa7c98b
+917, 0xadd58bbc8f43e399
+918, 0xbd8c741ada62c6a8
+919, 0xbdc6937bc55b49fa
+920, 0x4aefa82201b8502
+921, 0x17adf29a717b303
+922, 0xa6ed2197be168f6c
+923, 0x1ba47543f4359a95
+924, 0xe34299949ac01ae9
+925, 0x711c76cffc9b62f3
+926, 0xbac259895508a4b7
+927, 0x3c8b3b3626b0d900
+928, 0x1a8d23fbe2ae71bf
+929, 0xca984fa3b5a5c3a1
+930, 0xb1986ab7521a9c93
+931, 0xd6b5b2c8d47a75b5
+932, 0xc7f1c4a88afb4957
+933, 0xdeb58033a3acd6cc
+934, 0xabe49ddfe1167e67
+935, 0x8d559c10205c06e3
+936, 0xea07a1a7de67a651
+937, 0xcbef60db15b6fef8
+938, 0xbfca142cff280e7
+939, 0x362693eba0732221
+940, 0x7463237e134db103
+941, 0x45574ddb5035e17a
+942, 0xfc65e0cb9b94a1aa
+943, 0x3154c55f1d86b36d
+944, 0x2d93a96dd6ab2d8b
+945, 0xbe3bc1d1f2542a25
+946, 0xdd4b541f7385bdaa
+947, 0x3b56b919d914e3f8
+948, 0x82fd51468a21895f
+949, 0x8988cf120731b916
+950, 0xa06a61db5fb93e32
+951, 0x6ed66c1b36f68623
+952, 0x875ae844d2f01c59
+953, 0x17ccd7ac912e5925
+954, 0x12fe2a66b8e40cb1
+955, 0xf843e5e3923ad791
+956, 0xa17560f2fd4ef48
+957, 0x27a2968191a8ee07
+958, 0xa9aab4d22ff44a3c
+959, 0x63cd0dcc3bb083ae
+960, 0x7a30b48c6160bf85
+961, 0x956160fb572503b3
+962, 0xc47f6b7546640257
+963, 0xaf4b625f7f49153
+964, 0x2f5c86a790e0c7e8
+965, 0xb52e0610ae07f0b8
+966, 0x38a589292c3d849e
+967, 0xc3e9ef655d30b4ef
+968, 0xb5695f765cda998a
+969, 0xde5d5e692a028e91
+970, 0x839476721555f72e
+971, 0x48b20679b17d9ebf
+972, 0xe3d4c6b2c26fb0df
+973, 0xce5a9834f0b4e71f
+974, 0x533abb253d5d420e
+975, 0x9eac5ad9aed34627
+976, 0xc0f2a01ab3c90dbb
+977, 0x6528eda93f6a066c
+978, 0xc16a1b625e467ade
+979, 0x1a4a320fb5e8b098
+980, 0x8819cccd8b4ab32f
+981, 0x42daa88531fd0bfd
+982, 0xcf732226409be17c
+983, 0xfddcdb25ccbf378c
+984, 0x9b15b603bf589fc1
+985, 0x2436066b95d366fe
+986, 0x8d42eff2e9cbda90
+987, 0x694b2fc8a4e8303c
+988, 0x8e207f98aaea3ccd
+989, 0x4730d7a620f822d9
+990, 0x468dc9ca30fe2fd4
+991, 0x74b36d8a1c0f031b
+992, 0x3c1aac1c488c1a94
+993, 0x19d0101042444585
+994, 0x8ec50c56d0c8adf4
+995, 0x721ec629e4d66394
+996, 0x3ca5ad93abeac4a4
+997, 0xaaebc76e71592623
+998, 0x969cc319e3ed6058
+999, 0xc0a277e3b2bfc3de
diff --git a/numpy/random/tests/test_direct.py b/numpy/random/tests/test_direct.py
index d602b36b4..29054b70b 100644
--- a/numpy/random/tests/test_direct.py
+++ b/numpy/random/tests/test_direct.py
@@ -8,8 +8,8 @@ from numpy.testing import (assert_equal, assert_allclose, assert_array_equal,
import pytest
from numpy.random import (
- Generator, MT19937, PCG64, Philox, RandomState, SeedSequence, SFC64,
- default_rng
+ Generator, MT19937, PCG64, PCG64DXSM, Philox, RandomState, SeedSequence,
+ SFC64, default_rng
)
from numpy.random._common import interface
@@ -359,6 +359,34 @@ class TestPCG64(Base):
assert val_big == val_pos
+class TestPCG64DXSM(Base):
+ @classmethod
+ def setup_class(cls):
+ cls.bit_generator = PCG64DXSM
+ cls.bits = 64
+ cls.dtype = np.uint64
+ cls.data1 = cls._read_csv(join(pwd, './data/pcg64dxsm-testset-1.csv'))
+ cls.data2 = cls._read_csv(join(pwd, './data/pcg64dxsm-testset-2.csv'))
+ cls.seed_error_type = (ValueError, TypeError)
+ cls.invalid_init_types = [(3.2,), ([None],), (1, None)]
+ cls.invalid_init_values = [(-1,)]
+
+ def test_advance_symmetry(self):
+ rs = Generator(self.bit_generator(*self.data1['seed']))
+ state = rs.bit_generator.state
+ step = -0x9e3779b97f4a7c150000000000000000
+ rs.bit_generator.advance(step)
+ val_neg = rs.integers(10)
+ rs.bit_generator.state = state
+ rs.bit_generator.advance(2**128 + step)
+ val_pos = rs.integers(10)
+ rs.bit_generator.state = state
+ rs.bit_generator.advance(10 * 2**128 + step)
+ val_big = rs.integers(10)
+ assert val_neg == val_pos
+ assert val_big == val_pos
+
+
class TestMT19937(Base):
@classmethod
def setup_class(cls):
diff --git a/numpy/random/tests/test_generator_mt19937.py b/numpy/random/tests/test_generator_mt19937.py
index b69cd38d4..7ddccaf86 100644
--- a/numpy/random/tests/test_generator_mt19937.py
+++ b/numpy/random/tests/test_generator_mt19937.py
@@ -10,7 +10,7 @@ from numpy.testing import (
assert_warns, assert_no_warnings, assert_array_equal,
assert_array_almost_equal, suppress_warnings)
-from numpy.random import Generator, MT19937, SeedSequence
+from numpy.random import Generator, MT19937, SeedSequence, RandomState
random = Generator(MT19937())
@@ -142,6 +142,14 @@ class TestMultinomial:
assert_raises(ValueError, random.multinomial, 10, [[[0], [1]], [[1], [0]]])
assert_raises(ValueError, random.multinomial, 10, np.array([[0, 1], [1, 0]]))
+ def test_multinomial_pvals_float32(self):
+ x = np.array([9.9e-01, 9.9e-01, 1.0e-09, 1.0e-09, 1.0e-09, 1.0e-09,
+ 1.0e-09, 1.0e-09, 1.0e-09, 1.0e-09], dtype=np.float32)
+ pvals = x / x.sum()
+ random = Generator(MT19937(1432985819))
+ match = r"[\w\s]*pvals array is cast to 64-bit floating"
+ with pytest.raises(ValueError, match=match):
+ random.multinomial(1, pvals)
class TestMultivariateHypergeometric:
@@ -960,6 +968,14 @@ class TestRandomDist:
random.shuffle(actual, axis=-1)
assert_array_equal(actual, desired)
+ def test_shuffle_custom_axis_empty(self):
+ random = Generator(MT19937(self.seed))
+ desired = np.array([]).reshape((0, 6))
+ for axis in (0, 1):
+ actual = np.array([]).reshape((0, 6))
+ random.shuffle(actual, axis=axis)
+ assert_array_equal(actual, desired)
+
def test_shuffle_axis_nonsquare(self):
y1 = np.arange(20).reshape(2, 10)
y2 = y1.copy()
@@ -993,6 +1009,11 @@ class TestRandomDist:
arr = [[1, 2, 3], [4, 5, 6]]
assert_raises(NotImplementedError, random.shuffle, arr, 1)
+ arr = np.array(3)
+ assert_raises(TypeError, random.shuffle, arr)
+ arr = np.ones((3, 2))
+ assert_raises(np.AxisError, random.shuffle, arr, 2)
+
def test_permutation(self):
random = Generator(MT19937(self.seed))
alist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
@@ -1004,7 +1025,7 @@ class TestRandomDist:
arr_2d = np.atleast_2d([1, 2, 3, 4, 5, 6, 7, 8, 9, 0]).T
actual = random.permutation(arr_2d)
assert_array_equal(actual, np.atleast_2d(desired).T)
-
+
bad_x_str = "abcd"
assert_raises(np.AxisError, random.permutation, bad_x_str)
@@ -1231,9 +1252,9 @@ class TestRandomDist:
def test_geometric(self):
random = Generator(MT19937(self.seed))
actual = random.geometric(.123456789, size=(3, 2))
- desired = np.array([[ 1, 10],
- [ 1, 12],
- [ 9, 10]])
+ desired = np.array([[1, 11],
+ [1, 12],
+ [11, 17]])
assert_array_equal(actual, desired)
def test_geometric_exceptions(self):
@@ -1536,9 +1557,9 @@ class TestRandomDist:
def test_rayleigh(self):
random = Generator(MT19937(self.seed))
actual = random.rayleigh(scale=10, size=(3, 2))
- desired = np.array([[ 4.51734079831581, 15.6802442485758 ],
- [ 4.19850651287094, 17.08718809823704],
- [14.7907457708776 , 15.85545333419775]])
+ desired = np.array([[4.19494429102666, 16.66920198906598],
+ [3.67184544902662, 17.74695521962917],
+ [16.27935397855501, 21.08355560691792]])
assert_array_almost_equal(actual, desired, decimal=14)
def test_rayleigh_0(self):
@@ -1666,6 +1687,21 @@ class TestRandomDist:
# DBL_MAX by increasing fmin a bit
random.uniform(low=np.nextafter(fmin, 1), high=fmax / 1e17)
+ def test_uniform_zero_range(self):
+ func = random.uniform
+ result = func(1.5, 1.5)
+ assert_allclose(result, 1.5)
+ result = func([0.0, np.pi], [0.0, np.pi])
+ assert_allclose(result, [0.0, np.pi])
+ result = func([[2145.12], [2145.12]], [2145.12, 2145.12])
+ assert_allclose(result, 2145.12 + np.zeros((2, 2)))
+
+ def test_uniform_neg_range(self):
+ func = random.uniform
+ assert_raises(ValueError, func, 2, 1)
+ assert_raises(ValueError, func, [1, 2], [1, 1])
+ assert_raises(ValueError, func, [[0, 1],[2, 3]], 2)
+
def test_scalar_exception_propagation(self):
# Tests that exceptions are correctly propagated in distributions
# when called with objects that throw exceptions when converted to
@@ -1707,6 +1743,27 @@ class TestRandomDist:
r = random.vonmises(mu=0., kappa=np.nan)
assert_(np.isnan(r))
+ @pytest.mark.parametrize("kappa", [1e4, 1e15])
+ def test_vonmises_large_kappa(self, kappa):
+ random = Generator(MT19937(self.seed))
+ rs = RandomState(random.bit_generator)
+ state = random.bit_generator.state
+
+ random_state_vals = rs.vonmises(0, kappa, size=10)
+ random.bit_generator.state = state
+ gen_vals = random.vonmises(0, kappa, size=10)
+ if kappa < 1e6:
+ assert_allclose(random_state_vals, gen_vals)
+ else:
+ assert np.all(random_state_vals != gen_vals)
+
+ @pytest.mark.parametrize("mu", [-7., -np.pi, -3.1, np.pi, 3.2])
+ @pytest.mark.parametrize("kappa", [1e-9, 1e-6, 1, 1e3, 1e15])
+ def test_vonmises_large_kappa_range(self, mu, kappa):
+ random = Generator(MT19937(self.seed))
+ r = random.vonmises(mu, kappa, 50)
+ assert_(np.all(r > -np.pi) and np.all(r <= np.pi))
+
def test_wald(self):
random = Generator(MT19937(self.seed))
actual = random.wald(mean=1.23, scale=1.54, size=(3, 2))
@@ -2058,7 +2115,11 @@ class TestBroadcast:
def test_rayleigh(self):
scale = [1]
bad_scale = [-1]
- desired = np.array([0.60439534475066, 0.66120048396359, 1.67873398389499])
+ desired = np.array(
+ [1.1597068009872629,
+ 0.6539188836253857,
+ 1.1981526554349398]
+ )
random = Generator(MT19937(self.seed))
actual = random.rayleigh(scale * 3)
@@ -2498,3 +2559,49 @@ def test_broadcast_size_scalar():
random.normal(mu, sigma, size=3)
with pytest.raises(ValueError):
random.normal(mu, sigma, size=2)
+
+
+def test_ragged_shuffle():
+ # GH 18142
+ seq = [[], [], 1]
+ gen = Generator(MT19937(0))
+ assert_no_warnings(gen.shuffle, seq)
+ assert seq == [1, [], []]
+
+
+@pytest.mark.parametrize("high", [-2, [-2]])
+@pytest.mark.parametrize("endpoint", [True, False])
+def test_single_arg_integer_exception(high, endpoint):
+ # GH 14333
+ gen = Generator(MT19937(0))
+ msg = 'high < 0' if endpoint else 'high <= 0'
+ with pytest.raises(ValueError, match=msg):
+ gen.integers(high, endpoint=endpoint)
+ msg = 'low > high' if endpoint else 'low >= high'
+ with pytest.raises(ValueError, match=msg):
+ gen.integers(-1, high, endpoint=endpoint)
+ with pytest.raises(ValueError, match=msg):
+ gen.integers([-1], high, endpoint=endpoint)
+
+
+@pytest.mark.parametrize("dtype", ["f4", "f8"])
+def test_c_contig_req_out(dtype):
+ # GH 18704
+ out = np.empty((2, 3), order="F", dtype=dtype)
+ shape = [1, 2, 3]
+ with pytest.raises(ValueError, match="Supplied output array"):
+ random.standard_gamma(shape, out=out, dtype=dtype)
+ with pytest.raises(ValueError, match="Supplied output array"):
+ random.standard_gamma(shape, out=out, size=out.shape, dtype=dtype)
+
+
+@pytest.mark.parametrize("dtype", ["f4", "f8"])
+@pytest.mark.parametrize("order", ["F", "C"])
+@pytest.mark.parametrize("dist", [random.standard_normal, random.random])
+def test_contig_req_out(dist, order, dtype):
+ # GH 18704
+ out = np.empty((2, 3), dtype=dtype, order=order)
+ variates = dist(out=out, dtype=dtype)
+ assert variates is out
+ variates = dist(out=out, dtype=dtype, size=out.shape)
+ assert variates is out
diff --git a/numpy/random/tests/test_generator_mt19937_regressions.py b/numpy/random/tests/test_generator_mt19937_regressions.py
index 2ef6b0631..9f6dcdc6b 100644
--- a/numpy/random/tests/test_generator_mt19937_regressions.py
+++ b/numpy/random/tests/test_generator_mt19937_regressions.py
@@ -1,14 +1,14 @@
from numpy.testing import (assert_, assert_array_equal)
import numpy as np
import pytest
-from numpy.random import Generator, MT19937
+from numpy.random import Generator, MT19937, RandomState
mt19937 = Generator(MT19937())
class TestRegression:
- def test_VonMises_range(self):
+ def test_vonmises_range(self):
# Make sure generated random variables are in [-pi, pi].
# Regression test for ticket #986.
for mu in np.linspace(-7., 7., 5):
diff --git a/numpy/random/tests/test_random.py b/numpy/random/tests/test_random.py
index c13fc39e3..6a584a511 100644
--- a/numpy/random/tests/test_random.py
+++ b/numpy/random/tests/test_random.py
@@ -1,5 +1,7 @@
import warnings
+import pytest
+
import numpy as np
from numpy.testing import (
assert_, assert_raises, assert_equal, assert_warns,
@@ -510,6 +512,58 @@ class TestRandomDist:
assert_equal(
sorted(b.data[~b.mask]), sorted(b_orig.data[~b_orig.mask]))
+ @pytest.mark.parametrize("random",
+ [np.random, np.random.RandomState(), np.random.default_rng()])
+ def test_shuffle_untyped_warning(self, random):
+ # Create a dict works like a sequence but isn't one
+ values = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6}
+ with pytest.warns(UserWarning,
+ match="you are shuffling a 'dict' object") as rec:
+ random.shuffle(values)
+ assert "test_random" in rec[0].filename
+
+ @pytest.mark.parametrize("random",
+ [np.random, np.random.RandomState(), np.random.default_rng()])
+ @pytest.mark.parametrize("use_array_like", [True, False])
+ def test_shuffle_no_object_unpacking(self, random, use_array_like):
+ class MyArr(np.ndarray):
+ pass
+
+ items = [
+ None, np.array([3]), np.float64(3), np.array(10), np.float64(7)
+ ]
+ arr = np.array(items, dtype=object)
+ item_ids = {id(i) for i in items}
+ if use_array_like:
+ arr = arr.view(MyArr)
+
+ # The array was created fine, and did not modify any objects:
+ assert all(id(i) in item_ids for i in arr)
+
+ if use_array_like and not isinstance(random, np.random.Generator):
+ # The old API gives incorrect results, but warns about it.
+ with pytest.warns(UserWarning,
+ match="Shuffling a one dimensional array.*"):
+ random.shuffle(arr)
+ else:
+ random.shuffle(arr)
+ assert all(id(i) in item_ids for i in arr)
+
+ def test_shuffle_memoryview(self):
+ # gh-18273
+ # allow graceful handling of memoryviews
+ # (treat the same as arrays)
+ np.random.seed(self.seed)
+ a = np.arange(5).data
+ np.random.shuffle(a)
+ assert_equal(np.asarray(a), [0, 1, 4, 3, 2])
+ rng = np.random.RandomState(self.seed)
+ rng.shuffle(a)
+ assert_equal(np.asarray(a), [0, 1, 2, 3, 4])
+ rng = np.random.default_rng(self.seed)
+ rng.shuffle(a)
+ assert_equal(np.asarray(a), [4, 1, 0, 3, 2])
+
def test_beta(self):
np.random.seed(self.seed)
actual = np.random.beta(.1, .9, size=(3, 2))
diff --git a/numpy/random/tests/test_randomstate.py b/numpy/random/tests/test_randomstate.py
index b70a04347..861813a95 100644
--- a/numpy/random/tests/test_randomstate.py
+++ b/numpy/random/tests/test_randomstate.py
@@ -167,6 +167,14 @@ class TestMultinomial:
contig = random.multinomial(100, pvals=np.ascontiguousarray(pvals))
assert_array_equal(non_contig, contig)
+ def test_multinomial_pvals_float32(self):
+ x = np.array([9.9e-01, 9.9e-01, 1.0e-09, 1.0e-09, 1.0e-09, 1.0e-09,
+ 1.0e-09, 1.0e-09, 1.0e-09, 1.0e-09], dtype=np.float32)
+ pvals = x / x.sum()
+ match = r"[\w\s]*pvals array is cast to 64-bit floating"
+ with pytest.raises(ValueError, match=match):
+ random.multinomial(1, pvals)
+
class TestSetState:
def setup(self):
@@ -642,7 +650,7 @@ class TestRandomDist:
a = np.array([42, 1, 2])
p = [None, None, None]
assert_raises(ValueError, random.choice, a, p=p)
-
+
def test_choice_p_non_contiguous(self):
p = np.ones(10) / 5
p[1::2] = 3.0
@@ -699,6 +707,10 @@ class TestRandomDist:
assert_equal(
sorted(b.data[~b.mask]), sorted(b_orig.data[~b_orig.mask]))
+ def test_shuffle_invalid_objects(self):
+ x = np.array(3)
+ assert_raises(TypeError, random.shuffle, x)
+
def test_permutation(self):
random.seed(self.seed)
alist = [1, 2, 3, 4, 5, 6, 7, 8, 9, 0]
@@ -1234,6 +1246,15 @@ class TestRandomDist:
r = random.vonmises(mu=0., kappa=1.1e-8, size=10**6)
assert_(np.isfinite(r).all())
+ def test_vonmises_large(self):
+ # guard against changes in RandomState when Generator is fixed
+ random.seed(self.seed)
+ actual = random.vonmises(mu=0., kappa=1e7, size=3)
+ desired = np.array([4.634253748521111e-04,
+ 3.558873596114509e-04,
+ -2.337119622577433e-04])
+ assert_array_almost_equal(actual, desired, decimal=8)
+
def test_vonmises_nan(self):
random.seed(self.seed)
r = random.vonmises(mu=0., kappa=np.nan)
diff --git a/numpy/random/tests/test_smoke.py b/numpy/random/tests/test_smoke.py
index 909bfaa8d..9becc434d 100644
--- a/numpy/random/tests/test_smoke.py
+++ b/numpy/random/tests/test_smoke.py
@@ -4,7 +4,7 @@ from functools import partial
import numpy as np
import pytest
from numpy.testing import assert_equal, assert_, assert_array_equal
-from numpy.random import (Generator, MT19937, PCG64, Philox, SFC64)
+from numpy.random import (Generator, MT19937, PCG64, PCG64DXSM, Philox, SFC64)
@pytest.fixture(scope='module',
params=(np.bool_, np.int8, np.int16, np.int32, np.int64,
@@ -774,6 +774,18 @@ class TestPCG64(RNG):
cls._extra_setup()
+class TestPCG64DXSM(RNG):
+ @classmethod
+ def setup_class(cls):
+ cls.bit_generator = PCG64DXSM
+ cls.advance = 2**63 + 2**31 + 2**15 + 1
+ cls.seed = [12345]
+ cls.rg = Generator(cls.bit_generator(*cls.seed))
+ cls.initial_state = cls.rg.bit_generator.state
+ cls.seed_vector_bits = 64
+ cls._extra_setup()
+
+
class TestDefaultRNG(RNG):
@classmethod
def setup_class(cls):
diff --git a/numpy/rec.pyi b/numpy/rec.pyi
index c70ee5374..198636058 100644
--- a/numpy/rec.pyi
+++ b/numpy/rec.pyi
@@ -1,5 +1,65 @@
-from typing import Any
+from typing import List
-record: Any
-recarray: Any
-format_parser: Any
+from numpy import (
+ format_parser as format_parser,
+ record as record,
+ recarray as recarray,
+)
+
+__all__: List[str]
+
+def fromarrays(
+ arrayList,
+ dtype=...,
+ shape=...,
+ formats=...,
+ names=...,
+ titles=...,
+ aligned=...,
+ byteorder=...,
+): ...
+def fromrecords(
+ recList,
+ dtype=...,
+ shape=...,
+ formats=...,
+ names=...,
+ titles=...,
+ aligned=...,
+ byteorder=...,
+): ...
+def fromstring(
+ datastring,
+ dtype=...,
+ shape=...,
+ offset=...,
+ formats=...,
+ names=...,
+ titles=...,
+ aligned=...,
+ byteorder=...,
+): ...
+def fromfile(
+ fd,
+ dtype=...,
+ shape=...,
+ offset=...,
+ formats=...,
+ names=...,
+ titles=...,
+ aligned=...,
+ byteorder=...,
+): ...
+def array(
+ obj,
+ dtype=...,
+ shape=...,
+ offset=...,
+ strides=...,
+ formats=...,
+ names=...,
+ titles=...,
+ aligned=...,
+ byteorder=...,
+ copy=...,
+): ...
diff --git a/numpy/testing/__init__.py b/numpy/testing/__init__.py
index e1f87621f..bca1d3670 100644
--- a/numpy/testing/__init__.py
+++ b/numpy/testing/__init__.py
@@ -8,6 +8,8 @@ away.
from unittest import TestCase
from ._private.utils import *
+from ._private.utils import (_assert_valid_refcount, _gen_alignment_data,
+ IS_PYSTON)
from ._private import decorators as dec
from ._private.nosetester import (
run_module_suite, NoseTester as Tester
diff --git a/numpy/testing/__init__.pyi b/numpy/testing/__init__.pyi
index c394a387d..def0f9f58 100644
--- a/numpy/testing/__init__.pyi
+++ b/numpy/testing/__init__.pyi
@@ -1,44 +1,58 @@
-from typing import Any
+from typing import List
-assert_equal: Any
-assert_almost_equal: Any
-assert_approx_equal: Any
-assert_array_equal: Any
-assert_array_less: Any
-assert_string_equal: Any
-assert_array_almost_equal: Any
-assert_raises: Any
-build_err_msg: Any
-decorate_methods: Any
-jiffies: Any
-memusage: Any
-print_assert_equal: Any
-raises: Any
-rundocs: Any
-runstring: Any
-verbose: Any
-measure: Any
-assert_: Any
-assert_array_almost_equal_nulp: Any
-assert_raises_regex: Any
-assert_array_max_ulp: Any
-assert_warns: Any
-assert_no_warnings: Any
-assert_allclose: Any
-IgnoreException: Any
-clear_and_catch_warnings: Any
-SkipTest: Any
-KnownFailureException: Any
-temppath: Any
-tempdir: Any
-IS_PYPY: Any
-HAS_REFCOUNT: Any
-suppress_warnings: Any
-assert_array_compare: Any
-_assert_valid_refcount: Any
-_gen_alignment_data: Any
-assert_no_gc_cycles: Any
-break_cycles: Any
-HAS_LAPACK64: Any
-TestCase: Any
-run_module_suite: Any
+from numpy._pytesttester import PytestTester
+
+from unittest import (
+ TestCase as TestCase,
+)
+
+from numpy.testing._private.utils import (
+ assert_equal as assert_equal,
+ assert_almost_equal as assert_almost_equal,
+ assert_approx_equal as assert_approx_equal,
+ assert_array_equal as assert_array_equal,
+ assert_array_less as assert_array_less,
+ assert_string_equal as assert_string_equal,
+ assert_array_almost_equal as assert_array_almost_equal,
+ assert_raises as assert_raises,
+ build_err_msg as build_err_msg,
+ decorate_methods as decorate_methods,
+ jiffies as jiffies,
+ memusage as memusage,
+ print_assert_equal as print_assert_equal,
+ raises as raises,
+ rundocs as rundocs,
+ runstring as runstring,
+ verbose as verbose,
+ measure as measure,
+ assert_ as assert_,
+ assert_array_almost_equal_nulp as assert_array_almost_equal_nulp,
+ assert_raises_regex as assert_raises_regex,
+ assert_array_max_ulp as assert_array_max_ulp,
+ assert_warns as assert_warns,
+ assert_no_warnings as assert_no_warnings,
+ assert_allclose as assert_allclose,
+ IgnoreException as IgnoreException,
+ clear_and_catch_warnings as clear_and_catch_warnings,
+ SkipTest as SkipTest,
+ KnownFailureException as KnownFailureException,
+ temppath as temppath,
+ tempdir as tempdir,
+ IS_PYPY as IS_PYPY,
+ IS_PYSTON as IS_PYSTON,
+ HAS_REFCOUNT as HAS_REFCOUNT,
+ suppress_warnings as suppress_warnings,
+ assert_array_compare as assert_array_compare,
+ assert_no_gc_cycles as assert_no_gc_cycles,
+ break_cycles as break_cycles,
+ HAS_LAPACK64 as HAS_LAPACK64,
+)
+
+__all__: List[str]
+__path__: List[str]
+test: PytestTester
+
+def run_module_suite(
+ file_to_run: None | str = ...,
+ argv: None | List[str] = ...,
+) -> None: ...
diff --git a/numpy/testing/_private/decorators.py b/numpy/testing/_private/decorators.py
index 4c87d1a49..cb49d9a73 100644
--- a/numpy/testing/_private/decorators.py
+++ b/numpy/testing/_private/decorators.py
@@ -14,6 +14,7 @@ function name, setup and teardown functions and so on - see
"""
import collections.abc
+import warnings
from .utils import SkipTest, assert_warns, HAS_REFCOUNT
@@ -23,6 +24,10 @@ __all__ = ['slow', 'setastest', 'skipif', 'knownfailureif', 'deprecated',
def slow(t):
"""
+ .. deprecated:: 1.21
+ This decorator is retained for compatibility with the nose testing framework, which is being phased out.
+ Please use the nose2 or pytest frameworks instead.
+
Label a test as 'slow'.
The exact definition of a slow test is obviously both subjective and
@@ -52,12 +57,19 @@ def slow(t):
print('Big, slow test')
"""
+ # Numpy 1.21, 2020-12-20
+ warnings.warn('the np.testing.dec decorators are included for nose support, and are '
+ 'deprecated since NumPy v1.21. Use the nose2 or pytest frameworks instead.', DeprecationWarning, stacklevel=2)
t.slow = True
return t
def setastest(tf=True):
"""
+ .. deprecated:: 1.21
+ This decorator is retained for compatibility with the nose testing framework, which is being phased out.
+ Please use the nose2 or pytest frameworks instead.
+
Signals to nose that this function is or is not a test.
Parameters
@@ -84,6 +96,9 @@ def setastest(tf=True):
pass
"""
+ # Numpy 1.21, 2020-12-20
+ warnings.warn('the np.testing.dec decorators are included for nose support, and are '
+ 'deprecated since NumPy v1.21. Use the nose2 or pytest frameworks instead.', DeprecationWarning, stacklevel=2)
def set_test(t):
t.__test__ = tf
return t
@@ -91,6 +106,10 @@ def setastest(tf=True):
def skipif(skip_condition, msg=None):
"""
+ .. deprecated:: 1.21
+ This decorator is retained for compatibility with the nose testing framework, which is being phased out.
+ Please use the nose2 or pytest frameworks instead.
+
Make function raise SkipTest exception if a given condition is true.
If the condition is a callable, it is used at runtime to dynamically
@@ -123,6 +142,10 @@ def skipif(skip_condition, msg=None):
# import time overhead at actual test-time.
import nose
+ # Numpy 1.21, 2020-12-20
+ warnings.warn('the np.testing.dec decorators are included for nose support, and are '
+ 'deprecated since NumPy v1.21. Use the nose2 or pytest frameworks instead.', DeprecationWarning, stacklevel=2)
+
# Allow for both boolean or callable skip conditions.
if isinstance(skip_condition, collections.abc.Callable):
skip_val = lambda: skip_condition()
@@ -167,6 +190,10 @@ def skipif(skip_condition, msg=None):
def knownfailureif(fail_condition, msg=None):
"""
+ .. deprecated:: 1.21
+ This decorator is retained for compatibility with the nose testing framework, which is being phased out.
+ Please use the nose2 or pytest frameworks instead.
+
Make function raise KnownFailureException exception if given condition is true.
If the condition is a callable, it is used at runtime to dynamically
@@ -195,6 +222,10 @@ def knownfailureif(fail_condition, msg=None):
function in order to transmit function name, and various other metadata.
"""
+ # Numpy 1.21, 2020-12-20
+ warnings.warn('the np.testing.dec decorators are included for nose support, and are '
+ 'deprecated since NumPy v1.21. Use the nose2 or pytest frameworks instead.', DeprecationWarning, stacklevel=2)
+
if msg is None:
msg = 'Test skipped due to known failure'
@@ -221,6 +252,10 @@ def knownfailureif(fail_condition, msg=None):
def deprecated(conditional=True):
"""
+ .. deprecated:: 1.21
+ This decorator is retained for compatibility with the nose testing framework, which is being phased out.
+ Please use the nose2 or pytest frameworks instead.
+
Filter deprecation warnings while running the test suite.
This decorator can be used to filter DeprecationWarning's, to avoid
@@ -249,6 +284,10 @@ def deprecated(conditional=True):
# import time overhead at actual test-time.
import nose
+ # Numpy 1.21, 2020-12-20
+ warnings.warn('the np.testing.dec decorators are included for nose support, and are '
+ 'deprecated since NumPy v1.21. Use the nose2 or pytest frameworks instead.', DeprecationWarning, stacklevel=2)
+
def _deprecated_imp(*args, **kwargs):
# Poor man's replacement for the with statement
with assert_warns(DeprecationWarning):
@@ -267,6 +306,10 @@ def deprecated(conditional=True):
def parametrize(vars, input):
"""
+ .. deprecated:: 1.21
+ This decorator is retained for compatibility with the nose testing framework, which is being phased out.
+ Please use the nose2 or pytest frameworks instead.
+
Pytest compatibility class. This implements the simplest level of
pytest.mark.parametrize for use in nose as an aid in making the transition
to pytest. It achieves that by adding a dummy var parameter and ignoring
@@ -279,6 +322,10 @@ def parametrize(vars, input):
"""
from .parameterized import parameterized
+ # Numpy 1.21, 2020-12-20
+ warnings.warn('the np.testing.dec decorators are included for nose support, and are '
+ 'deprecated since NumPy v1.21. Use the nose2 or pytest frameworks instead.', DeprecationWarning, stacklevel=2)
+
return parameterized(input)
_needs_refcount = skipif(not HAS_REFCOUNT, "python has no sys.getrefcount")
diff --git a/numpy/testing/_private/parameterized.py b/numpy/testing/_private/parameterized.py
index ac7db6c40..db9629a94 100644
--- a/numpy/testing/_private/parameterized.py
+++ b/numpy/testing/_private/parameterized.py
@@ -37,11 +37,6 @@ from functools import wraps
from types import MethodType
from collections import namedtuple
-try:
- from collections import OrderedDict as MaybeOrderedDict
-except ImportError:
- MaybeOrderedDict = dict
-
from unittest import TestCase
_param = namedtuple("param", "args kwargs")
@@ -113,13 +108,6 @@ class param(_param):
return "param(*%r, **%r)" %self
-class QuietOrderedDict(MaybeOrderedDict):
- """ When OrderedDict is available, use it to make sure that the kwargs in
- doc strings are consistently ordered. """
- __str__ = dict.__str__
- __repr__ = dict.__repr__
-
-
def parameterized_argument_value_pairs(func, p):
"""Return tuples of parameterized arguments and their values.
@@ -165,7 +153,7 @@ def parameterized_argument_value_pairs(func, p):
])
seen_arg_names = {n for (n, _) in result}
- keywords = QuietOrderedDict(sorted([
+ keywords = dict(sorted([
(name, p.kwargs[name])
for name in p.kwargs
if name not in seen_arg_names
@@ -339,7 +327,7 @@ class parameterized:
"'@parameterized.expand' instead.")
def _terrible_magic_get_defining_classes(self):
- """ Returns the set of parent classes of the class currently being defined.
+ """ Returns the list of parent classes of the class currently being defined.
Will likely only work if called from the ``parameterized`` decorator.
This function is entirely @brandon_rhodes's fault, as he suggested
the implementation: http://stackoverflow.com/a/8793684/71522
diff --git a/numpy/testing/_private/utils.py b/numpy/testing/_private/utils.py
index fb33bdcbd..77ca4ef85 100644
--- a/numpy/testing/_private/utils.py
+++ b/numpy/testing/_private/utils.py
@@ -17,6 +17,7 @@ from unittest.case import SkipTest
from warnings import WarningMessage
import pprint
+import numpy as np
from numpy.core import(
intp, float32, empty, arange, array_repr, ndarray, isnat, array)
import numpy.linalg.lapack_lite
@@ -34,8 +35,7 @@ __all__ = [
'assert_allclose', 'IgnoreException', 'clear_and_catch_warnings',
'SkipTest', 'KnownFailureException', 'temppath', 'tempdir', 'IS_PYPY',
'HAS_REFCOUNT', 'suppress_warnings', 'assert_array_compare',
- '_assert_valid_refcount', '_gen_alignment_data', 'assert_no_gc_cycles',
- 'break_cycles', 'HAS_LAPACK64'
+ 'assert_no_gc_cycles', 'break_cycles', 'HAS_LAPACK64'
]
@@ -48,7 +48,8 @@ KnownFailureTest = KnownFailureException # backwards compat
verbose = 0
IS_PYPY = platform.python_implementation() == 'PyPy'
-HAS_REFCOUNT = getattr(sys, 'getrefcount', None) is not None
+IS_PYSTON = hasattr(sys, "pyston_version_info")
+HAS_REFCOUNT = getattr(sys, 'getrefcount', None) is not None and not IS_PYSTON
HAS_LAPACK64 = numpy.linalg.lapack_lite._ilp64
@@ -378,7 +379,8 @@ def assert_equal(actual, desired, err_msg='', verbose=True):
try:
isdesnat = isnat(desired)
isactnat = isnat(actual)
- dtypes_match = array(desired).dtype.type == array(actual).dtype.type
+ dtypes_match = (np.asarray(desired).dtype.type ==
+ np.asarray(actual).dtype.type)
if isdesnat and isactnat:
# If both are NaT (and have the same dtype -- datetime or
# timedelta) they are considered equal.
@@ -398,8 +400,8 @@ def assert_equal(actual, desired, err_msg='', verbose=True):
return # both nan, so equal
# handle signed zero specially for floats
- array_actual = array(actual)
- array_desired = array(desired)
+ array_actual = np.asarray(actual)
+ array_desired = np.asarray(desired)
if (array_actual.dtype.char in 'Mm' or
array_desired.dtype.char in 'Mm'):
# version 1.18
@@ -481,7 +483,7 @@ def assert_almost_equal(actual,desired,decimal=7,err_msg='',verbose=True):
instead of this function for more consistent floating point
comparisons.
- The test verifies that the elements of ``actual`` and ``desired`` satisfy.
+ The test verifies that the elements of `actual` and `desired` satisfy.
``abs(desired-actual) < 1.5 * 10**(-decimal)``
@@ -516,9 +518,9 @@ def assert_almost_equal(actual,desired,decimal=7,err_msg='',verbose=True):
Examples
--------
- >>> import numpy.testing as npt
- >>> npt.assert_almost_equal(2.3333333333333, 2.33333334)
- >>> npt.assert_almost_equal(2.3333333333333, 2.33333334, decimal=10)
+ >>> from numpy.testing import assert_almost_equal
+ >>> assert_almost_equal(2.3333333333333, 2.33333334)
+ >>> assert_almost_equal(2.3333333333333, 2.33333334, decimal=10)
Traceback (most recent call last):
...
AssertionError:
@@ -526,8 +528,8 @@ def assert_almost_equal(actual,desired,decimal=7,err_msg='',verbose=True):
ACTUAL: 2.3333333333333
DESIRED: 2.33333334
- >>> npt.assert_almost_equal(np.array([1.0,2.3333333333333]),
- ... np.array([1.0,2.33333334]), decimal=9)
+ >>> assert_almost_equal(np.array([1.0,2.3333333333333]),
+ ... np.array([1.0,2.33333334]), decimal=9)
Traceback (most recent call last):
...
AssertionError:
@@ -701,8 +703,8 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True, header='',
__tracebackhide__ = True # Hide traceback for py.test
from numpy.core import array, array2string, isnan, inf, bool_, errstate, all, max, object_
- x = array(x, copy=False, subok=True)
- y = array(y, copy=False, subok=True)
+ x = np.asanyarray(x)
+ y = np.asanyarray(y)
# original array for output formatting
ox, oy = x, y
@@ -745,7 +747,7 @@ def assert_array_compare(comparison, x, y, err_msg='', verbose=True, header='',
# flag as it everywhere, so we should return the scalar flag.
if isinstance(x_id, bool) or x_id.ndim == 0:
return bool_(x_id)
- elif isinstance(x_id, bool) or y_id.ndim == 0:
+ elif isinstance(y_id, bool) or y_id.ndim == 0:
return bool_(y_id)
else:
return y_id
@@ -1033,7 +1035,7 @@ def assert_array_almost_equal(x, y, decimal=6, err_msg='', verbose=True):
# make sure y is an inexact type to avoid abs(MIN_INT); will cause
# casting of x later.
dtype = result_type(y, 1.)
- y = array(y, dtype=dtype, copy=False, subok=True)
+ y = np.asanyarray(y, dtype)
z = abs(x - y)
if not issubdtype(z.dtype, number):
@@ -1678,11 +1680,11 @@ def nulp_diff(x, y, dtype=None):
"""
import numpy as np
if dtype:
- x = np.array(x, dtype=dtype)
- y = np.array(y, dtype=dtype)
+ x = np.asarray(x, dtype=dtype)
+ y = np.asarray(y, dtype=dtype)
else:
- x = np.array(x)
- y = np.array(y)
+ x = np.asarray(x)
+ y = np.asarray(y)
t = np.common_type(x, y)
if np.iscomplexobj(x) or np.iscomplexobj(y):
@@ -1699,7 +1701,7 @@ def nulp_diff(x, y, dtype=None):
(x.shape, y.shape))
def _diff(rx, ry, vdt):
- diff = np.array(rx-ry, dtype=vdt)
+ diff = np.asarray(rx-ry, dtype=vdt)
return np.abs(diff)
rx = integer_repr(x)
@@ -2006,7 +2008,7 @@ class clear_and_catch_warnings(warnings.catch_warnings):
def __init__(self, record=False, modules=()):
self.modules = set(modules).union(self.class_modules)
self._warnreg_copies = {}
- super(clear_and_catch_warnings, self).__init__(record=record)
+ super().__init__(record=record)
def __enter__(self):
for mod in self.modules:
@@ -2014,10 +2016,10 @@ class clear_and_catch_warnings(warnings.catch_warnings):
mod_reg = mod.__warningregistry__
self._warnreg_copies[mod] = mod_reg.copy()
mod_reg.clear()
- return super(clear_and_catch_warnings, self).__enter__()
+ return super().__enter__()
def __exit__(self, *exc_info):
- super(clear_and_catch_warnings, self).__exit__(*exc_info)
+ super().__exit__(*exc_info)
for mod in self.modules:
if hasattr(mod, '__warningregistry__'):
mod.__warningregistry__.clear()
@@ -2516,4 +2518,3 @@ def _no_tracing(func):
finally:
sys.settrace(original_trace)
return wrapper
-
diff --git a/numpy/testing/_private/utils.pyi b/numpy/testing/_private/utils.pyi
new file mode 100644
index 000000000..29915309f
--- /dev/null
+++ b/numpy/testing/_private/utils.pyi
@@ -0,0 +1,396 @@
+import os
+import sys
+import ast
+import types
+import warnings
+import unittest
+import contextlib
+from typing import (
+ Any,
+ AnyStr,
+ Callable,
+ ClassVar,
+ Dict,
+ Iterable,
+ List,
+ NoReturn,
+ overload,
+ Pattern,
+ Sequence,
+ Set,
+ Tuple,
+ Type,
+ type_check_only,
+ TypeVar,
+ Union,
+)
+
+from numpy import generic, dtype, number, object_, bool_, _FloatValue
+from numpy.typing import (
+ NDArray,
+ ArrayLike,
+ DTypeLike,
+ _ArrayLikeNumber_co,
+ _ArrayLikeObject_co,
+ _ArrayLikeTD64_co,
+ _ArrayLikeDT64_co,
+)
+
+from unittest.case import (
+ SkipTest as SkipTest,
+)
+
+if sys.version_info >= (3, 8):
+ from typing import Final, SupportsIndex, Literal as L
+else:
+ from typing_extensions import Final, SupportsIndex, Literal as L
+
+_T = TypeVar("_T")
+_ET = TypeVar("_ET", bound=BaseException)
+_FT = TypeVar("_FT", bound=Callable[..., Any])
+
+# Must return a bool or an ndarray/generic type
+# that is supported by `np.logical_and.reduce`
+_ComparisonFunc = Callable[
+ [NDArray[Any], NDArray[Any]],
+ Union[
+ bool,
+ bool_,
+ number[Any],
+ NDArray[Union[bool_, number[Any], object_]],
+ ],
+]
+
+__all__: List[str]
+
+class KnownFailureException(Exception): ...
+class IgnoreException(Exception): ...
+
+class clear_and_catch_warnings(warnings.catch_warnings):
+ class_modules: ClassVar[Tuple[types.ModuleType, ...]]
+ modules: Set[types.ModuleType]
+ @overload
+ def __new__(
+ cls,
+ record: L[False] = ...,
+ modules: Iterable[types.ModuleType] = ...,
+ ) -> _clear_and_catch_warnings_without_records: ...
+ @overload
+ def __new__(
+ cls,
+ record: L[True],
+ modules: Iterable[types.ModuleType] = ...,
+ ) -> _clear_and_catch_warnings_with_records: ...
+ @overload
+ def __new__(
+ cls,
+ record: bool,
+ modules: Iterable[types.ModuleType] = ...,
+ ) -> clear_and_catch_warnings: ...
+ def __enter__(self) -> None | List[warnings.WarningMessage]: ...
+ def __exit__(
+ self,
+ __exc_type: None | Type[BaseException] = ...,
+ __exc_val: None | BaseException = ...,
+ __exc_tb: None | types.TracebackType = ...,
+ ) -> None: ...
+
+# Type-check only `clear_and_catch_warnings` subclasses for both values of the
+# `record` parameter. Copied from the stdlib `warnings` stubs.
+
+@type_check_only
+class _clear_and_catch_warnings_with_records(clear_and_catch_warnings):
+ def __enter__(self) -> List[warnings.WarningMessage]: ...
+
+@type_check_only
+class _clear_and_catch_warnings_without_records(clear_and_catch_warnings):
+ def __enter__(self) -> None: ...
+
+class suppress_warnings:
+ log: List[warnings.WarningMessage]
+ def __init__(
+ self,
+ forwarding_rule: L["always", "module", "once", "location"] = ...,
+ ) -> None: ...
+ def filter(
+ self,
+ category: Type[Warning] = ...,
+ message: str = ...,
+ module: None | types.ModuleType = ...,
+ ) -> None: ...
+ def record(
+ self,
+ category: Type[Warning] = ...,
+ message: str = ...,
+ module: None | types.ModuleType = ...,
+ ) -> List[warnings.WarningMessage]: ...
+ def __enter__(self: _T) -> _T: ...
+ def __exit__(
+ self,
+ __exc_type: None | Type[BaseException] = ...,
+ __exc_val: None | BaseException = ...,
+ __exc_tb: None | types.TracebackType = ...,
+ ) -> None: ...
+ def __call__(self, func: _FT) -> _FT: ...
+
+verbose: int
+IS_PYPY: Final[bool]
+HAS_REFCOUNT: Final[bool]
+HAS_LAPACK64: Final[bool]
+
+def assert_(val: object, msg: str | Callable[[], str] = ...) -> None: ...
+
+# Contrary to runtime we can't do `os.name` checks while type checking,
+# only `sys.platform` checks
+if sys.platform == "win32" or sys.platform == "cygwin":
+ def memusage(processName: str = ..., instance: int = ...) -> int: ...
+elif sys.platform == "linux":
+ def memusage(_proc_pid_stat: str | bytes | os.PathLike[Any] = ...) -> None | int: ...
+else:
+ def memusage() -> NoReturn: ...
+
+if sys.platform == "linux":
+ def jiffies(
+ _proc_pid_stat: str | bytes | os.PathLike[Any] = ...,
+ _load_time: List[float] = ...,
+ ) -> int: ...
+else:
+ def jiffies(_load_time: List[float] = ...) -> int: ...
+
+def build_err_msg(
+ arrays: Iterable[object],
+ err_msg: str,
+ header: str = ...,
+ verbose: bool = ...,
+ names: Sequence[str] = ...,
+ precision: None | SupportsIndex = ...,
+) -> str: ...
+
+def assert_equal(
+ actual: object,
+ desired: object,
+ err_msg: str = ...,
+ verbose: bool = ...,
+) -> None: ...
+
+def print_assert_equal(
+ test_string: str,
+ actual: object,
+ desired: object,
+) -> None: ...
+
+def assert_almost_equal(
+ actual: _ArrayLikeNumber_co | _ArrayLikeObject_co,
+ desired: _ArrayLikeNumber_co | _ArrayLikeObject_co,
+ decimal: int = ...,
+ err_msg: str = ...,
+ verbose: bool = ...,
+) -> None: ...
+
+# Anything that can be coerced into `builtins.float`
+def assert_approx_equal(
+ actual: _FloatValue,
+ desired: _FloatValue,
+ significant: int = ...,
+ err_msg: str = ...,
+ verbose: bool = ...,
+) -> None: ...
+
+def assert_array_compare(
+ comparison: _ComparisonFunc,
+ x: ArrayLike,
+ y: ArrayLike,
+ err_msg: str = ...,
+ verbose: bool = ...,
+ header: str = ...,
+ precision: SupportsIndex = ...,
+ equal_nan: bool = ...,
+ equal_inf: bool = ...,
+) -> None: ...
+
+def assert_array_equal(
+ x: ArrayLike,
+ y: ArrayLike,
+ err_msg: str = ...,
+ verbose: bool = ...,
+) -> None: ...
+
+def assert_array_almost_equal(
+ x: _ArrayLikeNumber_co | _ArrayLikeObject_co,
+ y: _ArrayLikeNumber_co | _ArrayLikeObject_co,
+ decimal: float = ...,
+ err_msg: str = ...,
+ verbose: bool = ...,
+) -> None: ...
+
+@overload
+def assert_array_less(
+ x: _ArrayLikeNumber_co | _ArrayLikeObject_co,
+ y: _ArrayLikeNumber_co | _ArrayLikeObject_co,
+ err_msg: str = ...,
+ verbose: bool = ...,
+) -> None: ...
+@overload
+def assert_array_less(
+ x: _ArrayLikeTD64_co,
+ y: _ArrayLikeTD64_co,
+ err_msg: str = ...,
+ verbose: bool = ...,
+) -> None: ...
+@overload
+def assert_array_less(
+ x: _ArrayLikeDT64_co,
+ y: _ArrayLikeDT64_co,
+ err_msg: str = ...,
+ verbose: bool = ...,
+) -> None: ...
+
+def runstring(
+ astr: str | bytes | types.CodeType,
+ dict: None | Dict[str, Any],
+) -> Any: ...
+
+def assert_string_equal(actual: str, desired: str) -> None: ...
+
+def rundocs(
+ filename: None | str | os.PathLike[str] = ...,
+ raise_on_error: bool = ...,
+) -> None: ...
+
+def raises(*args: Type[BaseException]) -> Callable[[_FT], _FT]: ...
+
+@overload
+def assert_raises( # type: ignore
+ __expected_exception: Type[BaseException] | Tuple[Type[BaseException], ...],
+ __callable: Callable[..., Any],
+ *args: Any,
+ **kwargs: Any,
+) -> None: ...
+@overload
+def assert_raises(
+ expected_exception: Type[_ET] | Tuple[Type[_ET], ...],
+ *,
+ msg: None | str = ...,
+) -> unittest.case._AssertRaisesContext[_ET]: ...
+
+@overload
+def assert_raises_regex(
+ __expected_exception: Type[BaseException] | Tuple[Type[BaseException], ...],
+ __expected_regex: str | bytes | Pattern[Any],
+ __callable: Callable[..., Any],
+ *args: Any,
+ **kwargs: Any,
+) -> None: ...
+@overload
+def assert_raises_regex(
+ expected_exception: Type[_ET] | Tuple[Type[_ET], ...],
+ expected_regex: str | bytes | Pattern[Any],
+ *,
+ msg: None | str = ...,
+) -> unittest.case._AssertRaisesContext[_ET]: ...
+
+def decorate_methods(
+ cls: Type[Any],
+ decorator: Callable[[Callable[..., Any]], Any],
+ testmatch: None | str | bytes | Pattern[Any] = ...,
+) -> None: ...
+
+def measure(
+ code_str: str | bytes | ast.mod | ast.AST,
+ times: int = ...,
+ label: None | str = ...,
+) -> float: ...
+
+@overload
+def assert_allclose(
+ actual: _ArrayLikeNumber_co | _ArrayLikeObject_co,
+ desired: _ArrayLikeNumber_co | _ArrayLikeObject_co,
+ rtol: float = ...,
+ atol: float = ...,
+ equal_nan: bool = ...,
+ err_msg: str = ...,
+ verbose: bool = ...,
+) -> None: ...
+@overload
+def assert_allclose(
+ actual: _ArrayLikeTD64_co,
+ desired: _ArrayLikeTD64_co,
+ rtol: float = ...,
+ atol: float = ...,
+ equal_nan: bool = ...,
+ err_msg: str = ...,
+ verbose: bool = ...,
+) -> None: ...
+
+def assert_array_almost_equal_nulp(
+ x: _ArrayLikeNumber_co,
+ y: _ArrayLikeNumber_co,
+ nulp: float = ...,
+) -> None: ...
+
+def assert_array_max_ulp(
+ a: _ArrayLikeNumber_co,
+ b: _ArrayLikeNumber_co,
+ maxulp: float = ...,
+ dtype: DTypeLike = ...,
+) -> NDArray[Any]: ...
+
+@overload
+def assert_warns(
+ warning_class: Type[Warning],
+) -> contextlib._GeneratorContextManager[None]: ...
+@overload
+def assert_warns(
+ __warning_class: Type[Warning],
+ __func: Callable[..., _T],
+ *args: Any,
+ **kwargs: Any,
+) -> _T: ...
+
+@overload
+def assert_no_warnings() -> contextlib._GeneratorContextManager[None]: ...
+@overload
+def assert_no_warnings(
+ __func: Callable[..., _T],
+ *args: Any,
+ **kwargs: Any,
+) -> _T: ...
+
+@overload
+def tempdir(
+ suffix: None = ...,
+ prefix: None = ...,
+ dir: None = ...,
+) -> contextlib._GeneratorContextManager[str]: ...
+@overload
+def tempdir(
+ suffix: None | AnyStr = ...,
+ prefix: None | AnyStr = ...,
+ dir: None | AnyStr | os.PathLike[AnyStr] = ...,
+) -> contextlib._GeneratorContextManager[AnyStr]: ...
+
+@overload
+def temppath(
+ suffix: None = ...,
+ prefix: None = ...,
+ dir: None = ...,
+ text: bool = ...,
+) -> contextlib._GeneratorContextManager[str]: ...
+@overload
+def temppath(
+ suffix: None | AnyStr = ...,
+ prefix: None | AnyStr = ...,
+ dir: None | AnyStr | os.PathLike[AnyStr] = ...,
+ text: bool = ...,
+) -> contextlib._GeneratorContextManager[AnyStr]: ...
+
+@overload
+def assert_no_gc_cycles() -> contextlib._GeneratorContextManager[None]: ...
+@overload
+def assert_no_gc_cycles(
+ __func: Callable[..., Any],
+ *args: Any,
+ **kwargs: Any,
+) -> None: ...
+
+def break_cycles() -> None: ...
diff --git a/numpy/testing/setup.py b/numpy/testing/setup.py
index 7652a94a2..6f203e872 100755
--- a/numpy/testing/setup.py
+++ b/numpy/testing/setup.py
@@ -7,6 +7,7 @@ def configuration(parent_package='',top_path=None):
config.add_subpackage('_private')
config.add_subpackage('tests')
config.add_data_files('*.pyi')
+ config.add_data_files('_private/*.pyi')
return config
if __name__ == '__main__':
diff --git a/numpy/testing/tests/test_decorators.py b/numpy/testing/tests/test_decorators.py
deleted file mode 100644
index b60d6dfbc..000000000
--- a/numpy/testing/tests/test_decorators.py
+++ /dev/null
@@ -1,210 +0,0 @@
-"""
-Test the decorators from ``testing.decorators``.
-
-"""
-import warnings
-import pytest
-
-from numpy.testing import (
- assert_, assert_raises, dec, SkipTest, KnownFailureException,
- )
-
-
-try:
- with warnings.catch_warnings():
- warnings.simplefilter("always")
- import nose # noqa: F401
-except ImportError:
- HAVE_NOSE = False
-else:
- HAVE_NOSE = True
-
-
-@pytest.mark.skipif(not HAVE_NOSE, reason="Needs nose")
-class TestNoseDecorators:
- # These tests are run in a class for simplicity while still
- # getting a report on each, skipped or success.
-
- class DidntSkipException(Exception):
- pass
-
- def test_slow(self):
- @dec.slow
- def slow_func(x, y, z):
- pass
-
- assert_(slow_func.slow)
-
- def test_setastest(self):
- @dec.setastest()
- def f_default(a):
- pass
-
- @dec.setastest(True)
- def f_istest(a):
- pass
-
- @dec.setastest(False)
- def f_isnottest(a):
- pass
-
- assert_(f_default.__test__)
- assert_(f_istest.__test__)
- assert_(not f_isnottest.__test__)
-
- def test_skip_functions_hardcoded(self):
- @dec.skipif(True)
- def f1(x):
- raise self.DidntSkipException
-
- try:
- f1('a')
- except self.DidntSkipException:
- raise Exception('Failed to skip')
- except SkipTest().__class__:
- pass
-
- @dec.skipif(False)
- def f2(x):
- raise self.DidntSkipException
-
- try:
- f2('a')
- except self.DidntSkipException:
- pass
- except SkipTest().__class__:
- raise Exception('Skipped when not expected to')
-
- def test_skip_functions_callable(self):
- def skip_tester():
- return skip_flag == 'skip me!'
-
- @dec.skipif(skip_tester)
- def f1(x):
- raise self.DidntSkipException
-
- try:
- skip_flag = 'skip me!'
- f1('a')
- except self.DidntSkipException:
- raise Exception('Failed to skip')
- except SkipTest().__class__:
- pass
-
- @dec.skipif(skip_tester)
- def f2(x):
- raise self.DidntSkipException
-
- try:
- skip_flag = 'five is right out!'
- f2('a')
- except self.DidntSkipException:
- pass
- except SkipTest().__class__:
- raise Exception('Skipped when not expected to')
-
- def test_skip_generators_hardcoded(self):
- @dec.knownfailureif(True, "This test is known to fail")
- def g1(x):
- yield from range(x)
-
- try:
- for j in g1(10):
- pass
- except KnownFailureException().__class__:
- pass
- else:
- raise Exception('Failed to mark as known failure')
-
- @dec.knownfailureif(False, "This test is NOT known to fail")
- def g2(x):
- yield from range(x)
- raise self.DidntSkipException('FAIL')
-
- try:
- for j in g2(10):
- pass
- except KnownFailureException().__class__:
- raise Exception('Marked incorrectly as known failure')
- except self.DidntSkipException:
- pass
-
- def test_skip_generators_callable(self):
- def skip_tester():
- return skip_flag == 'skip me!'
-
- @dec.knownfailureif(skip_tester, "This test is known to fail")
- def g1(x):
- yield from range(x)
-
- try:
- skip_flag = 'skip me!'
- for j in g1(10):
- pass
- except KnownFailureException().__class__:
- pass
- else:
- raise Exception('Failed to mark as known failure')
-
- @dec.knownfailureif(skip_tester, "This test is NOT known to fail")
- def g2(x):
- yield from range(x)
- raise self.DidntSkipException('FAIL')
-
- try:
- skip_flag = 'do not skip'
- for j in g2(10):
- pass
- except KnownFailureException().__class__:
- raise Exception('Marked incorrectly as known failure')
- except self.DidntSkipException:
- pass
-
- def test_deprecated(self):
- @dec.deprecated(True)
- def non_deprecated_func():
- pass
-
- @dec.deprecated()
- def deprecated_func():
- import warnings
- warnings.warn("TEST: deprecated func", DeprecationWarning)
-
- @dec.deprecated()
- def deprecated_func2():
- import warnings
- warnings.warn("AHHHH")
- raise ValueError
-
- @dec.deprecated()
- def deprecated_func3():
- import warnings
- warnings.warn("AHHHH")
-
- # marked as deprecated, but does not raise DeprecationWarning
- assert_raises(AssertionError, non_deprecated_func)
- # should be silent
- deprecated_func()
- with warnings.catch_warnings(record=True):
- warnings.simplefilter("always") # do not propagate unrelated warnings
- # fails if deprecated decorator just disables test. See #1453.
- assert_raises(ValueError, deprecated_func2)
- # warning is not a DeprecationWarning
- assert_raises(AssertionError, deprecated_func3)
-
- def test_parametrize(self):
- # dec.parametrize assumes that it is being run by nose. Because
- # we are running under pytest, we need to explicitly check the
- # results.
- @dec.parametrize('base, power, expected',
- [(1, 1, 1),
- (2, 1, 2),
- (2, 2, 4)])
- def check_parametrize(base, power, expected):
- assert_(base**power == expected)
-
- count = 0
- for test in check_parametrize():
- test[0](*test[1:])
- count += 1
- assert_(count == 3)
diff --git a/numpy/testing/tests/test_utils.py b/numpy/testing/tests/test_utils.py
index c3b9e04b6..31d2cdc76 100644
--- a/numpy/testing/tests/test_utils.py
+++ b/numpy/testing/tests/test_utils.py
@@ -434,10 +434,10 @@ class TestArrayAlmostEqual(_GenericTest):
# (which, e.g., astropy Quantity cannot usefully do). See gh-8452.
class MyArray(np.ndarray):
def __eq__(self, other):
- return super(MyArray, self).__eq__(other).view(np.ndarray)
+ return super().__eq__(other).view(np.ndarray)
def __lt__(self, other):
- return super(MyArray, self).__lt__(other).view(np.ndarray)
+ return super().__lt__(other).view(np.ndarray)
def all(self, *args, **kwargs):
raise NotImplementedError
@@ -585,10 +585,10 @@ class TestAlmostEqual(_GenericTest):
# (which, e.g., astropy Quantity cannot usefully do). See gh-8452.
class MyArray(np.ndarray):
def __eq__(self, other):
- return super(MyArray, self).__eq__(other).view(np.ndarray)
+ return super().__eq__(other).view(np.ndarray)
def __lt__(self, other):
- return super(MyArray, self).__lt__(other).view(np.ndarray)
+ return super().__lt__(other).view(np.ndarray)
def all(self, *args, **kwargs):
raise NotImplementedError
@@ -904,6 +904,11 @@ class TestAssertAllclose:
msg = str(exc_info.value)
assert_('Max relative difference: 0.5' in msg)
+ def test_timedelta(self):
+ # see gh-18286
+ a = np.array([[1, 2, 3, "NaT"]], dtype="m8[ns]")
+ assert_allclose(a, a)
+
class TestArrayAlmostEqualNulp:
diff --git a/numpy/testing/utils.py b/numpy/testing/utils.py
index 753258c13..20a883304 100644
--- a/numpy/testing/utils.py
+++ b/numpy/testing/utils.py
@@ -12,6 +12,7 @@ warnings.warn("Importing from numpy.testing.utils is deprecated "
DeprecationWarning, stacklevel=2)
from ._private.utils import *
+from ._private.utils import _assert_valid_refcount, _gen_alignment_data
__all__ = [
'assert_equal', 'assert_almost_equal', 'assert_approx_equal',
@@ -24,5 +25,5 @@ __all__ = [
'assert_allclose', 'IgnoreException', 'clear_and_catch_warnings',
'SkipTest', 'KnownFailureException', 'temppath', 'tempdir', 'IS_PYPY',
'HAS_REFCOUNT', 'suppress_warnings', 'assert_array_compare',
- '_assert_valid_refcount', '_gen_alignment_data', 'assert_no_gc_cycles'
+ 'assert_no_gc_cycles'
]
diff --git a/numpy/tests/test_numpy_version.py b/numpy/tests/test_numpy_version.py
index 916ab9383..bccbcb8e9 100644
--- a/numpy/tests/test_numpy_version.py
+++ b/numpy/tests/test_numpy_version.py
@@ -1,3 +1,20 @@
+"""
+Check the numpy version is valid.
+
+Note that a development version is marked by the presence of 'dev0' or '+'
+in the version string, all else is treated as a release. The version string
+itself is set from the output of ``git describe`` which relies on tags.
+
+Examples
+--------
+
+Valid Development: 1.22.0.dev0 1.22.0.dev0+5-g7999db4df2 1.22.0+5-g7999db4df2
+Valid Release: 1.21.0.rc1, 1.21.0.b1, 1.21.0
+Invalid: 1.22.0.dev, 1.22.0.dev0-5-g7999db4dfB, 1.21.0.d1, 1.21.a
+
+Note that a release is determined by the version string, which in turn
+is controlled by the result of the ``git describe`` command.
+"""
import re
import numpy as np
@@ -7,11 +24,21 @@ from numpy.testing import assert_
def test_valid_numpy_version():
# Verify that the numpy version is a valid one (no .post suffix or other
# nonsense). See gh-6431 for an issue caused by an invalid version.
- version_pattern = r"^[0-9]+\.[0-9]+\.[0-9]+(|a[0-9]|b[0-9]|rc[0-9])"
- dev_suffix = r"(\.dev0\+([0-9a-f]{7}|Unknown))"
+ version_pattern = r"^[0-9]+\.[0-9]+\.[0-9]+(a[0-9]|b[0-9]|rc[0-9]|)"
+ dev_suffix = r"(\.dev0|)(\+[0-9]*\.g[0-9a-f]+|)"
if np.version.release:
- res = re.match(version_pattern, np.__version__)
+ res = re.match(version_pattern + '$', np.__version__)
else:
- res = re.match(version_pattern + dev_suffix, np.__version__)
+ res = re.match(version_pattern + dev_suffix + '$', np.__version__)
assert_(res is not None, np.__version__)
+
+
+def test_short_version():
+ # Check numpy.short_version actually exists
+ if np.version.release:
+ assert_(np.__version__ == np.version.short_version,
+ "short_version mismatch in release version")
+ else:
+ assert_(np.__version__.split("+")[0] == np.version.short_version,
+ "short_version mismatch in development version")
diff --git a/numpy/tests/test_public_api.py b/numpy/tests/test_public_api.py
index a7bd0f115..6e4a8dee0 100644
--- a/numpy/tests/test_public_api.py
+++ b/numpy/tests/test_public_api.py
@@ -40,7 +40,7 @@ def test_numpy_namespace():
'byte_bounds': 'numpy.lib.utils.byte_bounds',
'compare_chararrays': 'numpy.core._multiarray_umath.compare_chararrays',
'deprecate': 'numpy.lib.utils.deprecate',
- 'deprecate_with_doc': 'numpy.lib.utils.<lambda>',
+ 'deprecate_with_doc': 'numpy.lib.utils.deprecate_with_doc',
'disp': 'numpy.lib.function_base.disp',
'fastCopyAndTranspose': 'numpy.core._multiarray_umath._fastCopyAndTranspose',
'get_array_wrap': 'numpy.lib.shape_base.get_array_wrap',
@@ -154,6 +154,7 @@ PUBLIC_MODULES = ['numpy.' + s for s in [
"lib.mixins",
"lib.recfunctions",
"lib.scimath",
+ "lib.stride_tricks",
"linalg",
"ma",
"ma.extras",
@@ -166,10 +167,10 @@ PUBLIC_MODULES = ['numpy.' + s for s in [
"polynomial.laguerre",
"polynomial.legendre",
"polynomial.polynomial",
- "polynomial.polyutils",
"random",
"testing",
"typing",
+ "typing.mypy_plugin",
"version",
]]
@@ -243,6 +244,7 @@ PRIVATE_BUT_PRESENT_MODULES = ['numpy.' + s for s in [
"distutils.fcompiler.nv",
"distutils.fcompiler.sun",
"distutils.fcompiler.vast",
+ "distutils.fcompiler.fujitsu",
"distutils.from_template",
"distutils.intelccompiler",
"distutils.lib2def",
@@ -278,7 +280,6 @@ PRIVATE_BUT_PRESENT_MODULES = ['numpy.' + s for s in [
"lib.npyio",
"lib.polynomial",
"lib.shape_base",
- "lib.stride_tricks",
"lib.twodim_base",
"lib.type_check",
"lib.ufunclike",
@@ -292,6 +293,7 @@ PRIVATE_BUT_PRESENT_MODULES = ['numpy.' + s for s in [
"ma.timer_comparison",
"matrixlib",
"matrixlib.defmatrix",
+ "polynomial.polyutils",
"random.mtrand",
"random.bit_generator",
"testing.print_coercion_tables",
diff --git a/numpy/tests/test_reloading.py b/numpy/tests/test_reloading.py
index 61ae91b00..8d8c8aa34 100644
--- a/numpy/tests/test_reloading.py
+++ b/numpy/tests/test_reloading.py
@@ -1,4 +1,4 @@
-from numpy.testing import assert_raises, assert_, assert_equal
+from numpy.testing import assert_raises, assert_warns, assert_, assert_equal
from numpy.compat import pickle
import sys
@@ -16,13 +16,15 @@ def test_numpy_reloading():
VisibleDeprecationWarning = np.VisibleDeprecationWarning
ModuleDeprecationWarning = np.ModuleDeprecationWarning
- reload(np)
+ with assert_warns(UserWarning):
+ reload(np)
assert_(_NoValue is np._NoValue)
assert_(ModuleDeprecationWarning is np.ModuleDeprecationWarning)
assert_(VisibleDeprecationWarning is np.VisibleDeprecationWarning)
assert_raises(RuntimeError, reload, numpy._globals)
- reload(np)
+ with assert_warns(UserWarning):
+ reload(np)
assert_(_NoValue is np._NoValue)
assert_(ModuleDeprecationWarning is np.ModuleDeprecationWarning)
assert_(VisibleDeprecationWarning is np.VisibleDeprecationWarning)
@@ -45,13 +47,18 @@ def test_full_reimport():
# This is generally unsafe, especially, since we also reload the C-modules.
code = textwrap.dedent(r"""
import sys
+ from pytest import warns
import numpy as np
for k in list(sys.modules.keys()):
if "numpy" in k:
del sys.modules[k]
- import numpy as np
+ with warns(UserWarning):
+ import numpy as np
""")
- p = subprocess.run([sys.executable, '-c', code])
- assert p.returncode == 0
+ p = subprocess.run([sys.executable, '-c', code], capture_output=True)
+ if p.returncode:
+ raise AssertionError(
+ f"Non-zero return code: {p.returncode!r}\n\n{p.stderr.decode()}"
+ )
diff --git a/numpy/typing/__init__.py b/numpy/typing/__init__.py
index e72e8fb4d..d731f00ef 100644
--- a/numpy/typing/__init__.py
+++ b/numpy/typing/__init__.py
@@ -3,6 +3,8 @@
Typing (:mod:`numpy.typing`)
============================
+.. versionadded:: 1.20
+
.. warning::
Some of the types in this module rely on features only present in
@@ -19,6 +21,13 @@ the two below:
.. _typing-extensions: https://pypi.org/project/typing-extensions/
+Mypy plugin
+-----------
+
+.. versionadded:: 1.21
+
+.. automodule:: numpy.typing.mypy_plugin
+
Differences from the runtime NumPy API
--------------------------------------
@@ -69,7 +78,7 @@ the following code is valid:
>>> x.dtype = np.bool_
This sort of mutation is not allowed by the types. Users who want to
-write statically typed code should insted use the `numpy.ndarray.view`
+write statically typed code should instead use the `numpy.ndarray.view`
method to create a view of the array with a different dtype.
DTypeLike
@@ -82,15 +91,15 @@ dictionary of fields like below:
>>> x = np.dtype({"field1": (float, 1), "field2": (int, 3)})
-Although this is valid Numpy code, the type checker will complain about it,
+Although this is valid NumPy code, the type checker will complain about it,
since its usage is discouraged.
Please see : :ref:`Data type objects <arrays.dtypes>`
-Number Precision
+Number precision
~~~~~~~~~~~~~~~~
The precision of `numpy.number` subclasses is treated as a covariant generic
-parameter (see :class:`~NBitBase`), simplifying the annoting of proccesses
+parameter (see :class:`~NBitBase`), simplifying the annotating of processes
involving precision-based casting.
.. code-block:: python
@@ -113,6 +122,20 @@ Timedelta64
The `~numpy.timedelta64` class is not considered a subclass of `~numpy.signedinteger`,
the former only inheriting from `~numpy.generic` while static type checking.
+0D arrays
+~~~~~~~~~
+
+During runtime numpy aggressively casts any passed 0D arrays into their
+corresponding `~numpy.generic` instance. Until the introduction of shape
+typing (see :pep:`646`) it is unfortunately not possible to make the
+necessary distinction between 0D and >0D arrays. While thus not strictly
+correct, all operations are that can potentially perform a 0D-array -> scalar
+cast are currently annotated as exclusively returning an `ndarray`.
+
+If it is known in advance that an operation _will_ perform a
+0D-array -> scalar cast, then one can consider manually remedying the
+situation with either `typing.cast` or a ``# type: ignore`` comment.
+
API
---
@@ -120,19 +143,27 @@ API
# NOTE: The API section will be appended with additional entries
# further down in this file
-from typing import TYPE_CHECKING, List
+from typing import TYPE_CHECKING, List, Any
if TYPE_CHECKING:
- import sys
- if sys.version_info >= (3, 8):
- from typing import final
+ # typing_extensions is always available when type-checking
+ from typing_extensions import Literal as L
+ _HAS_TYPING_EXTENSIONS: L[True]
+else:
+ try:
+ import typing_extensions
+ except ImportError:
+ _HAS_TYPING_EXTENSIONS = False
else:
- from typing_extensions import final
+ _HAS_TYPING_EXTENSIONS = True
+
+if TYPE_CHECKING:
+ from typing_extensions import final
else:
def final(f): return f
if not TYPE_CHECKING:
- __all__ = ["ArrayLike", "DTypeLike", "NBitBase"]
+ __all__ = ["ArrayLike", "DTypeLike", "NBitBase", "NDArray"]
else:
# Ensure that all objects within this module are accessible while
# static type checking. This includes private ones, as we need them
@@ -141,6 +172,7 @@ else:
# Declare to mypy that `__all__` is a list of strings without assigning
# an explicit value
__all__: List[str]
+ __path__: List[str]
@final # Dissallow the creation of arbitrary `NBitBase` subclasses
@@ -149,10 +181,12 @@ class NBitBase:
An object representing `numpy.number` precision during static type checking.
Used exclusively for the purpose static type checking, `NBitBase`
- represents the base of a hierachieral set of subclasses.
+ represents the base of a hierarchical set of subclasses.
Each subsequent subclass is herein used for representing a lower level
of precision, *e.g.* ``64Bit > 32Bit > 16Bit``.
+ .. versionadded:: 1.20
+
Examples
--------
Below is a typical usage example: `NBitBase` is herein used for annotating a
@@ -162,13 +196,15 @@ class NBitBase:
.. code-block:: python
+ >>> from __future__ import annotations
>>> from typing import TypeVar, TYPE_CHECKING
>>> import numpy as np
>>> import numpy.typing as npt
- >>> T = TypeVar("T", bound=npt.NBitBase)
+ >>> T1 = TypeVar("T1", bound=npt.NBitBase)
+ >>> T2 = TypeVar("T2", bound=npt.NBitBase)
- >>> def add(a: "np.floating[T]", b: "np.integer[T]") -> "np.floating[T]":
+ >>> def add(a: np.floating[T1], b: np.integer[T2]) -> np.floating[T1 | T2]:
... return a + b
>>> a = np.float16()
@@ -204,22 +240,132 @@ class _32Bit(_64Bit): ... # type: ignore[misc]
class _16Bit(_32Bit): ... # type: ignore[misc]
class _8Bit(_16Bit): ... # type: ignore[misc]
-# Clean up the namespace
-del TYPE_CHECKING, final, List
-
+from ._nbit import (
+ _NBitByte,
+ _NBitShort,
+ _NBitIntC,
+ _NBitIntP,
+ _NBitInt,
+ _NBitLongLong,
+ _NBitHalf,
+ _NBitSingle,
+ _NBitDouble,
+ _NBitLongDouble,
+)
+from ._char_codes import (
+ _BoolCodes,
+ _UInt8Codes,
+ _UInt16Codes,
+ _UInt32Codes,
+ _UInt64Codes,
+ _Int8Codes,
+ _Int16Codes,
+ _Int32Codes,
+ _Int64Codes,
+ _Float16Codes,
+ _Float32Codes,
+ _Float64Codes,
+ _Complex64Codes,
+ _Complex128Codes,
+ _ByteCodes,
+ _ShortCodes,
+ _IntCCodes,
+ _IntPCodes,
+ _IntCodes,
+ _LongLongCodes,
+ _UByteCodes,
+ _UShortCodes,
+ _UIntCCodes,
+ _UIntPCodes,
+ _UIntCodes,
+ _ULongLongCodes,
+ _HalfCodes,
+ _SingleCodes,
+ _DoubleCodes,
+ _LongDoubleCodes,
+ _CSingleCodes,
+ _CDoubleCodes,
+ _CLongDoubleCodes,
+ _DT64Codes,
+ _TD64Codes,
+ _StrCodes,
+ _BytesCodes,
+ _VoidCodes,
+ _ObjectCodes,
+)
from ._scalars import (
- _CharLike,
- _BoolLike,
- _IntLike,
- _FloatLike,
- _ComplexLike,
- _NumberLike,
- _ScalarLike,
- _VoidLike,
+ _CharLike_co,
+ _BoolLike_co,
+ _UIntLike_co,
+ _IntLike_co,
+ _FloatLike_co,
+ _ComplexLike_co,
+ _TD64Like_co,
+ _NumberLike_co,
+ _ScalarLike_co,
+ _VoidLike_co,
)
-from ._array_like import _SupportsArray, ArrayLike
from ._shape import _Shape, _ShapeLike
-from ._dtype_like import _SupportsDType, _VoidDTypeLike, DTypeLike
+from ._dtype_like import (
+ DTypeLike as DTypeLike,
+ _SupportsDType,
+ _VoidDTypeLike,
+ _DTypeLikeBool,
+ _DTypeLikeUInt,
+ _DTypeLikeInt,
+ _DTypeLikeFloat,
+ _DTypeLikeComplex,
+ _DTypeLikeTD64,
+ _DTypeLikeDT64,
+ _DTypeLikeObject,
+ _DTypeLikeVoid,
+ _DTypeLikeStr,
+ _DTypeLikeBytes,
+ _DTypeLikeComplex_co,
+)
+from ._array_like import (
+ ArrayLike as ArrayLike,
+ _ArrayLike,
+ _NestedSequence,
+ _RecursiveSequence,
+ _SupportsArray,
+ _ArrayLikeInt,
+ _ArrayLikeBool_co,
+ _ArrayLikeUInt_co,
+ _ArrayLikeInt_co,
+ _ArrayLikeFloat_co,
+ _ArrayLikeComplex_co,
+ _ArrayLikeNumber_co,
+ _ArrayLikeTD64_co,
+ _ArrayLikeDT64_co,
+ _ArrayLikeObject_co,
+ _ArrayLikeVoid_co,
+ _ArrayLikeStr_co,
+ _ArrayLikeBytes_co,
+)
+from ._generic_alias import (
+ NDArray as NDArray,
+ _DType,
+ _GenericAlias,
+)
+
+if TYPE_CHECKING:
+ from ._ufunc import (
+ _UFunc_Nin1_Nout1,
+ _UFunc_Nin2_Nout1,
+ _UFunc_Nin1_Nout2,
+ _UFunc_Nin2_Nout2,
+ _GUFunc_Nin2_Nout1,
+ )
+else:
+ _UFunc_Nin1_Nout1 = Any
+ _UFunc_Nin2_Nout1 = Any
+ _UFunc_Nin1_Nout2 = Any
+ _UFunc_Nin2_Nout2 = Any
+ _GUFunc_Nin2_Nout1 = Any
+
+# Clean up the namespace
+del TYPE_CHECKING, final, List, Any
if __doc__ is not None:
from ._add_docstring import _docstrings
diff --git a/numpy/typing/_add_docstring.py b/numpy/typing/_add_docstring.py
index 8e39fe2c6..846b67042 100644
--- a/numpy/typing/_add_docstring.py
+++ b/numpy/typing/_add_docstring.py
@@ -3,14 +3,32 @@
import re
import textwrap
+from ._generic_alias import NDArray
+
_docstrings_list = []
-def add_newdoc(name, value, doc):
+def add_newdoc(name: str, value: str, doc: str) -> None:
+ """Append ``_docstrings_list`` with a docstring for `name`.
+
+ Parameters
+ ----------
+ name : str
+ The name of the object.
+ value : str
+ A string-representation of the object.
+ doc : str
+ The docstring of the object.
+
+ """
_docstrings_list.append((name, value, doc))
-def _parse_docstrings():
+def _parse_docstrings() -> str:
+ """Convert all docstrings in ``_docstrings_list`` into a single
+ sphinx-legible text block.
+
+ """
type_list_ret = []
for name, value, doc in _docstrings_list:
s = textwrap.dedent(doc).replace("\n", "\n ")
@@ -49,6 +67,8 @@ add_newdoc('ArrayLike', 'typing.Union[...]',
* (Nested) sequences.
* Objects implementing the `~class.__array__` protocol.
+ .. versionadded:: 1.20
+
See Also
--------
:term:`array_like`:
@@ -76,6 +96,8 @@ add_newdoc('DTypeLike', 'typing.Union[...]',
* Character codes or the names of :class:`type` objects.
* Objects with the ``.dtype`` attribute.
+ .. versionadded:: 1.20
+
See Also
--------
:ref:`Specifying and constructing data types <arrays.dtypes.constructing>`
@@ -93,4 +115,35 @@ add_newdoc('DTypeLike', 'typing.Union[...]',
""")
+add_newdoc('NDArray', repr(NDArray),
+ """
+ A :term:`generic <generic type>` version of
+ `np.ndarray[Any, np.dtype[+ScalarType]] <numpy.ndarray>`.
+
+ Can be used during runtime for typing arrays with a given dtype
+ and unspecified shape.
+
+ .. versionadded:: 1.21
+
+ Examples
+ --------
+ .. code-block:: python
+
+ >>> import numpy as np
+ >>> import numpy.typing as npt
+
+ >>> print(npt.NDArray)
+ numpy.ndarray[typing.Any, numpy.dtype[+ScalarType]]
+
+ >>> print(npt.NDArray[np.float64])
+ numpy.ndarray[typing.Any, numpy.dtype[numpy.float64]]
+
+ >>> NDArrayInt = npt.NDArray[np.int_]
+ >>> a: NDArrayInt = np.arange(10)
+
+ >>> def func(a: npt.ArrayLike) -> npt.NDArray[Any]:
+ ... return np.array(a)
+
+ """)
+
_docstrings = _parse_docstrings()
diff --git a/numpy/typing/_array_like.py b/numpy/typing/_array_like.py
index a1a604239..c562f3c1f 100644
--- a/numpy/typing/_array_like.py
+++ b/numpy/typing/_array_like.py
@@ -1,29 +1,64 @@
-import sys
-from typing import Any, overload, Sequence, TYPE_CHECKING, Union
+from __future__ import annotations
-from numpy import ndarray
-from ._scalars import _ScalarLike
-from ._dtype_like import DTypeLike
+import sys
+from typing import Any, Sequence, TYPE_CHECKING, Union, TypeVar, Generic
+from numpy import (
+ ndarray,
+ dtype,
+ generic,
+ bool_,
+ unsignedinteger,
+ integer,
+ floating,
+ complexfloating,
+ number,
+ timedelta64,
+ datetime64,
+ object_,
+ void,
+ str_,
+ bytes_,
+)
+from . import _HAS_TYPING_EXTENSIONS
if sys.version_info >= (3, 8):
from typing import Protocol
- HAVE_PROTOCOL = True
-else:
- try:
- from typing_extensions import Protocol
- except ImportError:
- HAVE_PROTOCOL = False
- else:
- HAVE_PROTOCOL = True
-
-if TYPE_CHECKING or HAVE_PROTOCOL:
- class _SupportsArray(Protocol):
- @overload
- def __array__(self, __dtype: DTypeLike = ...) -> ndarray: ...
- @overload
- def __array__(self, dtype: DTypeLike = ...) -> ndarray: ...
+elif _HAS_TYPING_EXTENSIONS:
+ from typing_extensions import Protocol
+
+_T = TypeVar("_T")
+_ScalarType = TypeVar("_ScalarType", bound=generic)
+_DType = TypeVar("_DType", bound="dtype[Any]")
+_DType_co = TypeVar("_DType_co", covariant=True, bound="dtype[Any]")
+
+if TYPE_CHECKING or _HAS_TYPING_EXTENSIONS or sys.version_info >= (3, 8):
+ # The `_SupportsArray` protocol only cares about the default dtype
+ # (i.e. `dtype=None` or no `dtype` parameter at all) of the to-be returned
+ # array.
+ # Concrete implementations of the protocol are responsible for adding
+ # any and all remaining overloads
+ class _SupportsArray(Protocol[_DType_co]):
+ def __array__(self) -> ndarray[Any, _DType_co]: ...
else:
- _SupportsArray = Any
+ class _SupportsArray(Generic[_DType_co]): ...
+
+# TODO: Wait for support for recursive types
+_NestedSequence = Union[
+ _T,
+ Sequence[_T],
+ Sequence[Sequence[_T]],
+ Sequence[Sequence[Sequence[_T]]],
+ Sequence[Sequence[Sequence[Sequence[_T]]]],
+]
+_RecursiveSequence = Sequence[Sequence[Sequence[Sequence[Sequence[Any]]]]]
+
+# A union representing array-like objects; consists of two typevars:
+# One representing types that can be parametrized w.r.t. `np.dtype`
+# and another one for the rest
+_ArrayLike = Union[
+ _NestedSequence[_SupportsArray[_DType]],
+ _NestedSequence[_T],
+]
# TODO: support buffer protocols once
#
@@ -33,8 +68,57 @@ else:
#
# https://github.com/python/typing/issues/593
ArrayLike = Union[
- _ScalarLike,
- Sequence[_ScalarLike],
- Sequence[Sequence[Any]], # TODO: Wait for support for recursive types
- _SupportsArray,
+ _RecursiveSequence,
+ _ArrayLike[
+ dtype,
+ Union[bool, int, float, complex, str, bytes]
+ ],
+]
+
+# `ArrayLike<X>_co`: array-like objects that can be coerced into `X`
+# given the casting rules `same_kind`
+_ArrayLikeBool_co = _ArrayLike[
+ "dtype[bool_]",
+ bool,
+]
+_ArrayLikeUInt_co = _ArrayLike[
+ "dtype[Union[bool_, unsignedinteger[Any]]]",
+ bool,
+]
+_ArrayLikeInt_co = _ArrayLike[
+ "dtype[Union[bool_, integer[Any]]]",
+ Union[bool, int],
+]
+_ArrayLikeFloat_co = _ArrayLike[
+ "dtype[Union[bool_, integer[Any], floating[Any]]]",
+ Union[bool, int, float],
+]
+_ArrayLikeComplex_co = _ArrayLike[
+ "dtype[Union[bool_, integer[Any], floating[Any], complexfloating[Any, Any]]]",
+ Union[bool, int, float, complex],
+]
+_ArrayLikeNumber_co = _ArrayLike[
+ "dtype[Union[bool_, number[Any]]]",
+ Union[bool, int, float, complex],
+]
+_ArrayLikeTD64_co = _ArrayLike[
+ "dtype[Union[bool_, integer[Any], timedelta64]]",
+ Union[bool, int],
+]
+_ArrayLikeDT64_co = _NestedSequence[_SupportsArray["dtype[datetime64]"]]
+_ArrayLikeObject_co = _NestedSequence[_SupportsArray["dtype[object_]"]]
+
+_ArrayLikeVoid_co = _NestedSequence[_SupportsArray["dtype[void]"]]
+_ArrayLikeStr_co = _ArrayLike[
+ "dtype[str_]",
+ str,
+]
+_ArrayLikeBytes_co = _ArrayLike[
+ "dtype[bytes_]",
+ bytes,
+]
+
+_ArrayLikeInt = _ArrayLike[
+ "dtype[integer[Any]]",
+ int,
]
diff --git a/numpy/typing/_callable.py b/numpy/typing/_callable.py
index c703df28a..8f911da3b 100644
--- a/numpy/typing/_callable.py
+++ b/numpy/typing/_callable.py
@@ -8,6 +8,8 @@ See the `Mypy documentation`_ on protocols for more details.
"""
+from __future__ import annotations
+
import sys
from typing import (
Union,
@@ -21,6 +23,7 @@ from typing import (
from numpy import (
ndarray,
+ dtype,
generic,
bool_,
timedelta64,
@@ -29,38 +32,34 @@ from numpy import (
unsignedinteger,
signedinteger,
int8,
+ int_,
floating,
float64,
complexfloating,
complex128,
)
+from ._nbit import _NBitInt, _NBitDouble
from ._scalars import (
- _BoolLike,
- _IntLike,
- _FloatLike,
- _ComplexLike,
- _NumberLike,
+ _BoolLike_co,
+ _IntLike_co,
+ _FloatLike_co,
+ _NumberLike_co,
)
-from . import NBitBase
-from ._array_like import ArrayLike
+from . import NBitBase, _HAS_TYPING_EXTENSIONS
+from ._generic_alias import NDArray
if sys.version_info >= (3, 8):
from typing import Protocol
- HAVE_PROTOCOL = True
-else:
- try:
- from typing_extensions import Protocol
- except ImportError:
- HAVE_PROTOCOL = False
- else:
- HAVE_PROTOCOL = True
+elif _HAS_TYPING_EXTENSIONS:
+ from typing_extensions import Protocol
-if TYPE_CHECKING or HAVE_PROTOCOL:
- _T = TypeVar("_T")
- _2Tuple = Tuple[_T, _T]
+if TYPE_CHECKING or _HAS_TYPING_EXTENSIONS or sys.version_info >= (3, 8):
+ _T1 = TypeVar("_T1")
+ _T2 = TypeVar("_T2")
+ _2Tuple = Tuple[_T1, _T1]
- _NBit_co = TypeVar("_NBit_co", covariant=True, bound=NBitBase)
- _NBit = TypeVar("_NBit", bound=NBitBase)
+ _NBit1 = TypeVar("_NBit1", bound=NBitBase)
+ _NBit2 = TypeVar("_NBit2", bound=NBitBase)
_IntType = TypeVar("_IntType", bound=integer)
_FloatType = TypeVar("_FloatType", bound=floating)
@@ -70,9 +69,9 @@ if TYPE_CHECKING or HAVE_PROTOCOL:
class _BoolOp(Protocol[_GenericType_co]):
@overload
- def __call__(self, __other: _BoolLike) -> _GenericType_co: ...
+ def __call__(self, __other: _BoolLike_co) -> _GenericType_co: ...
@overload # platform dependent
- def __call__(self, __other: int) -> signedinteger[Any]: ...
+ def __call__(self, __other: int) -> int_: ...
@overload
def __call__(self, __other: float) -> float64: ...
@overload
@@ -82,9 +81,9 @@ if TYPE_CHECKING or HAVE_PROTOCOL:
class _BoolBitOp(Protocol[_GenericType_co]):
@overload
- def __call__(self, __other: _BoolLike) -> _GenericType_co: ...
+ def __call__(self, __other: _BoolLike_co) -> _GenericType_co: ...
@overload # platform dependent
- def __call__(self, __other: int) -> signedinteger[Any]: ...
+ def __call__(self, __other: int) -> int_: ...
@overload
def __call__(self, __other: _IntType) -> _IntType: ...
@@ -93,7 +92,7 @@ if TYPE_CHECKING or HAVE_PROTOCOL:
@overload
def __call__(self, __other: bool) -> NoReturn: ...
@overload # platform dependent
- def __call__(self, __other: int) -> signedinteger[Any]: ...
+ def __call__(self, __other: int) -> int_: ...
@overload
def __call__(self, __other: float) -> float64: ...
@overload
@@ -103,7 +102,7 @@ if TYPE_CHECKING or HAVE_PROTOCOL:
class _BoolTrueDiv(Protocol):
@overload
- def __call__(self, __other: Union[float, _IntLike, _BoolLike]) -> float64: ...
+ def __call__(self, __other: float | _IntLike_co) -> float64: ...
@overload
def __call__(self, __other: complex) -> complex128: ...
@overload
@@ -111,9 +110,9 @@ if TYPE_CHECKING or HAVE_PROTOCOL:
class _BoolMod(Protocol):
@overload
- def __call__(self, __other: _BoolLike) -> int8: ...
+ def __call__(self, __other: _BoolLike_co) -> int8: ...
@overload # platform dependent
- def __call__(self, __other: int) -> signedinteger[Any]: ...
+ def __call__(self, __other: int) -> int_: ...
@overload
def __call__(self, __other: float) -> float64: ...
@overload
@@ -123,11 +122,11 @@ if TYPE_CHECKING or HAVE_PROTOCOL:
class _BoolDivMod(Protocol):
@overload
- def __call__(self, __other: _BoolLike) -> _2Tuple[int8]: ...
+ def __call__(self, __other: _BoolLike_co) -> _2Tuple[int8]: ...
@overload # platform dependent
- def __call__(self, __other: int) -> _2Tuple[signedinteger[Any]]: ...
+ def __call__(self, __other: int) -> _2Tuple[int_]: ...
@overload
- def __call__(self, __other: float) -> _2Tuple[float64]: ...
+ def __call__(self, __other: float) -> _2Tuple[floating[_NBit1 | _NBitDouble]]: ...
@overload
def __call__(self, __other: _IntType) -> _2Tuple[_IntType]: ...
@overload
@@ -137,188 +136,200 @@ if TYPE_CHECKING or HAVE_PROTOCOL:
@overload
def __call__(self, __other: timedelta64) -> _NumberType_co: ...
@overload
- def __call__(self, __other: _FloatLike) -> timedelta64: ...
+ def __call__(self, __other: _BoolLike_co) -> NoReturn: ...
+ @overload
+ def __call__(self, __other: _FloatLike_co) -> timedelta64: ...
- class _IntTrueDiv(Protocol[_NBit_co]):
+ class _IntTrueDiv(Protocol[_NBit1]):
@overload
- def __call__(self, __other: bool) -> floating[_NBit_co]: ...
+ def __call__(self, __other: bool) -> floating[_NBit1]: ...
@overload
- def __call__(self, __other: int) -> floating[Any]: ...
+ def __call__(self, __other: int) -> floating[_NBit1 | _NBitInt]: ...
@overload
- def __call__(self, __other: float) -> float64: ...
+ def __call__(self, __other: float) -> floating[_NBit1 | _NBitDouble]: ...
@overload
- def __call__(self, __other: complex) -> complex128: ...
+ def __call__(
+ self, __other: complex
+ ) -> complexfloating[_NBit1 | _NBitDouble, _NBit1 | _NBitDouble]: ...
@overload
- def __call__(self, __other: integer[_NBit]) -> floating[Union[_NBit_co, _NBit]]: ...
+ def __call__(self, __other: integer[_NBit2]) -> floating[_NBit1 | _NBit2]: ...
- class _UnsignedIntOp(Protocol[_NBit_co]):
+ class _UnsignedIntOp(Protocol[_NBit1]):
# NOTE: `uint64 + signedinteger -> float64`
@overload
- def __call__(self, __other: bool) -> unsignedinteger[_NBit_co]: ...
+ def __call__(self, __other: bool) -> unsignedinteger[_NBit1]: ...
@overload
def __call__(
- self, __other: Union[int, signedinteger[Any]]
- ) -> Union[signedinteger[Any], float64]: ...
+ self, __other: int | signedinteger[Any]
+ ) -> Any: ...
@overload
- def __call__(self, __other: float) -> float64: ...
+ def __call__(self, __other: float) -> floating[_NBit1 | _NBitDouble]: ...
@overload
- def __call__(self, __other: complex) -> complex128: ...
+ def __call__(
+ self, __other: complex
+ ) -> complexfloating[_NBit1 | _NBitDouble, _NBit1 | _NBitDouble]: ...
@overload
def __call__(
- self, __other: unsignedinteger[_NBit]
- ) -> unsignedinteger[Union[_NBit_co, _NBit]]: ...
+ self, __other: unsignedinteger[_NBit2]
+ ) -> unsignedinteger[_NBit1 | _NBit2]: ...
- class _UnsignedIntBitOp(Protocol[_NBit_co]):
+ class _UnsignedIntBitOp(Protocol[_NBit1]):
@overload
- def __call__(self, __other: bool) -> unsignedinteger[_NBit_co]: ...
+ def __call__(self, __other: bool) -> unsignedinteger[_NBit1]: ...
@overload
def __call__(self, __other: int) -> signedinteger[Any]: ...
@overload
def __call__(self, __other: signedinteger[Any]) -> signedinteger[Any]: ...
@overload
def __call__(
- self, __other: unsignedinteger[_NBit]
- ) -> unsignedinteger[Union[_NBit_co, _NBit]]: ...
+ self, __other: unsignedinteger[_NBit2]
+ ) -> unsignedinteger[_NBit1 | _NBit2]: ...
- class _UnsignedIntMod(Protocol[_NBit_co]):
+ class _UnsignedIntMod(Protocol[_NBit1]):
@overload
- def __call__(self, __other: bool) -> unsignedinteger[_NBit_co]: ...
+ def __call__(self, __other: bool) -> unsignedinteger[_NBit1]: ...
@overload
def __call__(
- self, __other: Union[int, signedinteger[Any]]
- ) -> Union[signedinteger[Any], float64]: ...
+ self, __other: int | signedinteger[Any]
+ ) -> Any: ...
@overload
- def __call__(self, __other: float) -> float64: ...
+ def __call__(self, __other: float) -> floating[_NBit1 | _NBitDouble]: ...
@overload
def __call__(
- self, __other: unsignedinteger[_NBit]
- ) -> unsignedinteger[Union[_NBit_co, _NBit]]: ...
+ self, __other: unsignedinteger[_NBit2]
+ ) -> unsignedinteger[_NBit1 | _NBit2]: ...
- class _UnsignedIntDivMod(Protocol[_NBit_co]):
+ class _UnsignedIntDivMod(Protocol[_NBit1]):
@overload
- def __call__(self, __other: bool) -> _2Tuple[signedinteger[_NBit_co]]: ...
+ def __call__(self, __other: bool) -> _2Tuple[signedinteger[_NBit1]]: ...
@overload
def __call__(
- self, __other: Union[int, signedinteger[Any]]
- ) -> Union[_2Tuple[signedinteger[Any]], _2Tuple[float64]]: ...
+ self, __other: int | signedinteger[Any]
+ ) -> _2Tuple[Any]: ...
@overload
- def __call__(self, __other: float) -> _2Tuple[float64]: ...
+ def __call__(self, __other: float) -> _2Tuple[floating[_NBit1 | _NBitDouble]]: ...
@overload
def __call__(
- self, __other: unsignedinteger[_NBit]
- ) -> _2Tuple[unsignedinteger[Union[_NBit_co, _NBit]]]: ...
+ self, __other: unsignedinteger[_NBit2]
+ ) -> _2Tuple[unsignedinteger[_NBit1 | _NBit2]]: ...
- class _SignedIntOp(Protocol[_NBit_co]):
+ class _SignedIntOp(Protocol[_NBit1]):
@overload
- def __call__(self, __other: bool) -> signedinteger[_NBit_co]: ...
+ def __call__(self, __other: bool) -> signedinteger[_NBit1]: ...
@overload
- def __call__(self, __other: int) -> signedinteger[Any]: ...
+ def __call__(self, __other: int) -> signedinteger[_NBit1 | _NBitInt]: ...
@overload
- def __call__(self, __other: float) -> float64: ...
+ def __call__(self, __other: float) -> floating[_NBit1 | _NBitDouble]: ...
@overload
- def __call__(self, __other: complex) -> complex128: ...
+ def __call__(
+ self, __other: complex
+ ) -> complexfloating[_NBit1 | _NBitDouble, _NBit1 | _NBitDouble]: ...
@overload
def __call__(
- self, __other: signedinteger[_NBit]
- ) -> signedinteger[Union[_NBit_co, _NBit]]: ...
+ self, __other: signedinteger[_NBit2]
+ ) -> signedinteger[_NBit1 | _NBit2]: ...
- class _SignedIntBitOp(Protocol[_NBit_co]):
+ class _SignedIntBitOp(Protocol[_NBit1]):
@overload
- def __call__(self, __other: bool) -> signedinteger[_NBit_co]: ...
+ def __call__(self, __other: bool) -> signedinteger[_NBit1]: ...
@overload
- def __call__(self, __other: int) -> signedinteger[Any]: ...
+ def __call__(self, __other: int) -> signedinteger[_NBit1 | _NBitInt]: ...
@overload
def __call__(
- self, __other: signedinteger[_NBit]
- ) -> signedinteger[Union[_NBit_co, _NBit]]: ...
+ self, __other: signedinteger[_NBit2]
+ ) -> signedinteger[_NBit1 | _NBit2]: ...
- class _SignedIntMod(Protocol[_NBit_co]):
+ class _SignedIntMod(Protocol[_NBit1]):
@overload
- def __call__(self, __other: bool) -> signedinteger[_NBit_co]: ...
+ def __call__(self, __other: bool) -> signedinteger[_NBit1]: ...
@overload
- def __call__(self, __other: int) -> signedinteger[Any]: ...
+ def __call__(self, __other: int) -> signedinteger[_NBit1 | _NBitInt]: ...
@overload
- def __call__(self, __other: float) -> float64: ...
+ def __call__(self, __other: float) -> floating[_NBit1 | _NBitDouble]: ...
@overload
def __call__(
- self, __other: signedinteger[_NBit]
- ) -> signedinteger[Union[_NBit_co, _NBit]]: ...
+ self, __other: signedinteger[_NBit2]
+ ) -> signedinteger[_NBit1 | _NBit2]: ...
- class _SignedIntDivMod(Protocol[_NBit_co]):
+ class _SignedIntDivMod(Protocol[_NBit1]):
@overload
- def __call__(self, __other: bool) -> _2Tuple[signedinteger[_NBit_co]]: ...
+ def __call__(self, __other: bool) -> _2Tuple[signedinteger[_NBit1]]: ...
@overload
- def __call__(self, __other: int) -> _2Tuple[signedinteger[Any]]: ...
+ def __call__(self, __other: int) -> _2Tuple[signedinteger[_NBit1 | _NBitInt]]: ...
@overload
- def __call__(self, __other: float) -> _2Tuple[float64]: ...
+ def __call__(self, __other: float) -> _2Tuple[floating[_NBit1 | _NBitDouble]]: ...
@overload
def __call__(
- self, __other: signedinteger[_NBit]
- ) -> _2Tuple[signedinteger[Union[_NBit_co, _NBit]]]: ...
+ self, __other: signedinteger[_NBit2]
+ ) -> _2Tuple[signedinteger[_NBit1 | _NBit2]]: ...
- class _FloatOp(Protocol[_NBit_co]):
+ class _FloatOp(Protocol[_NBit1]):
@overload
- def __call__(self, __other: bool) -> floating[_NBit_co]: ...
+ def __call__(self, __other: bool) -> floating[_NBit1]: ...
@overload
- def __call__(self, __other: int) -> floating[Any]: ...
+ def __call__(self, __other: int) -> floating[_NBit1 | _NBitInt]: ...
@overload
- def __call__(self, __other: float) -> float64: ...
+ def __call__(self, __other: float) -> floating[_NBit1 | _NBitDouble]: ...
@overload
- def __call__(self, __other: complex) -> complex128: ...
+ def __call__(
+ self, __other: complex
+ ) -> complexfloating[_NBit1 | _NBitDouble, _NBit1 | _NBitDouble]: ...
@overload
def __call__(
- self, __other: Union[integer[_NBit], floating[_NBit]]
- ) -> floating[Union[_NBit_co, _NBit]]: ...
+ self, __other: integer[_NBit2] | floating[_NBit2]
+ ) -> floating[_NBit1 | _NBit2]: ...
- class _FloatMod(Protocol[_NBit_co]):
+ class _FloatMod(Protocol[_NBit1]):
@overload
- def __call__(self, __other: bool) -> floating[_NBit_co]: ...
+ def __call__(self, __other: bool) -> floating[_NBit1]: ...
@overload
- def __call__(self, __other: int) -> floating[Any]: ...
+ def __call__(self, __other: int) -> floating[_NBit1 | _NBitInt]: ...
@overload
- def __call__(self, __other: float) -> float64: ...
+ def __call__(self, __other: float) -> floating[_NBit1 | _NBitDouble]: ...
@overload
def __call__(
- self, __other: Union[integer[_NBit], floating[_NBit]]
- ) -> floating[Union[_NBit_co, _NBit]]: ...
+ self, __other: integer[_NBit2] | floating[_NBit2]
+ ) -> floating[_NBit1 | _NBit2]: ...
- class _FloatDivMod(Protocol[_NBit_co]):
+ class _FloatDivMod(Protocol[_NBit1]):
@overload
- def __call__(self, __other: bool) -> _2Tuple[floating[_NBit_co]]: ...
+ def __call__(self, __other: bool) -> _2Tuple[floating[_NBit1]]: ...
@overload
- def __call__(self, __other: int) -> _2Tuple[floating[Any]]: ...
+ def __call__(self, __other: int) -> _2Tuple[floating[_NBit1 | _NBitInt]]: ...
@overload
- def __call__(self, __other: float) -> _2Tuple[float64]: ...
+ def __call__(self, __other: float) -> _2Tuple[floating[_NBit1 | _NBitDouble]]: ...
@overload
def __call__(
- self, __other: Union[integer[_NBit], floating[_NBit]]
- ) -> _2Tuple[floating[Union[_NBit_co, _NBit]]]: ...
+ self, __other: integer[_NBit2] | floating[_NBit2]
+ ) -> _2Tuple[floating[_NBit1 | _NBit2]]: ...
- class _ComplexOp(Protocol[_NBit_co]):
+ class _ComplexOp(Protocol[_NBit1]):
@overload
- def __call__(self, __other: bool) -> complexfloating[_NBit_co, _NBit_co]: ...
+ def __call__(self, __other: bool) -> complexfloating[_NBit1, _NBit1]: ...
@overload
- def __call__(self, __other: int) -> complexfloating[Any, Any]: ...
+ def __call__(self, __other: int) -> complexfloating[_NBit1 | _NBitInt, _NBit1 | _NBitInt]: ...
@overload
- def __call__(self, __other: Union[float, complex]) -> complex128: ...
+ def __call__(
+ self, __other: complex
+ ) -> complexfloating[_NBit1 | _NBitDouble, _NBit1 | _NBitDouble]: ...
@overload
def __call__(
self,
__other: Union[
- integer[_NBit],
- floating[_NBit],
- complexfloating[_NBit, _NBit],
+ integer[_NBit2],
+ floating[_NBit2],
+ complexfloating[_NBit2, _NBit2],
]
- ) -> complexfloating[Union[_NBit_co, _NBit], Union[_NBit_co, _NBit]]: ...
+ ) -> complexfloating[_NBit1 | _NBit2, _NBit1 | _NBit2]: ...
class _NumberOp(Protocol):
- def __call__(self, __other: _NumberLike) -> number: ...
+ def __call__(self, __other: _NumberLike_co) -> Any: ...
- class _ComparisonOp(Protocol[_T]):
+ class _ComparisonOp(Protocol[_T1, _T2]):
@overload
- def __call__(self, __other: _T) -> bool_: ...
+ def __call__(self, __other: _T1) -> bool_: ...
@overload
- def __call__(self, __other: ArrayLike) -> Union[ndarray, bool_]: ...
+ def __call__(self, __other: _T2) -> NDArray[bool_]: ...
else:
_BoolOp = Any
diff --git a/numpy/typing/_char_codes.py b/numpy/typing/_char_codes.py
new file mode 100644
index 000000000..22ee168e9
--- /dev/null
+++ b/numpy/typing/_char_codes.py
@@ -0,0 +1,171 @@
+import sys
+from typing import Any, TYPE_CHECKING
+
+from . import _HAS_TYPING_EXTENSIONS
+
+if sys.version_info >= (3, 8):
+ from typing import Literal
+elif _HAS_TYPING_EXTENSIONS:
+ from typing_extensions import Literal
+
+if TYPE_CHECKING or _HAS_TYPING_EXTENSIONS or sys.version_info >= (3, 8):
+ _BoolCodes = Literal["?", "=?", "<?", ">?", "bool", "bool_", "bool8"]
+
+ _UInt8Codes = Literal["uint8", "u1", "=u1", "<u1", ">u1"]
+ _UInt16Codes = Literal["uint16", "u2", "=u2", "<u2", ">u2"]
+ _UInt32Codes = Literal["uint32", "u4", "=u4", "<u4", ">u4"]
+ _UInt64Codes = Literal["uint64", "u8", "=u8", "<u8", ">u8"]
+
+ _Int8Codes = Literal["int8", "i1", "=i1", "<i1", ">i1"]
+ _Int16Codes = Literal["int16", "i2", "=i2", "<i2", ">i2"]
+ _Int32Codes = Literal["int32", "i4", "=i4", "<i4", ">i4"]
+ _Int64Codes = Literal["int64", "i8", "=i8", "<i8", ">i8"]
+
+ _Float16Codes = Literal["float16", "f2", "=f2", "<f2", ">f2"]
+ _Float32Codes = Literal["float32", "f4", "=f4", "<f4", ">f4"]
+ _Float64Codes = Literal["float64", "f8", "=f8", "<f8", ">f8"]
+
+ _Complex64Codes = Literal["complex64", "c8", "=c8", "<c8", ">c8"]
+ _Complex128Codes = Literal["complex128", "c16", "=c16", "<c16", ">c16"]
+
+ _ByteCodes = Literal["byte", "b", "=b", "<b", ">b"]
+ _ShortCodes = Literal["short", "h", "=h", "<h", ">h"]
+ _IntCCodes = Literal["intc", "i", "=i", "<i", ">i"]
+ _IntPCodes = Literal["intp", "int0", "p", "=p", "<p", ">p"]
+ _IntCodes = Literal["long", "int", "int_", "l", "=l", "<l", ">l"]
+ _LongLongCodes = Literal["longlong", "q", "=q", "<q", ">q"]
+
+ _UByteCodes = Literal["ubyte", "B", "=B", "<B", ">B"]
+ _UShortCodes = Literal["ushort", "H", "=H", "<H", ">H"]
+ _UIntCCodes = Literal["uintc", "I", "=I", "<I", ">I"]
+ _UIntPCodes = Literal["uintp", "uint0", "P", "=P", "<P", ">P"]
+ _UIntCodes = Literal["uint", "L", "=L", "<L", ">L"]
+ _ULongLongCodes = Literal["ulonglong", "Q", "=Q", "<Q", ">Q"]
+
+ _HalfCodes = Literal["half", "e", "=e", "<e", ">e"]
+ _SingleCodes = Literal["single", "f", "=f", "<f", ">f"]
+ _DoubleCodes = Literal["double", "float", "float_", "d", "=d", "<d", ">d"]
+ _LongDoubleCodes = Literal["longdouble", "longfloat", "g", "=g", "<g", ">g"]
+
+ _CSingleCodes = Literal["csingle", "singlecomplex", "F", "=F", "<F", ">F"]
+ _CDoubleCodes = Literal["cdouble", "complex", "complex_", "cfloat", "D", "=D", "<D", ">D"]
+ _CLongDoubleCodes = Literal["clongdouble", "clongfloat", "longcomplex", "G", "=G", "<G", ">G"]
+
+ _StrCodes = Literal["str", "str_", "str0", "unicode", "unicode_", "U", "=U", "<U", ">U"]
+ _BytesCodes = Literal["bytes", "bytes_", "bytes0", "S", "=S", "<S", ">S"]
+ _VoidCodes = Literal["void", "void0", "V", "=V", "<V", ">V"]
+ _ObjectCodes = Literal["object", "object_", "O", "=O", "<O", ">O"]
+
+ _DT64Codes = Literal[
+ "datetime64", "=datetime64", "<datetime64", ">datetime64",
+ "datetime64[Y]", "=datetime64[Y]", "<datetime64[Y]", ">datetime64[Y]",
+ "datetime64[M]", "=datetime64[M]", "<datetime64[M]", ">datetime64[M]",
+ "datetime64[W]", "=datetime64[W]", "<datetime64[W]", ">datetime64[W]",
+ "datetime64[D]", "=datetime64[D]", "<datetime64[D]", ">datetime64[D]",
+ "datetime64[h]", "=datetime64[h]", "<datetime64[h]", ">datetime64[h]",
+ "datetime64[m]", "=datetime64[m]", "<datetime64[m]", ">datetime64[m]",
+ "datetime64[s]", "=datetime64[s]", "<datetime64[s]", ">datetime64[s]",
+ "datetime64[ms]", "=datetime64[ms]", "<datetime64[ms]", ">datetime64[ms]",
+ "datetime64[us]", "=datetime64[us]", "<datetime64[us]", ">datetime64[us]",
+ "datetime64[ns]", "=datetime64[ns]", "<datetime64[ns]", ">datetime64[ns]",
+ "datetime64[ps]", "=datetime64[ps]", "<datetime64[ps]", ">datetime64[ps]",
+ "datetime64[fs]", "=datetime64[fs]", "<datetime64[fs]", ">datetime64[fs]",
+ "datetime64[as]", "=datetime64[as]", "<datetime64[as]", ">datetime64[as]",
+ "M", "=M", "<M", ">M",
+ "M8", "=M8", "<M8", ">M8",
+ "M8[Y]", "=M8[Y]", "<M8[Y]", ">M8[Y]",
+ "M8[M]", "=M8[M]", "<M8[M]", ">M8[M]",
+ "M8[W]", "=M8[W]", "<M8[W]", ">M8[W]",
+ "M8[D]", "=M8[D]", "<M8[D]", ">M8[D]",
+ "M8[h]", "=M8[h]", "<M8[h]", ">M8[h]",
+ "M8[m]", "=M8[m]", "<M8[m]", ">M8[m]",
+ "M8[s]", "=M8[s]", "<M8[s]", ">M8[s]",
+ "M8[ms]", "=M8[ms]", "<M8[ms]", ">M8[ms]",
+ "M8[us]", "=M8[us]", "<M8[us]", ">M8[us]",
+ "M8[ns]", "=M8[ns]", "<M8[ns]", ">M8[ns]",
+ "M8[ps]", "=M8[ps]", "<M8[ps]", ">M8[ps]",
+ "M8[fs]", "=M8[fs]", "<M8[fs]", ">M8[fs]",
+ "M8[as]", "=M8[as]", "<M8[as]", ">M8[as]",
+ ]
+ _TD64Codes = Literal[
+ "timedelta64", "=timedelta64", "<timedelta64", ">timedelta64",
+ "timedelta64[Y]", "=timedelta64[Y]", "<timedelta64[Y]", ">timedelta64[Y]",
+ "timedelta64[M]", "=timedelta64[M]", "<timedelta64[M]", ">timedelta64[M]",
+ "timedelta64[W]", "=timedelta64[W]", "<timedelta64[W]", ">timedelta64[W]",
+ "timedelta64[D]", "=timedelta64[D]", "<timedelta64[D]", ">timedelta64[D]",
+ "timedelta64[h]", "=timedelta64[h]", "<timedelta64[h]", ">timedelta64[h]",
+ "timedelta64[m]", "=timedelta64[m]", "<timedelta64[m]", ">timedelta64[m]",
+ "timedelta64[s]", "=timedelta64[s]", "<timedelta64[s]", ">timedelta64[s]",
+ "timedelta64[ms]", "=timedelta64[ms]", "<timedelta64[ms]", ">timedelta64[ms]",
+ "timedelta64[us]", "=timedelta64[us]", "<timedelta64[us]", ">timedelta64[us]",
+ "timedelta64[ns]", "=timedelta64[ns]", "<timedelta64[ns]", ">timedelta64[ns]",
+ "timedelta64[ps]", "=timedelta64[ps]", "<timedelta64[ps]", ">timedelta64[ps]",
+ "timedelta64[fs]", "=timedelta64[fs]", "<timedelta64[fs]", ">timedelta64[fs]",
+ "timedelta64[as]", "=timedelta64[as]", "<timedelta64[as]", ">timedelta64[as]",
+ "m", "=m", "<m", ">m",
+ "m8", "=m8", "<m8", ">m8",
+ "m8[Y]", "=m8[Y]", "<m8[Y]", ">m8[Y]",
+ "m8[M]", "=m8[M]", "<m8[M]", ">m8[M]",
+ "m8[W]", "=m8[W]", "<m8[W]", ">m8[W]",
+ "m8[D]", "=m8[D]", "<m8[D]", ">m8[D]",
+ "m8[h]", "=m8[h]", "<m8[h]", ">m8[h]",
+ "m8[m]", "=m8[m]", "<m8[m]", ">m8[m]",
+ "m8[s]", "=m8[s]", "<m8[s]", ">m8[s]",
+ "m8[ms]", "=m8[ms]", "<m8[ms]", ">m8[ms]",
+ "m8[us]", "=m8[us]", "<m8[us]", ">m8[us]",
+ "m8[ns]", "=m8[ns]", "<m8[ns]", ">m8[ns]",
+ "m8[ps]", "=m8[ps]", "<m8[ps]", ">m8[ps]",
+ "m8[fs]", "=m8[fs]", "<m8[fs]", ">m8[fs]",
+ "m8[as]", "=m8[as]", "<m8[as]", ">m8[as]",
+ ]
+
+else:
+ _BoolCodes = Any
+
+ _UInt8Codes = Any
+ _UInt16Codes = Any
+ _UInt32Codes = Any
+ _UInt64Codes = Any
+
+ _Int8Codes = Any
+ _Int16Codes = Any
+ _Int32Codes = Any
+ _Int64Codes = Any
+
+ _Float16Codes = Any
+ _Float32Codes = Any
+ _Float64Codes = Any
+
+ _Complex64Codes = Any
+ _Complex128Codes = Any
+
+ _ByteCodes = Any
+ _ShortCodes = Any
+ _IntCCodes = Any
+ _IntPCodes = Any
+ _IntCodes = Any
+ _LongLongCodes = Any
+
+ _UByteCodes = Any
+ _UShortCodes = Any
+ _UIntCCodes = Any
+ _UIntPCodes = Any
+ _UIntCodes = Any
+ _ULongLongCodes = Any
+
+ _HalfCodes = Any
+ _SingleCodes = Any
+ _DoubleCodes = Any
+ _LongDoubleCodes = Any
+
+ _CSingleCodes = Any
+ _CDoubleCodes = Any
+ _CLongDoubleCodes = Any
+
+ _StrCodes = Any
+ _BytesCodes = Any
+ _VoidCodes = Any
+ _ObjectCodes = Any
+
+ _DT64Codes = Any
+ _TD64Codes = Any
diff --git a/numpy/typing/_dtype_like.py b/numpy/typing/_dtype_like.py
index 1953bd5fc..b2ce3adb4 100644
--- a/numpy/typing/_dtype_like.py
+++ b/numpy/typing/_dtype_like.py
@@ -1,23 +1,65 @@
import sys
-from typing import Any, List, Sequence, Tuple, Union, TYPE_CHECKING
+from typing import Any, List, Sequence, Tuple, Union, Type, TypeVar, TYPE_CHECKING
-from numpy import dtype
+import numpy as np
+
+from . import _HAS_TYPING_EXTENSIONS
from ._shape import _ShapeLike
+from ._generic_alias import _DType as DType
if sys.version_info >= (3, 8):
from typing import Protocol, TypedDict
- HAVE_PROTOCOL = True
+elif _HAS_TYPING_EXTENSIONS:
+ from typing_extensions import Protocol, TypedDict
else:
- try:
- from typing_extensions import Protocol, TypedDict
- except ImportError:
- HAVE_PROTOCOL = False
- else:
- HAVE_PROTOCOL = True
+ from ._generic_alias import _GenericAlias as GenericAlias
+
+from ._char_codes import (
+ _BoolCodes,
+ _UInt8Codes,
+ _UInt16Codes,
+ _UInt32Codes,
+ _UInt64Codes,
+ _Int8Codes,
+ _Int16Codes,
+ _Int32Codes,
+ _Int64Codes,
+ _Float16Codes,
+ _Float32Codes,
+ _Float64Codes,
+ _Complex64Codes,
+ _Complex128Codes,
+ _ByteCodes,
+ _ShortCodes,
+ _IntCCodes,
+ _IntPCodes,
+ _IntCodes,
+ _LongLongCodes,
+ _UByteCodes,
+ _UShortCodes,
+ _UIntCCodes,
+ _UIntPCodes,
+ _UIntCodes,
+ _ULongLongCodes,
+ _HalfCodes,
+ _SingleCodes,
+ _DoubleCodes,
+ _LongDoubleCodes,
+ _CSingleCodes,
+ _CDoubleCodes,
+ _CLongDoubleCodes,
+ _DT64Codes,
+ _TD64Codes,
+ _StrCodes,
+ _BytesCodes,
+ _VoidCodes,
+ _ObjectCodes,
+)
_DTypeLikeNested = Any # TODO: wait for support for recursive types
+_DType_co = TypeVar("_DType_co", covariant=True, bound=DType[Any])
-if TYPE_CHECKING or HAVE_PROTOCOL:
+if TYPE_CHECKING or _HAS_TYPING_EXTENSIONS or sys.version_info >= (3, 8):
# Mandatory keys
class _DTypeDictBase(TypedDict):
names: Sequence[str]
@@ -31,12 +73,15 @@ if TYPE_CHECKING or HAVE_PROTOCOL:
aligned: bool
# A protocol for anything with the dtype attribute
- class _SupportsDType(Protocol):
- dtype: _DTypeLikeNested
+ class _SupportsDType(Protocol[_DType_co]):
+ @property
+ def dtype(self) -> _DType_co: ...
else:
_DTypeDict = Any
- _SupportsDType = Any
+
+ class _SupportsDType: ...
+ _SupportsDType = GenericAlias(_SupportsDType, _DType_co)
# Would create a dtype[np.void]
@@ -61,13 +106,13 @@ _VoidDTypeLike = Union[
# Anything that can be coerced into numpy.dtype.
# Reference: https://docs.scipy.org/doc/numpy/reference/arrays.dtypes.html
DTypeLike = Union[
- dtype,
+ DType[Any],
# default data type (float64)
None,
# array-scalar types and generic types
- type, # TODO: enumerate these when we add type hints for numpy scalars
+ Type[Any], # TODO: enumerate these when we add type hints for numpy scalars
# anything with a dtype attribute
- _SupportsDType,
+ _SupportsDType[DType[Any]],
# character codes, type strings or comma-separated fields, e.g., 'float64'
str,
_VoidDTypeLike,
@@ -79,3 +124,115 @@ DTypeLike = Union[
# therefore not included in the Union defining `DTypeLike`.
#
# See https://github.com/numpy/numpy/issues/16891 for more details.
+
+# Aliases for commonly used dtype-like objects.
+# Note that the precision of `np.number` subclasses is ignored herein.
+_DTypeLikeBool = Union[
+ Type[bool],
+ Type[np.bool_],
+ DType[np.bool_],
+ _SupportsDType[DType[np.bool_]],
+ _BoolCodes,
+]
+_DTypeLikeUInt = Union[
+ Type[np.unsignedinteger],
+ DType[np.unsignedinteger],
+ _SupportsDType[DType[np.unsignedinteger]],
+ _UInt8Codes,
+ _UInt16Codes,
+ _UInt32Codes,
+ _UInt64Codes,
+ _UByteCodes,
+ _UShortCodes,
+ _UIntCCodes,
+ _UIntPCodes,
+ _UIntCodes,
+ _ULongLongCodes,
+]
+_DTypeLikeInt = Union[
+ Type[int],
+ Type[np.signedinteger],
+ DType[np.signedinteger],
+ _SupportsDType[DType[np.signedinteger]],
+ _Int8Codes,
+ _Int16Codes,
+ _Int32Codes,
+ _Int64Codes,
+ _ByteCodes,
+ _ShortCodes,
+ _IntCCodes,
+ _IntPCodes,
+ _IntCodes,
+ _LongLongCodes,
+]
+_DTypeLikeFloat = Union[
+ Type[float],
+ Type[np.floating],
+ DType[np.floating],
+ _SupportsDType[DType[np.floating]],
+ _Float16Codes,
+ _Float32Codes,
+ _Float64Codes,
+ _HalfCodes,
+ _SingleCodes,
+ _DoubleCodes,
+ _LongDoubleCodes,
+]
+_DTypeLikeComplex = Union[
+ Type[complex],
+ Type[np.complexfloating],
+ DType[np.complexfloating],
+ _SupportsDType[DType[np.complexfloating]],
+ _Complex64Codes,
+ _Complex128Codes,
+ _CSingleCodes,
+ _CDoubleCodes,
+ _CLongDoubleCodes,
+]
+_DTypeLikeDT64 = Union[
+ Type[np.timedelta64],
+ DType[np.timedelta64],
+ _SupportsDType[DType[np.timedelta64]],
+ _TD64Codes,
+]
+_DTypeLikeTD64 = Union[
+ Type[np.datetime64],
+ DType[np.datetime64],
+ _SupportsDType[DType[np.datetime64]],
+ _DT64Codes,
+]
+_DTypeLikeStr = Union[
+ Type[str],
+ Type[np.str_],
+ DType[np.str_],
+ _SupportsDType[DType[np.str_]],
+ _StrCodes,
+]
+_DTypeLikeBytes = Union[
+ Type[bytes],
+ Type[np.bytes_],
+ DType[np.bytes_],
+ _SupportsDType[DType[np.bytes_]],
+ _BytesCodes,
+]
+_DTypeLikeVoid = Union[
+ Type[np.void],
+ DType[np.void],
+ _SupportsDType[DType[np.void]],
+ _VoidCodes,
+ _VoidDTypeLike,
+]
+_DTypeLikeObject = Union[
+ type,
+ DType[np.object_],
+ _SupportsDType[DType[np.object_]],
+ _ObjectCodes,
+]
+
+_DTypeLikeComplex_co = Union[
+ _DTypeLikeBool,
+ _DTypeLikeUInt,
+ _DTypeLikeInt,
+ _DTypeLikeFloat,
+ _DTypeLikeComplex,
+]
diff --git a/numpy/typing/_extended_precision.py b/numpy/typing/_extended_precision.py
new file mode 100644
index 000000000..0900bc659
--- /dev/null
+++ b/numpy/typing/_extended_precision.py
@@ -0,0 +1,42 @@
+"""A module with platform-specific extended precision `numpy.number` subclasses.
+
+The subclasses are defined here (instead of ``__init__.pyi``) such
+that they can be imported conditionally via the numpy's mypy plugin.
+"""
+
+from typing import TYPE_CHECKING
+
+import numpy as np
+from . import (
+ _80Bit,
+ _96Bit,
+ _128Bit,
+ _256Bit,
+)
+
+if TYPE_CHECKING:
+ uint128 = np.unsignedinteger[_128Bit]
+ uint256 = np.unsignedinteger[_256Bit]
+ int128 = np.signedinteger[_128Bit]
+ int256 = np.signedinteger[_256Bit]
+ float80 = np.floating[_80Bit]
+ float96 = np.floating[_96Bit]
+ float128 = np.floating[_128Bit]
+ float256 = np.floating[_256Bit]
+ complex160 = np.complexfloating[_80Bit, _80Bit]
+ complex192 = np.complexfloating[_96Bit, _96Bit]
+ complex256 = np.complexfloating[_128Bit, _128Bit]
+ complex512 = np.complexfloating[_256Bit, _256Bit]
+else:
+ uint128 = Any
+ uint256 = Any
+ int128 = Any
+ int256 = Any
+ float80 = Any
+ float96 = Any
+ float128 = Any
+ float256 = Any
+ complex160 = Any
+ complex192 = Any
+ complex256 = Any
+ complex512 = Any
diff --git a/numpy/typing/_generic_alias.py b/numpy/typing/_generic_alias.py
new file mode 100644
index 000000000..8d65ef855
--- /dev/null
+++ b/numpy/typing/_generic_alias.py
@@ -0,0 +1,216 @@
+from __future__ import annotations
+
+import sys
+import types
+from typing import (
+ Any,
+ ClassVar,
+ FrozenSet,
+ Generator,
+ Iterable,
+ Iterator,
+ List,
+ NoReturn,
+ Tuple,
+ Type,
+ TypeVar,
+ TYPE_CHECKING,
+)
+
+import numpy as np
+
+__all__ = ["_GenericAlias", "NDArray"]
+
+_T = TypeVar("_T", bound="_GenericAlias")
+
+
+def _to_str(obj: object) -> str:
+ """Helper function for `_GenericAlias.__repr__`."""
+ if obj is Ellipsis:
+ return '...'
+ elif isinstance(obj, type) and not isinstance(obj, _GENERIC_ALIAS_TYPE):
+ if obj.__module__ == 'builtins':
+ return obj.__qualname__
+ else:
+ return f'{obj.__module__}.{obj.__qualname__}'
+ else:
+ return repr(obj)
+
+
+def _parse_parameters(args: Iterable[Any]) -> Generator[TypeVar, None, None]:
+ """Search for all typevars and typevar-containing objects in `args`.
+
+ Helper function for `_GenericAlias.__init__`.
+
+ """
+ for i in args:
+ if hasattr(i, "__parameters__"):
+ yield from i.__parameters__
+ elif isinstance(i, TypeVar):
+ yield i
+
+
+def _reconstruct_alias(alias: _T, parameters: Iterator[TypeVar]) -> _T:
+ """Recursivelly replace all typevars with those from `parameters`.
+
+ Helper function for `_GenericAlias.__getitem__`.
+
+ """
+ args = []
+ for i in alias.__args__:
+ if isinstance(i, TypeVar):
+ value: Any = next(parameters)
+ elif isinstance(i, _GenericAlias):
+ value = _reconstruct_alias(i, parameters)
+ elif hasattr(i, "__parameters__"):
+ prm_tup = tuple(next(parameters) for _ in i.__parameters__)
+ value = i[prm_tup]
+ else:
+ value = i
+ args.append(value)
+
+ cls = type(alias)
+ return cls(alias.__origin__, tuple(args))
+
+
+class _GenericAlias:
+ """A python-based backport of the `types.GenericAlias` class.
+
+ E.g. for ``t = list[int]``, ``t.__origin__`` is ``list`` and
+ ``t.__args__`` is ``(int,)``.
+
+ See Also
+ --------
+ :pep:`585`
+ The PEP responsible for introducing `types.GenericAlias`.
+
+ """
+
+ __slots__ = ("__weakref__", "_origin", "_args", "_parameters", "_hash")
+
+ @property
+ def __origin__(self) -> type:
+ return super().__getattribute__("_origin")
+
+ @property
+ def __args__(self) -> Tuple[object, ...]:
+ return super().__getattribute__("_args")
+
+ @property
+ def __parameters__(self) -> Tuple[TypeVar, ...]:
+ """Type variables in the ``GenericAlias``."""
+ return super().__getattribute__("_parameters")
+
+ def __init__(
+ self,
+ origin: type,
+ args: object | Tuple[object, ...],
+ ) -> None:
+ self._origin = origin
+ self._args = args if isinstance(args, tuple) else (args,)
+ self._parameters = tuple(_parse_parameters(self.__args__))
+
+ @property
+ def __call__(self) -> type:
+ return self.__origin__
+
+ def __reduce__(self: _T) -> Tuple[
+ Type[_T],
+ Tuple[type, Tuple[object, ...]],
+ ]:
+ cls = type(self)
+ return cls, (self.__origin__, self.__args__)
+
+ def __mro_entries__(self, bases: Iterable[object]) -> Tuple[type]:
+ return (self.__origin__,)
+
+ def __dir__(self) -> List[str]:
+ """Implement ``dir(self)``."""
+ cls = type(self)
+ dir_origin = set(dir(self.__origin__))
+ return sorted(cls._ATTR_EXCEPTIONS | dir_origin)
+
+ def __hash__(self) -> int:
+ """Return ``hash(self)``."""
+ # Attempt to use the cached hash
+ try:
+ return super().__getattribute__("_hash")
+ except AttributeError:
+ self._hash: int = hash(self.__origin__) ^ hash(self.__args__)
+ return super().__getattribute__("_hash")
+
+ def __instancecheck__(self, obj: object) -> NoReturn:
+ """Check if an `obj` is an instance."""
+ raise TypeError("isinstance() argument 2 cannot be a "
+ "parameterized generic")
+
+ def __subclasscheck__(self, cls: type) -> NoReturn:
+ """Check if a `cls` is a subclass."""
+ raise TypeError("issubclass() argument 2 cannot be a "
+ "parameterized generic")
+
+ def __repr__(self) -> str:
+ """Return ``repr(self)``."""
+ args = ", ".join(_to_str(i) for i in self.__args__)
+ origin = _to_str(self.__origin__)
+ return f"{origin}[{args}]"
+
+ def __getitem__(self: _T, key: object | Tuple[object, ...]) -> _T:
+ """Return ``self[key]``."""
+ key_tup = key if isinstance(key, tuple) else (key,)
+
+ if len(self.__parameters__) == 0:
+ raise TypeError(f"There are no type variables left in {self}")
+ elif len(key_tup) > len(self.__parameters__):
+ raise TypeError(f"Too many arguments for {self}")
+ elif len(key_tup) < len(self.__parameters__):
+ raise TypeError(f"Too few arguments for {self}")
+
+ key_iter = iter(key_tup)
+ return _reconstruct_alias(self, key_iter)
+
+ def __eq__(self, value: object) -> bool:
+ """Return ``self == value``."""
+ if not isinstance(value, _GENERIC_ALIAS_TYPE):
+ return NotImplemented
+ return (
+ self.__origin__ == value.__origin__ and
+ self.__args__ == value.__args__
+ )
+
+ _ATTR_EXCEPTIONS: ClassVar[FrozenSet[str]] = frozenset({
+ "__origin__",
+ "__args__",
+ "__parameters__",
+ "__mro_entries__",
+ "__reduce__",
+ "__reduce_ex__",
+ })
+
+ def __getattribute__(self, name: str) -> Any:
+ """Return ``getattr(self, name)``."""
+ # Pull the attribute from `__origin__` unless its
+ # name is in `_ATTR_EXCEPTIONS`
+ cls = type(self)
+ if name in cls._ATTR_EXCEPTIONS:
+ return super().__getattribute__(name)
+ return getattr(self.__origin__, name)
+
+
+# See `_GenericAlias.__eq__`
+if sys.version_info >= (3, 9):
+ _GENERIC_ALIAS_TYPE = (_GenericAlias, types.GenericAlias)
+else:
+ _GENERIC_ALIAS_TYPE = (_GenericAlias,)
+
+ScalarType = TypeVar("ScalarType", bound=np.generic, covariant=True)
+
+if TYPE_CHECKING:
+ _DType = np.dtype[ScalarType]
+ NDArray = np.ndarray[Any, np.dtype[ScalarType]]
+elif sys.version_info >= (3, 9):
+ _DType = types.GenericAlias(np.dtype, (ScalarType,))
+ NDArray = types.GenericAlias(np.ndarray, (Any, _DType))
+else:
+ _DType = _GenericAlias(np.dtype, (ScalarType,))
+ NDArray = _GenericAlias(np.ndarray, (Any, _DType))
diff --git a/numpy/typing/_nbit.py b/numpy/typing/_nbit.py
new file mode 100644
index 000000000..b8d35db4f
--- /dev/null
+++ b/numpy/typing/_nbit.py
@@ -0,0 +1,16 @@
+"""A module with the precisions of platform-specific `~numpy.number`s."""
+
+from typing import Any
+
+# To-be replaced with a `npt.NBitBase` subclass by numpy's mypy plugin
+_NBitByte = Any
+_NBitShort = Any
+_NBitIntC = Any
+_NBitIntP = Any
+_NBitInt = Any
+_NBitLongLong = Any
+
+_NBitHalf = Any
+_NBitSingle = Any
+_NBitDouble = Any
+_NBitLongDouble = Any
diff --git a/numpy/typing/_scalars.py b/numpy/typing/_scalars.py
index e4fc28b07..516b996dc 100644
--- a/numpy/typing/_scalars.py
+++ b/numpy/typing/_scalars.py
@@ -2,18 +2,22 @@ from typing import Union, Tuple, Any
import numpy as np
-# NOTE: `_StrLike` and `_BytesLike` are pointless, as `np.str_` and `np.bytes_`
-# are already subclasses of their builtin counterpart
+# NOTE: `_StrLike_co` and `_BytesLike_co` are pointless, as `np.str_` and
+# `np.bytes_` are already subclasses of their builtin counterpart
-_CharLike = Union[str, bytes]
+_CharLike_co = Union[str, bytes]
-_BoolLike = Union[bool, np.bool_]
-_IntLike = Union[int, np.integer]
-_FloatLike = Union[_IntLike, float, np.floating]
-_ComplexLike = Union[_FloatLike, complex, np.complexfloating]
-_NumberLike = Union[int, float, complex, np.number, np.bool_]
+# The 6 `<X>Like_co` type-aliases below represent all scalars that can be
+# coerced into `<X>` (with the casting rule `same_kind`)
+_BoolLike_co = Union[bool, np.bool_]
+_UIntLike_co = Union[_BoolLike_co, np.unsignedinteger]
+_IntLike_co = Union[_BoolLike_co, int, np.integer]
+_FloatLike_co = Union[_IntLike_co, float, np.floating]
+_ComplexLike_co = Union[_FloatLike_co, complex, np.complexfloating]
+_TD64Like_co = Union[_IntLike_co, np.timedelta64]
-_ScalarLike = Union[
+_NumberLike_co = Union[int, float, complex, np.number, np.bool_]
+_ScalarLike_co = Union[
int,
float,
complex,
@@ -22,5 +26,5 @@ _ScalarLike = Union[
np.generic,
]
-# `_VoidLike` is technically not a scalar, but it's close enough
-_VoidLike = Union[Tuple[Any, ...], np.void]
+# `_VoidLike_co` is technically not a scalar, but it's close enough
+_VoidLike_co = Union[Tuple[Any, ...], np.void]
diff --git a/numpy/typing/_shape.py b/numpy/typing/_shape.py
index 4629046ea..75698f3d3 100644
--- a/numpy/typing/_shape.py
+++ b/numpy/typing/_shape.py
@@ -1,6 +1,16 @@
-from typing import Sequence, Tuple, Union
+import sys
+from typing import Sequence, Tuple, Union, Any
+
+from . import _HAS_TYPING_EXTENSIONS
+
+if sys.version_info >= (3, 8):
+ from typing import SupportsIndex
+elif _HAS_TYPING_EXTENSIONS:
+ from typing_extensions import SupportsIndex
+else:
+ SupportsIndex = Any
_Shape = Tuple[int, ...]
# Anything that can be coerced to a shape tuple
-_ShapeLike = Union[int, Sequence[int]]
+_ShapeLike = Union[SupportsIndex, Sequence[SupportsIndex]]
diff --git a/numpy/typing/_ufunc.pyi b/numpy/typing/_ufunc.pyi
new file mode 100644
index 000000000..be1e654c2
--- /dev/null
+++ b/numpy/typing/_ufunc.pyi
@@ -0,0 +1,403 @@
+"""A module with private type-check-only `numpy.ufunc` subclasses.
+
+The signatures of the ufuncs are too varied to reasonably type
+with a single class. So instead, `ufunc` has been expanded into
+four private subclasses, one for each combination of
+`~ufunc.nin` and `~ufunc.nout`.
+
+"""
+
+from typing import (
+ Any,
+ Generic,
+ List,
+ overload,
+ Tuple,
+ TypeVar,
+)
+
+from numpy import ufunc, _CastingKind, _OrderKACF
+from numpy.typing import NDArray
+
+from ._shape import _ShapeLike
+from ._scalars import _ScalarLike_co
+from ._array_like import ArrayLike, _ArrayLikeBool_co, _ArrayLikeInt_co
+from ._dtype_like import DTypeLike
+
+from typing_extensions import Literal, SupportsIndex
+
+_T = TypeVar("_T")
+_2Tuple = Tuple[_T, _T]
+_3Tuple = Tuple[_T, _T, _T]
+_4Tuple = Tuple[_T, _T, _T, _T]
+
+_NTypes = TypeVar("_NTypes", bound=int)
+_IDType = TypeVar("_IDType", bound=Any)
+_NameType = TypeVar("_NameType", bound=str)
+
+# NOTE: In reality `extobj` should be a length of list 3 containing an
+# int, an int, and a callable, but there's no way to properly express
+# non-homogenous lists.
+# Use `Any` over `Union` to avoid issues related to lists invariance.
+
+# NOTE: `reduce`, `accumulate`, `reduceat` and `outer` raise a ValueError for
+# ufuncs that don't accept two input arguments and return one output argument.
+# In such cases the respective methods are simply typed as `None`.
+
+# NOTE: Similarly, `at` won't be defined for ufuncs that return
+# multiple outputs; in such cases `at` is typed as `None`
+
+# NOTE: If 2 output types are returned then `out` must be a
+# 2-tuple of arrays. Otherwise `None` or a plain array are also acceptable
+
+class _UFunc_Nin1_Nout1(ufunc, Generic[_NameType, _NTypes, _IDType]):
+ @property
+ def __name__(self) -> _NameType: ...
+ @property
+ def ntypes(self) -> _NTypes: ...
+ @property
+ def identity(self) -> _IDType: ...
+ @property
+ def nin(self) -> Literal[1]: ...
+ @property
+ def nout(self) -> Literal[1]: ...
+ @property
+ def nargs(self) -> Literal[2]: ...
+ @property
+ def signature(self) -> None: ...
+ @property
+ def reduce(self) -> None: ...
+ @property
+ def accumulate(self) -> None: ...
+ @property
+ def reduceat(self) -> None: ...
+ @property
+ def outer(self) -> None: ...
+
+ @overload
+ def __call__(
+ self,
+ __x1: _ScalarLike_co,
+ out: None = ...,
+ *,
+ where: None | _ArrayLikeBool_co = ...,
+ casting: _CastingKind = ...,
+ order: _OrderKACF = ...,
+ dtype: DTypeLike = ...,
+ subok: bool = ...,
+ signature: str | _2Tuple[None | str] = ...,
+ extobj: List[Any] = ...,
+ ) -> Any: ...
+ @overload
+ def __call__(
+ self,
+ __x1: ArrayLike,
+ out: None | NDArray[Any] | Tuple[NDArray[Any]] = ...,
+ *,
+ where: None | _ArrayLikeBool_co = ...,
+ casting: _CastingKind = ...,
+ order: _OrderKACF = ...,
+ dtype: DTypeLike = ...,
+ subok: bool = ...,
+ signature: str | _2Tuple[None | str] = ...,
+ extobj: List[Any] = ...,
+ ) -> NDArray[Any]: ...
+
+ def at(
+ self,
+ __a: NDArray[Any],
+ __indices: _ArrayLikeInt_co,
+ ) -> None: ...
+
+class _UFunc_Nin2_Nout1(ufunc, Generic[_NameType, _NTypes, _IDType]):
+ @property
+ def __name__(self) -> _NameType: ...
+ @property
+ def ntypes(self) -> _NTypes: ...
+ @property
+ def identity(self) -> _IDType: ...
+ @property
+ def nin(self) -> Literal[2]: ...
+ @property
+ def nout(self) -> Literal[1]: ...
+ @property
+ def nargs(self) -> Literal[3]: ...
+ @property
+ def signature(self) -> None: ...
+
+ @overload
+ def __call__(
+ self,
+ __x1: _ScalarLike_co,
+ __x2: _ScalarLike_co,
+ out: None = ...,
+ *,
+ where: None | _ArrayLikeBool_co = ...,
+ casting: _CastingKind = ...,
+ order: _OrderKACF = ...,
+ dtype: DTypeLike = ...,
+ subok: bool = ...,
+ signature: str | _3Tuple[None | str] = ...,
+ extobj: List[Any] = ...,
+ ) -> Any: ...
+ @overload
+ def __call__(
+ self,
+ __x1: ArrayLike,
+ __x2: ArrayLike,
+ out: None | NDArray[Any] | Tuple[NDArray[Any]] = ...,
+ *,
+ where: None | _ArrayLikeBool_co = ...,
+ casting: _CastingKind = ...,
+ order: _OrderKACF = ...,
+ dtype: DTypeLike = ...,
+ subok: bool = ...,
+ signature: str | _3Tuple[None | str] = ...,
+ extobj: List[Any] = ...,
+ ) -> NDArray[Any]: ...
+
+ def at(
+ self,
+ __a: NDArray[Any],
+ __indices: _ArrayLikeInt_co,
+ __b: ArrayLike,
+ ) -> None: ...
+
+ def reduce(
+ self,
+ array: ArrayLike,
+ axis: None | _ShapeLike = ...,
+ dtype: DTypeLike = ...,
+ out: None | NDArray[Any] = ...,
+ keepdims: bool = ...,
+ initial: Any = ...,
+ where: _ArrayLikeBool_co = ...,
+ ) -> Any: ...
+
+ def accumulate(
+ self,
+ array: ArrayLike,
+ axis: SupportsIndex = ...,
+ dtype: DTypeLike = ...,
+ out: None | NDArray[Any] = ...,
+ ) -> NDArray[Any]: ...
+
+ def reduceat(
+ self,
+ array: ArrayLike,
+ indices: _ArrayLikeInt_co,
+ axis: SupportsIndex = ...,
+ dtype: DTypeLike = ...,
+ out: None | NDArray[Any] = ...,
+ ) -> NDArray[Any]: ...
+
+ # Expand `**kwargs` into explicit keyword-only arguments
+ @overload
+ def outer(
+ self,
+ __A: _ScalarLike_co,
+ __B: _ScalarLike_co,
+ *,
+ out: None = ...,
+ where: None | _ArrayLikeBool_co = ...,
+ casting: _CastingKind = ...,
+ order: _OrderKACF = ...,
+ dtype: DTypeLike = ...,
+ subok: bool = ...,
+ signature: str | _3Tuple[None | str] = ...,
+ extobj: List[Any] = ...,
+ ) -> Any: ...
+ @overload
+ def outer( # type: ignore[misc]
+ self,
+ __A: ArrayLike,
+ __B: ArrayLike,
+ *,
+ out: None | NDArray[Any] | Tuple[NDArray[Any]] = ...,
+ where: None | _ArrayLikeBool_co = ...,
+ casting: _CastingKind = ...,
+ order: _OrderKACF = ...,
+ dtype: DTypeLike = ...,
+ subok: bool = ...,
+ signature: str | _3Tuple[None | str] = ...,
+ extobj: List[Any] = ...,
+ ) -> NDArray[Any]: ...
+
+class _UFunc_Nin1_Nout2(ufunc, Generic[_NameType, _NTypes, _IDType]):
+ @property
+ def __name__(self) -> _NameType: ...
+ @property
+ def ntypes(self) -> _NTypes: ...
+ @property
+ def identity(self) -> _IDType: ...
+ @property
+ def nin(self) -> Literal[1]: ...
+ @property
+ def nout(self) -> Literal[2]: ...
+ @property
+ def nargs(self) -> Literal[3]: ...
+ @property
+ def signature(self) -> None: ...
+ @property
+ def at(self) -> None: ...
+ @property
+ def reduce(self) -> None: ...
+ @property
+ def accumulate(self) -> None: ...
+ @property
+ def reduceat(self) -> None: ...
+ @property
+ def outer(self) -> None: ...
+
+ @overload
+ def __call__(
+ self,
+ __x1: _ScalarLike_co,
+ __out1: None = ...,
+ __out2: None = ...,
+ *,
+ where: None | _ArrayLikeBool_co = ...,
+ casting: _CastingKind = ...,
+ order: _OrderKACF = ...,
+ dtype: DTypeLike = ...,
+ subok: bool = ...,
+ signature: str | _3Tuple[None | str] = ...,
+ extobj: List[Any] = ...,
+ ) -> _2Tuple[Any]: ...
+ @overload
+ def __call__(
+ self,
+ __x1: ArrayLike,
+ __out1: None | NDArray[Any] = ...,
+ __out2: None | NDArray[Any] = ...,
+ *,
+ out: _2Tuple[NDArray[Any]] = ...,
+ where: None | _ArrayLikeBool_co = ...,
+ casting: _CastingKind = ...,
+ order: _OrderKACF = ...,
+ dtype: DTypeLike = ...,
+ subok: bool = ...,
+ signature: str | _3Tuple[None | str] = ...,
+ extobj: List[Any] = ...,
+ ) -> _2Tuple[NDArray[Any]]: ...
+
+class _UFunc_Nin2_Nout2(ufunc, Generic[_NameType, _NTypes, _IDType]):
+ @property
+ def __name__(self) -> _NameType: ...
+ @property
+ def ntypes(self) -> _NTypes: ...
+ @property
+ def identity(self) -> _IDType: ...
+ @property
+ def nin(self) -> Literal[2]: ...
+ @property
+ def nout(self) -> Literal[2]: ...
+ @property
+ def nargs(self) -> Literal[4]: ...
+ @property
+ def signature(self) -> None: ...
+ @property
+ def at(self) -> None: ...
+ @property
+ def reduce(self) -> None: ...
+ @property
+ def accumulate(self) -> None: ...
+ @property
+ def reduceat(self) -> None: ...
+ @property
+ def outer(self) -> None: ...
+
+ @overload
+ def __call__(
+ self,
+ __x1: _ScalarLike_co,
+ __x2: _ScalarLike_co,
+ __out1: None = ...,
+ __out2: None = ...,
+ *,
+ where: None | _ArrayLikeBool_co = ...,
+ casting: _CastingKind = ...,
+ order: _OrderKACF = ...,
+ dtype: DTypeLike = ...,
+ subok: bool = ...,
+ signature: str | _4Tuple[None | str] = ...,
+ extobj: List[Any] = ...,
+ ) -> _2Tuple[Any]: ...
+ @overload
+ def __call__(
+ self,
+ __x1: ArrayLike,
+ __x2: ArrayLike,
+ __out1: None | NDArray[Any] = ...,
+ __out2: None | NDArray[Any] = ...,
+ *,
+ out: _2Tuple[NDArray[Any]] = ...,
+ where: None | _ArrayLikeBool_co = ...,
+ casting: _CastingKind = ...,
+ order: _OrderKACF = ...,
+ dtype: DTypeLike = ...,
+ subok: bool = ...,
+ signature: str | _4Tuple[None | str] = ...,
+ extobj: List[Any] = ...,
+ ) -> _2Tuple[NDArray[Any]]: ...
+
+class _GUFunc_Nin2_Nout1(ufunc, Generic[_NameType, _NTypes, _IDType]):
+ @property
+ def __name__(self) -> _NameType: ...
+ @property
+ def ntypes(self) -> _NTypes: ...
+ @property
+ def identity(self) -> _IDType: ...
+ @property
+ def nin(self) -> Literal[2]: ...
+ @property
+ def nout(self) -> Literal[1]: ...
+ @property
+ def nargs(self) -> Literal[3]: ...
+
+ # NOTE: In practice the only gufunc in the main name is `matmul`,
+ # so we can use its signature here
+ @property
+ def signature(self) -> Literal["(n?,k),(k,m?)->(n?,m?)"]: ...
+ @property
+ def reduce(self) -> None: ...
+ @property
+ def accumulate(self) -> None: ...
+ @property
+ def reduceat(self) -> None: ...
+ @property
+ def outer(self) -> None: ...
+ @property
+ def at(self) -> None: ...
+
+ # Scalar for 1D array-likes; ndarray otherwise
+ @overload
+ def __call__(
+ self,
+ __x1: ArrayLike,
+ __x2: ArrayLike,
+ out: None = ...,
+ *,
+ casting: _CastingKind = ...,
+ order: _OrderKACF = ...,
+ dtype: DTypeLike = ...,
+ subok: bool = ...,
+ signature: str | _3Tuple[None | str] = ...,
+ extobj: List[Any] = ...,
+ axes: List[_2Tuple[SupportsIndex]] = ...,
+ ) -> Any: ...
+ @overload
+ def __call__(
+ self,
+ __x1: ArrayLike,
+ __x2: ArrayLike,
+ out: NDArray[Any] | Tuple[NDArray[Any]],
+ *,
+ casting: _CastingKind = ...,
+ order: _OrderKACF = ...,
+ dtype: DTypeLike = ...,
+ subok: bool = ...,
+ signature: str | _3Tuple[None | str] = ...,
+ extobj: List[Any] = ...,
+ axes: List[_2Tuple[SupportsIndex]] = ...,
+ ) -> NDArray[Any]: ...
diff --git a/numpy/typing/mypy_plugin.py b/numpy/typing/mypy_plugin.py
new file mode 100644
index 000000000..091980d65
--- /dev/null
+++ b/numpy/typing/mypy_plugin.py
@@ -0,0 +1,194 @@
+"""A mypy_ plugin for managing a number of platform-specific annotations.
+Its functionality can be split into three distinct parts:
+
+* Assigning the (platform-dependent) precisions of certain `~numpy.number`
+ subclasses, including the likes of `~numpy.int_`, `~numpy.intp` and
+ `~numpy.longlong`. See the documentation on
+ :ref:`scalar types <arrays.scalars.built-in>` for a comprehensive overview
+ of the affected classes. Without the plugin the precision of all relevant
+ classes will be inferred as `~typing.Any`.
+* Removing all extended-precision `~numpy.number` subclasses that are
+ unavailable for the platform in question. Most notably this includes the
+ likes of `~numpy.float128` and `~numpy.complex256`. Without the plugin *all*
+ extended-precision types will, as far as mypy is concerned, be available
+ to all platforms.
+* Assigning the (platform-dependent) precision of `~numpy.ctypeslib.c_intp`.
+ Without the plugin the type will default to `ctypes.c_int64`.
+
+ .. versionadded:: 1.22
+
+Examples
+--------
+To enable the plugin, one must add it to their mypy `configuration file`_:
+
+.. code-block:: ini
+
+ [mypy]
+ plugins = numpy.typing.mypy_plugin
+
+.. _mypy: http://mypy-lang.org/
+.. _configuration file: https://mypy.readthedocs.io/en/stable/config_file.html
+
+"""
+
+from __future__ import annotations
+
+import typing as t
+
+import numpy as np
+
+try:
+ import mypy.types
+ from mypy.types import Type
+ from mypy.plugin import Plugin, AnalyzeTypeContext
+ from mypy.nodes import MypyFile, ImportFrom, Statement
+ from mypy.build import PRI_MED
+
+ _HookFunc = t.Callable[[AnalyzeTypeContext], Type]
+ MYPY_EX: None | ModuleNotFoundError = None
+except ModuleNotFoundError as ex:
+ MYPY_EX = ex
+
+__all__: t.List[str] = []
+
+
+def _get_precision_dict() -> t.Dict[str, str]:
+ names = [
+ ("_NBitByte", np.byte),
+ ("_NBitShort", np.short),
+ ("_NBitIntC", np.intc),
+ ("_NBitIntP", np.intp),
+ ("_NBitInt", np.int_),
+ ("_NBitLongLong", np.longlong),
+
+ ("_NBitHalf", np.half),
+ ("_NBitSingle", np.single),
+ ("_NBitDouble", np.double),
+ ("_NBitLongDouble", np.longdouble),
+ ]
+ ret = {}
+ for name, typ in names:
+ n: int = 8 * typ().dtype.itemsize
+ ret[f'numpy.typing._nbit.{name}'] = f"numpy._{n}Bit"
+ return ret
+
+
+def _get_extended_precision_list() -> t.List[str]:
+ extended_types = [np.ulonglong, np.longlong, np.longdouble, np.clongdouble]
+ extended_names = {
+ "uint128",
+ "uint256",
+ "int128",
+ "int256",
+ "float80",
+ "float96",
+ "float128",
+ "float256",
+ "complex160",
+ "complex192",
+ "complex256",
+ "complex512",
+ }
+ return [i.__name__ for i in extended_types if i.__name__ in extended_names]
+
+
+def _get_c_intp_name() -> str:
+ # Adapted from `np.core._internal._getintp_ctype`
+ char = np.dtype('p').char
+ if char == 'i':
+ return "c_int"
+ elif char == 'l':
+ return "c_long"
+ elif char == 'q':
+ return "c_longlong"
+ else:
+ return "c_long"
+
+
+#: A dictionary mapping type-aliases in `numpy.typing._nbit` to
+#: concrete `numpy.typing.NBitBase` subclasses.
+_PRECISION_DICT: t.Final = _get_precision_dict()
+
+#: A list with the names of all extended precision `np.number` subclasses.
+_EXTENDED_PRECISION_LIST: t.Final = _get_extended_precision_list()
+
+#: The name of the ctypes quivalent of `np.intp`
+_C_INTP: t.Final = _get_c_intp_name()
+
+
+def _hook(ctx: AnalyzeTypeContext) -> Type:
+ """Replace a type-alias with a concrete ``NBitBase`` subclass."""
+ typ, _, api = ctx
+ name = typ.name.split(".")[-1]
+ name_new = _PRECISION_DICT[f"numpy.typing._nbit.{name}"]
+ return api.named_type(name_new)
+
+
+if t.TYPE_CHECKING or MYPY_EX is None:
+ def _index(iterable: t.Iterable[Statement], id: str) -> int:
+ """Identify the first ``ImportFrom`` instance the specified `id`."""
+ for i, value in enumerate(iterable):
+ if getattr(value, "id", None) == id:
+ return i
+ else:
+ raise ValueError("Failed to identify a `ImportFrom` instance "
+ f"with the following id: {id!r}")
+
+ def _override_imports(
+ file: MypyFile,
+ module: str,
+ imports: t.List[t.Tuple[str, t.Optional[str]]],
+ ) -> None:
+ """Override the first `module`-based import with new `imports`."""
+ # Construct a new `from module import y` statement
+ import_obj = ImportFrom(module, 0, names=imports)
+ import_obj.is_top_level = True
+
+ # Replace the first `module`-based import statement with `import_obj`
+ for lst in [file.defs, file.imports]: # type: t.List[Statement]
+ i = _index(lst, module)
+ lst[i] = import_obj
+
+ class _NumpyPlugin(Plugin):
+ """A mypy plugin for handling versus numpy-specific typing tasks."""
+
+ def get_type_analyze_hook(self, fullname: str) -> None | _HookFunc:
+ """Set the precision of platform-specific `numpy.number` subclasses.
+
+ For example: `numpy.int_`, `numpy.longlong` and `numpy.longdouble`.
+ """
+ if fullname in _PRECISION_DICT:
+ return _hook
+ return None
+
+ def get_additional_deps(self, file: MypyFile) -> t.List[t.Tuple[int, str, int]]:
+ """Handle all import-based overrides.
+
+ * Import platform-specific extended-precision `numpy.number`
+ subclasses (*e.g.* `numpy.float96`, `numpy.float128` and
+ `numpy.complex256`).
+ * Import the appropriate `ctypes` equivalent to `numpy.intp`.
+
+ """
+ ret = [(PRI_MED, file.fullname, -1)]
+
+ if file.fullname == "numpy":
+ _override_imports(
+ file, "numpy.typing._extended_precision",
+ imports=[(v, v) for v in _EXTENDED_PRECISION_LIST],
+ )
+ elif file.fullname == "numpy.ctypeslib":
+ _override_imports(
+ file, "ctypes",
+ imports=[(_C_INTP, "_c_intp")],
+ )
+ return ret
+
+ def plugin(version: str) -> t.Type[_NumpyPlugin]:
+ """An entry-point for mypy."""
+ return _NumpyPlugin
+
+else:
+ def plugin(version: str) -> t.Type[_NumpyPlugin]:
+ """An entry-point for mypy."""
+ raise MYPY_EX
diff --git a/numpy/typing/tests/data/fail/arithmetic.py b/numpy/typing/tests/data/fail/arithmetic.py
index f32eddc4b..02bbffa53 100644
--- a/numpy/typing/tests/data/fail/arithmetic.py
+++ b/numpy/typing/tests/data/fail/arithmetic.py
@@ -1,9 +1,113 @@
+from typing import List, Any
import numpy as np
b_ = np.bool_()
dt = np.datetime64(0, "D")
td = np.timedelta64(0, "D")
+AR_b: np.ndarray[Any, np.dtype[np.bool_]]
+AR_u: np.ndarray[Any, np.dtype[np.uint32]]
+AR_i: np.ndarray[Any, np.dtype[np.int64]]
+AR_f: np.ndarray[Any, np.dtype[np.float64]]
+AR_c: np.ndarray[Any, np.dtype[np.complex128]]
+AR_m: np.ndarray[Any, np.dtype[np.timedelta64]]
+AR_M: np.ndarray[Any, np.dtype[np.datetime64]]
+
+ANY: Any
+
+AR_LIKE_b: List[bool]
+AR_LIKE_u: List[np.uint32]
+AR_LIKE_i: List[int]
+AR_LIKE_f: List[float]
+AR_LIKE_c: List[complex]
+AR_LIKE_m: List[np.timedelta64]
+AR_LIKE_M: List[np.datetime64]
+
+# Array subtraction
+
+# NOTE: mypys `NoReturn` errors are, unfortunately, not that great
+_1 = AR_b - AR_LIKE_b # E: Need type annotation
+_2 = AR_LIKE_b - AR_b # E: Need type annotation
+
+AR_f - AR_LIKE_m # E: Unsupported operand types
+AR_f - AR_LIKE_M # E: Unsupported operand types
+AR_c - AR_LIKE_m # E: Unsupported operand types
+AR_c - AR_LIKE_M # E: Unsupported operand types
+
+AR_m - AR_LIKE_f # E: Unsupported operand types
+AR_M - AR_LIKE_f # E: Unsupported operand types
+AR_m - AR_LIKE_c # E: Unsupported operand types
+AR_M - AR_LIKE_c # E: Unsupported operand types
+
+AR_m - AR_LIKE_M # E: Unsupported operand types
+AR_LIKE_m - AR_M # E: Unsupported operand types
+
+# array floor division
+
+AR_M // AR_LIKE_b # E: Unsupported operand types
+AR_M // AR_LIKE_u # E: Unsupported operand types
+AR_M // AR_LIKE_i # E: Unsupported operand types
+AR_M // AR_LIKE_f # E: Unsupported operand types
+AR_M // AR_LIKE_c # E: Unsupported operand types
+AR_M // AR_LIKE_m # E: Unsupported operand types
+AR_M // AR_LIKE_M # E: Unsupported operand types
+
+AR_b // AR_LIKE_M # E: Unsupported operand types
+AR_u // AR_LIKE_M # E: Unsupported operand types
+AR_i // AR_LIKE_M # E: Unsupported operand types
+AR_f // AR_LIKE_M # E: Unsupported operand types
+AR_c // AR_LIKE_M # E: Unsupported operand types
+AR_m // AR_LIKE_M # E: Unsupported operand types
+AR_M // AR_LIKE_M # E: Unsupported operand types
+
+_3 = AR_m // AR_LIKE_b # E: Need type annotation
+AR_m // AR_LIKE_c # E: Unsupported operand types
+
+AR_b // AR_LIKE_m # E: Unsupported operand types
+AR_u // AR_LIKE_m # E: Unsupported operand types
+AR_i // AR_LIKE_m # E: Unsupported operand types
+AR_f // AR_LIKE_m # E: Unsupported operand types
+AR_c // AR_LIKE_m # E: Unsupported operand types
+
+# Array multiplication
+
+AR_b *= AR_LIKE_u # E: incompatible type
+AR_b *= AR_LIKE_i # E: incompatible type
+AR_b *= AR_LIKE_f # E: incompatible type
+AR_b *= AR_LIKE_c # E: incompatible type
+AR_b *= AR_LIKE_m # E: incompatible type
+
+AR_u *= AR_LIKE_i # E: incompatible type
+AR_u *= AR_LIKE_f # E: incompatible type
+AR_u *= AR_LIKE_c # E: incompatible type
+AR_u *= AR_LIKE_m # E: incompatible type
+
+AR_i *= AR_LIKE_f # E: incompatible type
+AR_i *= AR_LIKE_c # E: incompatible type
+AR_i *= AR_LIKE_m # E: incompatible type
+
+AR_f *= AR_LIKE_c # E: incompatible type
+AR_f *= AR_LIKE_m # E: incompatible type
+
+# Array power
+
+AR_b **= AR_LIKE_b # E: incompatible type
+AR_b **= AR_LIKE_u # E: incompatible type
+AR_b **= AR_LIKE_i # E: incompatible type
+AR_b **= AR_LIKE_f # E: incompatible type
+AR_b **= AR_LIKE_c # E: incompatible type
+
+AR_u **= AR_LIKE_i # E: incompatible type
+AR_u **= AR_LIKE_f # E: incompatible type
+AR_u **= AR_LIKE_c # E: incompatible type
+
+AR_i **= AR_LIKE_f # E: incompatible type
+AR_i **= AR_LIKE_c # E: incompatible type
+
+AR_f **= AR_LIKE_c # E: incompatible type
+
+# Scalars
+
b_ - b_ # E: No overload variant
dt + dt # E: Unsupported operand types
diff --git a/numpy/typing/tests/data/fail/array_constructors.py b/numpy/typing/tests/data/fail/array_constructors.py
index 9cb59fe5f..0e2250513 100644
--- a/numpy/typing/tests/data/fail/array_constructors.py
+++ b/numpy/typing/tests/data/fail/array_constructors.py
@@ -7,12 +7,12 @@ np.require(a, requirements=1) # E: No overload variant
np.require(a, requirements="TEST") # E: incompatible type
np.zeros("test") # E: incompatible type
-np.zeros() # E: Too few arguments
+np.zeros() # E: require at least one argument
np.ones("test") # E: incompatible type
-np.ones() # E: Too few arguments
+np.ones() # E: Missing positional argument
-np.array(0, float, True) # E: Too many positional
+np.array(0, float, True) # E: No overload variant
np.linspace(None, 'bob') # E: No overload variant
np.linspace(0, 2, num=10.0) # E: No overload variant
@@ -27,5 +27,5 @@ np.logspace(0, 2, base=None) # E: Argument "base"
np.geomspace(None, 'bob') # E: Argument 1
np.stack(generator) # E: No overload variant
-np.hstack({1, 2}) # E: incompatible type
-np.vstack(1) # E: incompatible type
+np.hstack({1, 2}) # E: No overload variant
+np.vstack(1) # E: No overload variant
diff --git a/numpy/typing/tests/data/fail/array_like.py b/numpy/typing/tests/data/fail/array_like.py
index a97e72dc7..3bbd29061 100644
--- a/numpy/typing/tests/data/fail/array_like.py
+++ b/numpy/typing/tests/data/fail/array_like.py
@@ -11,6 +11,6 @@ x2: ArrayLike = A() # E: Incompatible types in assignment
x3: ArrayLike = {1: "foo", 2: "bar"} # E: Incompatible types in assignment
scalar = np.int64(1)
-scalar.__array__(dtype=np.float64) # E: Unexpected keyword argument
+scalar.__array__(dtype=np.float64) # E: No overload variant
array = np.array([1])
-array.__array__(dtype=np.float64) # E: Unexpected keyword argument
+array.__array__(dtype=np.float64) # E: No overload variant
diff --git a/numpy/typing/tests/data/fail/array_pad.py b/numpy/typing/tests/data/fail/array_pad.py
new file mode 100644
index 000000000..2be51a871
--- /dev/null
+++ b/numpy/typing/tests/data/fail/array_pad.py
@@ -0,0 +1,6 @@
+import numpy as np
+import numpy.typing as npt
+
+AR_i8: npt.NDArray[np.int64]
+
+np.pad(AR_i8, 2, mode="bob") # E: No overload variant
diff --git a/numpy/typing/tests/data/fail/arrayprint.py b/numpy/typing/tests/data/fail/arrayprint.py
new file mode 100644
index 000000000..86297a0b2
--- /dev/null
+++ b/numpy/typing/tests/data/fail/arrayprint.py
@@ -0,0 +1,13 @@
+from typing import Callable, Any
+import numpy as np
+
+AR: np.ndarray
+func1: Callable[[Any], str]
+func2: Callable[[np.integer[Any]], str]
+
+np.array2string(AR, style=None) # E: Unexpected keyword argument
+np.array2string(AR, legacy="1.14") # E: incompatible type
+np.array2string(AR, sign="*") # E: incompatible type
+np.array2string(AR, floatmode="default") # E: incompatible type
+np.array2string(AR, formatter={"A": func1}) # E: incompatible type
+np.array2string(AR, formatter={"float": func2}) # E: Incompatible types
diff --git a/numpy/typing/tests/data/fail/arrayterator.py b/numpy/typing/tests/data/fail/arrayterator.py
new file mode 100644
index 000000000..c50fb2ec4
--- /dev/null
+++ b/numpy/typing/tests/data/fail/arrayterator.py
@@ -0,0 +1,14 @@
+from typing import Any
+import numpy as np
+
+AR_i8: np.ndarray[Any, np.dtype[np.int64]]
+ar_iter = np.lib.Arrayterator(AR_i8)
+
+np.lib.Arrayterator(np.int64()) # E: incompatible type
+ar_iter.shape = (10, 5) # E: is read-only
+ar_iter[None] # E: Invalid index type
+ar_iter[None, 1] # E: Invalid index type
+ar_iter[np.intp()] # E: Invalid index type
+ar_iter[np.intp(), ...] # E: Invalid index type
+ar_iter[AR_i8] # E: Invalid index type
+ar_iter[AR_i8, :] # E: Invalid index type
diff --git a/numpy/typing/tests/data/fail/comparisons.py b/numpy/typing/tests/data/fail/comparisons.py
new file mode 100644
index 000000000..cad1c6555
--- /dev/null
+++ b/numpy/typing/tests/data/fail/comparisons.py
@@ -0,0 +1,28 @@
+from typing import Any
+import numpy as np
+
+AR_i: np.ndarray[Any, np.dtype[np.int64]]
+AR_f: np.ndarray[Any, np.dtype[np.float64]]
+AR_c: np.ndarray[Any, np.dtype[np.complex128]]
+AR_m: np.ndarray[Any, np.dtype[np.timedelta64]]
+AR_M: np.ndarray[Any, np.dtype[np.datetime64]]
+
+AR_f > AR_m # E: Unsupported operand types
+AR_c > AR_m # E: Unsupported operand types
+
+AR_m > AR_f # E: Unsupported operand types
+AR_m > AR_c # E: Unsupported operand types
+
+AR_i > AR_M # E: Unsupported operand types
+AR_f > AR_M # E: Unsupported operand types
+AR_m > AR_M # E: Unsupported operand types
+
+AR_M > AR_i # E: Unsupported operand types
+AR_M > AR_f # E: Unsupported operand types
+AR_M > AR_m # E: Unsupported operand types
+
+# Unfortunately `NoReturn` errors are not the most descriptive
+_1 = AR_i > str() # E: Need type annotation
+_2 = AR_i > bytes() # E: Need type annotation
+_3 = str() > AR_M # E: Need type annotation
+_4 = bytes() > AR_M # E: Need type annotation
diff --git a/numpy/typing/tests/data/fail/constants.py b/numpy/typing/tests/data/fail/constants.py
index 67ee0e0bc..324cbe9fa 100644
--- a/numpy/typing/tests/data/fail/constants.py
+++ b/numpy/typing/tests/data/fail/constants.py
@@ -3,4 +3,5 @@ import numpy as np
np.Inf = np.Inf # E: Cannot assign to final
np.ALLOW_THREADS = np.ALLOW_THREADS # E: Cannot assign to final
np.little_endian = np.little_endian # E: Cannot assign to final
-np.UFUNC_PYVALS_NAME = np.UFUNC_PYVALS_NAME # E: Cannot assign to final
+np.UFUNC_PYVALS_NAME = "bob" # E: Incompatible types
+np.CLIP = 2 # E: Incompatible types
diff --git a/numpy/typing/tests/data/fail/datasource.py b/numpy/typing/tests/data/fail/datasource.py
new file mode 100644
index 000000000..345277d45
--- /dev/null
+++ b/numpy/typing/tests/data/fail/datasource.py
@@ -0,0 +1,15 @@
+from pathlib import Path
+import numpy as np
+
+path: Path
+d1: np.DataSource
+
+d1.abspath(path) # E: incompatible type
+d1.abspath(b"...") # E: incompatible type
+
+d1.exists(path) # E: incompatible type
+d1.exists(b"...") # E: incompatible type
+
+d1.open(path, "r") # E: incompatible type
+d1.open(b"...", encoding="utf8") # E: incompatible type
+d1.open(None, newline="/n") # E: incompatible type
diff --git a/numpy/typing/tests/data/fail/dtype.py b/numpy/typing/tests/data/fail/dtype.py
index 7d4783d8f..0f3810f3c 100644
--- a/numpy/typing/tests/data/fail/dtype.py
+++ b/numpy/typing/tests/data/fail/dtype.py
@@ -1,10 +1,16 @@
import numpy as np
-class Test:
- not_dtype = float
+class Test1:
+ not_dtype = np.dtype(float)
-np.dtype(Test()) # E: No overload variant of "dtype" matches
+
+class Test2:
+ dtype = float
+
+
+np.dtype(Test1()) # E: No overload variant of "dtype" matches
+np.dtype(Test2()) # E: incompatible type
np.dtype( # E: No overload variant of "dtype" matches
{
@@ -12,5 +18,3 @@ np.dtype( # E: No overload variant of "dtype" matches
"field2": (int, 3),
}
)
-
-np.dtype[np.float64](np.int64) # E: Argument 1 to "dtype" has incompatible type
diff --git a/numpy/typing/tests/data/fail/einsumfunc.py b/numpy/typing/tests/data/fail/einsumfunc.py
new file mode 100644
index 000000000..33722f861
--- /dev/null
+++ b/numpy/typing/tests/data/fail/einsumfunc.py
@@ -0,0 +1,15 @@
+from typing import List, Any
+import numpy as np
+
+AR_i: np.ndarray[Any, np.dtype[np.int64]]
+AR_f: np.ndarray[Any, np.dtype[np.float64]]
+AR_m: np.ndarray[Any, np.dtype[np.timedelta64]]
+AR_O: np.ndarray[Any, np.dtype[np.object_]]
+AR_U: np.ndarray[Any, np.dtype[np.str_]]
+
+np.einsum("i,i->i", AR_i, AR_m) # E: incompatible type
+np.einsum("i,i->i", AR_O, AR_O) # E: incompatible type
+np.einsum("i,i->i", AR_f, AR_f, dtype=np.int32) # E: incompatible type
+np.einsum("i,i->i", AR_i, AR_i, dtype=np.timedelta64, casting="unsafe") # E: No overload variant
+np.einsum("i,i->i", AR_i, AR_i, out=AR_U) # E: Value of type variable "_ArrayType" of "einsum" cannot be
+np.einsum("i,i->i", AR_i, AR_i, out=AR_U, casting="unsafe") # E: No overload variant
diff --git a/numpy/typing/tests/data/fail/fromnumeric.py b/numpy/typing/tests/data/fail/fromnumeric.py
index c9156895d..8fafed1b7 100644
--- a/numpy/typing/tests/data/fail/fromnumeric.py
+++ b/numpy/typing/tests/data/fail/fromnumeric.py
@@ -7,17 +7,17 @@ A.setflags(write=False)
a = np.bool_(True)
-np.take(a, None) # E: No overload variant of "take" matches argument type
-np.take(a, axis=1.0) # E: No overload variant of "take" matches argument type
-np.take(A, out=1) # E: No overload variant of "take" matches argument type
-np.take(A, mode="bob") # E: No overload variant of "take" matches argument type
+np.take(a, None) # E: incompatible type
+np.take(a, axis=1.0) # E: incompatible type
+np.take(A, out=1) # E: incompatible type
+np.take(A, mode="bob") # E: incompatible type
np.reshape(a, None) # E: Argument 2 to "reshape" has incompatible type
np.reshape(A, 1, order="bob") # E: Argument "order" to "reshape" has incompatible type
-np.choose(a, None) # E: No overload variant of "choose" matches argument type
-np.choose(a, out=1.0) # E: No overload variant of "choose" matches argument type
-np.choose(A, mode="bob") # E: No overload variant of "choose" matches argument type
+np.choose(a, None) # E: incompatible type
+np.choose(a, out=1.0) # E: incompatible type
+np.choose(A, mode="bob") # E: incompatible type
np.repeat(a, None) # E: Argument 2 to "repeat" has incompatible type
np.repeat(A, 1, axis=1.0) # E: Argument "axis" to "repeat" has incompatible type
@@ -38,14 +38,14 @@ np.partition(
A, 0, order=range(5) # E: Argument "order" to "partition" has incompatible type
)
-np.argpartition( # E: No overload variant of "argpartition" matches argument type
- a, None
+np.argpartition(
+ a, None # E: incompatible type
)
-np.argpartition( # E: No overload variant of "argpartition" matches argument type
- a, 0, axis="bob"
+np.argpartition(
+ a, 0, axis="bob" # E: incompatible type
)
-np.argpartition( # E: No overload variant of "argpartition" matches argument type
- A, 0, kind="bob"
+np.argpartition(
+ A, 0, kind="bob" # E: incompatible type
)
np.argpartition(
A, 0, order=range(5) # E: Argument "order" to "argpartition" has incompatible type
@@ -93,62 +93,62 @@ np.compress(
np.clip(a, 1, 2, out=1) # E: No overload variant of "clip" matches argument type
np.clip(1, None, None) # E: No overload variant of "clip" matches argument type
-np.sum(a, axis=1.0) # E: No overload variant of "sum" matches argument type
-np.sum(a, keepdims=1.0) # E: No overload variant of "sum" matches argument type
-np.sum(a, initial=[1]) # E: No overload variant of "sum" matches argument type
+np.sum(a, axis=1.0) # E: incompatible type
+np.sum(a, keepdims=1.0) # E: incompatible type
+np.sum(a, initial=[1]) # E: incompatible type
-np.all(a, axis=1.0) # E: No overload variant of "all" matches argument type
-np.all(a, keepdims=1.0) # E: No overload variant of "all" matches argument type
-np.all(a, out=1.0) # E: No overload variant of "all" matches argument type
+np.all(a, axis=1.0) # E: No overload variant
+np.all(a, keepdims=1.0) # E: No overload variant
+np.all(a, out=1.0) # E: No overload variant
-np.any(a, axis=1.0) # E: No overload variant of "any" matches argument type
-np.any(a, keepdims=1.0) # E: No overload variant of "any" matches argument type
-np.any(a, out=1.0) # E: No overload variant of "any" matches argument type
+np.any(a, axis=1.0) # E: No overload variant
+np.any(a, keepdims=1.0) # E: No overload variant
+np.any(a, out=1.0) # E: No overload variant
-np.cumsum(a, axis=1.0) # E: Argument "axis" to "cumsum" has incompatible type
-np.cumsum(a, dtype=1.0) # E: Argument "dtype" to "cumsum" has incompatible type
-np.cumsum(a, out=1.0) # E: Argument "out" to "cumsum" has incompatible type
+np.cumsum(a, axis=1.0) # E: incompatible type
+np.cumsum(a, dtype=1.0) # E: incompatible type
+np.cumsum(a, out=1.0) # E: incompatible type
-np.ptp(a, axis=1.0) # E: No overload variant of "ptp" matches argument type
-np.ptp(a, keepdims=1.0) # E: No overload variant of "ptp" matches argument type
-np.ptp(a, out=1.0) # E: No overload variant of "ptp" matches argument type
+np.ptp(a, axis=1.0) # E: incompatible type
+np.ptp(a, keepdims=1.0) # E: incompatible type
+np.ptp(a, out=1.0) # E: incompatible type
-np.amax(a, axis=1.0) # E: No overload variant of "amax" matches argument type
-np.amax(a, keepdims=1.0) # E: No overload variant of "amax" matches argument type
-np.amax(a, out=1.0) # E: No overload variant of "amax" matches argument type
-np.amax(a, initial=[1.0]) # E: No overload variant of "amax" matches argument type
-np.amax(a, where=[1.0]) # E: List item 0 has incompatible type
+np.amax(a, axis=1.0) # E: incompatible type
+np.amax(a, keepdims=1.0) # E: incompatible type
+np.amax(a, out=1.0) # E: incompatible type
+np.amax(a, initial=[1.0]) # E: incompatible type
+np.amax(a, where=[1.0]) # E: incompatible type
-np.amin(a, axis=1.0) # E: No overload variant of "amin" matches argument type
-np.amin(a, keepdims=1.0) # E: No overload variant of "amin" matches argument type
-np.amin(a, out=1.0) # E: No overload variant of "amin" matches argument type
-np.amin(a, initial=[1.0]) # E: No overload variant of "amin" matches argument type
-np.amin(a, where=[1.0]) # E: List item 0 has incompatible type
+np.amin(a, axis=1.0) # E: incompatible type
+np.amin(a, keepdims=1.0) # E: incompatible type
+np.amin(a, out=1.0) # E: incompatible type
+np.amin(a, initial=[1.0]) # E: incompatible type
+np.amin(a, where=[1.0]) # E: incompatible type
-np.prod(a, axis=1.0) # E: No overload variant of "prod" matches argument type
-np.prod(a, out=False) # E: No overload variant of "prod" matches argument type
-np.prod(a, keepdims=1.0) # E: No overload variant of "prod" matches argument type
-np.prod(a, initial=int) # E: No overload variant of "prod" matches argument type
-np.prod(a, where=1.0) # E: No overload variant of "prod" matches argument type
+np.prod(a, axis=1.0) # E: incompatible type
+np.prod(a, out=False) # E: incompatible type
+np.prod(a, keepdims=1.0) # E: incompatible type
+np.prod(a, initial=int) # E: incompatible type
+np.prod(a, where=1.0) # E: incompatible type
np.cumprod(a, axis=1.0) # E: Argument "axis" to "cumprod" has incompatible type
np.cumprod(a, out=False) # E: Argument "out" to "cumprod" has incompatible type
np.size(a, axis=1.0) # E: Argument "axis" to "size" has incompatible type
-np.around(a, decimals=1.0) # E: No overload variant of "around" matches argument type
-np.around(a, out=type) # E: No overload variant of "around" matches argument type
+np.around(a, decimals=1.0) # E: incompatible type
+np.around(a, out=type) # E: incompatible type
-np.mean(a, axis=1.0) # E: No overload variant of "mean" matches argument type
-np.mean(a, out=False) # E: No overload variant of "mean" matches argument type
-np.mean(a, keepdims=1.0) # E: No overload variant of "mean" matches argument type
+np.mean(a, axis=1.0) # E: incompatible type
+np.mean(a, out=False) # E: incompatible type
+np.mean(a, keepdims=1.0) # E: incompatible type
-np.std(a, axis=1.0) # E: No overload variant of "std" matches argument type
-np.std(a, out=False) # E: No overload variant of "std" matches argument type
-np.std(a, ddof='test') # E: No overload variant of "std" matches argument type
-np.std(a, keepdims=1.0) # E: No overload variant of "std" matches argument type
+np.std(a, axis=1.0) # E: incompatible type
+np.std(a, out=False) # E: incompatible type
+np.std(a, ddof='test') # E: incompatible type
+np.std(a, keepdims=1.0) # E: incompatible type
-np.var(a, axis=1.0) # E: No overload variant of "var" matches argument type
-np.var(a, out=False) # E: No overload variant of "var" matches argument type
-np.var(a, ddof='test') # E: No overload variant of "var" matches argument type
-np.var(a, keepdims=1.0) # E: No overload variant of "var" matches argument type
+np.var(a, axis=1.0) # E: incompatible type
+np.var(a, out=False) # E: incompatible type
+np.var(a, ddof='test') # E: incompatible type
+np.var(a, keepdims=1.0) # E: incompatible type
diff --git a/numpy/typing/tests/data/fail/index_tricks.py b/numpy/typing/tests/data/fail/index_tricks.py
new file mode 100644
index 000000000..c508bf3ae
--- /dev/null
+++ b/numpy/typing/tests/data/fail/index_tricks.py
@@ -0,0 +1,14 @@
+from typing import List
+import numpy as np
+
+AR_LIKE_i: List[int]
+AR_LIKE_f: List[float]
+
+np.unravel_index(AR_LIKE_f, (1, 2, 3)) # E: incompatible type
+np.ravel_multi_index(AR_LIKE_i, (1, 2, 3), mode="bob") # E: No overload variant
+np.mgrid[1] # E: Invalid index type
+np.mgrid[...] # E: Invalid index type
+np.ogrid[1] # E: Invalid index type
+np.ogrid[...] # E: Invalid index type
+np.fill_diagonal(AR_LIKE_f, 2) # E: incompatible type
+np.diag_indices(1.0) # E: incompatible type
diff --git a/numpy/typing/tests/data/fail/lib_utils.py b/numpy/typing/tests/data/fail/lib_utils.py
new file mode 100644
index 000000000..e16c926aa
--- /dev/null
+++ b/numpy/typing/tests/data/fail/lib_utils.py
@@ -0,0 +1,13 @@
+import numpy as np
+
+np.deprecate(1) # E: No overload variant
+
+np.deprecate_with_doc(1) # E: incompatible type
+
+np.byte_bounds(1) # E: incompatible type
+
+np.who(1) # E: incompatible type
+
+np.lookfor(None) # E: incompatible type
+
+np.safe_eval(None) # E: incompatible type
diff --git a/numpy/typing/tests/data/fail/lib_version.py b/numpy/typing/tests/data/fail/lib_version.py
new file mode 100644
index 000000000..2758cfe40
--- /dev/null
+++ b/numpy/typing/tests/data/fail/lib_version.py
@@ -0,0 +1,6 @@
+from numpy.lib import NumpyVersion
+
+version: NumpyVersion
+
+NumpyVersion(b"1.8.0") # E: incompatible type
+version >= b"1.8.0" # E: Unsupported operand types
diff --git a/numpy/typing/tests/data/fail/modules.py b/numpy/typing/tests/data/fail/modules.py
index 5e2d820ab..7b9309329 100644
--- a/numpy/typing/tests/data/fail/modules.py
+++ b/numpy/typing/tests/data/fail/modules.py
@@ -8,3 +8,12 @@ np.warnings # E: Module has no attribute
np.sys # E: Module has no attribute
np.os # E: Module has no attribute
np.math # E: Module has no attribute
+
+# Public sub-modules that are not imported to their parent module by default;
+# e.g. one must first execute `import numpy.lib.recfunctions`
+np.lib.recfunctions # E: Module has no attribute
+np.ma.mrecords # E: Module has no attribute
+
+np.__NUMPY_SETUP__ # E: Module has no attribute
+np.__deprecated_attrs__ # E: Module has no attribute
+np.__expired_functions__ # E: Module has no attribute
diff --git a/numpy/typing/tests/data/fail/multiarray.py b/numpy/typing/tests/data/fail/multiarray.py
new file mode 100644
index 000000000..50361ec43
--- /dev/null
+++ b/numpy/typing/tests/data/fail/multiarray.py
@@ -0,0 +1,49 @@
+from typing import List
+import numpy as np
+import numpy.typing as npt
+
+i8: np.int64
+
+AR_b: npt.NDArray[np.bool_]
+AR_u1: npt.NDArray[np.uint8]
+AR_i8: npt.NDArray[np.int64]
+AR_f8: npt.NDArray[np.float64]
+AR_M: npt.NDArray[np.datetime64]
+
+M: np.datetime64
+
+AR_LIKE_f: List[float]
+
+def func(a: int) -> None: ...
+
+np.where(AR_b, 1) # E: No overload variant
+
+np.can_cast(AR_f8, 1) # E: incompatible type
+
+np.vdot(AR_M, AR_M) # E: incompatible type
+
+np.copyto(AR_LIKE_f, AR_f8) # E: incompatible type
+
+np.putmask(AR_LIKE_f, [True, True, False], 1.5) # E: incompatible type
+
+np.packbits(AR_f8) # E: incompatible type
+np.packbits(AR_u1, bitorder=">") # E: incompatible type
+
+np.unpackbits(AR_i8) # E: incompatible type
+np.unpackbits(AR_u1, bitorder=">") # E: incompatible type
+
+np.shares_memory(1, 1, max_work=i8) # E: incompatible type
+np.may_share_memory(1, 1, max_work=i8) # E: incompatible type
+
+np.arange(M) # E: No overload variant
+np.arange(stop=10) # E: No overload variant
+
+np.datetime_data(int) # E: incompatible type
+
+np.busday_offset("2012", 10) # E: incompatible type
+
+np.datetime_as_string("2012") # E: incompatible type
+
+np.compare_chararrays("a", b"a", "==", False) # E: No overload variant
+
+np.add_docstring(func, None) # E: incompatible type
diff --git a/numpy/typing/tests/data/fail/ndarray_misc.py b/numpy/typing/tests/data/fail/ndarray_misc.py
index 1e1496bfe..cf3fedc45 100644
--- a/numpy/typing/tests/data/fail/ndarray_misc.py
+++ b/numpy/typing/tests/data/fail/ndarray_misc.py
@@ -6,9 +6,20 @@ function-based counterpart in `../from_numeric.py`.
"""
+from typing import Any
import numpy as np
f8: np.float64
+AR_f8: np.ndarray[Any, np.dtype[np.float64]]
+AR_M: np.ndarray[Any, np.dtype[np.datetime64]]
+AR_b: np.ndarray[Any, np.dtype[np.bool_]]
+
+ctypes_obj = AR_f8.ctypes
+
+reveal_type(ctypes_obj.get_data()) # E: has no attribute
+reveal_type(ctypes_obj.get_shape()) # E: has no attribute
+reveal_type(ctypes_obj.get_strides()) # E: has no attribute
+reveal_type(ctypes_obj.get_as_parameter()) # E: has no attribute
f8.argpartition(0) # E: has no attribute
f8.diagonal() # E: has no attribute
@@ -19,3 +30,8 @@ f8.put(0, 2) # E: has no attribute
f8.setfield(2, np.float64) # E: has no attribute
f8.sort() # E: has no attribute
f8.trace() # E: has no attribute
+
+AR_M.__int__() # E: Invalid self argument
+AR_M.__float__() # E: Invalid self argument
+AR_M.__complex__() # E: Invalid self argument
+AR_b.__index__() # E: Invalid self argument
diff --git a/numpy/typing/tests/data/fail/numerictypes.py b/numpy/typing/tests/data/fail/numerictypes.py
index 94537a23b..9a81cd9dc 100644
--- a/numpy/typing/tests/data/fail/numerictypes.py
+++ b/numpy/typing/tests/data/fail/numerictypes.py
@@ -4,10 +4,10 @@ import numpy as np
#
# https://github.com/numpy/numpy/issues/16366
#
-np.maximum_sctype(1) # E: incompatible type "int"
+np.maximum_sctype(1) # E: No overload variant
-np.issubsctype(1, np.int64) # E: incompatible type "int"
+np.issubsctype(1, np.int64) # E: incompatible type
-np.issubdtype(1, np.int64) # E: incompatible type "int"
+np.issubdtype(1, np.int64) # E: incompatible type
-np.find_common_type(np.int64, np.int64) # E: incompatible type "Type[signedinteger[Any]]"
+np.find_common_type(np.int64, np.int64) # E: incompatible type
diff --git a/numpy/typing/tests/data/fail/random.py b/numpy/typing/tests/data/fail/random.py
new file mode 100644
index 000000000..c4d1e3e3e
--- /dev/null
+++ b/numpy/typing/tests/data/fail/random.py
@@ -0,0 +1,61 @@
+import numpy as np
+from typing import Any, List
+
+SEED_FLOAT: float = 457.3
+SEED_ARR_FLOAT: np.ndarray[Any, np.dtype[np.float64]] = np.array([1.0, 2, 3, 4])
+SEED_ARRLIKE_FLOAT: List[float] = [1.0, 2.0, 3.0, 4.0]
+SEED_SEED_SEQ: np.random.SeedSequence = np.random.SeedSequence(0)
+SEED_STR: str = "String seeding not allowed"
+# default rng
+np.random.default_rng(SEED_FLOAT) # E: incompatible type
+np.random.default_rng(SEED_ARR_FLOAT) # E: incompatible type
+np.random.default_rng(SEED_ARRLIKE_FLOAT) # E: incompatible type
+np.random.default_rng(SEED_STR) # E: incompatible type
+
+# Seed Sequence
+np.random.SeedSequence(SEED_FLOAT) # E: incompatible type
+np.random.SeedSequence(SEED_ARR_FLOAT) # E: incompatible type
+np.random.SeedSequence(SEED_ARRLIKE_FLOAT) # E: incompatible type
+np.random.SeedSequence(SEED_SEED_SEQ) # E: incompatible type
+np.random.SeedSequence(SEED_STR) # E: incompatible type
+
+seed_seq: np.random.bit_generator.SeedSequence = np.random.SeedSequence()
+seed_seq.spawn(11.5) # E: incompatible type
+seed_seq.generate_state(3.14) # E: incompatible type
+seed_seq.generate_state(3, np.uint8) # E: incompatible type
+seed_seq.generate_state(3, "uint8") # E: incompatible type
+seed_seq.generate_state(3, "u1") # E: incompatible type
+seed_seq.generate_state(3, np.uint16) # E: incompatible type
+seed_seq.generate_state(3, "uint16") # E: incompatible type
+seed_seq.generate_state(3, "u2") # E: incompatible type
+seed_seq.generate_state(3, np.int32) # E: incompatible type
+seed_seq.generate_state(3, "int32") # E: incompatible type
+seed_seq.generate_state(3, "i4") # E: incompatible type
+
+# Bit Generators
+np.random.MT19937(SEED_FLOAT) # E: incompatible type
+np.random.MT19937(SEED_ARR_FLOAT) # E: incompatible type
+np.random.MT19937(SEED_ARRLIKE_FLOAT) # E: incompatible type
+np.random.MT19937(SEED_STR) # E: incompatible type
+
+np.random.PCG64(SEED_FLOAT) # E: incompatible type
+np.random.PCG64(SEED_ARR_FLOAT) # E: incompatible type
+np.random.PCG64(SEED_ARRLIKE_FLOAT) # E: incompatible type
+np.random.PCG64(SEED_STR) # E: incompatible type
+
+np.random.Philox(SEED_FLOAT) # E: incompatible type
+np.random.Philox(SEED_ARR_FLOAT) # E: incompatible type
+np.random.Philox(SEED_ARRLIKE_FLOAT) # E: incompatible type
+np.random.Philox(SEED_STR) # E: incompatible type
+
+np.random.SFC64(SEED_FLOAT) # E: incompatible type
+np.random.SFC64(SEED_ARR_FLOAT) # E: incompatible type
+np.random.SFC64(SEED_ARRLIKE_FLOAT) # E: incompatible type
+np.random.SFC64(SEED_STR) # E: incompatible type
+
+# Generator
+np.random.Generator(None) # E: incompatible type
+np.random.Generator(12333283902830213) # E: incompatible type
+np.random.Generator("OxFEEDF00D") # E: incompatible type
+np.random.Generator([123, 234]) # E: incompatible type
+np.random.Generator(np.array([123, 234], dtype="u4")) # E: incompatible type
diff --git a/numpy/typing/tests/data/fail/scalars.py b/numpy/typing/tests/data/fail/scalars.py
index f09740875..099418e67 100644
--- a/numpy/typing/tests/data/fail/scalars.py
+++ b/numpy/typing/tests/data/fail/scalars.py
@@ -1,6 +1,9 @@
+import sys
import numpy as np
+f2: np.float16
f8: np.float64
+c8: np.complex64
# Construction
@@ -74,3 +77,18 @@ f8.item((0, 1)) # E: incompatible type
f8.squeeze(axis=1) # E: incompatible type
f8.squeeze(axis=(0, 1)) # E: incompatible type
f8.transpose(1) # E: incompatible type
+
+def func(a: np.float32) -> None: ...
+
+func(f2) # E: incompatible type
+func(f8) # E: incompatible type
+
+round(c8) # E: No overload variant
+
+c8.__getnewargs__() # E: Invalid self argument
+f2.__getnewargs__() # E: Invalid self argument
+f2.is_integer() # E: Invalid self argument
+f2.hex() # E: Invalid self argument
+np.float16.fromhex("0x0.0p+0") # E: Invalid self argument
+f2.__trunc__() # E: Invalid self argument
+f2.__getformat__("float") # E: Invalid self argument
diff --git a/numpy/typing/tests/data/fail/testing.py b/numpy/typing/tests/data/fail/testing.py
new file mode 100644
index 000000000..e753a9810
--- /dev/null
+++ b/numpy/typing/tests/data/fail/testing.py
@@ -0,0 +1,26 @@
+import numpy as np
+import numpy.typing as npt
+
+AR_U: npt.NDArray[np.str_]
+
+def func() -> bool: ...
+
+np.testing.assert_(True, msg=1) # E: incompatible type
+np.testing.build_err_msg(1, "test") # E: incompatible type
+np.testing.assert_almost_equal(AR_U, AR_U) # E: incompatible type
+np.testing.assert_approx_equal([1, 2, 3], [1, 2, 3]) # E: incompatible type
+np.testing.assert_array_almost_equal(AR_U, AR_U) # E: incompatible type
+np.testing.assert_array_less(AR_U, AR_U) # E: incompatible type
+np.testing.assert_string_equal(b"a", b"a") # E: incompatible type
+
+np.testing.assert_raises(expected_exception=TypeError, callable=func) # E: No overload variant
+np.testing.assert_raises_regex(expected_exception=TypeError, expected_regex="T", callable=func) # E: No overload variant
+
+np.testing.assert_allclose(AR_U, AR_U) # E: incompatible type
+np.testing.assert_array_almost_equal_nulp(AR_U, AR_U) # E: incompatible type
+np.testing.assert_array_max_ulp(AR_U, AR_U) # E: incompatible type
+
+np.testing.assert_warns(warning_class=RuntimeWarning, func=func) # E: No overload variant
+np.testing.assert_no_warnings(func=func) # E: No overload variant
+
+np.testing.assert_no_gc_cycles(func=func) # E: No overload variant
diff --git a/numpy/typing/tests/data/fail/twodim_base.py b/numpy/typing/tests/data/fail/twodim_base.py
new file mode 100644
index 000000000..ab34a374c
--- /dev/null
+++ b/numpy/typing/tests/data/fail/twodim_base.py
@@ -0,0 +1,37 @@
+from typing import Any, List, TypeVar
+
+import numpy as np
+import numpy.typing as npt
+
+
+def func1(ar: npt.NDArray[Any], a: int) -> npt.NDArray[np.str_]:
+ pass
+
+
+def func2(ar: npt.NDArray[Any], a: float) -> float:
+ pass
+
+
+AR_b: npt.NDArray[np.bool_]
+AR_m: npt.NDArray[np.timedelta64]
+
+AR_LIKE_b: List[bool]
+
+np.eye(10, M=20.0) # E: No overload variant
+np.eye(10, k=2.5, dtype=int) # E: No overload variant
+
+np.diag(AR_b, k=0.5) # E: No overload variant
+np.diagflat(AR_b, k=0.5) # E: No overload variant
+
+np.tri(10, M=20.0) # E: No overload variant
+np.tri(10, k=2.5, dtype=int) # E: No overload variant
+
+np.tril(AR_b, k=0.5) # E: No overload variant
+np.triu(AR_b, k=0.5) # E: No overload variant
+
+np.vander(AR_m) # E: incompatible type
+
+np.histogram2d(AR_m) # E: No overload variant
+
+np.mask_indices(10, func1) # E: incompatible type
+np.mask_indices(10, func2, 10.5) # E: incompatible type
diff --git a/numpy/typing/tests/data/fail/type_check.py b/numpy/typing/tests/data/fail/type_check.py
new file mode 100644
index 000000000..95f52bfbd
--- /dev/null
+++ b/numpy/typing/tests/data/fail/type_check.py
@@ -0,0 +1,13 @@
+import numpy as np
+import numpy.typing as npt
+
+DTYPE_i8: np.dtype[np.int64]
+
+np.mintypecode(DTYPE_i8) # E: incompatible type
+np.iscomplexobj(DTYPE_i8) # E: incompatible type
+np.isrealobj(DTYPE_i8) # E: incompatible type
+
+np.typename(DTYPE_i8) # E: No overload variant
+np.typename("invalid") # E: No overload variant
+
+np.common_type(np.timedelta64()) # E: incompatible type
diff --git a/numpy/typing/tests/data/fail/ufunclike.py b/numpy/typing/tests/data/fail/ufunclike.py
new file mode 100644
index 000000000..82a5f3a1d
--- /dev/null
+++ b/numpy/typing/tests/data/fail/ufunclike.py
@@ -0,0 +1,21 @@
+from typing import List, Any
+import numpy as np
+
+AR_c: np.ndarray[Any, np.dtype[np.complex128]]
+AR_m: np.ndarray[Any, np.dtype[np.timedelta64]]
+AR_M: np.ndarray[Any, np.dtype[np.datetime64]]
+AR_O: np.ndarray[Any, np.dtype[np.object_]]
+
+np.fix(AR_c) # E: incompatible type
+np.fix(AR_m) # E: incompatible type
+np.fix(AR_M) # E: incompatible type
+
+np.isposinf(AR_c) # E: incompatible type
+np.isposinf(AR_m) # E: incompatible type
+np.isposinf(AR_M) # E: incompatible type
+np.isposinf(AR_O) # E: incompatible type
+
+np.isneginf(AR_c) # E: incompatible type
+np.isneginf(AR_m) # E: incompatible type
+np.isneginf(AR_M) # E: incompatible type
+np.isneginf(AR_O) # E: incompatible type
diff --git a/numpy/typing/tests/data/fail/ufuncs.py b/numpy/typing/tests/data/fail/ufuncs.py
index 4da9d08ba..e827267c6 100644
--- a/numpy/typing/tests/data/fail/ufuncs.py
+++ b/numpy/typing/tests/data/fail/ufuncs.py
@@ -1,7 +1,41 @@
import numpy as np
+import numpy.typing as npt
+
+AR_f8: npt.NDArray[np.float64]
np.sin.nin + "foo" # E: Unsupported operand types
-np.sin(1, foo="bar") # E: Unexpected keyword argument
-np.sin(1, extobj=["foo", "foo", "foo"]) # E: incompatible type
+np.sin(1, foo="bar") # E: No overload variant
+
+np.abs(None) # E: No overload variant
+
+np.add(1, 1, 1) # E: No overload variant
+np.add(1, 1, axis=0) # E: No overload variant
+
+np.matmul(AR_f8, AR_f8, where=True) # E: No overload variant
+
+np.frexp(AR_f8, out=None) # E: No overload variant
+np.frexp(AR_f8, out=AR_f8) # E: No overload variant
+
+np.absolute.outer() # E: "None" not callable
+np.frexp.outer() # E: "None" not callable
+np.divmod.outer() # E: "None" not callable
+np.matmul.outer() # E: "None" not callable
+
+np.absolute.reduceat() # E: "None" not callable
+np.frexp.reduceat() # E: "None" not callable
+np.divmod.reduceat() # E: "None" not callable
+np.matmul.reduceat() # E: "None" not callable
+
+np.absolute.reduce() # E: "None" not callable
+np.frexp.reduce() # E: "None" not callable
+np.divmod.reduce() # E: "None" not callable
+np.matmul.reduce() # E: "None" not callable
+
+np.absolute.accumulate() # E: "None" not callable
+np.frexp.accumulate() # E: "None" not callable
+np.divmod.accumulate() # E: "None" not callable
+np.matmul.accumulate() # E: "None" not callable
-np.abs(None) # E: incompatible type
+np.frexp.at() # E: "None" not callable
+np.divmod.at() # E: "None" not callable
+np.matmul.at() # E: "None" not callable
diff --git a/numpy/typing/tests/data/fail/warnings_and_errors.py b/numpy/typing/tests/data/fail/warnings_and_errors.py
index 7390cc45f..f4fa38293 100644
--- a/numpy/typing/tests/data/fail/warnings_and_errors.py
+++ b/numpy/typing/tests/data/fail/warnings_and_errors.py
@@ -1,7 +1,5 @@
import numpy as np
-np.AxisError(1.0) # E: Argument 1 to "AxisError" has incompatible type
-np.AxisError(1, ndim=2.0) # E: Argument "ndim" to "AxisError" has incompatible type
-np.AxisError(
- 2, msg_prefix=404 # E: Argument "msg_prefix" to "AxisError" has incompatible type
-)
+np.AxisError(1.0) # E: No overload variant
+np.AxisError(1, ndim=2.0) # E: No overload variant
+np.AxisError(2, msg_prefix=404) # E: No overload variant
diff --git a/numpy/typing/tests/data/misc/extended_precision.py b/numpy/typing/tests/data/misc/extended_precision.py
new file mode 100644
index 000000000..1e495e4f3
--- /dev/null
+++ b/numpy/typing/tests/data/misc/extended_precision.py
@@ -0,0 +1,17 @@
+import numpy as np
+
+reveal_type(np.uint128())
+reveal_type(np.uint256())
+
+reveal_type(np.int128())
+reveal_type(np.int256())
+
+reveal_type(np.float80())
+reveal_type(np.float96())
+reveal_type(np.float128())
+reveal_type(np.float256())
+
+reveal_type(np.complex160())
+reveal_type(np.complex192())
+reveal_type(np.complex256())
+reveal_type(np.complex512())
diff --git a/numpy/typing/tests/data/mypy.ini b/numpy/typing/tests/data/mypy.ini
index 91d93588a..548f76261 100644
--- a/numpy/typing/tests/data/mypy.ini
+++ b/numpy/typing/tests/data/mypy.ini
@@ -1,5 +1,6 @@
[mypy]
-mypy_path = ../../..
+plugins = numpy.typing.mypy_plugin
+show_absolute_path = True
[mypy-numpy]
ignore_errors = True
diff --git a/numpy/typing/tests/data/pass/arithmetic.py b/numpy/typing/tests/data/pass/arithmetic.py
index ffbaf2975..fe1612906 100644
--- a/numpy/typing/tests/data/pass/arithmetic.py
+++ b/numpy/typing/tests/data/pass/arithmetic.py
@@ -1,3 +1,6 @@
+from __future__ import annotations
+
+from typing import Any
import numpy as np
c16 = np.complex128(1)
@@ -20,8 +23,300 @@ c = complex(1)
f = float(1)
i = int(1)
-AR = np.ones(1, dtype=np.float64)
-AR.setflags(write=False)
+
+class Object:
+ def __array__(self) -> np.ndarray[Any, np.dtype[np.object_]]:
+ ret = np.empty((), dtype=object)
+ ret[()] = self
+ return ret
+
+ def __sub__(self, value: Any) -> Object:
+ return self
+
+ def __rsub__(self, value: Any) -> Object:
+ return self
+
+ def __floordiv__(self, value: Any) -> Object:
+ return self
+
+ def __rfloordiv__(self, value: Any) -> Object:
+ return self
+
+ def __mul__(self, value: Any) -> Object:
+ return self
+
+ def __rmul__(self, value: Any) -> Object:
+ return self
+
+ def __pow__(self, value: Any) -> Object:
+ return self
+
+ def __rpow__(self, value: Any) -> Object:
+ return self
+
+
+AR_b: np.ndarray[Any, np.dtype[np.bool_]] = np.array([True])
+AR_u: np.ndarray[Any, np.dtype[np.uint32]] = np.array([1], dtype=np.uint32)
+AR_i: np.ndarray[Any, np.dtype[np.int64]] = np.array([1])
+AR_f: np.ndarray[Any, np.dtype[np.float64]] = np.array([1.0])
+AR_c: np.ndarray[Any, np.dtype[np.complex128]] = np.array([1j])
+AR_m: np.ndarray[Any, np.dtype[np.timedelta64]] = np.array([np.timedelta64(1, "D")])
+AR_M: np.ndarray[Any, np.dtype[np.datetime64]] = np.array([np.datetime64(1, "D")])
+AR_O: np.ndarray[Any, np.dtype[np.object_]] = np.array([Object()])
+
+AR_LIKE_b = [True]
+AR_LIKE_u = [np.uint32(1)]
+AR_LIKE_i = [1]
+AR_LIKE_f = [1.0]
+AR_LIKE_c = [1j]
+AR_LIKE_m = [np.timedelta64(1, "D")]
+AR_LIKE_M = [np.datetime64(1, "D")]
+AR_LIKE_O = [Object()]
+
+# Array subtractions
+
+AR_b - AR_LIKE_u
+AR_b - AR_LIKE_i
+AR_b - AR_LIKE_f
+AR_b - AR_LIKE_c
+AR_b - AR_LIKE_m
+AR_b - AR_LIKE_O
+
+AR_LIKE_u - AR_b
+AR_LIKE_i - AR_b
+AR_LIKE_f - AR_b
+AR_LIKE_c - AR_b
+AR_LIKE_m - AR_b
+AR_LIKE_M - AR_b
+AR_LIKE_O - AR_b
+
+AR_u - AR_LIKE_b
+AR_u - AR_LIKE_u
+AR_u - AR_LIKE_i
+AR_u - AR_LIKE_f
+AR_u - AR_LIKE_c
+AR_u - AR_LIKE_m
+AR_u - AR_LIKE_O
+
+AR_LIKE_b - AR_u
+AR_LIKE_u - AR_u
+AR_LIKE_i - AR_u
+AR_LIKE_f - AR_u
+AR_LIKE_c - AR_u
+AR_LIKE_m - AR_u
+AR_LIKE_M - AR_u
+AR_LIKE_O - AR_u
+
+AR_i - AR_LIKE_b
+AR_i - AR_LIKE_u
+AR_i - AR_LIKE_i
+AR_i - AR_LIKE_f
+AR_i - AR_LIKE_c
+AR_i - AR_LIKE_m
+AR_i - AR_LIKE_O
+
+AR_LIKE_b - AR_i
+AR_LIKE_u - AR_i
+AR_LIKE_i - AR_i
+AR_LIKE_f - AR_i
+AR_LIKE_c - AR_i
+AR_LIKE_m - AR_i
+AR_LIKE_M - AR_i
+AR_LIKE_O - AR_i
+
+AR_f - AR_LIKE_b
+AR_f - AR_LIKE_u
+AR_f - AR_LIKE_i
+AR_f - AR_LIKE_f
+AR_f - AR_LIKE_c
+AR_f - AR_LIKE_O
+
+AR_LIKE_b - AR_f
+AR_LIKE_u - AR_f
+AR_LIKE_i - AR_f
+AR_LIKE_f - AR_f
+AR_LIKE_c - AR_f
+AR_LIKE_O - AR_f
+
+AR_c - AR_LIKE_b
+AR_c - AR_LIKE_u
+AR_c - AR_LIKE_i
+AR_c - AR_LIKE_f
+AR_c - AR_LIKE_c
+AR_c - AR_LIKE_O
+
+AR_LIKE_b - AR_c
+AR_LIKE_u - AR_c
+AR_LIKE_i - AR_c
+AR_LIKE_f - AR_c
+AR_LIKE_c - AR_c
+AR_LIKE_O - AR_c
+
+AR_m - AR_LIKE_b
+AR_m - AR_LIKE_u
+AR_m - AR_LIKE_i
+AR_m - AR_LIKE_m
+
+AR_LIKE_b - AR_m
+AR_LIKE_u - AR_m
+AR_LIKE_i - AR_m
+AR_LIKE_m - AR_m
+AR_LIKE_M - AR_m
+
+AR_M - AR_LIKE_b
+AR_M - AR_LIKE_u
+AR_M - AR_LIKE_i
+AR_M - AR_LIKE_m
+AR_M - AR_LIKE_M
+
+AR_LIKE_M - AR_M
+
+AR_O - AR_LIKE_b
+AR_O - AR_LIKE_u
+AR_O - AR_LIKE_i
+AR_O - AR_LIKE_f
+AR_O - AR_LIKE_c
+AR_O - AR_LIKE_O
+
+AR_LIKE_b - AR_O
+AR_LIKE_u - AR_O
+AR_LIKE_i - AR_O
+AR_LIKE_f - AR_O
+AR_LIKE_c - AR_O
+AR_LIKE_O - AR_O
+
+# Array floor division
+
+AR_b // AR_LIKE_b
+AR_b // AR_LIKE_u
+AR_b // AR_LIKE_i
+AR_b // AR_LIKE_f
+AR_b // AR_LIKE_O
+
+AR_LIKE_b // AR_b
+AR_LIKE_u // AR_b
+AR_LIKE_i // AR_b
+AR_LIKE_f // AR_b
+AR_LIKE_O // AR_b
+
+AR_u // AR_LIKE_b
+AR_u // AR_LIKE_u
+AR_u // AR_LIKE_i
+AR_u // AR_LIKE_f
+AR_u // AR_LIKE_O
+
+AR_LIKE_b // AR_u
+AR_LIKE_u // AR_u
+AR_LIKE_i // AR_u
+AR_LIKE_f // AR_u
+AR_LIKE_m // AR_u
+AR_LIKE_O // AR_u
+
+AR_i // AR_LIKE_b
+AR_i // AR_LIKE_u
+AR_i // AR_LIKE_i
+AR_i // AR_LIKE_f
+AR_i // AR_LIKE_O
+
+AR_LIKE_b // AR_i
+AR_LIKE_u // AR_i
+AR_LIKE_i // AR_i
+AR_LIKE_f // AR_i
+AR_LIKE_m // AR_i
+AR_LIKE_O // AR_i
+
+AR_f // AR_LIKE_b
+AR_f // AR_LIKE_u
+AR_f // AR_LIKE_i
+AR_f // AR_LIKE_f
+AR_f // AR_LIKE_O
+
+AR_LIKE_b // AR_f
+AR_LIKE_u // AR_f
+AR_LIKE_i // AR_f
+AR_LIKE_f // AR_f
+AR_LIKE_m // AR_f
+AR_LIKE_O // AR_f
+
+AR_m // AR_LIKE_u
+AR_m // AR_LIKE_i
+AR_m // AR_LIKE_f
+AR_m // AR_LIKE_m
+
+AR_LIKE_m // AR_m
+
+AR_O // AR_LIKE_b
+AR_O // AR_LIKE_u
+AR_O // AR_LIKE_i
+AR_O // AR_LIKE_f
+AR_O // AR_LIKE_O
+
+AR_LIKE_b // AR_O
+AR_LIKE_u // AR_O
+AR_LIKE_i // AR_O
+AR_LIKE_f // AR_O
+AR_LIKE_O // AR_O
+
+# Inplace multiplication
+
+AR_b *= AR_LIKE_b
+
+AR_u *= AR_LIKE_b
+AR_u *= AR_LIKE_u
+
+AR_i *= AR_LIKE_b
+AR_i *= AR_LIKE_u
+AR_i *= AR_LIKE_i
+
+AR_f *= AR_LIKE_b
+AR_f *= AR_LIKE_u
+AR_f *= AR_LIKE_i
+AR_f *= AR_LIKE_f
+
+AR_c *= AR_LIKE_b
+AR_c *= AR_LIKE_u
+AR_c *= AR_LIKE_i
+AR_c *= AR_LIKE_f
+AR_c *= AR_LIKE_c
+
+AR_m *= AR_LIKE_b
+AR_m *= AR_LIKE_u
+AR_m *= AR_LIKE_i
+AR_m *= AR_LIKE_f
+
+AR_O *= AR_LIKE_b
+AR_O *= AR_LIKE_u
+AR_O *= AR_LIKE_i
+AR_O *= AR_LIKE_f
+AR_O *= AR_LIKE_c
+AR_O *= AR_LIKE_O
+
+# Inplace power
+
+AR_u **= AR_LIKE_b
+AR_u **= AR_LIKE_u
+
+AR_i **= AR_LIKE_b
+AR_i **= AR_LIKE_u
+AR_i **= AR_LIKE_i
+
+AR_f **= AR_LIKE_b
+AR_f **= AR_LIKE_u
+AR_f **= AR_LIKE_i
+AR_f **= AR_LIKE_f
+
+AR_c **= AR_LIKE_b
+AR_c **= AR_LIKE_u
+AR_c **= AR_LIKE_i
+AR_c **= AR_LIKE_f
+AR_c **= AR_LIKE_c
+
+AR_O **= AR_LIKE_b
+AR_O **= AR_LIKE_u
+AR_O **= AR_LIKE_i
+AR_O **= AR_LIKE_f
+AR_O **= AR_LIKE_c
+AR_O **= AR_LIKE_O
# unary ops
@@ -34,7 +329,7 @@ AR.setflags(write=False)
-u8
-u4
-td
--AR
+-AR_f
+c16
+c8
@@ -45,7 +340,7 @@ AR.setflags(write=False)
+u8
+u4
+td
-+AR
++AR_f
abs(c16)
abs(c8)
@@ -57,7 +352,7 @@ abs(u8)
abs(u4)
abs(td)
abs(b_)
-abs(AR)
+abs(AR_f)
# Time structures
@@ -129,7 +424,7 @@ c16 + b
c16 + c
c16 + f
c16 + i
-c16 + AR
+c16 + AR_f
c16 + c16
f8 + c16
@@ -142,7 +437,7 @@ b + c16
c + c16
f + c16
i + c16
-AR + c16
+AR_f + c16
c8 + c16
c8 + f8
@@ -155,7 +450,7 @@ c8 + b
c8 + c
c8 + f
c8 + i
-c8 + AR
+c8 + AR_f
c16 + c8
f8 + c8
@@ -168,7 +463,7 @@ b + c8
c + c8
f + c8
i + c8
-AR + c8
+AR_f + c8
# Float
@@ -181,7 +476,7 @@ f8 + b
f8 + c
f8 + f
f8 + i
-f8 + AR
+f8 + AR_f
f8 + f8
i8 + f8
@@ -192,7 +487,7 @@ b + f8
c + f8
f + f8
i + f8
-AR + f8
+AR_f + f8
f4 + f8
f4 + i8
@@ -203,7 +498,7 @@ f4 + b
f4 + c
f4 + f
f4 + i
-f4 + AR
+f4 + AR_f
f8 + f4
i8 + f4
@@ -214,7 +509,7 @@ b + f4
c + f4
f + f4
i + f4
-AR + f4
+AR_f + f4
# Int
@@ -227,7 +522,7 @@ i8 + b
i8 + c
i8 + f
i8 + i
-i8 + AR
+i8 + AR_f
u8 + u8
u8 + i4
@@ -237,7 +532,7 @@ u8 + b
u8 + c
u8 + f
u8 + i
-u8 + AR
+u8 + AR_f
i8 + i8
u8 + i8
@@ -248,7 +543,7 @@ b + i8
c + i8
f + i8
i + i8
-AR + i8
+AR_f + i8
u8 + u8
i4 + u8
@@ -258,14 +553,14 @@ b + u8
c + u8
f + u8
i + u8
-AR + u8
+AR_f + u8
i4 + i8
i4 + i4
i4 + i
i4 + b_
i4 + b
-i4 + AR
+i4 + AR_f
u4 + i8
u4 + i4
@@ -274,14 +569,14 @@ u4 + u4
u4 + i
u4 + b_
u4 + b
-u4 + AR
+u4 + AR_f
i8 + i4
i4 + i4
i + i4
b_ + i4
b + i4
-AR + i4
+AR_f + i4
i8 + u4
i4 + u4
@@ -290,4 +585,4 @@ u4 + u4
b_ + u4
b + u4
i + u4
-AR + u4
+AR_f + u4
diff --git a/numpy/typing/tests/data/pass/array_constructors.py b/numpy/typing/tests/data/pass/array_constructors.py
index 63208f139..206f70a15 100644
--- a/numpy/typing/tests/data/pass/array_constructors.py
+++ b/numpy/typing/tests/data/pass/array_constructors.py
@@ -1,11 +1,20 @@
+import sys
from typing import List, Any
import numpy as np
+
class Index:
def __index__(self) -> int:
return 0
-class SubClass(np.ndarray): ...
+
+class SubClass(np.ndarray):
+ pass
+
+
+def func(i: int, j: int, **kwargs: Any) -> SubClass:
+ return B
+
i8 = np.int64(1)
@@ -14,8 +23,9 @@ B = A.view(SubClass).copy()
B_stack = np.array([[1], [1]]).view(SubClass)
C = [1]
-def func(i: int, j: int, **kwargs: Any) -> SubClass:
- return B
+if sys.version_info >= (3, 8):
+ np.ndarray(Index())
+ np.ndarray([Index()])
np.array(1, dtype=float)
np.array(1, copy=False)
diff --git a/numpy/typing/tests/data/pass/array_like.py b/numpy/typing/tests/data/pass/array_like.py
index f85724267..e16d196b6 100644
--- a/numpy/typing/tests/data/pass/array_like.py
+++ b/numpy/typing/tests/data/pass/array_like.py
@@ -1,7 +1,7 @@
from typing import Any, List, Optional
import numpy as np
-from numpy.typing import ArrayLike, DTypeLike, _SupportsArray
+from numpy.typing import ArrayLike, _SupportsArray
x1: ArrayLike = True
x2: ArrayLike = 5
@@ -18,20 +18,20 @@ x12: ArrayLike = memoryview(b'foo')
class A:
- def __array__(self, dtype: DTypeLike = None) -> np.ndarray:
+ def __array__(self, dtype: Optional[np.dtype] = None) -> np.ndarray:
return np.array([1, 2, 3])
x13: ArrayLike = A()
scalar: _SupportsArray = np.int64(1)
-scalar.__array__(np.float64)
+scalar.__array__()
array: _SupportsArray = np.array(1)
-array.__array__(np.float64)
+array.__array__()
a: _SupportsArray = A()
-a.__array__(np.int64)
-a.__array__(dtype=np.int64)
+a.__array__()
+a.__array__()
# Escape hatch for when you mean to make something like an object
# array.
diff --git a/numpy/typing/tests/data/pass/arrayprint.py b/numpy/typing/tests/data/pass/arrayprint.py
new file mode 100644
index 000000000..6c704c755
--- /dev/null
+++ b/numpy/typing/tests/data/pass/arrayprint.py
@@ -0,0 +1,37 @@
+import numpy as np
+
+AR = np.arange(10)
+AR.setflags(write=False)
+
+with np.printoptions():
+ np.set_printoptions(
+ precision=1,
+ threshold=2,
+ edgeitems=3,
+ linewidth=4,
+ suppress=False,
+ nanstr="Bob",
+ infstr="Bill",
+ formatter={},
+ sign="+",
+ floatmode="unique",
+ )
+ np.get_printoptions()
+ str(AR)
+
+ np.array2string(
+ AR,
+ max_line_width=5,
+ precision=2,
+ suppress_small=True,
+ separator=";",
+ prefix="test",
+ threshold=5,
+ floatmode="fixed",
+ suffix="?",
+ legacy="1.13",
+ )
+ np.format_float_scientific(1, precision=5)
+ np.format_float_positional(1, trim="k")
+ np.array_repr(AR)
+ np.array_str(AR)
diff --git a/numpy/typing/tests/data/pass/arrayterator.py b/numpy/typing/tests/data/pass/arrayterator.py
new file mode 100644
index 000000000..572be5e2f
--- /dev/null
+++ b/numpy/typing/tests/data/pass/arrayterator.py
@@ -0,0 +1,27 @@
+
+from __future__ import annotations
+
+from typing import Any
+import numpy as np
+
+AR_i8: np.ndarray[Any, np.dtype[np.int_]] = np.arange(10)
+ar_iter = np.lib.Arrayterator(AR_i8)
+
+ar_iter.var
+ar_iter.buf_size
+ar_iter.start
+ar_iter.stop
+ar_iter.step
+ar_iter.shape
+ar_iter.flat
+
+ar_iter.__array__()
+
+for i in ar_iter:
+ pass
+
+ar_iter[0]
+ar_iter[...]
+ar_iter[:]
+ar_iter[0, 0, 0]
+ar_iter[..., 0, :]
diff --git a/numpy/typing/tests/data/pass/comparisons.py b/numpy/typing/tests/data/pass/comparisons.py
index b298117a6..ce41de435 100644
--- a/numpy/typing/tests/data/pass/comparisons.py
+++ b/numpy/typing/tests/data/pass/comparisons.py
@@ -1,3 +1,6 @@
+from __future__ import annotations
+
+from typing import Any
import numpy as np
c16 = np.complex128()
@@ -20,11 +23,62 @@ c = complex()
f = float()
i = int()
-AR = np.array([0], dtype=np.int64)
-AR.setflags(write=False)
-
SEQ = (0, 1, 2, 3, 4)
+AR_b: np.ndarray[Any, np.dtype[np.bool_]] = np.array([True])
+AR_u: np.ndarray[Any, np.dtype[np.uint32]] = np.array([1], dtype=np.uint32)
+AR_i: np.ndarray[Any, np.dtype[np.int_]] = np.array([1])
+AR_f: np.ndarray[Any, np.dtype[np.float_]] = np.array([1.0])
+AR_c: np.ndarray[Any, np.dtype[np.complex_]] = np.array([1.0j])
+AR_m: np.ndarray[Any, np.dtype[np.timedelta64]] = np.array([np.timedelta64("1")])
+AR_M: np.ndarray[Any, np.dtype[np.datetime64]] = np.array([np.datetime64("1")])
+AR_O: np.ndarray[Any, np.dtype[np.object_]] = np.array([1], dtype=object)
+
+# Arrays
+
+AR_b > AR_b
+AR_b > AR_u
+AR_b > AR_i
+AR_b > AR_f
+AR_b > AR_c
+
+AR_u > AR_b
+AR_u > AR_u
+AR_u > AR_i
+AR_u > AR_f
+AR_u > AR_c
+
+AR_i > AR_b
+AR_i > AR_u
+AR_i > AR_i
+AR_i > AR_f
+AR_i > AR_c
+
+AR_f > AR_b
+AR_f > AR_u
+AR_f > AR_i
+AR_f > AR_f
+AR_f > AR_c
+
+AR_c > AR_b
+AR_c > AR_u
+AR_c > AR_i
+AR_c > AR_f
+AR_c > AR_c
+
+AR_m > AR_b
+AR_m > AR_u
+AR_m > AR_i
+AR_b > AR_m
+AR_u > AR_m
+AR_i > AR_m
+
+AR_M > AR_M
+
+AR_O > AR_O
+1 > AR_O
+AR_O > 1
+
# Time structures
dt > dt
@@ -33,7 +87,7 @@ td > td
td > i
td > i4
td > i8
-td > AR
+td > AR_i
td > SEQ
# boolean
@@ -51,7 +105,7 @@ b_ > f4
b_ > c
b_ > c16
b_ > c8
-b_ > AR
+b_ > AR_i
b_ > SEQ
# Complex
@@ -67,7 +121,7 @@ c16 > b
c16 > c
c16 > f
c16 > i
-c16 > AR
+c16 > AR_i
c16 > SEQ
c16 > c16
@@ -81,7 +135,7 @@ b > c16
c > c16
f > c16
i > c16
-AR > c16
+AR_i > c16
SEQ > c16
c8 > c16
@@ -95,7 +149,7 @@ c8 > b
c8 > c
c8 > f
c8 > i
-c8 > AR
+c8 > AR_i
c8 > SEQ
c16 > c8
@@ -109,7 +163,7 @@ b > c8
c > c8
f > c8
i > c8
-AR > c8
+AR_i > c8
SEQ > c8
# Float
@@ -123,7 +177,7 @@ f8 > b
f8 > c
f8 > f
f8 > i
-f8 > AR
+f8 > AR_i
f8 > SEQ
f8 > f8
@@ -135,7 +189,7 @@ b > f8
c > f8
f > f8
i > f8
-AR > f8
+AR_i > f8
SEQ > f8
f4 > f8
@@ -147,7 +201,7 @@ f4 > b
f4 > c
f4 > f
f4 > i
-f4 > AR
+f4 > AR_i
f4 > SEQ
f8 > f4
@@ -159,7 +213,7 @@ b > f4
c > f4
f > f4
i > f4
-AR > f4
+AR_i > f4
SEQ > f4
# Int
@@ -173,7 +227,7 @@ i8 > b
i8 > c
i8 > f
i8 > i
-i8 > AR
+i8 > AR_i
i8 > SEQ
u8 > u8
@@ -184,7 +238,7 @@ u8 > b
u8 > c
u8 > f
u8 > i
-u8 > AR
+u8 > AR_i
u8 > SEQ
i8 > i8
@@ -196,7 +250,7 @@ b > i8
c > i8
f > i8
i > i8
-AR > i8
+AR_i > i8
SEQ > i8
u8 > u8
@@ -207,7 +261,7 @@ b > u8
c > u8
f > u8
i > u8
-AR > u8
+AR_i > u8
SEQ > u8
i4 > i8
@@ -215,7 +269,7 @@ i4 > i4
i4 > i
i4 > b_
i4 > b
-i4 > AR
+i4 > AR_i
i4 > SEQ
u4 > i8
@@ -225,7 +279,7 @@ u4 > u4
u4 > i
u4 > b_
u4 > b
-u4 > AR
+u4 > AR_i
u4 > SEQ
i8 > i4
@@ -233,7 +287,7 @@ i4 > i4
i > i4
b_ > i4
b > i4
-AR > i4
+AR_i > i4
SEQ > i4
i8 > u4
@@ -243,5 +297,5 @@ u4 > u4
b_ > u4
b > u4
i > u4
-AR > u4
+AR_i > u4
SEQ > u4
diff --git a/numpy/typing/tests/data/pass/dtype.py b/numpy/typing/tests/data/pass/dtype.py
index cbae8c078..e849cfdd4 100644
--- a/numpy/typing/tests/data/pass/dtype.py
+++ b/numpy/typing/tests/data/pass/dtype.py
@@ -1,5 +1,8 @@
import numpy as np
+dtype_obj = np.dtype(np.str_)
+void_dtype_obj = np.dtype([("f0", np.float64), ("f1", np.float32)])
+
np.dtype(dtype=np.int64)
np.dtype(int)
np.dtype("int")
@@ -29,7 +32,26 @@ np.dtype((np.float_, float))
class Test:
- dtype = float
+ dtype = np.dtype(float)
np.dtype(Test())
+
+# Methods and attributes
+dtype_obj.base
+dtype_obj.subdtype
+dtype_obj.newbyteorder()
+dtype_obj.type
+dtype_obj.name
+dtype_obj.names
+
+dtype_obj * 0
+dtype_obj * 2
+
+0 * dtype_obj
+2 * dtype_obj
+
+void_dtype_obj["f0"]
+void_dtype_obj[0]
+void_dtype_obj[["f0", "f1"]]
+void_dtype_obj[["f0"]]
diff --git a/numpy/typing/tests/data/pass/einsumfunc.py b/numpy/typing/tests/data/pass/einsumfunc.py
new file mode 100644
index 000000000..a2a39fb1c
--- /dev/null
+++ b/numpy/typing/tests/data/pass/einsumfunc.py
@@ -0,0 +1,36 @@
+from __future__ import annotations
+
+from typing import List, Any
+
+import numpy as np
+
+AR_LIKE_b = [True, True, True]
+AR_LIKE_u = [np.uint32(1), np.uint32(2), np.uint32(3)]
+AR_LIKE_i = [1, 2, 3]
+AR_LIKE_f = [1.0, 2.0, 3.0]
+AR_LIKE_c = [1j, 2j, 3j]
+AR_LIKE_U = ["1", "2", "3"]
+
+OUT_f: np.ndarray[Any, np.dtype[np.float64]] = np.empty(3, dtype=np.float64)
+OUT_c: np.ndarray[Any, np.dtype[np.complex128]] = np.empty(3, dtype=np.complex128)
+
+np.einsum("i,i->i", AR_LIKE_b, AR_LIKE_b)
+np.einsum("i,i->i", AR_LIKE_u, AR_LIKE_u)
+np.einsum("i,i->i", AR_LIKE_i, AR_LIKE_i)
+np.einsum("i,i->i", AR_LIKE_f, AR_LIKE_f)
+np.einsum("i,i->i", AR_LIKE_c, AR_LIKE_c)
+np.einsum("i,i->i", AR_LIKE_b, AR_LIKE_i)
+np.einsum("i,i,i,i->i", AR_LIKE_b, AR_LIKE_u, AR_LIKE_i, AR_LIKE_c)
+
+np.einsum("i,i->i", AR_LIKE_f, AR_LIKE_f, dtype="c16")
+np.einsum("i,i->i", AR_LIKE_U, AR_LIKE_U, dtype=bool, casting="unsafe")
+np.einsum("i,i->i", AR_LIKE_f, AR_LIKE_f, out=OUT_c)
+np.einsum("i,i->i", AR_LIKE_U, AR_LIKE_U, dtype=int, casting="unsafe", out=OUT_f)
+
+np.einsum_path("i,i->i", AR_LIKE_b, AR_LIKE_b)
+np.einsum_path("i,i->i", AR_LIKE_u, AR_LIKE_u)
+np.einsum_path("i,i->i", AR_LIKE_i, AR_LIKE_i)
+np.einsum_path("i,i->i", AR_LIKE_f, AR_LIKE_f)
+np.einsum_path("i,i->i", AR_LIKE_c, AR_LIKE_c)
+np.einsum_path("i,i->i", AR_LIKE_b, AR_LIKE_i)
+np.einsum_path("i,i,i,i->i", AR_LIKE_b, AR_LIKE_u, AR_LIKE_i, AR_LIKE_c)
diff --git a/numpy/typing/tests/data/pass/flatiter.py b/numpy/typing/tests/data/pass/flatiter.py
index c0219eb2b..63c839af4 100644
--- a/numpy/typing/tests/data/pass/flatiter.py
+++ b/numpy/typing/tests/data/pass/flatiter.py
@@ -12,3 +12,5 @@ a[0]
a[[0, 1, 2]]
a[...]
a[:]
+a.__array__()
+a.__array__(np.dtype(np.float64))
diff --git a/numpy/typing/tests/data/pass/index_tricks.py b/numpy/typing/tests/data/pass/index_tricks.py
new file mode 100644
index 000000000..4c4c11959
--- /dev/null
+++ b/numpy/typing/tests/data/pass/index_tricks.py
@@ -0,0 +1,64 @@
+from __future__ import annotations
+from typing import Any
+import numpy as np
+
+AR_LIKE_b = [[True, True], [True, True]]
+AR_LIKE_i = [[1, 2], [3, 4]]
+AR_LIKE_f = [[1.0, 2.0], [3.0, 4.0]]
+AR_LIKE_U = [["1", "2"], ["3", "4"]]
+
+AR_i8: np.ndarray[Any, np.dtype[np.int64]] = np.array(AR_LIKE_i, dtype=np.int64)
+
+np.ndenumerate(AR_i8)
+np.ndenumerate(AR_LIKE_f)
+np.ndenumerate(AR_LIKE_U)
+
+np.ndenumerate(AR_i8).iter
+np.ndenumerate(AR_LIKE_f).iter
+np.ndenumerate(AR_LIKE_U).iter
+
+next(np.ndenumerate(AR_i8))
+next(np.ndenumerate(AR_LIKE_f))
+next(np.ndenumerate(AR_LIKE_U))
+
+iter(np.ndenumerate(AR_i8))
+iter(np.ndenumerate(AR_LIKE_f))
+iter(np.ndenumerate(AR_LIKE_U))
+
+iter(np.ndindex(1, 2, 3))
+next(np.ndindex(1, 2, 3))
+
+np.unravel_index([22, 41, 37], (7, 6))
+np.unravel_index([31, 41, 13], (7, 6), order='F')
+np.unravel_index(1621, (6, 7, 8, 9))
+
+np.ravel_multi_index(AR_LIKE_i, (7, 6))
+np.ravel_multi_index(AR_LIKE_i, (7, 6), order='F')
+np.ravel_multi_index(AR_LIKE_i, (4, 6), mode='clip')
+np.ravel_multi_index(AR_LIKE_i, (4, 4), mode=('clip', 'wrap'))
+np.ravel_multi_index((3, 1, 4, 1), (6, 7, 8, 9))
+
+np.mgrid[1:1:2]
+np.mgrid[1:1:2, None:10]
+
+np.ogrid[1:1:2]
+np.ogrid[1:1:2, None:10]
+
+np.index_exp[0:1]
+np.index_exp[0:1, None:3]
+np.index_exp[0, 0:1, ..., [0, 1, 3]]
+
+np.s_[0:1]
+np.s_[0:1, None:3]
+np.s_[0, 0:1, ..., [0, 1, 3]]
+
+np.ix_(AR_LIKE_b[0])
+np.ix_(AR_LIKE_i[0], AR_LIKE_f[0])
+np.ix_(AR_i8[0])
+
+np.fill_diagonal(AR_i8, 5)
+
+np.diag_indices(4)
+np.diag_indices(2, 3)
+
+np.diag_indices_from(AR_i8)
diff --git a/numpy/typing/tests/data/pass/lib_utils.py b/numpy/typing/tests/data/pass/lib_utils.py
new file mode 100644
index 000000000..0a15dad22
--- /dev/null
+++ b/numpy/typing/tests/data/pass/lib_utils.py
@@ -0,0 +1,26 @@
+from __future__ import annotations
+
+from io import StringIO
+from typing import Any
+
+import numpy as np
+
+FILE = StringIO()
+AR = np.arange(10, dtype=np.float64)
+
+def func(a: int) -> bool: ...
+
+np.deprecate(func)
+np.deprecate()
+
+np.deprecate_with_doc("test")
+np.deprecate_with_doc(None)
+
+np.byte_bounds(AR)
+np.byte_bounds(np.float64())
+
+np.info(1, output=FILE)
+
+np.source(np.interp, output=FILE)
+
+np.lookfor("binary representation", output=FILE)
diff --git a/numpy/typing/tests/data/pass/lib_version.py b/numpy/typing/tests/data/pass/lib_version.py
new file mode 100644
index 000000000..f3825eca5
--- /dev/null
+++ b/numpy/typing/tests/data/pass/lib_version.py
@@ -0,0 +1,18 @@
+from numpy.lib import NumpyVersion
+
+version = NumpyVersion("1.8.0")
+
+version.vstring
+version.version
+version.major
+version.minor
+version.bugfix
+version.pre_release
+version.is_devversion
+
+version == version
+version != version
+version < "1.8.0"
+version <= version
+version > version
+version >= "1.8.0"
diff --git a/numpy/typing/tests/data/pass/modules.py b/numpy/typing/tests/data/pass/modules.py
new file mode 100644
index 000000000..9261874d5
--- /dev/null
+++ b/numpy/typing/tests/data/pass/modules.py
@@ -0,0 +1,43 @@
+import numpy as np
+from numpy import f2py
+
+np.char
+np.ctypeslib
+np.emath
+np.fft
+np.lib
+np.linalg
+np.ma
+np.matrixlib
+np.polynomial
+np.random
+np.rec
+np.testing
+np.version
+
+np.lib.format
+np.lib.mixins
+np.lib.scimath
+np.lib.stride_tricks
+np.ma.extras
+np.polynomial.chebyshev
+np.polynomial.hermite
+np.polynomial.hermite_e
+np.polynomial.laguerre
+np.polynomial.legendre
+np.polynomial.polynomial
+
+np.__path__
+np.__version__
+np.__git_version__
+
+np.__all__
+np.char.__all__
+np.ctypeslib.__all__
+np.emath.__all__
+np.lib.__all__
+np.ma.__all__
+np.random.__all__
+np.rec.__all__
+np.testing.__all__
+f2py.__all__
diff --git a/numpy/typing/tests/data/pass/multiarray.py b/numpy/typing/tests/data/pass/multiarray.py
new file mode 100644
index 000000000..e5d33c673
--- /dev/null
+++ b/numpy/typing/tests/data/pass/multiarray.py
@@ -0,0 +1,77 @@
+from typing import Any
+import numpy as np
+import numpy.typing as npt
+
+AR_f8: npt.NDArray[np.float64] = np.array([1.0])
+AR_i4 = np.array([1], dtype=np.int32)
+AR_u1 = np.array([1], dtype=np.uint8)
+
+AR_LIKE_f = [1.5]
+AR_LIKE_i = [1]
+
+b_f8 = np.broadcast(AR_f8)
+b_i4_f8_f8 = np.broadcast(AR_i4, AR_f8, AR_f8)
+
+next(b_f8)
+b_f8.reset()
+b_f8.index
+b_f8.iters
+b_f8.nd
+b_f8.ndim
+b_f8.numiter
+b_f8.shape
+b_f8.size
+
+next(b_i4_f8_f8)
+b_i4_f8_f8.reset()
+b_i4_f8_f8.ndim
+b_i4_f8_f8.index
+b_i4_f8_f8.iters
+b_i4_f8_f8.nd
+b_i4_f8_f8.numiter
+b_i4_f8_f8.shape
+b_i4_f8_f8.size
+
+np.inner(AR_f8, AR_i4)
+
+np.where([True, True, False])
+np.where([True, True, False], 1, 0)
+
+np.lexsort([0, 1, 2])
+
+np.can_cast(np.dtype("i8"), int)
+np.can_cast(AR_f8, "f8")
+np.can_cast(AR_f8, np.complex128, casting="unsafe")
+
+np.min_scalar_type([1])
+np.min_scalar_type(AR_f8)
+
+np.result_type(int, AR_i4)
+np.result_type(AR_f8, AR_u1)
+np.result_type(AR_f8, np.complex128)
+
+np.dot(AR_LIKE_f, AR_i4)
+np.dot(AR_u1, 1)
+np.dot(1.5j, 1)
+np.dot(AR_u1, 1, out=AR_f8)
+
+np.vdot(AR_LIKE_f, AR_i4)
+np.vdot(AR_u1, 1)
+np.vdot(1.5j, 1)
+
+np.bincount(AR_i4)
+
+np.copyto(AR_f8, [1.6])
+
+np.putmask(AR_f8, [True], 1.5)
+
+np.packbits(AR_i4)
+np.packbits(AR_u1)
+
+np.unpackbits(AR_u1)
+
+np.shares_memory(1, 2)
+np.shares_memory(AR_f8, AR_f8, max_work=1)
+
+np.may_share_memory(1, 2)
+np.may_share_memory(AR_f8, AR_f8, max_work=1)
diff --git a/numpy/typing/tests/data/pass/ndarray_misc.py b/numpy/typing/tests/data/pass/ndarray_misc.py
index 6c6f5d50b..62024603c 100644
--- a/numpy/typing/tests/data/pass/ndarray_misc.py
+++ b/numpy/typing/tests/data/pass/ndarray_misc.py
@@ -6,17 +6,21 @@ function-based counterpart in `../from_numeric.py`.
"""
-from typing import cast
+from __future__ import annotations
+
+import operator
+from typing import cast, Any
+
import numpy as np
class SubClass(np.ndarray): ...
i4 = np.int32(1)
-A = np.array([[1]], dtype=np.int32)
+A: np.ndarray[Any, np.dtype[np.int32]] = np.array([[1]], dtype=np.int32)
B0 = np.empty((), dtype=np.int32).view(SubClass)
B1 = np.empty((1,), dtype=np.int32).view(SubClass)
B2 = np.empty((1, 1), dtype=np.int32).view(SubClass)
-C = np.array([0, 1, 2], dtype=np.int32)
+C: np.ndarray[Any, np.dtype[np.int32]] = np.array([0, 1, 2], dtype=np.int32)
D = np.empty(3).view(SubClass)
i4.all()
@@ -157,3 +161,25 @@ A.trace(out=B0)
void = cast(np.void, np.array(1, dtype=[("f", np.float64)]).take(0))
void.setfield(10, np.float64)
+
+A.item(0)
+C.item(0)
+
+A.ravel()
+C.ravel()
+
+A.flatten()
+C.flatten()
+
+A.reshape(1)
+C.reshape(3)
+
+int(np.array(1.0, dtype=np.float64))
+int(np.array("1", dtype=np.str_))
+
+float(np.array(1.0, dtype=np.float64))
+float(np.array("1", dtype=np.str_))
+
+complex(np.array(1.0, dtype=np.float64))
+
+operator.index(np.array(1, dtype=np.int64))
diff --git a/numpy/typing/tests/data/pass/numerictypes.py b/numpy/typing/tests/data/pass/numerictypes.py
index 4f205cabc..5af0d171c 100644
--- a/numpy/typing/tests/data/pass/numerictypes.py
+++ b/numpy/typing/tests/data/pass/numerictypes.py
@@ -27,3 +27,21 @@ np.find_common_type([], [np.int64, np.float32, complex])
np.find_common_type((), (np.int64, np.float32, complex))
np.find_common_type([np.int64, np.float32], [])
np.find_common_type([np.float32], [np.int64, np.float64])
+
+np.cast[int]
+np.cast["i8"]
+np.cast[np.int64]
+
+np.nbytes[int]
+np.nbytes["i8"]
+np.nbytes[np.int64]
+
+np.ScalarType
+np.ScalarType[0]
+np.ScalarType[4]
+np.ScalarType[9]
+np.ScalarType[11]
+
+np.typecodes["Character"]
+np.typecodes["Complex"]
+np.typecodes["All"]
diff --git a/numpy/typing/tests/data/pass/random.py b/numpy/typing/tests/data/pass/random.py
new file mode 100644
index 000000000..05bd62112
--- /dev/null
+++ b/numpy/typing/tests/data/pass/random.py
@@ -0,0 +1,1497 @@
+from __future__ import annotations
+
+from typing import Any, List, Dict
+
+import numpy as np
+
+SEED_NONE = None
+SEED_INT = 4579435749574957634658964293569
+SEED_ARR: np.ndarray[Any, np.dtype[np.int64]] = np.array([1, 2, 3, 4], dtype=np.int64)
+SEED_ARRLIKE: List[int] = [1, 2, 3, 4]
+SEED_SEED_SEQ: np.random.SeedSequence = np.random.SeedSequence(0)
+SEED_MT19937: np.random.MT19937 = np.random.MT19937(0)
+SEED_PCG64: np.random.PCG64 = np.random.PCG64(0)
+SEED_PHILOX: np.random.Philox = np.random.Philox(0)
+SEED_SFC64: np.random.SFC64 = np.random.SFC64(0)
+
+# default rng
+np.random.default_rng()
+np.random.default_rng(SEED_NONE)
+np.random.default_rng(SEED_INT)
+np.random.default_rng(SEED_ARR)
+np.random.default_rng(SEED_ARRLIKE)
+np.random.default_rng(SEED_SEED_SEQ)
+np.random.default_rng(SEED_MT19937)
+np.random.default_rng(SEED_PCG64)
+np.random.default_rng(SEED_PHILOX)
+np.random.default_rng(SEED_SFC64)
+
+# Seed Sequence
+np.random.SeedSequence(SEED_NONE)
+np.random.SeedSequence(SEED_INT)
+np.random.SeedSequence(SEED_ARR)
+np.random.SeedSequence(SEED_ARRLIKE)
+
+# Bit Generators
+np.random.MT19937(SEED_NONE)
+np.random.MT19937(SEED_INT)
+np.random.MT19937(SEED_ARR)
+np.random.MT19937(SEED_ARRLIKE)
+np.random.MT19937(SEED_SEED_SEQ)
+
+np.random.PCG64(SEED_NONE)
+np.random.PCG64(SEED_INT)
+np.random.PCG64(SEED_ARR)
+np.random.PCG64(SEED_ARRLIKE)
+np.random.PCG64(SEED_SEED_SEQ)
+
+np.random.Philox(SEED_NONE)
+np.random.Philox(SEED_INT)
+np.random.Philox(SEED_ARR)
+np.random.Philox(SEED_ARRLIKE)
+np.random.Philox(SEED_SEED_SEQ)
+
+np.random.SFC64(SEED_NONE)
+np.random.SFC64(SEED_INT)
+np.random.SFC64(SEED_ARR)
+np.random.SFC64(SEED_ARRLIKE)
+np.random.SFC64(SEED_SEED_SEQ)
+
+seed_seq: np.random.bit_generator.SeedSequence = np.random.SeedSequence(SEED_NONE)
+seed_seq.spawn(10)
+seed_seq.generate_state(3)
+seed_seq.generate_state(3, "u4")
+seed_seq.generate_state(3, "uint32")
+seed_seq.generate_state(3, "u8")
+seed_seq.generate_state(3, "uint64")
+seed_seq.generate_state(3, np.uint32)
+seed_seq.generate_state(3, np.uint64)
+
+
+def_gen: np.random.Generator = np.random.default_rng()
+
+D_arr_0p1: np.ndarray[Any, np.dtype[np.float64]] = np.array([0.1])
+D_arr_0p5: np.ndarray[Any, np.dtype[np.float64]] = np.array([0.5])
+D_arr_0p9: np.ndarray[Any, np.dtype[np.float64]] = np.array([0.9])
+D_arr_1p5: np.ndarray[Any, np.dtype[np.float64]] = np.array([1.5])
+I_arr_10: np.ndarray[Any, np.dtype[np.int_]] = np.array([10], dtype=np.int_)
+I_arr_20: np.ndarray[Any, np.dtype[np.int_]] = np.array([20], dtype=np.int_)
+D_arr_like_0p1: List[float] = [0.1]
+D_arr_like_0p5: List[float] = [0.5]
+D_arr_like_0p9: List[float] = [0.9]
+D_arr_like_1p5: List[float] = [1.5]
+I_arr_like_10: List[int] = [10]
+I_arr_like_20: List[int] = [20]
+D_2D_like: List[List[float]] = [[1, 2], [2, 3], [3, 4], [4, 5.1]]
+D_2D: np.ndarray[Any, np.dtype[np.float64]] = np.array(D_2D_like)
+
+S_out: np.ndarray[Any, np.dtype[np.float32]] = np.empty(1, dtype=np.float32)
+D_out: np.ndarray[Any, np.dtype[np.float64]] = np.empty(1)
+
+def_gen.standard_normal()
+def_gen.standard_normal(dtype=np.float32)
+def_gen.standard_normal(dtype="float32")
+def_gen.standard_normal(dtype="double")
+def_gen.standard_normal(dtype=np.float64)
+def_gen.standard_normal(size=None)
+def_gen.standard_normal(size=1)
+def_gen.standard_normal(size=1, dtype=np.float32)
+def_gen.standard_normal(size=1, dtype="f4")
+def_gen.standard_normal(size=1, dtype="float32", out=S_out)
+def_gen.standard_normal(dtype=np.float32, out=S_out)
+def_gen.standard_normal(size=1, dtype=np.float64)
+def_gen.standard_normal(size=1, dtype="float64")
+def_gen.standard_normal(size=1, dtype="f8")
+def_gen.standard_normal(out=D_out)
+def_gen.standard_normal(size=1, dtype="float64")
+def_gen.standard_normal(size=1, dtype="float64", out=D_out)
+
+def_gen.random()
+def_gen.random(dtype=np.float32)
+def_gen.random(dtype="float32")
+def_gen.random(dtype="double")
+def_gen.random(dtype=np.float64)
+def_gen.random(size=None)
+def_gen.random(size=1)
+def_gen.random(size=1, dtype=np.float32)
+def_gen.random(size=1, dtype="f4")
+def_gen.random(size=1, dtype="float32", out=S_out)
+def_gen.random(dtype=np.float32, out=S_out)
+def_gen.random(size=1, dtype=np.float64)
+def_gen.random(size=1, dtype="float64")
+def_gen.random(size=1, dtype="f8")
+def_gen.random(out=D_out)
+def_gen.random(size=1, dtype="float64")
+def_gen.random(size=1, dtype="float64", out=D_out)
+
+def_gen.standard_cauchy()
+def_gen.standard_cauchy(size=None)
+def_gen.standard_cauchy(size=1)
+
+def_gen.standard_exponential()
+def_gen.standard_exponential(method="inv")
+def_gen.standard_exponential(dtype=np.float32)
+def_gen.standard_exponential(dtype="float32")
+def_gen.standard_exponential(dtype="double")
+def_gen.standard_exponential(dtype=np.float64)
+def_gen.standard_exponential(size=None)
+def_gen.standard_exponential(size=None, method="inv")
+def_gen.standard_exponential(size=1, method="inv")
+def_gen.standard_exponential(size=1, dtype=np.float32)
+def_gen.standard_exponential(size=1, dtype="f4", method="inv")
+def_gen.standard_exponential(size=1, dtype="float32", out=S_out)
+def_gen.standard_exponential(dtype=np.float32, out=S_out)
+def_gen.standard_exponential(size=1, dtype=np.float64, method="inv")
+def_gen.standard_exponential(size=1, dtype="float64")
+def_gen.standard_exponential(size=1, dtype="f8")
+def_gen.standard_exponential(out=D_out)
+def_gen.standard_exponential(size=1, dtype="float64")
+def_gen.standard_exponential(size=1, dtype="float64", out=D_out)
+
+def_gen.zipf(1.5)
+def_gen.zipf(1.5, size=None)
+def_gen.zipf(1.5, size=1)
+def_gen.zipf(D_arr_1p5)
+def_gen.zipf(D_arr_1p5, size=1)
+def_gen.zipf(D_arr_like_1p5)
+def_gen.zipf(D_arr_like_1p5, size=1)
+
+def_gen.weibull(0.5)
+def_gen.weibull(0.5, size=None)
+def_gen.weibull(0.5, size=1)
+def_gen.weibull(D_arr_0p5)
+def_gen.weibull(D_arr_0p5, size=1)
+def_gen.weibull(D_arr_like_0p5)
+def_gen.weibull(D_arr_like_0p5, size=1)
+
+def_gen.standard_t(0.5)
+def_gen.standard_t(0.5, size=None)
+def_gen.standard_t(0.5, size=1)
+def_gen.standard_t(D_arr_0p5)
+def_gen.standard_t(D_arr_0p5, size=1)
+def_gen.standard_t(D_arr_like_0p5)
+def_gen.standard_t(D_arr_like_0p5, size=1)
+
+def_gen.poisson(0.5)
+def_gen.poisson(0.5, size=None)
+def_gen.poisson(0.5, size=1)
+def_gen.poisson(D_arr_0p5)
+def_gen.poisson(D_arr_0p5, size=1)
+def_gen.poisson(D_arr_like_0p5)
+def_gen.poisson(D_arr_like_0p5, size=1)
+
+def_gen.power(0.5)
+def_gen.power(0.5, size=None)
+def_gen.power(0.5, size=1)
+def_gen.power(D_arr_0p5)
+def_gen.power(D_arr_0p5, size=1)
+def_gen.power(D_arr_like_0p5)
+def_gen.power(D_arr_like_0p5, size=1)
+
+def_gen.pareto(0.5)
+def_gen.pareto(0.5, size=None)
+def_gen.pareto(0.5, size=1)
+def_gen.pareto(D_arr_0p5)
+def_gen.pareto(D_arr_0p5, size=1)
+def_gen.pareto(D_arr_like_0p5)
+def_gen.pareto(D_arr_like_0p5, size=1)
+
+def_gen.chisquare(0.5)
+def_gen.chisquare(0.5, size=None)
+def_gen.chisquare(0.5, size=1)
+def_gen.chisquare(D_arr_0p5)
+def_gen.chisquare(D_arr_0p5, size=1)
+def_gen.chisquare(D_arr_like_0p5)
+def_gen.chisquare(D_arr_like_0p5, size=1)
+
+def_gen.exponential(0.5)
+def_gen.exponential(0.5, size=None)
+def_gen.exponential(0.5, size=1)
+def_gen.exponential(D_arr_0p5)
+def_gen.exponential(D_arr_0p5, size=1)
+def_gen.exponential(D_arr_like_0p5)
+def_gen.exponential(D_arr_like_0p5, size=1)
+
+def_gen.geometric(0.5)
+def_gen.geometric(0.5, size=None)
+def_gen.geometric(0.5, size=1)
+def_gen.geometric(D_arr_0p5)
+def_gen.geometric(D_arr_0p5, size=1)
+def_gen.geometric(D_arr_like_0p5)
+def_gen.geometric(D_arr_like_0p5, size=1)
+
+def_gen.logseries(0.5)
+def_gen.logseries(0.5, size=None)
+def_gen.logseries(0.5, size=1)
+def_gen.logseries(D_arr_0p5)
+def_gen.logseries(D_arr_0p5, size=1)
+def_gen.logseries(D_arr_like_0p5)
+def_gen.logseries(D_arr_like_0p5, size=1)
+
+def_gen.rayleigh(0.5)
+def_gen.rayleigh(0.5, size=None)
+def_gen.rayleigh(0.5, size=1)
+def_gen.rayleigh(D_arr_0p5)
+def_gen.rayleigh(D_arr_0p5, size=1)
+def_gen.rayleigh(D_arr_like_0p5)
+def_gen.rayleigh(D_arr_like_0p5, size=1)
+
+def_gen.standard_gamma(0.5)
+def_gen.standard_gamma(0.5, size=None)
+def_gen.standard_gamma(0.5, dtype="float32")
+def_gen.standard_gamma(0.5, size=None, dtype="float32")
+def_gen.standard_gamma(0.5, size=1)
+def_gen.standard_gamma(D_arr_0p5)
+def_gen.standard_gamma(D_arr_0p5, dtype="f4")
+def_gen.standard_gamma(0.5, size=1, dtype="float32", out=S_out)
+def_gen.standard_gamma(D_arr_0p5, dtype=np.float32, out=S_out)
+def_gen.standard_gamma(D_arr_0p5, size=1)
+def_gen.standard_gamma(D_arr_like_0p5)
+def_gen.standard_gamma(D_arr_like_0p5, size=1)
+def_gen.standard_gamma(0.5, out=D_out)
+def_gen.standard_gamma(D_arr_like_0p5, out=D_out)
+def_gen.standard_gamma(D_arr_like_0p5, size=1)
+def_gen.standard_gamma(D_arr_like_0p5, size=1, out=D_out, dtype=np.float64)
+
+def_gen.vonmises(0.5, 0.5)
+def_gen.vonmises(0.5, 0.5, size=None)
+def_gen.vonmises(0.5, 0.5, size=1)
+def_gen.vonmises(D_arr_0p5, 0.5)
+def_gen.vonmises(0.5, D_arr_0p5)
+def_gen.vonmises(D_arr_0p5, 0.5, size=1)
+def_gen.vonmises(0.5, D_arr_0p5, size=1)
+def_gen.vonmises(D_arr_like_0p5, 0.5)
+def_gen.vonmises(0.5, D_arr_like_0p5)
+def_gen.vonmises(D_arr_0p5, D_arr_0p5)
+def_gen.vonmises(D_arr_like_0p5, D_arr_like_0p5)
+def_gen.vonmises(D_arr_0p5, D_arr_0p5, size=1)
+def_gen.vonmises(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+def_gen.wald(0.5, 0.5)
+def_gen.wald(0.5, 0.5, size=None)
+def_gen.wald(0.5, 0.5, size=1)
+def_gen.wald(D_arr_0p5, 0.5)
+def_gen.wald(0.5, D_arr_0p5)
+def_gen.wald(D_arr_0p5, 0.5, size=1)
+def_gen.wald(0.5, D_arr_0p5, size=1)
+def_gen.wald(D_arr_like_0p5, 0.5)
+def_gen.wald(0.5, D_arr_like_0p5)
+def_gen.wald(D_arr_0p5, D_arr_0p5)
+def_gen.wald(D_arr_like_0p5, D_arr_like_0p5)
+def_gen.wald(D_arr_0p5, D_arr_0p5, size=1)
+def_gen.wald(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+def_gen.uniform(0.5, 0.5)
+def_gen.uniform(0.5, 0.5, size=None)
+def_gen.uniform(0.5, 0.5, size=1)
+def_gen.uniform(D_arr_0p5, 0.5)
+def_gen.uniform(0.5, D_arr_0p5)
+def_gen.uniform(D_arr_0p5, 0.5, size=1)
+def_gen.uniform(0.5, D_arr_0p5, size=1)
+def_gen.uniform(D_arr_like_0p5, 0.5)
+def_gen.uniform(0.5, D_arr_like_0p5)
+def_gen.uniform(D_arr_0p5, D_arr_0p5)
+def_gen.uniform(D_arr_like_0p5, D_arr_like_0p5)
+def_gen.uniform(D_arr_0p5, D_arr_0p5, size=1)
+def_gen.uniform(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+def_gen.beta(0.5, 0.5)
+def_gen.beta(0.5, 0.5, size=None)
+def_gen.beta(0.5, 0.5, size=1)
+def_gen.beta(D_arr_0p5, 0.5)
+def_gen.beta(0.5, D_arr_0p5)
+def_gen.beta(D_arr_0p5, 0.5, size=1)
+def_gen.beta(0.5, D_arr_0p5, size=1)
+def_gen.beta(D_arr_like_0p5, 0.5)
+def_gen.beta(0.5, D_arr_like_0p5)
+def_gen.beta(D_arr_0p5, D_arr_0p5)
+def_gen.beta(D_arr_like_0p5, D_arr_like_0p5)
+def_gen.beta(D_arr_0p5, D_arr_0p5, size=1)
+def_gen.beta(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+def_gen.f(0.5, 0.5)
+def_gen.f(0.5, 0.5, size=None)
+def_gen.f(0.5, 0.5, size=1)
+def_gen.f(D_arr_0p5, 0.5)
+def_gen.f(0.5, D_arr_0p5)
+def_gen.f(D_arr_0p5, 0.5, size=1)
+def_gen.f(0.5, D_arr_0p5, size=1)
+def_gen.f(D_arr_like_0p5, 0.5)
+def_gen.f(0.5, D_arr_like_0p5)
+def_gen.f(D_arr_0p5, D_arr_0p5)
+def_gen.f(D_arr_like_0p5, D_arr_like_0p5)
+def_gen.f(D_arr_0p5, D_arr_0p5, size=1)
+def_gen.f(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+def_gen.gamma(0.5, 0.5)
+def_gen.gamma(0.5, 0.5, size=None)
+def_gen.gamma(0.5, 0.5, size=1)
+def_gen.gamma(D_arr_0p5, 0.5)
+def_gen.gamma(0.5, D_arr_0p5)
+def_gen.gamma(D_arr_0p5, 0.5, size=1)
+def_gen.gamma(0.5, D_arr_0p5, size=1)
+def_gen.gamma(D_arr_like_0p5, 0.5)
+def_gen.gamma(0.5, D_arr_like_0p5)
+def_gen.gamma(D_arr_0p5, D_arr_0p5)
+def_gen.gamma(D_arr_like_0p5, D_arr_like_0p5)
+def_gen.gamma(D_arr_0p5, D_arr_0p5, size=1)
+def_gen.gamma(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+def_gen.gumbel(0.5, 0.5)
+def_gen.gumbel(0.5, 0.5, size=None)
+def_gen.gumbel(0.5, 0.5, size=1)
+def_gen.gumbel(D_arr_0p5, 0.5)
+def_gen.gumbel(0.5, D_arr_0p5)
+def_gen.gumbel(D_arr_0p5, 0.5, size=1)
+def_gen.gumbel(0.5, D_arr_0p5, size=1)
+def_gen.gumbel(D_arr_like_0p5, 0.5)
+def_gen.gumbel(0.5, D_arr_like_0p5)
+def_gen.gumbel(D_arr_0p5, D_arr_0p5)
+def_gen.gumbel(D_arr_like_0p5, D_arr_like_0p5)
+def_gen.gumbel(D_arr_0p5, D_arr_0p5, size=1)
+def_gen.gumbel(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+def_gen.laplace(0.5, 0.5)
+def_gen.laplace(0.5, 0.5, size=None)
+def_gen.laplace(0.5, 0.5, size=1)
+def_gen.laplace(D_arr_0p5, 0.5)
+def_gen.laplace(0.5, D_arr_0p5)
+def_gen.laplace(D_arr_0p5, 0.5, size=1)
+def_gen.laplace(0.5, D_arr_0p5, size=1)
+def_gen.laplace(D_arr_like_0p5, 0.5)
+def_gen.laplace(0.5, D_arr_like_0p5)
+def_gen.laplace(D_arr_0p5, D_arr_0p5)
+def_gen.laplace(D_arr_like_0p5, D_arr_like_0p5)
+def_gen.laplace(D_arr_0p5, D_arr_0p5, size=1)
+def_gen.laplace(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+def_gen.logistic(0.5, 0.5)
+def_gen.logistic(0.5, 0.5, size=None)
+def_gen.logistic(0.5, 0.5, size=1)
+def_gen.logistic(D_arr_0p5, 0.5)
+def_gen.logistic(0.5, D_arr_0p5)
+def_gen.logistic(D_arr_0p5, 0.5, size=1)
+def_gen.logistic(0.5, D_arr_0p5, size=1)
+def_gen.logistic(D_arr_like_0p5, 0.5)
+def_gen.logistic(0.5, D_arr_like_0p5)
+def_gen.logistic(D_arr_0p5, D_arr_0p5)
+def_gen.logistic(D_arr_like_0p5, D_arr_like_0p5)
+def_gen.logistic(D_arr_0p5, D_arr_0p5, size=1)
+def_gen.logistic(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+def_gen.lognormal(0.5, 0.5)
+def_gen.lognormal(0.5, 0.5, size=None)
+def_gen.lognormal(0.5, 0.5, size=1)
+def_gen.lognormal(D_arr_0p5, 0.5)
+def_gen.lognormal(0.5, D_arr_0p5)
+def_gen.lognormal(D_arr_0p5, 0.5, size=1)
+def_gen.lognormal(0.5, D_arr_0p5, size=1)
+def_gen.lognormal(D_arr_like_0p5, 0.5)
+def_gen.lognormal(0.5, D_arr_like_0p5)
+def_gen.lognormal(D_arr_0p5, D_arr_0p5)
+def_gen.lognormal(D_arr_like_0p5, D_arr_like_0p5)
+def_gen.lognormal(D_arr_0p5, D_arr_0p5, size=1)
+def_gen.lognormal(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+def_gen.noncentral_chisquare(0.5, 0.5)
+def_gen.noncentral_chisquare(0.5, 0.5, size=None)
+def_gen.noncentral_chisquare(0.5, 0.5, size=1)
+def_gen.noncentral_chisquare(D_arr_0p5, 0.5)
+def_gen.noncentral_chisquare(0.5, D_arr_0p5)
+def_gen.noncentral_chisquare(D_arr_0p5, 0.5, size=1)
+def_gen.noncentral_chisquare(0.5, D_arr_0p5, size=1)
+def_gen.noncentral_chisquare(D_arr_like_0p5, 0.5)
+def_gen.noncentral_chisquare(0.5, D_arr_like_0p5)
+def_gen.noncentral_chisquare(D_arr_0p5, D_arr_0p5)
+def_gen.noncentral_chisquare(D_arr_like_0p5, D_arr_like_0p5)
+def_gen.noncentral_chisquare(D_arr_0p5, D_arr_0p5, size=1)
+def_gen.noncentral_chisquare(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+def_gen.normal(0.5, 0.5)
+def_gen.normal(0.5, 0.5, size=None)
+def_gen.normal(0.5, 0.5, size=1)
+def_gen.normal(D_arr_0p5, 0.5)
+def_gen.normal(0.5, D_arr_0p5)
+def_gen.normal(D_arr_0p5, 0.5, size=1)
+def_gen.normal(0.5, D_arr_0p5, size=1)
+def_gen.normal(D_arr_like_0p5, 0.5)
+def_gen.normal(0.5, D_arr_like_0p5)
+def_gen.normal(D_arr_0p5, D_arr_0p5)
+def_gen.normal(D_arr_like_0p5, D_arr_like_0p5)
+def_gen.normal(D_arr_0p5, D_arr_0p5, size=1)
+def_gen.normal(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+def_gen.triangular(0.1, 0.5, 0.9)
+def_gen.triangular(0.1, 0.5, 0.9, size=None)
+def_gen.triangular(0.1, 0.5, 0.9, size=1)
+def_gen.triangular(D_arr_0p1, 0.5, 0.9)
+def_gen.triangular(0.1, D_arr_0p5, 0.9)
+def_gen.triangular(D_arr_0p1, 0.5, D_arr_like_0p9, size=1)
+def_gen.triangular(0.1, D_arr_0p5, 0.9, size=1)
+def_gen.triangular(D_arr_like_0p1, 0.5, D_arr_0p9)
+def_gen.triangular(0.5, D_arr_like_0p5, 0.9)
+def_gen.triangular(D_arr_0p1, D_arr_0p5, 0.9)
+def_gen.triangular(D_arr_like_0p1, D_arr_like_0p5, 0.9)
+def_gen.triangular(D_arr_0p1, D_arr_0p5, D_arr_0p9, size=1)
+def_gen.triangular(D_arr_like_0p1, D_arr_like_0p5, D_arr_like_0p9, size=1)
+
+def_gen.noncentral_f(0.1, 0.5, 0.9)
+def_gen.noncentral_f(0.1, 0.5, 0.9, size=None)
+def_gen.noncentral_f(0.1, 0.5, 0.9, size=1)
+def_gen.noncentral_f(D_arr_0p1, 0.5, 0.9)
+def_gen.noncentral_f(0.1, D_arr_0p5, 0.9)
+def_gen.noncentral_f(D_arr_0p1, 0.5, D_arr_like_0p9, size=1)
+def_gen.noncentral_f(0.1, D_arr_0p5, 0.9, size=1)
+def_gen.noncentral_f(D_arr_like_0p1, 0.5, D_arr_0p9)
+def_gen.noncentral_f(0.5, D_arr_like_0p5, 0.9)
+def_gen.noncentral_f(D_arr_0p1, D_arr_0p5, 0.9)
+def_gen.noncentral_f(D_arr_like_0p1, D_arr_like_0p5, 0.9)
+def_gen.noncentral_f(D_arr_0p1, D_arr_0p5, D_arr_0p9, size=1)
+def_gen.noncentral_f(D_arr_like_0p1, D_arr_like_0p5, D_arr_like_0p9, size=1)
+
+def_gen.binomial(10, 0.5)
+def_gen.binomial(10, 0.5, size=None)
+def_gen.binomial(10, 0.5, size=1)
+def_gen.binomial(I_arr_10, 0.5)
+def_gen.binomial(10, D_arr_0p5)
+def_gen.binomial(I_arr_10, 0.5, size=1)
+def_gen.binomial(10, D_arr_0p5, size=1)
+def_gen.binomial(I_arr_like_10, 0.5)
+def_gen.binomial(10, D_arr_like_0p5)
+def_gen.binomial(I_arr_10, D_arr_0p5)
+def_gen.binomial(I_arr_like_10, D_arr_like_0p5)
+def_gen.binomial(I_arr_10, D_arr_0p5, size=1)
+def_gen.binomial(I_arr_like_10, D_arr_like_0p5, size=1)
+
+def_gen.negative_binomial(10, 0.5)
+def_gen.negative_binomial(10, 0.5, size=None)
+def_gen.negative_binomial(10, 0.5, size=1)
+def_gen.negative_binomial(I_arr_10, 0.5)
+def_gen.negative_binomial(10, D_arr_0p5)
+def_gen.negative_binomial(I_arr_10, 0.5, size=1)
+def_gen.negative_binomial(10, D_arr_0p5, size=1)
+def_gen.negative_binomial(I_arr_like_10, 0.5)
+def_gen.negative_binomial(10, D_arr_like_0p5)
+def_gen.negative_binomial(I_arr_10, D_arr_0p5)
+def_gen.negative_binomial(I_arr_like_10, D_arr_like_0p5)
+def_gen.negative_binomial(I_arr_10, D_arr_0p5, size=1)
+def_gen.negative_binomial(I_arr_like_10, D_arr_like_0p5, size=1)
+
+def_gen.hypergeometric(20, 20, 10)
+def_gen.hypergeometric(20, 20, 10, size=None)
+def_gen.hypergeometric(20, 20, 10, size=1)
+def_gen.hypergeometric(I_arr_20, 20, 10)
+def_gen.hypergeometric(20, I_arr_20, 10)
+def_gen.hypergeometric(I_arr_20, 20, I_arr_like_10, size=1)
+def_gen.hypergeometric(20, I_arr_20, 10, size=1)
+def_gen.hypergeometric(I_arr_like_20, 20, I_arr_10)
+def_gen.hypergeometric(20, I_arr_like_20, 10)
+def_gen.hypergeometric(I_arr_20, I_arr_20, 10)
+def_gen.hypergeometric(I_arr_like_20, I_arr_like_20, 10)
+def_gen.hypergeometric(I_arr_20, I_arr_20, I_arr_10, size=1)
+def_gen.hypergeometric(I_arr_like_20, I_arr_like_20, I_arr_like_10, size=1)
+
+I_int64_100: np.ndarray[Any, np.dtype[np.int64]] = np.array([100], dtype=np.int64)
+
+def_gen.integers(0, 100)
+def_gen.integers(100)
+def_gen.integers([100])
+def_gen.integers(0, [100])
+
+I_bool_low: np.ndarray[Any, np.dtype[np.bool_]] = np.array([0], dtype=np.bool_)
+I_bool_low_like: List[int] = [0]
+I_bool_high_open: np.ndarray[Any, np.dtype[np.bool_]] = np.array([1], dtype=np.bool_)
+I_bool_high_closed: np.ndarray[Any, np.dtype[np.bool_]] = np.array([1], dtype=np.bool_)
+
+def_gen.integers(2, dtype=bool)
+def_gen.integers(0, 2, dtype=bool)
+def_gen.integers(1, dtype=bool, endpoint=True)
+def_gen.integers(0, 1, dtype=bool, endpoint=True)
+def_gen.integers(I_bool_low_like, 1, dtype=bool, endpoint=True)
+def_gen.integers(I_bool_high_open, dtype=bool)
+def_gen.integers(I_bool_low, I_bool_high_open, dtype=bool)
+def_gen.integers(0, I_bool_high_open, dtype=bool)
+def_gen.integers(I_bool_high_closed, dtype=bool, endpoint=True)
+def_gen.integers(I_bool_low, I_bool_high_closed, dtype=bool, endpoint=True)
+def_gen.integers(0, I_bool_high_closed, dtype=bool, endpoint=True)
+
+def_gen.integers(2, dtype=np.bool_)
+def_gen.integers(0, 2, dtype=np.bool_)
+def_gen.integers(1, dtype=np.bool_, endpoint=True)
+def_gen.integers(0, 1, dtype=np.bool_, endpoint=True)
+def_gen.integers(I_bool_low_like, 1, dtype=np.bool_, endpoint=True)
+def_gen.integers(I_bool_high_open, dtype=np.bool_)
+def_gen.integers(I_bool_low, I_bool_high_open, dtype=np.bool_)
+def_gen.integers(0, I_bool_high_open, dtype=np.bool_)
+def_gen.integers(I_bool_high_closed, dtype=np.bool_, endpoint=True)
+def_gen.integers(I_bool_low, I_bool_high_closed, dtype=np.bool_, endpoint=True)
+def_gen.integers(0, I_bool_high_closed, dtype=np.bool_, endpoint=True)
+
+I_u1_low: np.ndarray[Any, np.dtype[np.uint8]] = np.array([0], dtype=np.uint8)
+I_u1_low_like: List[int] = [0]
+I_u1_high_open: np.ndarray[Any, np.dtype[np.uint8]] = np.array([255], dtype=np.uint8)
+I_u1_high_closed: np.ndarray[Any, np.dtype[np.uint8]] = np.array([255], dtype=np.uint8)
+
+def_gen.integers(256, dtype="u1")
+def_gen.integers(0, 256, dtype="u1")
+def_gen.integers(255, dtype="u1", endpoint=True)
+def_gen.integers(0, 255, dtype="u1", endpoint=True)
+def_gen.integers(I_u1_low_like, 255, dtype="u1", endpoint=True)
+def_gen.integers(I_u1_high_open, dtype="u1")
+def_gen.integers(I_u1_low, I_u1_high_open, dtype="u1")
+def_gen.integers(0, I_u1_high_open, dtype="u1")
+def_gen.integers(I_u1_high_closed, dtype="u1", endpoint=True)
+def_gen.integers(I_u1_low, I_u1_high_closed, dtype="u1", endpoint=True)
+def_gen.integers(0, I_u1_high_closed, dtype="u1", endpoint=True)
+
+def_gen.integers(256, dtype="uint8")
+def_gen.integers(0, 256, dtype="uint8")
+def_gen.integers(255, dtype="uint8", endpoint=True)
+def_gen.integers(0, 255, dtype="uint8", endpoint=True)
+def_gen.integers(I_u1_low_like, 255, dtype="uint8", endpoint=True)
+def_gen.integers(I_u1_high_open, dtype="uint8")
+def_gen.integers(I_u1_low, I_u1_high_open, dtype="uint8")
+def_gen.integers(0, I_u1_high_open, dtype="uint8")
+def_gen.integers(I_u1_high_closed, dtype="uint8", endpoint=True)
+def_gen.integers(I_u1_low, I_u1_high_closed, dtype="uint8", endpoint=True)
+def_gen.integers(0, I_u1_high_closed, dtype="uint8", endpoint=True)
+
+def_gen.integers(256, dtype=np.uint8)
+def_gen.integers(0, 256, dtype=np.uint8)
+def_gen.integers(255, dtype=np.uint8, endpoint=True)
+def_gen.integers(0, 255, dtype=np.uint8, endpoint=True)
+def_gen.integers(I_u1_low_like, 255, dtype=np.uint8, endpoint=True)
+def_gen.integers(I_u1_high_open, dtype=np.uint8)
+def_gen.integers(I_u1_low, I_u1_high_open, dtype=np.uint8)
+def_gen.integers(0, I_u1_high_open, dtype=np.uint8)
+def_gen.integers(I_u1_high_closed, dtype=np.uint8, endpoint=True)
+def_gen.integers(I_u1_low, I_u1_high_closed, dtype=np.uint8, endpoint=True)
+def_gen.integers(0, I_u1_high_closed, dtype=np.uint8, endpoint=True)
+
+I_u2_low: np.ndarray[Any, np.dtype[np.uint16]] = np.array([0], dtype=np.uint16)
+I_u2_low_like: List[int] = [0]
+I_u2_high_open: np.ndarray[Any, np.dtype[np.uint16]] = np.array([65535], dtype=np.uint16)
+I_u2_high_closed: np.ndarray[Any, np.dtype[np.uint16]] = np.array([65535], dtype=np.uint16)
+
+def_gen.integers(65536, dtype="u2")
+def_gen.integers(0, 65536, dtype="u2")
+def_gen.integers(65535, dtype="u2", endpoint=True)
+def_gen.integers(0, 65535, dtype="u2", endpoint=True)
+def_gen.integers(I_u2_low_like, 65535, dtype="u2", endpoint=True)
+def_gen.integers(I_u2_high_open, dtype="u2")
+def_gen.integers(I_u2_low, I_u2_high_open, dtype="u2")
+def_gen.integers(0, I_u2_high_open, dtype="u2")
+def_gen.integers(I_u2_high_closed, dtype="u2", endpoint=True)
+def_gen.integers(I_u2_low, I_u2_high_closed, dtype="u2", endpoint=True)
+def_gen.integers(0, I_u2_high_closed, dtype="u2", endpoint=True)
+
+def_gen.integers(65536, dtype="uint16")
+def_gen.integers(0, 65536, dtype="uint16")
+def_gen.integers(65535, dtype="uint16", endpoint=True)
+def_gen.integers(0, 65535, dtype="uint16", endpoint=True)
+def_gen.integers(I_u2_low_like, 65535, dtype="uint16", endpoint=True)
+def_gen.integers(I_u2_high_open, dtype="uint16")
+def_gen.integers(I_u2_low, I_u2_high_open, dtype="uint16")
+def_gen.integers(0, I_u2_high_open, dtype="uint16")
+def_gen.integers(I_u2_high_closed, dtype="uint16", endpoint=True)
+def_gen.integers(I_u2_low, I_u2_high_closed, dtype="uint16", endpoint=True)
+def_gen.integers(0, I_u2_high_closed, dtype="uint16", endpoint=True)
+
+def_gen.integers(65536, dtype=np.uint16)
+def_gen.integers(0, 65536, dtype=np.uint16)
+def_gen.integers(65535, dtype=np.uint16, endpoint=True)
+def_gen.integers(0, 65535, dtype=np.uint16, endpoint=True)
+def_gen.integers(I_u2_low_like, 65535, dtype=np.uint16, endpoint=True)
+def_gen.integers(I_u2_high_open, dtype=np.uint16)
+def_gen.integers(I_u2_low, I_u2_high_open, dtype=np.uint16)
+def_gen.integers(0, I_u2_high_open, dtype=np.uint16)
+def_gen.integers(I_u2_high_closed, dtype=np.uint16, endpoint=True)
+def_gen.integers(I_u2_low, I_u2_high_closed, dtype=np.uint16, endpoint=True)
+def_gen.integers(0, I_u2_high_closed, dtype=np.uint16, endpoint=True)
+
+I_u4_low: np.ndarray[Any, np.dtype[np.uint32]] = np.array([0], dtype=np.uint32)
+I_u4_low_like: List[int] = [0]
+I_u4_high_open: np.ndarray[Any, np.dtype[np.uint32]] = np.array([4294967295], dtype=np.uint32)
+I_u4_high_closed: np.ndarray[Any, np.dtype[np.uint32]] = np.array([4294967295], dtype=np.uint32)
+
+def_gen.integers(4294967296, dtype="u4")
+def_gen.integers(0, 4294967296, dtype="u4")
+def_gen.integers(4294967295, dtype="u4", endpoint=True)
+def_gen.integers(0, 4294967295, dtype="u4", endpoint=True)
+def_gen.integers(I_u4_low_like, 4294967295, dtype="u4", endpoint=True)
+def_gen.integers(I_u4_high_open, dtype="u4")
+def_gen.integers(I_u4_low, I_u4_high_open, dtype="u4")
+def_gen.integers(0, I_u4_high_open, dtype="u4")
+def_gen.integers(I_u4_high_closed, dtype="u4", endpoint=True)
+def_gen.integers(I_u4_low, I_u4_high_closed, dtype="u4", endpoint=True)
+def_gen.integers(0, I_u4_high_closed, dtype="u4", endpoint=True)
+
+def_gen.integers(4294967296, dtype="uint32")
+def_gen.integers(0, 4294967296, dtype="uint32")
+def_gen.integers(4294967295, dtype="uint32", endpoint=True)
+def_gen.integers(0, 4294967295, dtype="uint32", endpoint=True)
+def_gen.integers(I_u4_low_like, 4294967295, dtype="uint32", endpoint=True)
+def_gen.integers(I_u4_high_open, dtype="uint32")
+def_gen.integers(I_u4_low, I_u4_high_open, dtype="uint32")
+def_gen.integers(0, I_u4_high_open, dtype="uint32")
+def_gen.integers(I_u4_high_closed, dtype="uint32", endpoint=True)
+def_gen.integers(I_u4_low, I_u4_high_closed, dtype="uint32", endpoint=True)
+def_gen.integers(0, I_u4_high_closed, dtype="uint32", endpoint=True)
+
+def_gen.integers(4294967296, dtype=np.uint32)
+def_gen.integers(0, 4294967296, dtype=np.uint32)
+def_gen.integers(4294967295, dtype=np.uint32, endpoint=True)
+def_gen.integers(0, 4294967295, dtype=np.uint32, endpoint=True)
+def_gen.integers(I_u4_low_like, 4294967295, dtype=np.uint32, endpoint=True)
+def_gen.integers(I_u4_high_open, dtype=np.uint32)
+def_gen.integers(I_u4_low, I_u4_high_open, dtype=np.uint32)
+def_gen.integers(0, I_u4_high_open, dtype=np.uint32)
+def_gen.integers(I_u4_high_closed, dtype=np.uint32, endpoint=True)
+def_gen.integers(I_u4_low, I_u4_high_closed, dtype=np.uint32, endpoint=True)
+def_gen.integers(0, I_u4_high_closed, dtype=np.uint32, endpoint=True)
+
+I_u8_low: np.ndarray[Any, np.dtype[np.uint64]] = np.array([0], dtype=np.uint64)
+I_u8_low_like: List[int] = [0]
+I_u8_high_open: np.ndarray[Any, np.dtype[np.uint64]] = np.array([18446744073709551615], dtype=np.uint64)
+I_u8_high_closed: np.ndarray[Any, np.dtype[np.uint64]] = np.array([18446744073709551615], dtype=np.uint64)
+
+def_gen.integers(18446744073709551616, dtype="u8")
+def_gen.integers(0, 18446744073709551616, dtype="u8")
+def_gen.integers(18446744073709551615, dtype="u8", endpoint=True)
+def_gen.integers(0, 18446744073709551615, dtype="u8", endpoint=True)
+def_gen.integers(I_u8_low_like, 18446744073709551615, dtype="u8", endpoint=True)
+def_gen.integers(I_u8_high_open, dtype="u8")
+def_gen.integers(I_u8_low, I_u8_high_open, dtype="u8")
+def_gen.integers(0, I_u8_high_open, dtype="u8")
+def_gen.integers(I_u8_high_closed, dtype="u8", endpoint=True)
+def_gen.integers(I_u8_low, I_u8_high_closed, dtype="u8", endpoint=True)
+def_gen.integers(0, I_u8_high_closed, dtype="u8", endpoint=True)
+
+def_gen.integers(18446744073709551616, dtype="uint64")
+def_gen.integers(0, 18446744073709551616, dtype="uint64")
+def_gen.integers(18446744073709551615, dtype="uint64", endpoint=True)
+def_gen.integers(0, 18446744073709551615, dtype="uint64", endpoint=True)
+def_gen.integers(I_u8_low_like, 18446744073709551615, dtype="uint64", endpoint=True)
+def_gen.integers(I_u8_high_open, dtype="uint64")
+def_gen.integers(I_u8_low, I_u8_high_open, dtype="uint64")
+def_gen.integers(0, I_u8_high_open, dtype="uint64")
+def_gen.integers(I_u8_high_closed, dtype="uint64", endpoint=True)
+def_gen.integers(I_u8_low, I_u8_high_closed, dtype="uint64", endpoint=True)
+def_gen.integers(0, I_u8_high_closed, dtype="uint64", endpoint=True)
+
+def_gen.integers(18446744073709551616, dtype=np.uint64)
+def_gen.integers(0, 18446744073709551616, dtype=np.uint64)
+def_gen.integers(18446744073709551615, dtype=np.uint64, endpoint=True)
+def_gen.integers(0, 18446744073709551615, dtype=np.uint64, endpoint=True)
+def_gen.integers(I_u8_low_like, 18446744073709551615, dtype=np.uint64, endpoint=True)
+def_gen.integers(I_u8_high_open, dtype=np.uint64)
+def_gen.integers(I_u8_low, I_u8_high_open, dtype=np.uint64)
+def_gen.integers(0, I_u8_high_open, dtype=np.uint64)
+def_gen.integers(I_u8_high_closed, dtype=np.uint64, endpoint=True)
+def_gen.integers(I_u8_low, I_u8_high_closed, dtype=np.uint64, endpoint=True)
+def_gen.integers(0, I_u8_high_closed, dtype=np.uint64, endpoint=True)
+
+I_i1_low: np.ndarray[Any, np.dtype[np.int8]] = np.array([-128], dtype=np.int8)
+I_i1_low_like: List[int] = [-128]
+I_i1_high_open: np.ndarray[Any, np.dtype[np.int8]] = np.array([127], dtype=np.int8)
+I_i1_high_closed: np.ndarray[Any, np.dtype[np.int8]] = np.array([127], dtype=np.int8)
+
+def_gen.integers(128, dtype="i1")
+def_gen.integers(-128, 128, dtype="i1")
+def_gen.integers(127, dtype="i1", endpoint=True)
+def_gen.integers(-128, 127, dtype="i1", endpoint=True)
+def_gen.integers(I_i1_low_like, 127, dtype="i1", endpoint=True)
+def_gen.integers(I_i1_high_open, dtype="i1")
+def_gen.integers(I_i1_low, I_i1_high_open, dtype="i1")
+def_gen.integers(-128, I_i1_high_open, dtype="i1")
+def_gen.integers(I_i1_high_closed, dtype="i1", endpoint=True)
+def_gen.integers(I_i1_low, I_i1_high_closed, dtype="i1", endpoint=True)
+def_gen.integers(-128, I_i1_high_closed, dtype="i1", endpoint=True)
+
+def_gen.integers(128, dtype="int8")
+def_gen.integers(-128, 128, dtype="int8")
+def_gen.integers(127, dtype="int8", endpoint=True)
+def_gen.integers(-128, 127, dtype="int8", endpoint=True)
+def_gen.integers(I_i1_low_like, 127, dtype="int8", endpoint=True)
+def_gen.integers(I_i1_high_open, dtype="int8")
+def_gen.integers(I_i1_low, I_i1_high_open, dtype="int8")
+def_gen.integers(-128, I_i1_high_open, dtype="int8")
+def_gen.integers(I_i1_high_closed, dtype="int8", endpoint=True)
+def_gen.integers(I_i1_low, I_i1_high_closed, dtype="int8", endpoint=True)
+def_gen.integers(-128, I_i1_high_closed, dtype="int8", endpoint=True)
+
+def_gen.integers(128, dtype=np.int8)
+def_gen.integers(-128, 128, dtype=np.int8)
+def_gen.integers(127, dtype=np.int8, endpoint=True)
+def_gen.integers(-128, 127, dtype=np.int8, endpoint=True)
+def_gen.integers(I_i1_low_like, 127, dtype=np.int8, endpoint=True)
+def_gen.integers(I_i1_high_open, dtype=np.int8)
+def_gen.integers(I_i1_low, I_i1_high_open, dtype=np.int8)
+def_gen.integers(-128, I_i1_high_open, dtype=np.int8)
+def_gen.integers(I_i1_high_closed, dtype=np.int8, endpoint=True)
+def_gen.integers(I_i1_low, I_i1_high_closed, dtype=np.int8, endpoint=True)
+def_gen.integers(-128, I_i1_high_closed, dtype=np.int8, endpoint=True)
+
+I_i2_low: np.ndarray[Any, np.dtype[np.int16]] = np.array([-32768], dtype=np.int16)
+I_i2_low_like: List[int] = [-32768]
+I_i2_high_open: np.ndarray[Any, np.dtype[np.int16]] = np.array([32767], dtype=np.int16)
+I_i2_high_closed: np.ndarray[Any, np.dtype[np.int16]] = np.array([32767], dtype=np.int16)
+
+def_gen.integers(32768, dtype="i2")
+def_gen.integers(-32768, 32768, dtype="i2")
+def_gen.integers(32767, dtype="i2", endpoint=True)
+def_gen.integers(-32768, 32767, dtype="i2", endpoint=True)
+def_gen.integers(I_i2_low_like, 32767, dtype="i2", endpoint=True)
+def_gen.integers(I_i2_high_open, dtype="i2")
+def_gen.integers(I_i2_low, I_i2_high_open, dtype="i2")
+def_gen.integers(-32768, I_i2_high_open, dtype="i2")
+def_gen.integers(I_i2_high_closed, dtype="i2", endpoint=True)
+def_gen.integers(I_i2_low, I_i2_high_closed, dtype="i2", endpoint=True)
+def_gen.integers(-32768, I_i2_high_closed, dtype="i2", endpoint=True)
+
+def_gen.integers(32768, dtype="int16")
+def_gen.integers(-32768, 32768, dtype="int16")
+def_gen.integers(32767, dtype="int16", endpoint=True)
+def_gen.integers(-32768, 32767, dtype="int16", endpoint=True)
+def_gen.integers(I_i2_low_like, 32767, dtype="int16", endpoint=True)
+def_gen.integers(I_i2_high_open, dtype="int16")
+def_gen.integers(I_i2_low, I_i2_high_open, dtype="int16")
+def_gen.integers(-32768, I_i2_high_open, dtype="int16")
+def_gen.integers(I_i2_high_closed, dtype="int16", endpoint=True)
+def_gen.integers(I_i2_low, I_i2_high_closed, dtype="int16", endpoint=True)
+def_gen.integers(-32768, I_i2_high_closed, dtype="int16", endpoint=True)
+
+def_gen.integers(32768, dtype=np.int16)
+def_gen.integers(-32768, 32768, dtype=np.int16)
+def_gen.integers(32767, dtype=np.int16, endpoint=True)
+def_gen.integers(-32768, 32767, dtype=np.int16, endpoint=True)
+def_gen.integers(I_i2_low_like, 32767, dtype=np.int16, endpoint=True)
+def_gen.integers(I_i2_high_open, dtype=np.int16)
+def_gen.integers(I_i2_low, I_i2_high_open, dtype=np.int16)
+def_gen.integers(-32768, I_i2_high_open, dtype=np.int16)
+def_gen.integers(I_i2_high_closed, dtype=np.int16, endpoint=True)
+def_gen.integers(I_i2_low, I_i2_high_closed, dtype=np.int16, endpoint=True)
+def_gen.integers(-32768, I_i2_high_closed, dtype=np.int16, endpoint=True)
+
+I_i4_low: np.ndarray[Any, np.dtype[np.int32]] = np.array([-2147483648], dtype=np.int32)
+I_i4_low_like: List[int] = [-2147483648]
+I_i4_high_open: np.ndarray[Any, np.dtype[np.int32]] = np.array([2147483647], dtype=np.int32)
+I_i4_high_closed: np.ndarray[Any, np.dtype[np.int32]] = np.array([2147483647], dtype=np.int32)
+
+def_gen.integers(2147483648, dtype="i4")
+def_gen.integers(-2147483648, 2147483648, dtype="i4")
+def_gen.integers(2147483647, dtype="i4", endpoint=True)
+def_gen.integers(-2147483648, 2147483647, dtype="i4", endpoint=True)
+def_gen.integers(I_i4_low_like, 2147483647, dtype="i4", endpoint=True)
+def_gen.integers(I_i4_high_open, dtype="i4")
+def_gen.integers(I_i4_low, I_i4_high_open, dtype="i4")
+def_gen.integers(-2147483648, I_i4_high_open, dtype="i4")
+def_gen.integers(I_i4_high_closed, dtype="i4", endpoint=True)
+def_gen.integers(I_i4_low, I_i4_high_closed, dtype="i4", endpoint=True)
+def_gen.integers(-2147483648, I_i4_high_closed, dtype="i4", endpoint=True)
+
+def_gen.integers(2147483648, dtype="int32")
+def_gen.integers(-2147483648, 2147483648, dtype="int32")
+def_gen.integers(2147483647, dtype="int32", endpoint=True)
+def_gen.integers(-2147483648, 2147483647, dtype="int32", endpoint=True)
+def_gen.integers(I_i4_low_like, 2147483647, dtype="int32", endpoint=True)
+def_gen.integers(I_i4_high_open, dtype="int32")
+def_gen.integers(I_i4_low, I_i4_high_open, dtype="int32")
+def_gen.integers(-2147483648, I_i4_high_open, dtype="int32")
+def_gen.integers(I_i4_high_closed, dtype="int32", endpoint=True)
+def_gen.integers(I_i4_low, I_i4_high_closed, dtype="int32", endpoint=True)
+def_gen.integers(-2147483648, I_i4_high_closed, dtype="int32", endpoint=True)
+
+def_gen.integers(2147483648, dtype=np.int32)
+def_gen.integers(-2147483648, 2147483648, dtype=np.int32)
+def_gen.integers(2147483647, dtype=np.int32, endpoint=True)
+def_gen.integers(-2147483648, 2147483647, dtype=np.int32, endpoint=True)
+def_gen.integers(I_i4_low_like, 2147483647, dtype=np.int32, endpoint=True)
+def_gen.integers(I_i4_high_open, dtype=np.int32)
+def_gen.integers(I_i4_low, I_i4_high_open, dtype=np.int32)
+def_gen.integers(-2147483648, I_i4_high_open, dtype=np.int32)
+def_gen.integers(I_i4_high_closed, dtype=np.int32, endpoint=True)
+def_gen.integers(I_i4_low, I_i4_high_closed, dtype=np.int32, endpoint=True)
+def_gen.integers(-2147483648, I_i4_high_closed, dtype=np.int32, endpoint=True)
+
+I_i8_low: np.ndarray[Any, np.dtype[np.int64]] = np.array([-9223372036854775808], dtype=np.int64)
+I_i8_low_like: List[int] = [-9223372036854775808]
+I_i8_high_open: np.ndarray[Any, np.dtype[np.int64]] = np.array([9223372036854775807], dtype=np.int64)
+I_i8_high_closed: np.ndarray[Any, np.dtype[np.int64]] = np.array([9223372036854775807], dtype=np.int64)
+
+def_gen.integers(9223372036854775808, dtype="i8")
+def_gen.integers(-9223372036854775808, 9223372036854775808, dtype="i8")
+def_gen.integers(9223372036854775807, dtype="i8", endpoint=True)
+def_gen.integers(-9223372036854775808, 9223372036854775807, dtype="i8", endpoint=True)
+def_gen.integers(I_i8_low_like, 9223372036854775807, dtype="i8", endpoint=True)
+def_gen.integers(I_i8_high_open, dtype="i8")
+def_gen.integers(I_i8_low, I_i8_high_open, dtype="i8")
+def_gen.integers(-9223372036854775808, I_i8_high_open, dtype="i8")
+def_gen.integers(I_i8_high_closed, dtype="i8", endpoint=True)
+def_gen.integers(I_i8_low, I_i8_high_closed, dtype="i8", endpoint=True)
+def_gen.integers(-9223372036854775808, I_i8_high_closed, dtype="i8", endpoint=True)
+
+def_gen.integers(9223372036854775808, dtype="int64")
+def_gen.integers(-9223372036854775808, 9223372036854775808, dtype="int64")
+def_gen.integers(9223372036854775807, dtype="int64", endpoint=True)
+def_gen.integers(-9223372036854775808, 9223372036854775807, dtype="int64", endpoint=True)
+def_gen.integers(I_i8_low_like, 9223372036854775807, dtype="int64", endpoint=True)
+def_gen.integers(I_i8_high_open, dtype="int64")
+def_gen.integers(I_i8_low, I_i8_high_open, dtype="int64")
+def_gen.integers(-9223372036854775808, I_i8_high_open, dtype="int64")
+def_gen.integers(I_i8_high_closed, dtype="int64", endpoint=True)
+def_gen.integers(I_i8_low, I_i8_high_closed, dtype="int64", endpoint=True)
+def_gen.integers(-9223372036854775808, I_i8_high_closed, dtype="int64", endpoint=True)
+
+def_gen.integers(9223372036854775808, dtype=np.int64)
+def_gen.integers(-9223372036854775808, 9223372036854775808, dtype=np.int64)
+def_gen.integers(9223372036854775807, dtype=np.int64, endpoint=True)
+def_gen.integers(-9223372036854775808, 9223372036854775807, dtype=np.int64, endpoint=True)
+def_gen.integers(I_i8_low_like, 9223372036854775807, dtype=np.int64, endpoint=True)
+def_gen.integers(I_i8_high_open, dtype=np.int64)
+def_gen.integers(I_i8_low, I_i8_high_open, dtype=np.int64)
+def_gen.integers(-9223372036854775808, I_i8_high_open, dtype=np.int64)
+def_gen.integers(I_i8_high_closed, dtype=np.int64, endpoint=True)
+def_gen.integers(I_i8_low, I_i8_high_closed, dtype=np.int64, endpoint=True)
+def_gen.integers(-9223372036854775808, I_i8_high_closed, dtype=np.int64, endpoint=True)
+
+
+def_gen.bit_generator
+
+def_gen.bytes(2)
+
+def_gen.choice(5)
+def_gen.choice(5, 3)
+def_gen.choice(5, 3, replace=True)
+def_gen.choice(5, 3, p=[1 / 5] * 5)
+def_gen.choice(5, 3, p=[1 / 5] * 5, replace=False)
+
+def_gen.choice(["pooh", "rabbit", "piglet", "Christopher"])
+def_gen.choice(["pooh", "rabbit", "piglet", "Christopher"], 3)
+def_gen.choice(["pooh", "rabbit", "piglet", "Christopher"], 3, p=[1 / 4] * 4)
+def_gen.choice(["pooh", "rabbit", "piglet", "Christopher"], 3, replace=True)
+def_gen.choice(["pooh", "rabbit", "piglet", "Christopher"], 3, replace=False, p=np.array([1 / 8, 1 / 8, 1 / 2, 1 / 4]))
+
+def_gen.dirichlet([0.5, 0.5])
+def_gen.dirichlet(np.array([0.5, 0.5]))
+def_gen.dirichlet(np.array([0.5, 0.5]), size=3)
+
+def_gen.multinomial(20, [1 / 6.0] * 6)
+def_gen.multinomial(20, np.array([0.5, 0.5]))
+def_gen.multinomial(20, [1 / 6.0] * 6, size=2)
+def_gen.multinomial([[10], [20]], [1 / 6.0] * 6, size=(2, 2))
+def_gen.multinomial(np.array([[10], [20]]), np.array([0.5, 0.5]), size=(2, 2))
+
+def_gen.multivariate_hypergeometric([3, 5, 7], 2)
+def_gen.multivariate_hypergeometric(np.array([3, 5, 7]), 2)
+def_gen.multivariate_hypergeometric(np.array([3, 5, 7]), 2, size=4)
+def_gen.multivariate_hypergeometric(np.array([3, 5, 7]), 2, size=(4, 7))
+def_gen.multivariate_hypergeometric([3, 5, 7], 2, method="count")
+def_gen.multivariate_hypergeometric(np.array([3, 5, 7]), 2, method="marginals")
+
+def_gen.multivariate_normal([0.0], [[1.0]])
+def_gen.multivariate_normal([0.0], np.array([[1.0]]))
+def_gen.multivariate_normal(np.array([0.0]), [[1.0]])
+def_gen.multivariate_normal([0.0], np.array([[1.0]]))
+
+def_gen.permutation(10)
+def_gen.permutation([1, 2, 3, 4])
+def_gen.permutation(np.array([1, 2, 3, 4]))
+def_gen.permutation(D_2D, axis=1)
+def_gen.permuted(D_2D)
+def_gen.permuted(D_2D_like)
+def_gen.permuted(D_2D, axis=1)
+def_gen.permuted(D_2D, out=D_2D)
+def_gen.permuted(D_2D_like, out=D_2D)
+def_gen.permuted(D_2D_like, out=D_2D)
+def_gen.permuted(D_2D, axis=1, out=D_2D)
+
+def_gen.shuffle(np.arange(10))
+def_gen.shuffle([1, 2, 3, 4, 5])
+def_gen.shuffle(D_2D, axis=1)
+
+def_gen.__str__()
+def_gen.__repr__()
+def_gen_state: Dict[str, Any]
+def_gen_state = def_gen.__getstate__()
+def_gen.__setstate__(def_gen_state)
+
+# RandomState
+random_st: np.random.RandomState = np.random.RandomState()
+
+random_st.standard_normal()
+random_st.standard_normal(size=None)
+random_st.standard_normal(size=1)
+
+random_st.random()
+random_st.random(size=None)
+random_st.random(size=1)
+
+random_st.standard_cauchy()
+random_st.standard_cauchy(size=None)
+random_st.standard_cauchy(size=1)
+
+random_st.standard_exponential()
+random_st.standard_exponential(size=None)
+random_st.standard_exponential(size=1)
+
+random_st.zipf(1.5)
+random_st.zipf(1.5, size=None)
+random_st.zipf(1.5, size=1)
+random_st.zipf(D_arr_1p5)
+random_st.zipf(D_arr_1p5, size=1)
+random_st.zipf(D_arr_like_1p5)
+random_st.zipf(D_arr_like_1p5, size=1)
+
+random_st.weibull(0.5)
+random_st.weibull(0.5, size=None)
+random_st.weibull(0.5, size=1)
+random_st.weibull(D_arr_0p5)
+random_st.weibull(D_arr_0p5, size=1)
+random_st.weibull(D_arr_like_0p5)
+random_st.weibull(D_arr_like_0p5, size=1)
+
+random_st.standard_t(0.5)
+random_st.standard_t(0.5, size=None)
+random_st.standard_t(0.5, size=1)
+random_st.standard_t(D_arr_0p5)
+random_st.standard_t(D_arr_0p5, size=1)
+random_st.standard_t(D_arr_like_0p5)
+random_st.standard_t(D_arr_like_0p5, size=1)
+
+random_st.poisson(0.5)
+random_st.poisson(0.5, size=None)
+random_st.poisson(0.5, size=1)
+random_st.poisson(D_arr_0p5)
+random_st.poisson(D_arr_0p5, size=1)
+random_st.poisson(D_arr_like_0p5)
+random_st.poisson(D_arr_like_0p5, size=1)
+
+random_st.power(0.5)
+random_st.power(0.5, size=None)
+random_st.power(0.5, size=1)
+random_st.power(D_arr_0p5)
+random_st.power(D_arr_0p5, size=1)
+random_st.power(D_arr_like_0p5)
+random_st.power(D_arr_like_0p5, size=1)
+
+random_st.pareto(0.5)
+random_st.pareto(0.5, size=None)
+random_st.pareto(0.5, size=1)
+random_st.pareto(D_arr_0p5)
+random_st.pareto(D_arr_0p5, size=1)
+random_st.pareto(D_arr_like_0p5)
+random_st.pareto(D_arr_like_0p5, size=1)
+
+random_st.chisquare(0.5)
+random_st.chisquare(0.5, size=None)
+random_st.chisquare(0.5, size=1)
+random_st.chisquare(D_arr_0p5)
+random_st.chisquare(D_arr_0p5, size=1)
+random_st.chisquare(D_arr_like_0p5)
+random_st.chisquare(D_arr_like_0p5, size=1)
+
+random_st.exponential(0.5)
+random_st.exponential(0.5, size=None)
+random_st.exponential(0.5, size=1)
+random_st.exponential(D_arr_0p5)
+random_st.exponential(D_arr_0p5, size=1)
+random_st.exponential(D_arr_like_0p5)
+random_st.exponential(D_arr_like_0p5, size=1)
+
+random_st.geometric(0.5)
+random_st.geometric(0.5, size=None)
+random_st.geometric(0.5, size=1)
+random_st.geometric(D_arr_0p5)
+random_st.geometric(D_arr_0p5, size=1)
+random_st.geometric(D_arr_like_0p5)
+random_st.geometric(D_arr_like_0p5, size=1)
+
+random_st.logseries(0.5)
+random_st.logseries(0.5, size=None)
+random_st.logseries(0.5, size=1)
+random_st.logseries(D_arr_0p5)
+random_st.logseries(D_arr_0p5, size=1)
+random_st.logseries(D_arr_like_0p5)
+random_st.logseries(D_arr_like_0p5, size=1)
+
+random_st.rayleigh(0.5)
+random_st.rayleigh(0.5, size=None)
+random_st.rayleigh(0.5, size=1)
+random_st.rayleigh(D_arr_0p5)
+random_st.rayleigh(D_arr_0p5, size=1)
+random_st.rayleigh(D_arr_like_0p5)
+random_st.rayleigh(D_arr_like_0p5, size=1)
+
+random_st.standard_gamma(0.5)
+random_st.standard_gamma(0.5, size=None)
+random_st.standard_gamma(0.5, size=1)
+random_st.standard_gamma(D_arr_0p5)
+random_st.standard_gamma(D_arr_0p5, size=1)
+random_st.standard_gamma(D_arr_like_0p5)
+random_st.standard_gamma(D_arr_like_0p5, size=1)
+random_st.standard_gamma(D_arr_like_0p5, size=1)
+
+random_st.vonmises(0.5, 0.5)
+random_st.vonmises(0.5, 0.5, size=None)
+random_st.vonmises(0.5, 0.5, size=1)
+random_st.vonmises(D_arr_0p5, 0.5)
+random_st.vonmises(0.5, D_arr_0p5)
+random_st.vonmises(D_arr_0p5, 0.5, size=1)
+random_st.vonmises(0.5, D_arr_0p5, size=1)
+random_st.vonmises(D_arr_like_0p5, 0.5)
+random_st.vonmises(0.5, D_arr_like_0p5)
+random_st.vonmises(D_arr_0p5, D_arr_0p5)
+random_st.vonmises(D_arr_like_0p5, D_arr_like_0p5)
+random_st.vonmises(D_arr_0p5, D_arr_0p5, size=1)
+random_st.vonmises(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+random_st.wald(0.5, 0.5)
+random_st.wald(0.5, 0.5, size=None)
+random_st.wald(0.5, 0.5, size=1)
+random_st.wald(D_arr_0p5, 0.5)
+random_st.wald(0.5, D_arr_0p5)
+random_st.wald(D_arr_0p5, 0.5, size=1)
+random_st.wald(0.5, D_arr_0p5, size=1)
+random_st.wald(D_arr_like_0p5, 0.5)
+random_st.wald(0.5, D_arr_like_0p5)
+random_st.wald(D_arr_0p5, D_arr_0p5)
+random_st.wald(D_arr_like_0p5, D_arr_like_0p5)
+random_st.wald(D_arr_0p5, D_arr_0p5, size=1)
+random_st.wald(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+random_st.uniform(0.5, 0.5)
+random_st.uniform(0.5, 0.5, size=None)
+random_st.uniform(0.5, 0.5, size=1)
+random_st.uniform(D_arr_0p5, 0.5)
+random_st.uniform(0.5, D_arr_0p5)
+random_st.uniform(D_arr_0p5, 0.5, size=1)
+random_st.uniform(0.5, D_arr_0p5, size=1)
+random_st.uniform(D_arr_like_0p5, 0.5)
+random_st.uniform(0.5, D_arr_like_0p5)
+random_st.uniform(D_arr_0p5, D_arr_0p5)
+random_st.uniform(D_arr_like_0p5, D_arr_like_0p5)
+random_st.uniform(D_arr_0p5, D_arr_0p5, size=1)
+random_st.uniform(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+random_st.beta(0.5, 0.5)
+random_st.beta(0.5, 0.5, size=None)
+random_st.beta(0.5, 0.5, size=1)
+random_st.beta(D_arr_0p5, 0.5)
+random_st.beta(0.5, D_arr_0p5)
+random_st.beta(D_arr_0p5, 0.5, size=1)
+random_st.beta(0.5, D_arr_0p5, size=1)
+random_st.beta(D_arr_like_0p5, 0.5)
+random_st.beta(0.5, D_arr_like_0p5)
+random_st.beta(D_arr_0p5, D_arr_0p5)
+random_st.beta(D_arr_like_0p5, D_arr_like_0p5)
+random_st.beta(D_arr_0p5, D_arr_0p5, size=1)
+random_st.beta(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+random_st.f(0.5, 0.5)
+random_st.f(0.5, 0.5, size=None)
+random_st.f(0.5, 0.5, size=1)
+random_st.f(D_arr_0p5, 0.5)
+random_st.f(0.5, D_arr_0p5)
+random_st.f(D_arr_0p5, 0.5, size=1)
+random_st.f(0.5, D_arr_0p5, size=1)
+random_st.f(D_arr_like_0p5, 0.5)
+random_st.f(0.5, D_arr_like_0p5)
+random_st.f(D_arr_0p5, D_arr_0p5)
+random_st.f(D_arr_like_0p5, D_arr_like_0p5)
+random_st.f(D_arr_0p5, D_arr_0p5, size=1)
+random_st.f(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+random_st.gamma(0.5, 0.5)
+random_st.gamma(0.5, 0.5, size=None)
+random_st.gamma(0.5, 0.5, size=1)
+random_st.gamma(D_arr_0p5, 0.5)
+random_st.gamma(0.5, D_arr_0p5)
+random_st.gamma(D_arr_0p5, 0.5, size=1)
+random_st.gamma(0.5, D_arr_0p5, size=1)
+random_st.gamma(D_arr_like_0p5, 0.5)
+random_st.gamma(0.5, D_arr_like_0p5)
+random_st.gamma(D_arr_0p5, D_arr_0p5)
+random_st.gamma(D_arr_like_0p5, D_arr_like_0p5)
+random_st.gamma(D_arr_0p5, D_arr_0p5, size=1)
+random_st.gamma(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+random_st.gumbel(0.5, 0.5)
+random_st.gumbel(0.5, 0.5, size=None)
+random_st.gumbel(0.5, 0.5, size=1)
+random_st.gumbel(D_arr_0p5, 0.5)
+random_st.gumbel(0.5, D_arr_0p5)
+random_st.gumbel(D_arr_0p5, 0.5, size=1)
+random_st.gumbel(0.5, D_arr_0p5, size=1)
+random_st.gumbel(D_arr_like_0p5, 0.5)
+random_st.gumbel(0.5, D_arr_like_0p5)
+random_st.gumbel(D_arr_0p5, D_arr_0p5)
+random_st.gumbel(D_arr_like_0p5, D_arr_like_0p5)
+random_st.gumbel(D_arr_0p5, D_arr_0p5, size=1)
+random_st.gumbel(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+random_st.laplace(0.5, 0.5)
+random_st.laplace(0.5, 0.5, size=None)
+random_st.laplace(0.5, 0.5, size=1)
+random_st.laplace(D_arr_0p5, 0.5)
+random_st.laplace(0.5, D_arr_0p5)
+random_st.laplace(D_arr_0p5, 0.5, size=1)
+random_st.laplace(0.5, D_arr_0p5, size=1)
+random_st.laplace(D_arr_like_0p5, 0.5)
+random_st.laplace(0.5, D_arr_like_0p5)
+random_st.laplace(D_arr_0p5, D_arr_0p5)
+random_st.laplace(D_arr_like_0p5, D_arr_like_0p5)
+random_st.laplace(D_arr_0p5, D_arr_0p5, size=1)
+random_st.laplace(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+random_st.logistic(0.5, 0.5)
+random_st.logistic(0.5, 0.5, size=None)
+random_st.logistic(0.5, 0.5, size=1)
+random_st.logistic(D_arr_0p5, 0.5)
+random_st.logistic(0.5, D_arr_0p5)
+random_st.logistic(D_arr_0p5, 0.5, size=1)
+random_st.logistic(0.5, D_arr_0p5, size=1)
+random_st.logistic(D_arr_like_0p5, 0.5)
+random_st.logistic(0.5, D_arr_like_0p5)
+random_st.logistic(D_arr_0p5, D_arr_0p5)
+random_st.logistic(D_arr_like_0p5, D_arr_like_0p5)
+random_st.logistic(D_arr_0p5, D_arr_0p5, size=1)
+random_st.logistic(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+random_st.lognormal(0.5, 0.5)
+random_st.lognormal(0.5, 0.5, size=None)
+random_st.lognormal(0.5, 0.5, size=1)
+random_st.lognormal(D_arr_0p5, 0.5)
+random_st.lognormal(0.5, D_arr_0p5)
+random_st.lognormal(D_arr_0p5, 0.5, size=1)
+random_st.lognormal(0.5, D_arr_0p5, size=1)
+random_st.lognormal(D_arr_like_0p5, 0.5)
+random_st.lognormal(0.5, D_arr_like_0p5)
+random_st.lognormal(D_arr_0p5, D_arr_0p5)
+random_st.lognormal(D_arr_like_0p5, D_arr_like_0p5)
+random_st.lognormal(D_arr_0p5, D_arr_0p5, size=1)
+random_st.lognormal(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+random_st.noncentral_chisquare(0.5, 0.5)
+random_st.noncentral_chisquare(0.5, 0.5, size=None)
+random_st.noncentral_chisquare(0.5, 0.5, size=1)
+random_st.noncentral_chisquare(D_arr_0p5, 0.5)
+random_st.noncentral_chisquare(0.5, D_arr_0p5)
+random_st.noncentral_chisquare(D_arr_0p5, 0.5, size=1)
+random_st.noncentral_chisquare(0.5, D_arr_0p5, size=1)
+random_st.noncentral_chisquare(D_arr_like_0p5, 0.5)
+random_st.noncentral_chisquare(0.5, D_arr_like_0p5)
+random_st.noncentral_chisquare(D_arr_0p5, D_arr_0p5)
+random_st.noncentral_chisquare(D_arr_like_0p5, D_arr_like_0p5)
+random_st.noncentral_chisquare(D_arr_0p5, D_arr_0p5, size=1)
+random_st.noncentral_chisquare(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+random_st.normal(0.5, 0.5)
+random_st.normal(0.5, 0.5, size=None)
+random_st.normal(0.5, 0.5, size=1)
+random_st.normal(D_arr_0p5, 0.5)
+random_st.normal(0.5, D_arr_0p5)
+random_st.normal(D_arr_0p5, 0.5, size=1)
+random_st.normal(0.5, D_arr_0p5, size=1)
+random_st.normal(D_arr_like_0p5, 0.5)
+random_st.normal(0.5, D_arr_like_0p5)
+random_st.normal(D_arr_0p5, D_arr_0p5)
+random_st.normal(D_arr_like_0p5, D_arr_like_0p5)
+random_st.normal(D_arr_0p5, D_arr_0p5, size=1)
+random_st.normal(D_arr_like_0p5, D_arr_like_0p5, size=1)
+
+random_st.triangular(0.1, 0.5, 0.9)
+random_st.triangular(0.1, 0.5, 0.9, size=None)
+random_st.triangular(0.1, 0.5, 0.9, size=1)
+random_st.triangular(D_arr_0p1, 0.5, 0.9)
+random_st.triangular(0.1, D_arr_0p5, 0.9)
+random_st.triangular(D_arr_0p1, 0.5, D_arr_like_0p9, size=1)
+random_st.triangular(0.1, D_arr_0p5, 0.9, size=1)
+random_st.triangular(D_arr_like_0p1, 0.5, D_arr_0p9)
+random_st.triangular(0.5, D_arr_like_0p5, 0.9)
+random_st.triangular(D_arr_0p1, D_arr_0p5, 0.9)
+random_st.triangular(D_arr_like_0p1, D_arr_like_0p5, 0.9)
+random_st.triangular(D_arr_0p1, D_arr_0p5, D_arr_0p9, size=1)
+random_st.triangular(D_arr_like_0p1, D_arr_like_0p5, D_arr_like_0p9, size=1)
+
+random_st.noncentral_f(0.1, 0.5, 0.9)
+random_st.noncentral_f(0.1, 0.5, 0.9, size=None)
+random_st.noncentral_f(0.1, 0.5, 0.9, size=1)
+random_st.noncentral_f(D_arr_0p1, 0.5, 0.9)
+random_st.noncentral_f(0.1, D_arr_0p5, 0.9)
+random_st.noncentral_f(D_arr_0p1, 0.5, D_arr_like_0p9, size=1)
+random_st.noncentral_f(0.1, D_arr_0p5, 0.9, size=1)
+random_st.noncentral_f(D_arr_like_0p1, 0.5, D_arr_0p9)
+random_st.noncentral_f(0.5, D_arr_like_0p5, 0.9)
+random_st.noncentral_f(D_arr_0p1, D_arr_0p5, 0.9)
+random_st.noncentral_f(D_arr_like_0p1, D_arr_like_0p5, 0.9)
+random_st.noncentral_f(D_arr_0p1, D_arr_0p5, D_arr_0p9, size=1)
+random_st.noncentral_f(D_arr_like_0p1, D_arr_like_0p5, D_arr_like_0p9, size=1)
+
+random_st.binomial(10, 0.5)
+random_st.binomial(10, 0.5, size=None)
+random_st.binomial(10, 0.5, size=1)
+random_st.binomial(I_arr_10, 0.5)
+random_st.binomial(10, D_arr_0p5)
+random_st.binomial(I_arr_10, 0.5, size=1)
+random_st.binomial(10, D_arr_0p5, size=1)
+random_st.binomial(I_arr_like_10, 0.5)
+random_st.binomial(10, D_arr_like_0p5)
+random_st.binomial(I_arr_10, D_arr_0p5)
+random_st.binomial(I_arr_like_10, D_arr_like_0p5)
+random_st.binomial(I_arr_10, D_arr_0p5, size=1)
+random_st.binomial(I_arr_like_10, D_arr_like_0p5, size=1)
+
+random_st.negative_binomial(10, 0.5)
+random_st.negative_binomial(10, 0.5, size=None)
+random_st.negative_binomial(10, 0.5, size=1)
+random_st.negative_binomial(I_arr_10, 0.5)
+random_st.negative_binomial(10, D_arr_0p5)
+random_st.negative_binomial(I_arr_10, 0.5, size=1)
+random_st.negative_binomial(10, D_arr_0p5, size=1)
+random_st.negative_binomial(I_arr_like_10, 0.5)
+random_st.negative_binomial(10, D_arr_like_0p5)
+random_st.negative_binomial(I_arr_10, D_arr_0p5)
+random_st.negative_binomial(I_arr_like_10, D_arr_like_0p5)
+random_st.negative_binomial(I_arr_10, D_arr_0p5, size=1)
+random_st.negative_binomial(I_arr_like_10, D_arr_like_0p5, size=1)
+
+random_st.hypergeometric(20, 20, 10)
+random_st.hypergeometric(20, 20, 10, size=None)
+random_st.hypergeometric(20, 20, 10, size=1)
+random_st.hypergeometric(I_arr_20, 20, 10)
+random_st.hypergeometric(20, I_arr_20, 10)
+random_st.hypergeometric(I_arr_20, 20, I_arr_like_10, size=1)
+random_st.hypergeometric(20, I_arr_20, 10, size=1)
+random_st.hypergeometric(I_arr_like_20, 20, I_arr_10)
+random_st.hypergeometric(20, I_arr_like_20, 10)
+random_st.hypergeometric(I_arr_20, I_arr_20, 10)
+random_st.hypergeometric(I_arr_like_20, I_arr_like_20, 10)
+random_st.hypergeometric(I_arr_20, I_arr_20, I_arr_10, size=1)
+random_st.hypergeometric(I_arr_like_20, I_arr_like_20, I_arr_like_10, size=1)
+
+random_st.randint(0, 100)
+random_st.randint(100)
+random_st.randint([100])
+random_st.randint(0, [100])
+
+random_st.randint(2, dtype=bool)
+random_st.randint(0, 2, dtype=bool)
+random_st.randint(I_bool_high_open, dtype=bool)
+random_st.randint(I_bool_low, I_bool_high_open, dtype=bool)
+random_st.randint(0, I_bool_high_open, dtype=bool)
+
+random_st.randint(2, dtype=np.bool_)
+random_st.randint(0, 2, dtype=np.bool_)
+random_st.randint(I_bool_high_open, dtype=np.bool_)
+random_st.randint(I_bool_low, I_bool_high_open, dtype=np.bool_)
+random_st.randint(0, I_bool_high_open, dtype=np.bool_)
+
+random_st.randint(256, dtype="u1")
+random_st.randint(0, 256, dtype="u1")
+random_st.randint(I_u1_high_open, dtype="u1")
+random_st.randint(I_u1_low, I_u1_high_open, dtype="u1")
+random_st.randint(0, I_u1_high_open, dtype="u1")
+
+random_st.randint(256, dtype="uint8")
+random_st.randint(0, 256, dtype="uint8")
+random_st.randint(I_u1_high_open, dtype="uint8")
+random_st.randint(I_u1_low, I_u1_high_open, dtype="uint8")
+random_st.randint(0, I_u1_high_open, dtype="uint8")
+
+random_st.randint(256, dtype=np.uint8)
+random_st.randint(0, 256, dtype=np.uint8)
+random_st.randint(I_u1_high_open, dtype=np.uint8)
+random_st.randint(I_u1_low, I_u1_high_open, dtype=np.uint8)
+random_st.randint(0, I_u1_high_open, dtype=np.uint8)
+
+random_st.randint(65536, dtype="u2")
+random_st.randint(0, 65536, dtype="u2")
+random_st.randint(I_u2_high_open, dtype="u2")
+random_st.randint(I_u2_low, I_u2_high_open, dtype="u2")
+random_st.randint(0, I_u2_high_open, dtype="u2")
+
+random_st.randint(65536, dtype="uint16")
+random_st.randint(0, 65536, dtype="uint16")
+random_st.randint(I_u2_high_open, dtype="uint16")
+random_st.randint(I_u2_low, I_u2_high_open, dtype="uint16")
+random_st.randint(0, I_u2_high_open, dtype="uint16")
+
+random_st.randint(65536, dtype=np.uint16)
+random_st.randint(0, 65536, dtype=np.uint16)
+random_st.randint(I_u2_high_open, dtype=np.uint16)
+random_st.randint(I_u2_low, I_u2_high_open, dtype=np.uint16)
+random_st.randint(0, I_u2_high_open, dtype=np.uint16)
+
+random_st.randint(4294967296, dtype="u4")
+random_st.randint(0, 4294967296, dtype="u4")
+random_st.randint(I_u4_high_open, dtype="u4")
+random_st.randint(I_u4_low, I_u4_high_open, dtype="u4")
+random_st.randint(0, I_u4_high_open, dtype="u4")
+
+random_st.randint(4294967296, dtype="uint32")
+random_st.randint(0, 4294967296, dtype="uint32")
+random_st.randint(I_u4_high_open, dtype="uint32")
+random_st.randint(I_u4_low, I_u4_high_open, dtype="uint32")
+random_st.randint(0, I_u4_high_open, dtype="uint32")
+
+random_st.randint(4294967296, dtype=np.uint32)
+random_st.randint(0, 4294967296, dtype=np.uint32)
+random_st.randint(I_u4_high_open, dtype=np.uint32)
+random_st.randint(I_u4_low, I_u4_high_open, dtype=np.uint32)
+random_st.randint(0, I_u4_high_open, dtype=np.uint32)
+
+
+random_st.randint(18446744073709551616, dtype="u8")
+random_st.randint(0, 18446744073709551616, dtype="u8")
+random_st.randint(I_u8_high_open, dtype="u8")
+random_st.randint(I_u8_low, I_u8_high_open, dtype="u8")
+random_st.randint(0, I_u8_high_open, dtype="u8")
+
+random_st.randint(18446744073709551616, dtype="uint64")
+random_st.randint(0, 18446744073709551616, dtype="uint64")
+random_st.randint(I_u8_high_open, dtype="uint64")
+random_st.randint(I_u8_low, I_u8_high_open, dtype="uint64")
+random_st.randint(0, I_u8_high_open, dtype="uint64")
+
+random_st.randint(18446744073709551616, dtype=np.uint64)
+random_st.randint(0, 18446744073709551616, dtype=np.uint64)
+random_st.randint(I_u8_high_open, dtype=np.uint64)
+random_st.randint(I_u8_low, I_u8_high_open, dtype=np.uint64)
+random_st.randint(0, I_u8_high_open, dtype=np.uint64)
+
+random_st.randint(128, dtype="i1")
+random_st.randint(-128, 128, dtype="i1")
+random_st.randint(I_i1_high_open, dtype="i1")
+random_st.randint(I_i1_low, I_i1_high_open, dtype="i1")
+random_st.randint(-128, I_i1_high_open, dtype="i1")
+
+random_st.randint(128, dtype="int8")
+random_st.randint(-128, 128, dtype="int8")
+random_st.randint(I_i1_high_open, dtype="int8")
+random_st.randint(I_i1_low, I_i1_high_open, dtype="int8")
+random_st.randint(-128, I_i1_high_open, dtype="int8")
+
+random_st.randint(128, dtype=np.int8)
+random_st.randint(-128, 128, dtype=np.int8)
+random_st.randint(I_i1_high_open, dtype=np.int8)
+random_st.randint(I_i1_low, I_i1_high_open, dtype=np.int8)
+random_st.randint(-128, I_i1_high_open, dtype=np.int8)
+
+random_st.randint(32768, dtype="i2")
+random_st.randint(-32768, 32768, dtype="i2")
+random_st.randint(I_i2_high_open, dtype="i2")
+random_st.randint(I_i2_low, I_i2_high_open, dtype="i2")
+random_st.randint(-32768, I_i2_high_open, dtype="i2")
+random_st.randint(32768, dtype="int16")
+random_st.randint(-32768, 32768, dtype="int16")
+random_st.randint(I_i2_high_open, dtype="int16")
+random_st.randint(I_i2_low, I_i2_high_open, dtype="int16")
+random_st.randint(-32768, I_i2_high_open, dtype="int16")
+random_st.randint(32768, dtype=np.int16)
+random_st.randint(-32768, 32768, dtype=np.int16)
+random_st.randint(I_i2_high_open, dtype=np.int16)
+random_st.randint(I_i2_low, I_i2_high_open, dtype=np.int16)
+random_st.randint(-32768, I_i2_high_open, dtype=np.int16)
+
+random_st.randint(2147483648, dtype="i4")
+random_st.randint(-2147483648, 2147483648, dtype="i4")
+random_st.randint(I_i4_high_open, dtype="i4")
+random_st.randint(I_i4_low, I_i4_high_open, dtype="i4")
+random_st.randint(-2147483648, I_i4_high_open, dtype="i4")
+
+random_st.randint(2147483648, dtype="int32")
+random_st.randint(-2147483648, 2147483648, dtype="int32")
+random_st.randint(I_i4_high_open, dtype="int32")
+random_st.randint(I_i4_low, I_i4_high_open, dtype="int32")
+random_st.randint(-2147483648, I_i4_high_open, dtype="int32")
+
+random_st.randint(2147483648, dtype=np.int32)
+random_st.randint(-2147483648, 2147483648, dtype=np.int32)
+random_st.randint(I_i4_high_open, dtype=np.int32)
+random_st.randint(I_i4_low, I_i4_high_open, dtype=np.int32)
+random_st.randint(-2147483648, I_i4_high_open, dtype=np.int32)
+
+random_st.randint(9223372036854775808, dtype="i8")
+random_st.randint(-9223372036854775808, 9223372036854775808, dtype="i8")
+random_st.randint(I_i8_high_open, dtype="i8")
+random_st.randint(I_i8_low, I_i8_high_open, dtype="i8")
+random_st.randint(-9223372036854775808, I_i8_high_open, dtype="i8")
+
+random_st.randint(9223372036854775808, dtype="int64")
+random_st.randint(-9223372036854775808, 9223372036854775808, dtype="int64")
+random_st.randint(I_i8_high_open, dtype="int64")
+random_st.randint(I_i8_low, I_i8_high_open, dtype="int64")
+random_st.randint(-9223372036854775808, I_i8_high_open, dtype="int64")
+
+random_st.randint(9223372036854775808, dtype=np.int64)
+random_st.randint(-9223372036854775808, 9223372036854775808, dtype=np.int64)
+random_st.randint(I_i8_high_open, dtype=np.int64)
+random_st.randint(I_i8_low, I_i8_high_open, dtype=np.int64)
+random_st.randint(-9223372036854775808, I_i8_high_open, dtype=np.int64)
+
+bg: np.random.BitGenerator = random_st._bit_generator
+
+random_st.bytes(2)
+
+random_st.choice(5)
+random_st.choice(5, 3)
+random_st.choice(5, 3, replace=True)
+random_st.choice(5, 3, p=[1 / 5] * 5)
+random_st.choice(5, 3, p=[1 / 5] * 5, replace=False)
+
+random_st.choice(["pooh", "rabbit", "piglet", "Christopher"])
+random_st.choice(["pooh", "rabbit", "piglet", "Christopher"], 3)
+random_st.choice(["pooh", "rabbit", "piglet", "Christopher"], 3, p=[1 / 4] * 4)
+random_st.choice(["pooh", "rabbit", "piglet", "Christopher"], 3, replace=True)
+random_st.choice(["pooh", "rabbit", "piglet", "Christopher"], 3, replace=False, p=np.array([1 / 8, 1 / 8, 1 / 2, 1 / 4]))
+
+random_st.dirichlet([0.5, 0.5])
+random_st.dirichlet(np.array([0.5, 0.5]))
+random_st.dirichlet(np.array([0.5, 0.5]), size=3)
+
+random_st.multinomial(20, [1 / 6.0] * 6)
+random_st.multinomial(20, np.array([0.5, 0.5]))
+random_st.multinomial(20, [1 / 6.0] * 6, size=2)
+
+random_st.multivariate_normal([0.0], [[1.0]])
+random_st.multivariate_normal([0.0], np.array([[1.0]]))
+random_st.multivariate_normal(np.array([0.0]), [[1.0]])
+random_st.multivariate_normal([0.0], np.array([[1.0]]))
+
+random_st.permutation(10)
+random_st.permutation([1, 2, 3, 4])
+random_st.permutation(np.array([1, 2, 3, 4]))
+random_st.permutation(D_2D)
+
+random_st.shuffle(np.arange(10))
+random_st.shuffle([1, 2, 3, 4, 5])
+random_st.shuffle(D_2D)
+
+np.random.RandomState(SEED_PCG64)
+np.random.RandomState(0)
+np.random.RandomState([0, 1, 2])
+random_st.__str__()
+random_st.__repr__()
+random_st_state = random_st.__getstate__()
+random_st.__setstate__(random_st_state)
+random_st.seed()
+random_st.seed(1)
+random_st.seed([0, 1])
+random_st_get_state = random_st.get_state()
+random_st_get_state_legacy = random_st.get_state(legacy=True)
+random_st.set_state(random_st_get_state)
+
+random_st.rand()
+random_st.rand(1)
+random_st.rand(1, 2)
+random_st.randn()
+random_st.randn(1)
+random_st.randn(1, 2)
+random_st.random_sample()
+random_st.random_sample(1)
+random_st.random_sample(size=(1, 2))
+
+random_st.tomaxint()
+random_st.tomaxint(1)
+random_st.tomaxint((1,))
diff --git a/numpy/typing/tests/data/pass/scalars.py b/numpy/typing/tests/data/pass/scalars.py
index b7f7880e4..b258db49f 100644
--- a/numpy/typing/tests/data/pass/scalars.py
+++ b/numpy/typing/tests/data/pass/scalars.py
@@ -4,6 +4,14 @@ import datetime as dt
import pytest
import numpy as np
+b = np.bool_()
+u8 = np.uint64()
+i8 = np.int64()
+f8 = np.float64()
+c16 = np.complex128()
+U = np.str_()
+S = np.bytes_()
+
# Construction
class D:
@@ -84,6 +92,7 @@ np.datetime64(b"2019")
np.datetime64("2019", "D")
np.datetime64(np.datetime64())
np.datetime64(dt.datetime(2000, 5, 3))
+np.datetime64(dt.date(2000, 5, 3))
np.datetime64(None)
np.datetime64(None, "D")
@@ -163,3 +172,83 @@ c16.strides
c16.squeeze()
c16.byteswap()
c16.transpose()
+
+# Aliases
+np.str0()
+np.bool8()
+np.bytes0()
+np.string_()
+np.object0()
+np.void0(0)
+
+np.byte()
+np.short()
+np.intc()
+np.intp()
+np.int0()
+np.int_()
+np.longlong()
+
+np.ubyte()
+np.ushort()
+np.uintc()
+np.uintp()
+np.uint0()
+np.uint()
+np.ulonglong()
+
+np.half()
+np.single()
+np.double()
+np.float_()
+np.longdouble()
+np.longfloat()
+
+np.csingle()
+np.singlecomplex()
+np.cdouble()
+np.complex_()
+np.cfloat()
+np.clongdouble()
+np.clongfloat()
+np.longcomplex()
+
+b.item()
+i8.item()
+u8.item()
+f8.item()
+c16.item()
+U.item()
+S.item()
+
+b.tolist()
+i8.tolist()
+u8.tolist()
+f8.tolist()
+c16.tolist()
+U.tolist()
+S.tolist()
+
+b.ravel()
+i8.ravel()
+u8.ravel()
+f8.ravel()
+c16.ravel()
+U.ravel()
+S.ravel()
+
+b.flatten()
+i8.flatten()
+u8.flatten()
+f8.flatten()
+c16.flatten()
+U.flatten()
+S.flatten()
+
+b.reshape(1)
+i8.reshape(1)
+u8.reshape(1)
+f8.reshape(1)
+c16.reshape(1)
+U.reshape(1)
+S.reshape(1)
diff --git a/numpy/typing/tests/data/pass/ufunclike.py b/numpy/typing/tests/data/pass/ufunclike.py
new file mode 100644
index 000000000..7eac89e8f
--- /dev/null
+++ b/numpy/typing/tests/data/pass/ufunclike.py
@@ -0,0 +1,46 @@
+from __future__ import annotations
+from typing import Any
+import numpy as np
+
+
+class Object:
+ def __ceil__(self) -> Object:
+ return self
+
+ def __floor__(self) -> Object:
+ return self
+
+ def __ge__(self, value: object) -> bool:
+ return True
+
+ def __array__(self) -> np.ndarray[Any, np.dtype[np.object_]]:
+ ret = np.empty((), dtype=object)
+ ret[()] = self
+ return ret
+
+
+AR_LIKE_b = [True, True, False]
+AR_LIKE_u = [np.uint32(1), np.uint32(2), np.uint32(3)]
+AR_LIKE_i = [1, 2, 3]
+AR_LIKE_f = [1.0, 2.0, 3.0]
+AR_LIKE_O = [Object(), Object(), Object()]
+AR_U: np.ndarray[Any, np.dtype[np.str_]] = np.zeros(3, dtype="U5")
+
+np.fix(AR_LIKE_b)
+np.fix(AR_LIKE_u)
+np.fix(AR_LIKE_i)
+np.fix(AR_LIKE_f)
+np.fix(AR_LIKE_O)
+np.fix(AR_LIKE_f, out=AR_U)
+
+np.isposinf(AR_LIKE_b)
+np.isposinf(AR_LIKE_u)
+np.isposinf(AR_LIKE_i)
+np.isposinf(AR_LIKE_f)
+np.isposinf(AR_LIKE_f, out=AR_U)
+
+np.isneginf(AR_LIKE_b)
+np.isneginf(AR_LIKE_u)
+np.isneginf(AR_LIKE_i)
+np.isneginf(AR_LIKE_f)
+np.isneginf(AR_LIKE_f, out=AR_U)
diff --git a/numpy/typing/tests/data/pass/ufuncs.py b/numpy/typing/tests/data/pass/ufuncs.py
index ad4d483d4..3cc31ae5e 100644
--- a/numpy/typing/tests/data/pass/ufuncs.py
+++ b/numpy/typing/tests/data/pass/ufuncs.py
@@ -4,7 +4,7 @@ np.sin(1)
np.sin([1, 2, 3])
np.sin(1, out=np.empty(1))
np.matmul(np.ones((2, 2, 2)), np.ones((2, 2, 2)), axes=[(0, 1), (0, 1), (0, 1)])
-np.sin(1, signature="D")
+np.sin(1, signature="D->D")
np.sin(1, extobj=[16, 1, lambda: None])
# NOTE: `np.generic` subclasses are not guaranteed to support addition;
# re-enable this we can infer the exact return type of `np.sin(...)`.
@@ -12,5 +12,6 @@ np.sin(1, extobj=[16, 1, lambda: None])
# np.sin(1) + np.sin(1)
np.sin.types[0]
np.sin.__name__
+np.sin.__doc__
np.abs(np.array([1]))
diff --git a/numpy/typing/tests/data/pass/warnings_and_errors.py b/numpy/typing/tests/data/pass/warnings_and_errors.py
index 5b6ec2626..a556bf6bc 100644
--- a/numpy/typing/tests/data/pass/warnings_and_errors.py
+++ b/numpy/typing/tests/data/pass/warnings_and_errors.py
@@ -1,7 +1,6 @@
import numpy as np
-np.AxisError(1)
+np.AxisError("test")
np.AxisError(1, ndim=2)
-np.AxisError(1, ndim=None)
np.AxisError(1, ndim=2, msg_prefix="error")
np.AxisError(1, ndim=2, msg_prefix=None)
diff --git a/numpy/typing/tests/data/reveal/arithmetic.py b/numpy/typing/tests/data/reveal/arithmetic.py
index 20310e691..0d9132e5b 100644
--- a/numpy/typing/tests/data/reveal/arithmetic.py
+++ b/numpy/typing/tests/data/reveal/arithmetic.py
@@ -1,4 +1,9 @@
+from typing import Any, List
import numpy as np
+import numpy.typing as npt
+
+# Can't directly import `np.float128` as it is not available on all platforms
+f16: np.floating[npt._128Bit]
c16 = np.complex128()
f8 = np.float64()
@@ -20,44 +25,260 @@ c = complex()
f = float()
i = int()
-AR = np.array([0], dtype=np.float64)
-AR.setflags(write=False)
+AR_b: np.ndarray[Any, np.dtype[np.bool_]]
+AR_u: np.ndarray[Any, np.dtype[np.uint32]]
+AR_i: np.ndarray[Any, np.dtype[np.int64]]
+AR_f: np.ndarray[Any, np.dtype[np.float64]]
+AR_c: np.ndarray[Any, np.dtype[np.complex128]]
+AR_m: np.ndarray[Any, np.dtype[np.timedelta64]]
+AR_M: np.ndarray[Any, np.dtype[np.datetime64]]
+AR_O: np.ndarray[Any, np.dtype[np.object_]]
+
+AR_LIKE_b: List[bool]
+AR_LIKE_u: List[np.uint32]
+AR_LIKE_i: List[int]
+AR_LIKE_f: List[float]
+AR_LIKE_c: List[complex]
+AR_LIKE_m: List[np.timedelta64]
+AR_LIKE_M: List[np.datetime64]
+AR_LIKE_O: List[np.object_]
+
+# Array subtraction
+
+reveal_type(AR_b - AR_LIKE_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[Any]]]
+reveal_type(AR_b - AR_LIKE_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(AR_b - AR_LIKE_f) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_b - AR_LIKE_c) # E: numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]
+reveal_type(AR_b - AR_LIKE_m) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(AR_b - AR_LIKE_O) # E: Any
+
+reveal_type(AR_LIKE_u - AR_b) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[Any]]]
+reveal_type(AR_LIKE_i - AR_b) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(AR_LIKE_f - AR_b) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_LIKE_c - AR_b) # E: numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]
+reveal_type(AR_LIKE_m - AR_b) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(AR_LIKE_M - AR_b) # E: numpy.ndarray[Any, numpy.dtype[numpy.datetime64]]
+reveal_type(AR_LIKE_O - AR_b) # E: Any
+
+reveal_type(AR_u - AR_LIKE_b) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[Any]]]
+reveal_type(AR_u - AR_LIKE_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[Any]]]
+reveal_type(AR_u - AR_LIKE_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(AR_u - AR_LIKE_f) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_u - AR_LIKE_c) # E: numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]
+reveal_type(AR_u - AR_LIKE_m) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(AR_u - AR_LIKE_O) # E: Any
+
+reveal_type(AR_LIKE_b - AR_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[Any]]]
+reveal_type(AR_LIKE_u - AR_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[Any]]]
+reveal_type(AR_LIKE_i - AR_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(AR_LIKE_f - AR_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_LIKE_c - AR_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]
+reveal_type(AR_LIKE_m - AR_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(AR_LIKE_M - AR_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.datetime64]]
+reveal_type(AR_LIKE_O - AR_u) # E: Any
+
+reveal_type(AR_i - AR_LIKE_b) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(AR_i - AR_LIKE_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(AR_i - AR_LIKE_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(AR_i - AR_LIKE_f) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_i - AR_LIKE_c) # E: numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]
+reveal_type(AR_i - AR_LIKE_m) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(AR_i - AR_LIKE_O) # E: Any
+
+reveal_type(AR_LIKE_b - AR_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(AR_LIKE_u - AR_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(AR_LIKE_i - AR_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(AR_LIKE_f - AR_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_LIKE_c - AR_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]
+reveal_type(AR_LIKE_m - AR_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(AR_LIKE_M - AR_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.datetime64]]
+reveal_type(AR_LIKE_O - AR_i) # E: Any
+
+reveal_type(AR_f - AR_LIKE_b) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_f - AR_LIKE_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_f - AR_LIKE_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_f - AR_LIKE_f) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_f - AR_LIKE_c) # E: numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]
+reveal_type(AR_f - AR_LIKE_O) # E: Any
+
+reveal_type(AR_LIKE_b - AR_f) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_LIKE_u - AR_f) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_LIKE_i - AR_f) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_LIKE_f - AR_f) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_LIKE_c - AR_f) # E: numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]
+reveal_type(AR_LIKE_O - AR_f) # E: Any
+
+reveal_type(AR_c - AR_LIKE_b) # E: numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]
+reveal_type(AR_c - AR_LIKE_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]
+reveal_type(AR_c - AR_LIKE_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]
+reveal_type(AR_c - AR_LIKE_f) # E: numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]
+reveal_type(AR_c - AR_LIKE_c) # E: numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]
+reveal_type(AR_c - AR_LIKE_O) # E: Any
+
+reveal_type(AR_LIKE_b - AR_c) # E: numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]
+reveal_type(AR_LIKE_u - AR_c) # E: numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]
+reveal_type(AR_LIKE_i - AR_c) # E: numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]
+reveal_type(AR_LIKE_f - AR_c) # E: numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]
+reveal_type(AR_LIKE_c - AR_c) # E: numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]
+reveal_type(AR_LIKE_O - AR_c) # E: Any
+
+reveal_type(AR_m - AR_LIKE_b) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(AR_m - AR_LIKE_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(AR_m - AR_LIKE_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(AR_m - AR_LIKE_m) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(AR_m - AR_LIKE_O) # E: Any
+
+reveal_type(AR_LIKE_b - AR_m) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(AR_LIKE_u - AR_m) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(AR_LIKE_i - AR_m) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(AR_LIKE_m - AR_m) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(AR_LIKE_M - AR_m) # E: numpy.ndarray[Any, numpy.dtype[numpy.datetime64]]
+reveal_type(AR_LIKE_O - AR_m) # E: Any
+
+reveal_type(AR_M - AR_LIKE_b) # E: numpy.ndarray[Any, numpy.dtype[numpy.datetime64]]
+reveal_type(AR_M - AR_LIKE_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.datetime64]]
+reveal_type(AR_M - AR_LIKE_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.datetime64]]
+reveal_type(AR_M - AR_LIKE_m) # E: numpy.ndarray[Any, numpy.dtype[numpy.datetime64]]
+reveal_type(AR_M - AR_LIKE_M) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(AR_M - AR_LIKE_O) # E: Any
+
+reveal_type(AR_LIKE_M - AR_M) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(AR_LIKE_O - AR_M) # E: Any
+
+reveal_type(AR_O - AR_LIKE_b) # E: Any
+reveal_type(AR_O - AR_LIKE_u) # E: Any
+reveal_type(AR_O - AR_LIKE_i) # E: Any
+reveal_type(AR_O - AR_LIKE_f) # E: Any
+reveal_type(AR_O - AR_LIKE_c) # E: Any
+reveal_type(AR_O - AR_LIKE_m) # E: Any
+reveal_type(AR_O - AR_LIKE_M) # E: Any
+reveal_type(AR_O - AR_LIKE_O) # E: Any
+
+reveal_type(AR_LIKE_b - AR_O) # E: Any
+reveal_type(AR_LIKE_u - AR_O) # E: Any
+reveal_type(AR_LIKE_i - AR_O) # E: Any
+reveal_type(AR_LIKE_f - AR_O) # E: Any
+reveal_type(AR_LIKE_c - AR_O) # E: Any
+reveal_type(AR_LIKE_m - AR_O) # E: Any
+reveal_type(AR_LIKE_M - AR_O) # E: Any
+reveal_type(AR_LIKE_O - AR_O) # E: Any
+
+# Array floor division
+
+reveal_type(AR_b // AR_LIKE_b) # E: numpy.ndarray[Any, numpy.dtype[{int8}]]
+reveal_type(AR_b // AR_LIKE_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[Any]]]
+reveal_type(AR_b // AR_LIKE_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(AR_b // AR_LIKE_f) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_b // AR_LIKE_O) # E: Any
+
+reveal_type(AR_LIKE_b // AR_b) # E: numpy.ndarray[Any, numpy.dtype[{int8}]]
+reveal_type(AR_LIKE_u // AR_b) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[Any]]]
+reveal_type(AR_LIKE_i // AR_b) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(AR_LIKE_f // AR_b) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_LIKE_O // AR_b) # E: Any
+
+reveal_type(AR_u // AR_LIKE_b) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[Any]]]
+reveal_type(AR_u // AR_LIKE_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[Any]]]
+reveal_type(AR_u // AR_LIKE_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(AR_u // AR_LIKE_f) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_u // AR_LIKE_O) # E: Any
+
+reveal_type(AR_LIKE_b // AR_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[Any]]]
+reveal_type(AR_LIKE_u // AR_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[Any]]]
+reveal_type(AR_LIKE_i // AR_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(AR_LIKE_f // AR_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_LIKE_m // AR_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(AR_LIKE_O // AR_u) # E: Any
+
+reveal_type(AR_i // AR_LIKE_b) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(AR_i // AR_LIKE_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(AR_i // AR_LIKE_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(AR_i // AR_LIKE_f) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_i // AR_LIKE_O) # E: Any
+
+reveal_type(AR_LIKE_b // AR_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(AR_LIKE_u // AR_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(AR_LIKE_i // AR_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(AR_LIKE_f // AR_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_LIKE_m // AR_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(AR_LIKE_O // AR_i) # E: Any
+
+reveal_type(AR_f // AR_LIKE_b) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_f // AR_LIKE_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_f // AR_LIKE_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_f // AR_LIKE_f) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_f // AR_LIKE_O) # E: Any
+
+reveal_type(AR_LIKE_b // AR_f) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_LIKE_u // AR_f) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_LIKE_i // AR_f) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_LIKE_f // AR_f) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(AR_LIKE_m // AR_f) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(AR_LIKE_O // AR_f) # E: Any
+
+reveal_type(AR_m // AR_LIKE_u) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(AR_m // AR_LIKE_i) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(AR_m // AR_LIKE_f) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(AR_m // AR_LIKE_m) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(AR_m // AR_LIKE_O) # E: Any
+
+reveal_type(AR_LIKE_m // AR_m) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(AR_LIKE_O // AR_m) # E: Any
+
+reveal_type(AR_O // AR_LIKE_b) # E: Any
+reveal_type(AR_O // AR_LIKE_u) # E: Any
+reveal_type(AR_O // AR_LIKE_i) # E: Any
+reveal_type(AR_O // AR_LIKE_f) # E: Any
+reveal_type(AR_O // AR_LIKE_m) # E: Any
+reveal_type(AR_O // AR_LIKE_M) # E: Any
+reveal_type(AR_O // AR_LIKE_O) # E: Any
+
+reveal_type(AR_LIKE_b // AR_O) # E: Any
+reveal_type(AR_LIKE_u // AR_O) # E: Any
+reveal_type(AR_LIKE_i // AR_O) # E: Any
+reveal_type(AR_LIKE_f // AR_O) # E: Any
+reveal_type(AR_LIKE_m // AR_O) # E: Any
+reveal_type(AR_LIKE_M // AR_O) # E: Any
+reveal_type(AR_LIKE_O // AR_O) # E: Any
# unary ops
-reveal_type(-c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(-c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
-reveal_type(-f8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(-f4) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(-i8) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(-i4) # E: numpy.signedinteger[numpy.typing._32Bit]
-reveal_type(-u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(-u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
+reveal_type(-f16) # E: {float128}
+reveal_type(-c16) # E: {complex128}
+reveal_type(-c8) # E: {complex64}
+reveal_type(-f8) # E: {float64}
+reveal_type(-f4) # E: {float32}
+reveal_type(-i8) # E: {int64}
+reveal_type(-i4) # E: {int32}
+reveal_type(-u8) # E: {uint64}
+reveal_type(-u4) # E: {uint32}
reveal_type(-td) # E: numpy.timedelta64
-reveal_type(-AR) # E: Any
-
-reveal_type(+c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(+c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
-reveal_type(+f8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(+f4) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(+i8) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(+i4) # E: numpy.signedinteger[numpy.typing._32Bit]
-reveal_type(+u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(+u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
+reveal_type(-AR_f) # E: Any
+
+reveal_type(+f16) # E: {float128}
+reveal_type(+c16) # E: {complex128}
+reveal_type(+c8) # E: {complex64}
+reveal_type(+f8) # E: {float64}
+reveal_type(+f4) # E: {float32}
+reveal_type(+i8) # E: {int64}
+reveal_type(+i4) # E: {int32}
+reveal_type(+u8) # E: {uint64}
+reveal_type(+u4) # E: {uint32}
reveal_type(+td) # E: numpy.timedelta64
-reveal_type(+AR) # E: Any
-
-reveal_type(abs(c16)) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(abs(c8)) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(abs(f8)) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(abs(f4)) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(abs(i8)) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(abs(i4)) # E: numpy.signedinteger[numpy.typing._32Bit]
-reveal_type(abs(u8)) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(abs(u4)) # E: numpy.unsignedinteger[numpy.typing._32Bit]
+reveal_type(+AR_f) # E: Any
+
+reveal_type(abs(f16)) # E: {float128}
+reveal_type(abs(c16)) # E: {float64}
+reveal_type(abs(c8)) # E: {float32}
+reveal_type(abs(f8)) # E: {float64}
+reveal_type(abs(f4)) # E: {float32}
+reveal_type(abs(i8)) # E: {int64}
+reveal_type(abs(i4)) # E: {int32}
+reveal_type(abs(u8)) # E: {uint64}
+reveal_type(abs(u4)) # E: {uint32}
reveal_type(abs(td)) # E: numpy.timedelta64
reveal_type(abs(b_)) # E: numpy.bool_
-reveal_type(abs(AR)) # E: Any
+reveal_type(abs(AR_f)) # E: Any
# Time structures
@@ -81,211 +302,221 @@ reveal_type(td - i8) # E: numpy.timedelta64
reveal_type(td / f) # E: numpy.timedelta64
reveal_type(td / f4) # E: numpy.timedelta64
reveal_type(td / f8) # E: numpy.timedelta64
-reveal_type(td / td) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(td // td) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(td / td) # E: {float64}
+reveal_type(td // td) # E: {int64}
# boolean
-reveal_type(b_ / b) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(b_ / b_) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(b_ / i) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(b_ / i8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(b_ / i4) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(b_ / u8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(b_ / u4) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(b_ / f) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(b_ / f8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(b_ / f4) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(b_ / c) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(b_ / c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(b_ / c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
-
-reveal_type(b / b_) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(b_ / b_) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(i / b_) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(i8 / b_) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(i4 / b_) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(u8 / b_) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(u4 / b_) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(f / b_) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(f8 / b_) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(f4 / b_) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(c / b_) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(c16 / b_) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(c8 / b_) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
+reveal_type(b_ / b) # E: {float64}
+reveal_type(b_ / b_) # E: {float64}
+reveal_type(b_ / i) # E: {float64}
+reveal_type(b_ / i8) # E: {float64}
+reveal_type(b_ / i4) # E: {float64}
+reveal_type(b_ / u8) # E: {float64}
+reveal_type(b_ / u4) # E: {float64}
+reveal_type(b_ / f) # E: {float64}
+reveal_type(b_ / f16) # E: {float128}
+reveal_type(b_ / f8) # E: {float64}
+reveal_type(b_ / f4) # E: {float32}
+reveal_type(b_ / c) # E: {complex128}
+reveal_type(b_ / c16) # E: {complex128}
+reveal_type(b_ / c8) # E: {complex64}
+
+reveal_type(b / b_) # E: {float64}
+reveal_type(b_ / b_) # E: {float64}
+reveal_type(i / b_) # E: {float64}
+reveal_type(i8 / b_) # E: {float64}
+reveal_type(i4 / b_) # E: {float64}
+reveal_type(u8 / b_) # E: {float64}
+reveal_type(u4 / b_) # E: {float64}
+reveal_type(f / b_) # E: {float64}
+reveal_type(f16 / b_) # E: {float128}
+reveal_type(f8 / b_) # E: {float64}
+reveal_type(f4 / b_) # E: {float32}
+reveal_type(c / b_) # E: {complex128}
+reveal_type(c16 / b_) # E: {complex128}
+reveal_type(c8 / b_) # E: {complex64}
# Complex
-reveal_type(c16 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(c16 + f8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(c16 + i8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(c16 + c8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(c16 + f4) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(c16 + i4) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(c16 + b_) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(c16 + b) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(c16 + c) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(c16 + f) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(c16 + i) # E: numpy.complexfloating[Any, Any]
-reveal_type(c16 + AR) # E: Any
-
-reveal_type(c16 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(f8 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(i8 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(c8 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(f4 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(i4 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(b_ + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(b + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(c + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(f + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(i + c16) # E: numpy.complexfloating[Any, Any]
-reveal_type(AR + c16) # E: Any
-
-reveal_type(c8 + c16) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(c8 + f8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(c8 + i8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(c8 + c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
-reveal_type(c8 + f4) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
-reveal_type(c8 + i4) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
-reveal_type(c8 + b_) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
-reveal_type(c8 + b) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
-reveal_type(c8 + c) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(c8 + f) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(c8 + i) # E: numpy.complexfloating[Any, Any]
-reveal_type(c8 + AR) # E: Any
-
-reveal_type(c16 + c8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(f8 + c8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(i8 + c8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(c8 + c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
-reveal_type(f4 + c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
-reveal_type(i4 + c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
-reveal_type(b_ + c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
-reveal_type(b + c8) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
-reveal_type(c + c8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(f + c8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(i + c8) # E: numpy.complexfloating[Any, Any]
-reveal_type(AR + c8) # E: Any
+reveal_type(c16 + f16) # E: {complex256}
+reveal_type(c16 + c16) # E: {complex128}
+reveal_type(c16 + f8) # E: {complex128}
+reveal_type(c16 + i8) # E: {complex128}
+reveal_type(c16 + c8) # E: {complex128}
+reveal_type(c16 + f4) # E: {complex128}
+reveal_type(c16 + i4) # E: {complex128}
+reveal_type(c16 + b_) # E: {complex128}
+reveal_type(c16 + b) # E: {complex128}
+reveal_type(c16 + c) # E: {complex128}
+reveal_type(c16 + f) # E: {complex128}
+reveal_type(c16 + i) # E: {complex128}
+reveal_type(c16 + AR_f) # E: Any
+
+reveal_type(f16 + c16) # E: {complex256}
+reveal_type(c16 + c16) # E: {complex128}
+reveal_type(f8 + c16) # E: {complex128}
+reveal_type(i8 + c16) # E: {complex128}
+reveal_type(c8 + c16) # E: {complex128}
+reveal_type(f4 + c16) # E: {complex128}
+reveal_type(i4 + c16) # E: {complex128}
+reveal_type(b_ + c16) # E: {complex128}
+reveal_type(b + c16) # E: {complex128}
+reveal_type(c + c16) # E: {complex128}
+reveal_type(f + c16) # E: {complex128}
+reveal_type(i + c16) # E: {complex128}
+reveal_type(AR_f + c16) # E: Any
+
+reveal_type(c8 + f16) # E: {complex256}
+reveal_type(c8 + c16) # E: {complex128}
+reveal_type(c8 + f8) # E: {complex128}
+reveal_type(c8 + i8) # E: {complex128}
+reveal_type(c8 + c8) # E: {complex64}
+reveal_type(c8 + f4) # E: {complex64}
+reveal_type(c8 + i4) # E: {complex64}
+reveal_type(c8 + b_) # E: {complex64}
+reveal_type(c8 + b) # E: {complex64}
+reveal_type(c8 + c) # E: {complex128}
+reveal_type(c8 + f) # E: {complex128}
+reveal_type(c8 + i) # E: numpy.complexfloating[{_NBitInt}, {_NBitInt}]
+reveal_type(c8 + AR_f) # E: Any
+
+reveal_type(f16 + c8) # E: {complex256}
+reveal_type(c16 + c8) # E: {complex128}
+reveal_type(f8 + c8) # E: {complex128}
+reveal_type(i8 + c8) # E: {complex128}
+reveal_type(c8 + c8) # E: {complex64}
+reveal_type(f4 + c8) # E: {complex64}
+reveal_type(i4 + c8) # E: {complex64}
+reveal_type(b_ + c8) # E: {complex64}
+reveal_type(b + c8) # E: {complex64}
+reveal_type(c + c8) # E: {complex128}
+reveal_type(f + c8) # E: {complex128}
+reveal_type(i + c8) # E: numpy.complexfloating[{_NBitInt}, {_NBitInt}]
+reveal_type(AR_f + c8) # E: Any
# Float
-reveal_type(f8 + f8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(f8 + i8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(f8 + f4) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(f8 + i4) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(f8 + b_) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(f8 + b) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(f8 + c) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(f8 + f) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(f8 + i) # E: numpy.floating[Any]
-reveal_type(f8 + AR) # E: Any
-
-reveal_type(f8 + f8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(i8 + f8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(f4 + f8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(i4 + f8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(b_ + f8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(b + f8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(c + f8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(f + f8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(i + f8) # E: numpy.floating[Any]
-reveal_type(AR + f8) # E: Any
-
-reveal_type(f4 + f8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(f4 + i8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(f4 + f4) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(f4 + i4) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(f4 + b_) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(f4 + b) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(f4 + c) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(f4 + f) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(f4 + i) # E: numpy.floating[Any]
-reveal_type(f4 + AR) # E: Any
-
-reveal_type(f8 + f4) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(i8 + f4) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(f4 + f4) # E: umpy.floating[numpy.typing._32Bit]
-reveal_type(i4 + f4) # E: umpy.floating[numpy.typing._32Bit]
-reveal_type(b_ + f4) # E: umpy.floating[numpy.typing._32Bit]
-reveal_type(b + f4) # E: umpy.floating[numpy.typing._32Bit]
-reveal_type(c + f4) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(f + f4) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(i + f4) # E: numpy.floating[Any]
-reveal_type(AR + f4) # E: Any
+reveal_type(f8 + f16) # E: {float128}
+reveal_type(f8 + f8) # E: {float64}
+reveal_type(f8 + i8) # E: {float64}
+reveal_type(f8 + f4) # E: {float64}
+reveal_type(f8 + i4) # E: {float64}
+reveal_type(f8 + b_) # E: {float64}
+reveal_type(f8 + b) # E: {float64}
+reveal_type(f8 + c) # E: {complex128}
+reveal_type(f8 + f) # E: {float64}
+reveal_type(f8 + i) # E: {float64}
+reveal_type(f8 + AR_f) # E: Any
+
+reveal_type(f16 + f8) # E: {float128}
+reveal_type(f8 + f8) # E: {float64}
+reveal_type(i8 + f8) # E: {float64}
+reveal_type(f4 + f8) # E: {float64}
+reveal_type(i4 + f8) # E: {float64}
+reveal_type(b_ + f8) # E: {float64}
+reveal_type(b + f8) # E: {float64}
+reveal_type(c + f8) # E: {complex128}
+reveal_type(f + f8) # E: {float64}
+reveal_type(i + f8) # E: {float64}
+reveal_type(AR_f + f8) # E: Any
+
+reveal_type(f4 + f16) # E: {float128}
+reveal_type(f4 + f8) # E: {float64}
+reveal_type(f4 + i8) # E: {float64}
+reveal_type(f4 + f4) # E: {float32}
+reveal_type(f4 + i4) # E: {float32}
+reveal_type(f4 + b_) # E: {float32}
+reveal_type(f4 + b) # E: {float32}
+reveal_type(f4 + c) # E: {complex128}
+reveal_type(f4 + f) # E: {float64}
+reveal_type(f4 + i) # E: numpy.floating[{_NBitInt}]
+reveal_type(f4 + AR_f) # E: Any
+
+reveal_type(f16 + f4) # E: {float128}
+reveal_type(f8 + f4) # E: {float64}
+reveal_type(i8 + f4) # E: {float64}
+reveal_type(f4 + f4) # E: {float32}
+reveal_type(i4 + f4) # E: {float32}
+reveal_type(b_ + f4) # E: {float32}
+reveal_type(b + f4) # E: {float32}
+reveal_type(c + f4) # E: {complex128}
+reveal_type(f + f4) # E: {float64}
+reveal_type(i + f4) # E: numpy.floating[{_NBitInt}]
+reveal_type(AR_f + f4) # E: Any
# Int
-reveal_type(i8 + i8) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i8 + u8) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
-reveal_type(i8 + i4) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i8 + u4) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
-reveal_type(i8 + b_) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i8 + b) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i8 + c) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(i8 + f) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(i8 + i) # E: numpy.signedinteger[Any]
-reveal_type(i8 + AR) # E: Any
-
-reveal_type(u8 + u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(u8 + i4) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
-reveal_type(u8 + u4) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(u8 + b_) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(u8 + b) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(u8 + c) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(u8 + f) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(u8 + i) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
-reveal_type(u8 + AR) # E: Any
-
-reveal_type(i8 + i8) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(u8 + i8) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
-reveal_type(i4 + i8) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(u4 + i8) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
-reveal_type(b_ + i8) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(b + i8) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(c + i8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(f + i8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(i + i8) # E: numpy.signedinteger[Any]
-reveal_type(AR + i8) # E: Any
-
-reveal_type(u8 + u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(i4 + u8) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
-reveal_type(u4 + u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(b_ + u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(b + u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(c + u8) # E: numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]
-reveal_type(f + u8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(i + u8) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
-reveal_type(AR + u8) # E: Any
-
-reveal_type(i4 + i8) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i4 + i4) # E: numpy.signedinteger[numpy.typing._32Bit]
-reveal_type(i4 + i) # E: numpy.signedinteger[Any]
-reveal_type(i4 + b_) # E: numpy.signedinteger[numpy.typing._32Bit]
-reveal_type(i4 + b) # E: numpy.signedinteger[numpy.typing._32Bit]
-reveal_type(i4 + AR) # E: Any
-
-reveal_type(u4 + i8) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
-reveal_type(u4 + i4) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
-reveal_type(u4 + u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(u4 + u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
-reveal_type(u4 + i) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
-reveal_type(u4 + b_) # E: numpy.unsignedinteger[numpy.typing._32Bit]
-reveal_type(u4 + b) # E: numpy.unsignedinteger[numpy.typing._32Bit]
-reveal_type(u4 + AR) # E: Any
-
-reveal_type(i8 + i4) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i4 + i4) # E: numpy.signedinteger[numpy.typing._32Bit]
-reveal_type(i + i4) # E: numpy.signedinteger[Any]
-reveal_type(b_ + i4) # E: numpy.signedinteger[numpy.typing._32Bit]
-reveal_type(b + i4) # E: numpy.signedinteger[numpy.typing._32Bit]
-reveal_type(AR + i4) # E: Any
-
-reveal_type(i8 + u4) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
-reveal_type(i4 + u4) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
-reveal_type(u8 + u4) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(u4 + u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
-reveal_type(b_ + u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
-reveal_type(b + u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
-reveal_type(i + u4) # E: Union[numpy.signedinteger[Any], numpy.floating[numpy.typing._64Bit]]
-reveal_type(AR + u4) # E: Any
+reveal_type(i8 + i8) # E: {int64}
+reveal_type(i8 + u8) # E: Any
+reveal_type(i8 + i4) # E: {int64}
+reveal_type(i8 + u4) # E: Any
+reveal_type(i8 + b_) # E: {int64}
+reveal_type(i8 + b) # E: {int64}
+reveal_type(i8 + c) # E: {complex128}
+reveal_type(i8 + f) # E: {float64}
+reveal_type(i8 + i) # E: {int64}
+reveal_type(i8 + AR_f) # E: Any
+
+reveal_type(u8 + u8) # E: {uint64}
+reveal_type(u8 + i4) # E: Any
+reveal_type(u8 + u4) # E: {uint64}
+reveal_type(u8 + b_) # E: {uint64}
+reveal_type(u8 + b) # E: {uint64}
+reveal_type(u8 + c) # E: {complex128}
+reveal_type(u8 + f) # E: {float64}
+reveal_type(u8 + i) # E: Any
+reveal_type(u8 + AR_f) # E: Any
+
+reveal_type(i8 + i8) # E: {int64}
+reveal_type(u8 + i8) # E: Any
+reveal_type(i4 + i8) # E: {int64}
+reveal_type(u4 + i8) # E: Any
+reveal_type(b_ + i8) # E: {int64}
+reveal_type(b + i8) # E: {int64}
+reveal_type(c + i8) # E: {complex128}
+reveal_type(f + i8) # E: {float64}
+reveal_type(i + i8) # E: {int64}
+reveal_type(AR_f + i8) # E: Any
+
+reveal_type(u8 + u8) # E: {uint64}
+reveal_type(i4 + u8) # E: Any
+reveal_type(u4 + u8) # E: {uint64}
+reveal_type(b_ + u8) # E: {uint64}
+reveal_type(b + u8) # E: {uint64}
+reveal_type(c + u8) # E: {complex128}
+reveal_type(f + u8) # E: {float64}
+reveal_type(i + u8) # E: Any
+reveal_type(AR_f + u8) # E: Any
+
+reveal_type(i4 + i8) # E: {int64}
+reveal_type(i4 + i4) # E: {int32}
+reveal_type(i4 + i) # E: {int_}
+reveal_type(i4 + b_) # E: {int32}
+reveal_type(i4 + b) # E: {int32}
+reveal_type(i4 + AR_f) # E: Any
+
+reveal_type(u4 + i8) # E: Any
+reveal_type(u4 + i4) # E: Any
+reveal_type(u4 + u8) # E: {uint64}
+reveal_type(u4 + u4) # E: {uint32}
+reveal_type(u4 + i) # E: Any
+reveal_type(u4 + b_) # E: {uint32}
+reveal_type(u4 + b) # E: {uint32}
+reveal_type(u4 + AR_f) # E: Any
+
+reveal_type(i8 + i4) # E: {int64}
+reveal_type(i4 + i4) # E: {int32}
+reveal_type(i + i4) # E: {int_}
+reveal_type(b_ + i4) # E: {int32}
+reveal_type(b + i4) # E: {int32}
+reveal_type(AR_f + i4) # E: Any
+
+reveal_type(i8 + u4) # E: Any
+reveal_type(i4 + u4) # E: Any
+reveal_type(u8 + u4) # E: {uint64}
+reveal_type(u4 + u4) # E: {uint32}
+reveal_type(b_ + u4) # E: {uint32}
+reveal_type(b + u4) # E: {uint32}
+reveal_type(i + u4) # E: Any
+reveal_type(AR_f + u4) # E: Any
diff --git a/numpy/typing/tests/data/reveal/array_constructors.py b/numpy/typing/tests/data/reveal/array_constructors.py
index 106174736..44c85e988 100644
--- a/numpy/typing/tests/data/reveal/array_constructors.py
+++ b/numpy/typing/tests/data/reveal/array_constructors.py
@@ -1,102 +1,173 @@
-from typing import List, Any
+from typing import List, Any, TypeVar
+from pathlib import Path
+
import numpy as np
+import numpy.typing as npt
+
+_SCT = TypeVar("_SCT", bound=np.generic, covariant=True)
-class SubClass(np.ndarray): ...
+class SubClass(np.ndarray[Any, np.dtype[_SCT]]): ...
i8: np.int64
-A: np.ndarray
-B: SubClass
+A: npt.NDArray[np.float64]
+B: SubClass[np.float64]
C: List[int]
-def func(i: int, j: int, **kwargs: Any) -> SubClass: ...
-
-reveal_type(np.asarray(A)) # E: ndarray
-reveal_type(np.asarray(B)) # E: ndarray
-reveal_type(np.asarray(C)) # E: ndarray
-
-reveal_type(np.asanyarray(A)) # E: ndarray
-reveal_type(np.asanyarray(B)) # E: SubClass
-reveal_type(np.asanyarray(B, dtype=int)) # E: ndarray
-reveal_type(np.asanyarray(C)) # E: ndarray
-
-reveal_type(np.ascontiguousarray(A)) # E: ndarray
-reveal_type(np.ascontiguousarray(B)) # E: ndarray
-reveal_type(np.ascontiguousarray(C)) # E: ndarray
-
-reveal_type(np.asfortranarray(A)) # E: ndarray
-reveal_type(np.asfortranarray(B)) # E: ndarray
-reveal_type(np.asfortranarray(C)) # E: ndarray
-
-reveal_type(np.require(A)) # E: ndarray
-reveal_type(np.require(B)) # E: SubClass
-reveal_type(np.require(B, requirements=None)) # E: SubClass
-reveal_type(np.require(B, dtype=int)) # E: ndarray
-reveal_type(np.require(B, requirements="E")) # E: ndarray
-reveal_type(np.require(B, requirements=["ENSUREARRAY"])) # E: ndarray
-reveal_type(np.require(B, requirements={"F", "E"})) # E: ndarray
-reveal_type(np.require(B, requirements=["C", "OWNDATA"])) # E: SubClass
-reveal_type(np.require(B, requirements="W")) # E: SubClass
-reveal_type(np.require(B, requirements="A")) # E: SubClass
-reveal_type(np.require(C)) # E: ndarray
-
-reveal_type(np.linspace(0, 10)) # E: numpy.ndarray
-reveal_type(np.linspace(0, 10, retstep=True)) # E: Tuple[numpy.ndarray, numpy.inexact[Any]]
-reveal_type(np.logspace(0, 10)) # E: numpy.ndarray
-reveal_type(np.geomspace(1, 10)) # E: numpy.ndarray
-
-reveal_type(np.zeros_like(A)) # E: numpy.ndarray
-reveal_type(np.zeros_like(C)) # E: numpy.ndarray
+def func(i: int, j: int, **kwargs: Any) -> SubClass[np.float64]: ...
+
+reveal_type(np.empty_like(A)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.empty_like(B)) # E: SubClass[{float64}]
+reveal_type(np.empty_like([1, 1.0])) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.empty_like(A, dtype=np.int64)) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.empty_like(A, dtype='c16')) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.array(A)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.array(B)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.array(B, subok=True)) # E: SubClass[{float64}]
+reveal_type(np.array([1, 1.0])) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.array(A, dtype=np.int64)) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.array(A, dtype='c16')) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.zeros([1, 5, 6])) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.zeros([1, 5, 6], dtype=np.int64)) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.zeros([1, 5, 6], dtype='c16')) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.empty([1, 5, 6])) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.empty([1, 5, 6], dtype=np.int64)) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.empty([1, 5, 6], dtype='c16')) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.concatenate(A)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.concatenate([1, 1.0])) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.concatenate(A, dtype=np.int64)) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.concatenate(A, dtype='c16')) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.concatenate([1, 1.0], out=A)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+
+reveal_type(np.asarray(A)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.asarray(B)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.asarray([1, 1.0])) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.asarray(A, dtype=np.int64)) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.asarray(A, dtype='c16')) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.asanyarray(A)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.asanyarray(B)) # E: SubClass[{float64}]
+reveal_type(np.asanyarray([1, 1.0])) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.asanyarray(A, dtype=np.int64)) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.asanyarray(A, dtype='c16')) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.ascontiguousarray(A)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.ascontiguousarray(B)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.ascontiguousarray([1, 1.0])) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.ascontiguousarray(A, dtype=np.int64)) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.ascontiguousarray(A, dtype='c16')) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.asfortranarray(A)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.asfortranarray(B)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.asfortranarray([1, 1.0])) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.asfortranarray(A, dtype=np.int64)) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.asfortranarray(A, dtype='c16')) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.fromstring("1 1 1", sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.fromstring(b"1 1 1", sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.fromstring("1 1 1", dtype=np.int64, sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.fromstring(b"1 1 1", dtype=np.int64, sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.fromstring("1 1 1", dtype="c16", sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.fromstring(b"1 1 1", dtype="c16", sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.fromfile("test.txt", sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.fromfile("test.txt", dtype=np.int64, sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.fromfile("test.txt", dtype="c16", sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+with open("test.txt") as f:
+ reveal_type(np.fromfile(f, sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+ reveal_type(np.fromfile(b"test.txt", sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+ reveal_type(np.fromfile(Path("test.txt"), sep=" ")) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+
+reveal_type(np.fromiter("12345", np.float64)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.fromiter("12345", float)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.frombuffer(A)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.frombuffer(A, dtype=np.int64)) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.frombuffer(A, dtype="c16")) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.arange(False, True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(np.arange(10)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(np.arange(0, 10, step=2)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(np.arange(10.0)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(np.arange(start=0, stop=10.0)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(np.arange(np.timedelta64(0))) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(np.arange(0, np.timedelta64(10))) # E: numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]
+reveal_type(np.arange(np.datetime64("0"), np.datetime64("10"))) # E: numpy.ndarray[Any, numpy.dtype[numpy.datetime64]]
+reveal_type(np.arange(10, dtype=np.float64)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.arange(0, 10, step=2, dtype=np.int16)) # E: numpy.ndarray[Any, numpy.dtype[{int16}]]
+reveal_type(np.arange(10, dtype=int)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.arange(0, 10, dtype="f8")) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.require(A)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.require(B)) # E: SubClass[{float64}]
+reveal_type(np.require(B, requirements=None)) # E: SubClass[{float64}]
+reveal_type(np.require(B, dtype=int)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.require(B, requirements="E")) # E: numpy.ndarray[Any, Any]
+reveal_type(np.require(B, requirements=["ENSUREARRAY"])) # E: numpy.ndarray[Any, Any]
+reveal_type(np.require(B, requirements={"F", "E"})) # E: numpy.ndarray[Any, Any]
+reveal_type(np.require(B, requirements=["C", "OWNDATA"])) # E: SubClass[{float64}]
+reveal_type(np.require(B, requirements="W")) # E: SubClass[{float64}]
+reveal_type(np.require(B, requirements="A")) # E: SubClass[{float64}]
+reveal_type(np.require(C)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.linspace(0, 10)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.linspace(0, 10, retstep=True)) # E: Tuple[numpy.ndarray[Any, Any], Any]
+reveal_type(np.logspace(0, 10)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.geomspace(1, 10)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.zeros_like(A)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.zeros_like(C)) # E: numpy.ndarray[Any, Any]
reveal_type(np.zeros_like(B)) # E: SubClass
-reveal_type(np.zeros_like(B, dtype=np.int64)) # E: numpy.ndarray
+reveal_type(np.zeros_like(B, dtype=np.int64)) # E: numpy.ndarray[Any, Any]
-reveal_type(np.ones_like(A)) # E: numpy.ndarray
-reveal_type(np.ones_like(C)) # E: numpy.ndarray
+reveal_type(np.ones_like(A)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.ones_like(C)) # E: numpy.ndarray[Any, Any]
reveal_type(np.ones_like(B)) # E: SubClass
-reveal_type(np.ones_like(B, dtype=np.int64)) # E: numpy.ndarray
-
-reveal_type(np.empty_like(A)) # E: numpy.ndarray
-reveal_type(np.empty_like(C)) # E: numpy.ndarray
-reveal_type(np.empty_like(B)) # E: SubClass
-reveal_type(np.empty_like(B, dtype=np.int64)) # E: numpy.ndarray
+reveal_type(np.ones_like(B, dtype=np.int64)) # E: numpy.ndarray[Any, Any]
-reveal_type(np.full_like(A, i8)) # E: numpy.ndarray
-reveal_type(np.full_like(C, i8)) # E: numpy.ndarray
-reveal_type(np.full_like(B, i8)) # E: SubClass
-reveal_type(np.full_like(B, i8, dtype=np.int64)) # E: numpy.ndarray
+reveal_type(np.full_like(A, i8)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.full_like(C, i8)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.full_like(B, i8)) # E: SubClass[{float64}]
+reveal_type(np.full_like(B, i8, dtype=np.int64)) # E: numpy.ndarray[Any, Any]
-reveal_type(np.ones(1)) # E: numpy.ndarray
-reveal_type(np.ones([1, 1, 1])) # E: numpy.ndarray
+reveal_type(np.ones(1)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.ones([1, 1, 1])) # E: numpy.ndarray[Any, Any]
-reveal_type(np.full(1, i8)) # E: numpy.ndarray
-reveal_type(np.full([1, 1, 1], i8)) # E: numpy.ndarray
+reveal_type(np.full(1, i8)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.full([1, 1, 1], i8)) # E: numpy.ndarray[Any, Any]
-reveal_type(np.indices([1, 2, 3])) # E: numpy.ndarray
-reveal_type(np.indices([1, 2, 3], sparse=True)) # E: tuple[numpy.ndarray]
+reveal_type(np.indices([1, 2, 3])) # E: numpy.ndarray[Any, Any]
+reveal_type(np.indices([1, 2, 3], sparse=True)) # E: tuple[numpy.ndarray[Any, Any]]
-reveal_type(np.fromfunction(func, (3, 5))) # E: SubClass
+reveal_type(np.fromfunction(func, (3, 5))) # E: SubClass[{float64}]
-reveal_type(np.identity(10)) # E: numpy.ndarray
+reveal_type(np.identity(10)) # E: numpy.ndarray[Any, Any]
-reveal_type(np.atleast_1d(A)) # E: numpy.ndarray
-reveal_type(np.atleast_1d(C)) # E: numpy.ndarray
-reveal_type(np.atleast_1d(A, A)) # E: list[numpy.ndarray]
-reveal_type(np.atleast_1d(A, C)) # E: list[numpy.ndarray]
-reveal_type(np.atleast_1d(C, C)) # E: list[numpy.ndarray]
+reveal_type(np.atleast_1d(A)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.atleast_1d(C)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.atleast_1d(A, A)) # E: list[numpy.ndarray[Any, numpy.dtype[Any]]]
+reveal_type(np.atleast_1d(A, C)) # E: list[numpy.ndarray[Any, numpy.dtype[Any]]]
+reveal_type(np.atleast_1d(C, C)) # E: list[numpy.ndarray[Any, numpy.dtype[Any]]]
-reveal_type(np.atleast_2d(A)) # E: numpy.ndarray
+reveal_type(np.atleast_2d(A)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
-reveal_type(np.atleast_3d(A)) # E: numpy.ndarray
+reveal_type(np.atleast_3d(A)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
-reveal_type(np.vstack([A, A])) # E: numpy.ndarray
-reveal_type(np.vstack([A, C])) # E: numpy.ndarray
-reveal_type(np.vstack([C, C])) # E: numpy.ndarray
+reveal_type(np.vstack([A, A])) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.vstack([A, C])) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.vstack([C, C])) # E: numpy.ndarray[Any, numpy.dtype[Any]]
-reveal_type(np.hstack([A, A])) # E: numpy.ndarray
+reveal_type(np.hstack([A, A])) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
-reveal_type(np.stack([A, A])) # E: numpy.ndarray
-reveal_type(np.stack([A, A], axis=0)) # E: numpy.ndarray
-reveal_type(np.stack([A, A], out=B)) # E: SubClass
+reveal_type(np.stack([A, A])) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.stack([A, C])) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.stack([C, C])) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.stack([A, A], axis=0)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.stack([A, A], out=B)) # E: SubClass[{float64}]
-reveal_type(np.block([[A, A], [A, A]])) # E: numpy.ndarray
-reveal_type(np.block(C)) # E: numpy.ndarray
+reveal_type(np.block([[A, A], [A, A]])) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.block(C)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
diff --git a/numpy/typing/tests/data/reveal/arraypad.py b/numpy/typing/tests/data/reveal/arraypad.py
new file mode 100644
index 000000000..ba5577ee0
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/arraypad.py
@@ -0,0 +1,22 @@
+from typing import List, Any, Mapping, Tuple
+from typing_extensions import SupportsIndex
+
+import numpy as np
+import numpy.typing as npt
+
+def mode_func(
+ ar: npt.NDArray[np.number[Any]],
+ width: Tuple[int, int],
+ iaxis: SupportsIndex,
+ kwargs: Mapping[str, Any],
+) -> None: ...
+
+AR_i8: npt.NDArray[np.int64]
+AR_f8: npt.NDArray[np.float64]
+AR_LIKE: List[int]
+
+reveal_type(np.pad(AR_i8, (2, 3), "constant")) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.pad(AR_LIKE, (2, 3), "constant")) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.pad(AR_f8, (2, 3), mode_func)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.pad(AR_f8, (2, 3), mode_func, a=1, b=2)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
diff --git a/numpy/typing/tests/data/reveal/arrayprint.py b/numpy/typing/tests/data/reveal/arrayprint.py
new file mode 100644
index 000000000..e797097eb
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/arrayprint.py
@@ -0,0 +1,19 @@
+from typing import Any, Callable
+import numpy as np
+
+AR: np.ndarray[Any, Any]
+func_float: Callable[[np.floating[Any]], str]
+func_int: Callable[[np.integer[Any]], str]
+
+reveal_type(np.get_printoptions()) # E: TypedDict
+reveal_type(np.array2string( # E: str
+ AR, formatter={'float_kind': func_float, 'int_kind': func_int}
+))
+reveal_type(np.format_float_scientific(1.0)) # E: str
+reveal_type(np.format_float_positional(1)) # E: str
+reveal_type(np.array_repr(AR)) # E: str
+reveal_type(np.array_str(AR)) # E: str
+
+reveal_type(np.printoptions()) # E: contextlib._GeneratorContextManager
+with np.printoptions() as dct:
+ reveal_type(dct) # E: TypedDict
diff --git a/numpy/typing/tests/data/reveal/arrayterator.py b/numpy/typing/tests/data/reveal/arrayterator.py
new file mode 100644
index 000000000..ea4e75612
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/arrayterator.py
@@ -0,0 +1,24 @@
+from typing import Any
+import numpy as np
+
+AR_i8: np.ndarray[Any, np.dtype[np.int64]]
+ar_iter = np.lib.Arrayterator(AR_i8)
+
+reveal_type(ar_iter.var) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(ar_iter.buf_size) # E: Union[None, builtins.int]
+reveal_type(ar_iter.start) # E: builtins.list[builtins.int]
+reveal_type(ar_iter.stop) # E: builtins.list[builtins.int]
+reveal_type(ar_iter.step) # E: builtins.list[builtins.int]
+reveal_type(ar_iter.shape) # E: builtins.tuple[builtins.int]
+reveal_type(ar_iter.flat) # E: typing.Generator[{int64}, None, None]
+
+reveal_type(ar_iter.__array__()) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+
+for i in ar_iter:
+ reveal_type(i) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+
+reveal_type(ar_iter[0]) # E: numpy.lib.arrayterator.Arrayterator[Any, numpy.dtype[{int64}]]
+reveal_type(ar_iter[...]) # E: numpy.lib.arrayterator.Arrayterator[Any, numpy.dtype[{int64}]]
+reveal_type(ar_iter[:]) # E: numpy.lib.arrayterator.Arrayterator[Any, numpy.dtype[{int64}]]
+reveal_type(ar_iter[0, 0, 0]) # E: numpy.lib.arrayterator.Arrayterator[Any, numpy.dtype[{int64}]]
+reveal_type(ar_iter[..., 0, :]) # E: numpy.lib.arrayterator.Arrayterator[Any, numpy.dtype[{int64}]]
diff --git a/numpy/typing/tests/data/reveal/bitwise_ops.py b/numpy/typing/tests/data/reveal/bitwise_ops.py
index cb9131a96..6b9969568 100644
--- a/numpy/typing/tests/data/reveal/bitwise_ops.py
+++ b/numpy/typing/tests/data/reveal/bitwise_ops.py
@@ -15,11 +15,11 @@ AR = np.array([0, 1, 2], dtype=np.int32)
AR.setflags(write=False)
-reveal_type(i8 << i8) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i8 >> i8) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i8 | i8) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i8 ^ i8) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i8 & i8) # E: numpy.signedinteger[numpy.typing._64Bit]
+reveal_type(i8 << i8) # E: {int64}
+reveal_type(i8 >> i8) # E: {int64}
+reveal_type(i8 | i8) # E: {int64}
+reveal_type(i8 ^ i8) # E: {int64}
+reveal_type(i8 & i8) # E: {int64}
reveal_type(i8 << AR) # E: Any
reveal_type(i8 >> AR) # E: Any
@@ -27,41 +27,41 @@ reveal_type(i8 | AR) # E: Any
reveal_type(i8 ^ AR) # E: Any
reveal_type(i8 & AR) # E: Any
-reveal_type(i4 << i4) # E: numpy.signedinteger[numpy.typing._32Bit]
-reveal_type(i4 >> i4) # E: numpy.signedinteger[numpy.typing._32Bit]
-reveal_type(i4 | i4) # E: numpy.signedinteger[numpy.typing._32Bit]
-reveal_type(i4 ^ i4) # E: numpy.signedinteger[numpy.typing._32Bit]
-reveal_type(i4 & i4) # E: numpy.signedinteger[numpy.typing._32Bit]
-
-reveal_type(i8 << i4) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i8 >> i4) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i8 | i4) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i8 ^ i4) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i8 & i4) # E: numpy.signedinteger[numpy.typing._64Bit]
-
-reveal_type(i8 << i) # E: numpy.signedinteger[Any]
-reveal_type(i8 >> i) # E: numpy.signedinteger[Any]
-reveal_type(i8 | i) # E: numpy.signedinteger[Any]
-reveal_type(i8 ^ i) # E: numpy.signedinteger[Any]
-reveal_type(i8 & i) # E: numpy.signedinteger[Any]
-
-reveal_type(i8 << b_) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i8 >> b_) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i8 | b_) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i8 ^ b_) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i8 & b_) # E: numpy.signedinteger[numpy.typing._64Bit]
-
-reveal_type(i8 << b) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i8 >> b) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i8 | b) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i8 ^ b) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i8 & b) # E: numpy.signedinteger[numpy.typing._64Bit]
-
-reveal_type(u8 << u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(u8 >> u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(u8 | u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(u8 ^ u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(u8 & u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(i4 << i4) # E: {int32}
+reveal_type(i4 >> i4) # E: {int32}
+reveal_type(i4 | i4) # E: {int32}
+reveal_type(i4 ^ i4) # E: {int32}
+reveal_type(i4 & i4) # E: {int32}
+
+reveal_type(i8 << i4) # E: {int64}
+reveal_type(i8 >> i4) # E: {int64}
+reveal_type(i8 | i4) # E: {int64}
+reveal_type(i8 ^ i4) # E: {int64}
+reveal_type(i8 & i4) # E: {int64}
+
+reveal_type(i8 << i) # E: {int64}
+reveal_type(i8 >> i) # E: {int64}
+reveal_type(i8 | i) # E: {int64}
+reveal_type(i8 ^ i) # E: {int64}
+reveal_type(i8 & i) # E: {int64}
+
+reveal_type(i8 << b_) # E: {int64}
+reveal_type(i8 >> b_) # E: {int64}
+reveal_type(i8 | b_) # E: {int64}
+reveal_type(i8 ^ b_) # E: {int64}
+reveal_type(i8 & b_) # E: {int64}
+
+reveal_type(i8 << b) # E: {int64}
+reveal_type(i8 >> b) # E: {int64}
+reveal_type(i8 | b) # E: {int64}
+reveal_type(i8 ^ b) # E: {int64}
+reveal_type(i8 & b) # E: {int64}
+
+reveal_type(u8 << u8) # E: {uint64}
+reveal_type(u8 >> u8) # E: {uint64}
+reveal_type(u8 | u8) # E: {uint64}
+reveal_type(u8 ^ u8) # E: {uint64}
+reveal_type(u8 & u8) # E: {uint64}
reveal_type(u8 << AR) # E: Any
reveal_type(u8 >> AR) # E: Any
@@ -69,11 +69,11 @@ reveal_type(u8 | AR) # E: Any
reveal_type(u8 ^ AR) # E: Any
reveal_type(u8 & AR) # E: Any
-reveal_type(u4 << u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
-reveal_type(u4 >> u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
-reveal_type(u4 | u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
-reveal_type(u4 ^ u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
-reveal_type(u4 & u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
+reveal_type(u4 << u4) # E: {uint32}
+reveal_type(u4 >> u4) # E: {uint32}
+reveal_type(u4 | u4) # E: {uint32}
+reveal_type(u4 ^ u4) # E: {uint32}
+reveal_type(u4 & u4) # E: {uint32}
reveal_type(u4 << i4) # E: numpy.signedinteger[Any]
reveal_type(u4 >> i4) # E: numpy.signedinteger[Any]
@@ -87,20 +87,20 @@ reveal_type(u4 | i) # E: numpy.signedinteger[Any]
reveal_type(u4 ^ i) # E: numpy.signedinteger[Any]
reveal_type(u4 & i) # E: numpy.signedinteger[Any]
-reveal_type(u8 << b_) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(u8 >> b_) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(u8 | b_) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(u8 ^ b_) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(u8 & b_) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(u8 << b_) # E: {uint64}
+reveal_type(u8 >> b_) # E: {uint64}
+reveal_type(u8 | b_) # E: {uint64}
+reveal_type(u8 ^ b_) # E: {uint64}
+reveal_type(u8 & b_) # E: {uint64}
-reveal_type(u8 << b) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(u8 >> b) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(u8 | b) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(u8 ^ b) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(u8 & b) # E: numpy.unsignedinteger[numpy.typing._64Bit]
+reveal_type(u8 << b) # E: {uint64}
+reveal_type(u8 >> b) # E: {uint64}
+reveal_type(u8 | b) # E: {uint64}
+reveal_type(u8 ^ b) # E: {uint64}
+reveal_type(u8 & b) # E: {uint64}
-reveal_type(b_ << b_) # E: numpy.signedinteger[numpy.typing._8Bit]
-reveal_type(b_ >> b_) # E: numpy.signedinteger[numpy.typing._8Bit]
+reveal_type(b_ << b_) # E: {int8}
+reveal_type(b_ >> b_) # E: {int8}
reveal_type(b_ | b_) # E: numpy.bool_
reveal_type(b_ ^ b_) # E: numpy.bool_
reveal_type(b_ & b_) # E: numpy.bool_
@@ -111,21 +111,21 @@ reveal_type(b_ | AR) # E: Any
reveal_type(b_ ^ AR) # E: Any
reveal_type(b_ & AR) # E: Any
-reveal_type(b_ << b) # E: numpy.signedinteger[numpy.typing._8Bit]
-reveal_type(b_ >> b) # E: numpy.signedinteger[numpy.typing._8Bit]
+reveal_type(b_ << b) # E: {int8}
+reveal_type(b_ >> b) # E: {int8}
reveal_type(b_ | b) # E: numpy.bool_
reveal_type(b_ ^ b) # E: numpy.bool_
reveal_type(b_ & b) # E: numpy.bool_
-reveal_type(b_ << i) # E: numpy.signedinteger[Any]
-reveal_type(b_ >> i) # E: numpy.signedinteger[Any]
-reveal_type(b_ | i) # E: numpy.signedinteger[Any]
-reveal_type(b_ ^ i) # E: numpy.signedinteger[Any]
-reveal_type(b_ & i) # E: numpy.signedinteger[Any]
+reveal_type(b_ << i) # E: {int_}
+reveal_type(b_ >> i) # E: {int_}
+reveal_type(b_ | i) # E: {int_}
+reveal_type(b_ ^ i) # E: {int_}
+reveal_type(b_ & i) # E: {int_}
-reveal_type(~i8) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(~i4) # E: numpy.signedinteger[numpy.typing._32Bit]
-reveal_type(~u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(~u4) # E: numpy.unsignedinteger[numpy.typing._32Bit]
+reveal_type(~i8) # E: {int64}
+reveal_type(~i4) # E: {int32}
+reveal_type(~u8) # E: {uint64}
+reveal_type(~u4) # E: {uint32}
reveal_type(~b_) # E: numpy.bool_
reveal_type(~AR) # E: Any
diff --git a/numpy/typing/tests/data/reveal/comparisons.py b/numpy/typing/tests/data/reveal/comparisons.py
index 82d1fa6de..16f21cc39 100644
--- a/numpy/typing/tests/data/reveal/comparisons.py
+++ b/numpy/typing/tests/data/reveal/comparisons.py
@@ -33,8 +33,13 @@ reveal_type(td > td) # E: numpy.bool_
reveal_type(td > i) # E: numpy.bool_
reveal_type(td > i4) # E: numpy.bool_
reveal_type(td > i8) # E: numpy.bool_
-reveal_type(td > AR) # E: Union[numpy.ndarray, numpy.bool_]
-reveal_type(td > SEQ) # E: Union[numpy.ndarray, numpy.bool_]
+
+reveal_type(td > AR) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(td > SEQ) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(AR > SEQ) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(AR > td) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(SEQ > td) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(SEQ > AR) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
# boolean
@@ -51,8 +56,8 @@ reveal_type(b_ > f4) # E: numpy.bool_
reveal_type(b_ > c) # E: numpy.bool_
reveal_type(b_ > c16) # E: numpy.bool_
reveal_type(b_ > c8) # E: numpy.bool_
-reveal_type(b_ > AR) # E: Union[numpy.ndarray, numpy.bool_]
-reveal_type(b_ > SEQ) # E: Union[numpy.ndarray, numpy.bool_]
+reveal_type(b_ > AR) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(b_ > SEQ) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
# Complex
@@ -67,8 +72,8 @@ reveal_type(c16 > b) # E: numpy.bool_
reveal_type(c16 > c) # E: numpy.bool_
reveal_type(c16 > f) # E: numpy.bool_
reveal_type(c16 > i) # E: numpy.bool_
-reveal_type(c16 > AR) # E: Union[numpy.ndarray, numpy.bool_]
-reveal_type(c16 > SEQ) # E: Union[numpy.ndarray, numpy.bool_]
+reveal_type(c16 > AR) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(c16 > SEQ) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
reveal_type(c16 > c16) # E: numpy.bool_
reveal_type(f8 > c16) # E: numpy.bool_
@@ -81,8 +86,8 @@ reveal_type(b > c16) # E: numpy.bool_
reveal_type(c > c16) # E: numpy.bool_
reveal_type(f > c16) # E: numpy.bool_
reveal_type(i > c16) # E: numpy.bool_
-reveal_type(AR > c16) # E: Union[numpy.ndarray, numpy.bool_]
-reveal_type(SEQ > c16) # E: Union[numpy.ndarray, numpy.bool_]
+reveal_type(AR > c16) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(SEQ > c16) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
reveal_type(c8 > c16) # E: numpy.bool_
reveal_type(c8 > f8) # E: numpy.bool_
@@ -95,8 +100,8 @@ reveal_type(c8 > b) # E: numpy.bool_
reveal_type(c8 > c) # E: numpy.bool_
reveal_type(c8 > f) # E: numpy.bool_
reveal_type(c8 > i) # E: numpy.bool_
-reveal_type(c8 > AR) # E: Union[numpy.ndarray, numpy.bool_]
-reveal_type(c8 > SEQ) # E: Union[numpy.ndarray, numpy.bool_]
+reveal_type(c8 > AR) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(c8 > SEQ) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
reveal_type(c16 > c8) # E: numpy.bool_
reveal_type(f8 > c8) # E: numpy.bool_
@@ -109,8 +114,8 @@ reveal_type(b > c8) # E: numpy.bool_
reveal_type(c > c8) # E: numpy.bool_
reveal_type(f > c8) # E: numpy.bool_
reveal_type(i > c8) # E: numpy.bool_
-reveal_type(AR > c8) # E: Union[numpy.ndarray, numpy.bool_]
-reveal_type(SEQ > c8) # E: Union[numpy.ndarray, numpy.bool_]
+reveal_type(AR > c8) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(SEQ > c8) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
# Float
@@ -123,8 +128,8 @@ reveal_type(f8 > b) # E: numpy.bool_
reveal_type(f8 > c) # E: numpy.bool_
reveal_type(f8 > f) # E: numpy.bool_
reveal_type(f8 > i) # E: numpy.bool_
-reveal_type(f8 > AR) # E: Union[numpy.ndarray, numpy.bool_]
-reveal_type(f8 > SEQ) # E: Union[numpy.ndarray, numpy.bool_]
+reveal_type(f8 > AR) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(f8 > SEQ) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
reveal_type(f8 > f8) # E: numpy.bool_
reveal_type(i8 > f8) # E: numpy.bool_
@@ -135,8 +140,8 @@ reveal_type(b > f8) # E: numpy.bool_
reveal_type(c > f8) # E: numpy.bool_
reveal_type(f > f8) # E: numpy.bool_
reveal_type(i > f8) # E: numpy.bool_
-reveal_type(AR > f8) # E: Union[numpy.ndarray, numpy.bool_]
-reveal_type(SEQ > f8) # E: Union[numpy.ndarray, numpy.bool_]
+reveal_type(AR > f8) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(SEQ > f8) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
reveal_type(f4 > f8) # E: numpy.bool_
reveal_type(f4 > i8) # E: numpy.bool_
@@ -147,8 +152,8 @@ reveal_type(f4 > b) # E: numpy.bool_
reveal_type(f4 > c) # E: numpy.bool_
reveal_type(f4 > f) # E: numpy.bool_
reveal_type(f4 > i) # E: numpy.bool_
-reveal_type(f4 > AR) # E: Union[numpy.ndarray, numpy.bool_]
-reveal_type(f4 > SEQ) # E: Union[numpy.ndarray, numpy.bool_]
+reveal_type(f4 > AR) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(f4 > SEQ) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
reveal_type(f8 > f4) # E: numpy.bool_
reveal_type(i8 > f4) # E: numpy.bool_
@@ -159,8 +164,8 @@ reveal_type(b > f4) # E: numpy.bool_
reveal_type(c > f4) # E: numpy.bool_
reveal_type(f > f4) # E: numpy.bool_
reveal_type(i > f4) # E: numpy.bool_
-reveal_type(AR > f4) # E: Union[numpy.ndarray, numpy.bool_]
-reveal_type(SEQ > f4) # E: Union[numpy.ndarray, numpy.bool_]
+reveal_type(AR > f4) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(SEQ > f4) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
# Int
@@ -173,8 +178,8 @@ reveal_type(i8 > b) # E: numpy.bool_
reveal_type(i8 > c) # E: numpy.bool_
reveal_type(i8 > f) # E: numpy.bool_
reveal_type(i8 > i) # E: numpy.bool_
-reveal_type(i8 > AR) # E: Union[numpy.ndarray, numpy.bool_]
-reveal_type(i8 > SEQ) # E: Union[numpy.ndarray, numpy.bool_]
+reveal_type(i8 > AR) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(i8 > SEQ) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
reveal_type(u8 > u8) # E: numpy.bool_
reveal_type(u8 > i4) # E: numpy.bool_
@@ -184,8 +189,8 @@ reveal_type(u8 > b) # E: numpy.bool_
reveal_type(u8 > c) # E: numpy.bool_
reveal_type(u8 > f) # E: numpy.bool_
reveal_type(u8 > i) # E: numpy.bool_
-reveal_type(u8 > AR) # E: Union[numpy.ndarray, numpy.bool_]
-reveal_type(u8 > SEQ) # E: Union[numpy.ndarray, numpy.bool_]
+reveal_type(u8 > AR) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(u8 > SEQ) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
reveal_type(i8 > i8) # E: numpy.bool_
reveal_type(u8 > i8) # E: numpy.bool_
@@ -196,8 +201,8 @@ reveal_type(b > i8) # E: numpy.bool_
reveal_type(c > i8) # E: numpy.bool_
reveal_type(f > i8) # E: numpy.bool_
reveal_type(i > i8) # E: numpy.bool_
-reveal_type(AR > i8) # E: Union[numpy.ndarray, numpy.bool_]
-reveal_type(SEQ > i8) # E: Union[numpy.ndarray, numpy.bool_]
+reveal_type(AR > i8) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(SEQ > i8) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
reveal_type(u8 > u8) # E: numpy.bool_
reveal_type(i4 > u8) # E: numpy.bool_
@@ -207,16 +212,16 @@ reveal_type(b > u8) # E: numpy.bool_
reveal_type(c > u8) # E: numpy.bool_
reveal_type(f > u8) # E: numpy.bool_
reveal_type(i > u8) # E: numpy.bool_
-reveal_type(AR > u8) # E: Union[numpy.ndarray, numpy.bool_]
-reveal_type(SEQ > u8) # E: Union[numpy.ndarray, numpy.bool_]
+reveal_type(AR > u8) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(SEQ > u8) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
reveal_type(i4 > i8) # E: numpy.bool_
reveal_type(i4 > i4) # E: numpy.bool_
reveal_type(i4 > i) # E: numpy.bool_
reveal_type(i4 > b_) # E: numpy.bool_
reveal_type(i4 > b) # E: numpy.bool_
-reveal_type(i4 > AR) # E: Union[numpy.ndarray, numpy.bool_]
-reveal_type(i4 > SEQ) # E: Union[numpy.ndarray, numpy.bool_]
+reveal_type(i4 > AR) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(i4 > SEQ) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
reveal_type(u4 > i8) # E: numpy.bool_
reveal_type(u4 > i4) # E: numpy.bool_
@@ -225,16 +230,16 @@ reveal_type(u4 > u4) # E: numpy.bool_
reveal_type(u4 > i) # E: numpy.bool_
reveal_type(u4 > b_) # E: numpy.bool_
reveal_type(u4 > b) # E: numpy.bool_
-reveal_type(u4 > AR) # E: Union[numpy.ndarray, numpy.bool_]
-reveal_type(u4 > SEQ) # E: Union[numpy.ndarray, numpy.bool_]
+reveal_type(u4 > AR) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(u4 > SEQ) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
reveal_type(i8 > i4) # E: numpy.bool_
reveal_type(i4 > i4) # E: numpy.bool_
reveal_type(i > i4) # E: numpy.bool_
reveal_type(b_ > i4) # E: numpy.bool_
reveal_type(b > i4) # E: numpy.bool_
-reveal_type(AR > i4) # E: Union[numpy.ndarray, numpy.bool_]
-reveal_type(SEQ > i4) # E: Union[numpy.ndarray, numpy.bool_]
+reveal_type(AR > i4) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(SEQ > i4) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
reveal_type(i8 > u4) # E: numpy.bool_
reveal_type(i4 > u4) # E: numpy.bool_
@@ -243,5 +248,5 @@ reveal_type(u4 > u4) # E: numpy.bool_
reveal_type(b_ > u4) # E: numpy.bool_
reveal_type(b > u4) # E: numpy.bool_
reveal_type(i > u4) # E: numpy.bool_
-reveal_type(AR > u4) # E: Union[numpy.ndarray, numpy.bool_]
-reveal_type(SEQ > u4) # E: Union[numpy.ndarray, numpy.bool_]
+reveal_type(AR > u4) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(SEQ > u4) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
diff --git a/numpy/typing/tests/data/reveal/constants.py b/numpy/typing/tests/data/reveal/constants.py
index b2382e861..9a46bfded 100644
--- a/numpy/typing/tests/data/reveal/constants.py
+++ b/numpy/typing/tests/data/reveal/constants.py
@@ -16,37 +16,37 @@ reveal_type(np.nan) # E: float
reveal_type(np.pi) # E: float
reveal_type(np.ALLOW_THREADS) # E: int
-reveal_type(np.BUFSIZE) # E: int
-reveal_type(np.CLIP) # E: int
-reveal_type(np.ERR_CALL) # E: int
-reveal_type(np.ERR_DEFAULT) # E: int
-reveal_type(np.ERR_IGNORE) # E: int
-reveal_type(np.ERR_LOG) # E: int
-reveal_type(np.ERR_PRINT) # E: int
-reveal_type(np.ERR_RAISE) # E: int
-reveal_type(np.ERR_WARN) # E: int
-reveal_type(np.FLOATING_POINT_SUPPORT) # E: int
-reveal_type(np.FPE_DIVIDEBYZERO) # E: int
-reveal_type(np.FPE_INVALID) # E: int
-reveal_type(np.FPE_OVERFLOW) # E: int
-reveal_type(np.FPE_UNDERFLOW) # E: int
-reveal_type(np.MAXDIMS) # E: int
-reveal_type(np.MAY_SHARE_BOUNDS) # E: int
-reveal_type(np.MAY_SHARE_EXACT) # E: int
-reveal_type(np.RAISE) # E: int
-reveal_type(np.SHIFT_DIVIDEBYZERO) # E: int
-reveal_type(np.SHIFT_INVALID) # E: int
-reveal_type(np.SHIFT_OVERFLOW) # E: int
-reveal_type(np.SHIFT_UNDERFLOW) # E: int
-reveal_type(np.UFUNC_BUFSIZE_DEFAULT) # E: int
-reveal_type(np.WRAP) # E: int
-reveal_type(np.tracemalloc_domain) # E: int
+reveal_type(np.BUFSIZE) # E: Literal[8192]
+reveal_type(np.CLIP) # E: Literal[0]
+reveal_type(np.ERR_CALL) # E: Literal[3]
+reveal_type(np.ERR_DEFAULT) # E: Literal[521]
+reveal_type(np.ERR_IGNORE) # E: Literal[0]
+reveal_type(np.ERR_LOG) # E: Literal[5]
+reveal_type(np.ERR_PRINT) # E: Literal[4]
+reveal_type(np.ERR_RAISE) # E: Literal[2]
+reveal_type(np.ERR_WARN) # E: Literal[1]
+reveal_type(np.FLOATING_POINT_SUPPORT) # E: Literal[1]
+reveal_type(np.FPE_DIVIDEBYZERO) # E: Literal[1]
+reveal_type(np.FPE_INVALID) # E: Literal[8]
+reveal_type(np.FPE_OVERFLOW) # E: Literal[2]
+reveal_type(np.FPE_UNDERFLOW) # E: Literal[4]
+reveal_type(np.MAXDIMS) # E: Literal[32]
+reveal_type(np.MAY_SHARE_BOUNDS) # E: Literal[0]
+reveal_type(np.MAY_SHARE_EXACT) # E: Literal[-1]
+reveal_type(np.RAISE) # E: Literal[2]
+reveal_type(np.SHIFT_DIVIDEBYZERO) # E: Literal[0]
+reveal_type(np.SHIFT_INVALID) # E: Literal[9]
+reveal_type(np.SHIFT_OVERFLOW) # E: Literal[3]
+reveal_type(np.SHIFT_UNDERFLOW) # E: Literal[6]
+reveal_type(np.UFUNC_BUFSIZE_DEFAULT) # E: Literal[8192]
+reveal_type(np.WRAP) # E: Literal[1]
+reveal_type(np.tracemalloc_domain) # E: Literal[389047]
reveal_type(np.little_endian) # E: bool
reveal_type(np.True_) # E: numpy.bool_
reveal_type(np.False_) # E: numpy.bool_
-reveal_type(np.UFUNC_PYVALS_NAME) # E: str
+reveal_type(np.UFUNC_PYVALS_NAME) # E: Literal['UFUNC_PYVALS']
reveal_type(np.sctypeDict) # E: dict
reveal_type(np.sctypes) # E: TypedDict
diff --git a/numpy/typing/tests/data/reveal/ctypeslib.py b/numpy/typing/tests/data/reveal/ctypeslib.py
new file mode 100644
index 000000000..0c32d70ed
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/ctypeslib.py
@@ -0,0 +1,3 @@
+import numpy as np
+
+reveal_type(np.ctypeslib.c_intp()) # E: {c_intp}
diff --git a/numpy/typing/tests/data/reveal/datasource.py b/numpy/typing/tests/data/reveal/datasource.py
new file mode 100644
index 000000000..245ac7649
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/datasource.py
@@ -0,0 +1,21 @@
+from pathlib import Path
+import numpy as np
+
+path1: Path
+path2: str
+
+d1 = np.DataSource(path1)
+d2 = np.DataSource(path2)
+d3 = np.DataSource(None)
+
+reveal_type(d1.abspath("...")) # E: str
+reveal_type(d2.abspath("...")) # E: str
+reveal_type(d3.abspath("...")) # E: str
+
+reveal_type(d1.exists("...")) # E: bool
+reveal_type(d2.exists("...")) # E: bool
+reveal_type(d3.exists("...")) # E: bool
+
+reveal_type(d1.open("...", "r")) # E: IO[Any]
+reveal_type(d2.open("...", encoding="utf8")) # E: IO[Any]
+reveal_type(d3.open("...", newline="/n")) # E: IO[Any]
diff --git a/numpy/typing/tests/data/reveal/dtype.py b/numpy/typing/tests/data/reveal/dtype.py
index d414f2c49..364d1dcab 100644
--- a/numpy/typing/tests/data/reveal/dtype.py
+++ b/numpy/typing/tests/data/reveal/dtype.py
@@ -1,33 +1,76 @@
+import ctypes as ct
import numpy as np
-reveal_type(np.dtype(np.float64)) # E: numpy.dtype[numpy.floating[numpy.typing._64Bit]]
-reveal_type(np.dtype(np.int64)) # E: numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]
+dtype_U: np.dtype[np.str_]
+dtype_V: np.dtype[np.void]
+dtype_i8: np.dtype[np.int64]
+
+reveal_type(np.dtype(np.float64)) # E: numpy.dtype[{float64}]
+reveal_type(np.dtype(np.int64)) # E: numpy.dtype[{int64}]
# String aliases
-reveal_type(np.dtype("float64")) # E: numpy.dtype[numpy.floating[numpy.typing._64Bit]]
-reveal_type(np.dtype("float32")) # E: numpy.dtype[numpy.floating[numpy.typing._32Bit]]
-reveal_type(np.dtype("int64")) # E: numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]
-reveal_type(np.dtype("int32")) # E: numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]
+reveal_type(np.dtype("float64")) # E: numpy.dtype[{float64}]
+reveal_type(np.dtype("float32")) # E: numpy.dtype[{float32}]
+reveal_type(np.dtype("int64")) # E: numpy.dtype[{int64}]
+reveal_type(np.dtype("int32")) # E: numpy.dtype[{int32}]
reveal_type(np.dtype("bool")) # E: numpy.dtype[numpy.bool_]
reveal_type(np.dtype("bytes")) # E: numpy.dtype[numpy.bytes_]
reveal_type(np.dtype("str")) # E: numpy.dtype[numpy.str_]
# Python types
-reveal_type(np.dtype(complex)) # E: numpy.dtype[numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]]
-reveal_type(np.dtype(float)) # E: numpy.dtype[numpy.floating[numpy.typing._64Bit]]
-reveal_type(np.dtype(int)) # E: numpy.dtype
+reveal_type(np.dtype(complex)) # E: numpy.dtype[{cdouble}]
+reveal_type(np.dtype(float)) # E: numpy.dtype[{double}]
+reveal_type(np.dtype(int)) # E: numpy.dtype[{int_}]
reveal_type(np.dtype(bool)) # E: numpy.dtype[numpy.bool_]
reveal_type(np.dtype(str)) # E: numpy.dtype[numpy.str_]
reveal_type(np.dtype(bytes)) # E: numpy.dtype[numpy.bytes_]
+reveal_type(np.dtype(object)) # E: numpy.dtype[numpy.object_]
+
+# ctypes
+reveal_type(np.dtype(ct.c_double)) # E: numpy.dtype[{double}]
+reveal_type(np.dtype(ct.c_longlong)) # E: numpy.dtype[{longlong}]
+reveal_type(np.dtype(ct.c_uint32)) # E: numpy.dtype[{uint32}]
+reveal_type(np.dtype(ct.c_bool)) # E: numpy.dtype[numpy.bool_]
+reveal_type(np.dtype(ct.c_char)) # E: numpy.dtype[numpy.bytes_]
+reveal_type(np.dtype(ct.py_object)) # E: numpy.dtype[numpy.object_]
# Special case for None
-reveal_type(np.dtype(None)) # E: numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(np.dtype(None)) # E: numpy.dtype[{double}]
# Dtypes of dtypes
-reveal_type(np.dtype(np.dtype(np.float64))) # E: numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(np.dtype(np.dtype(np.float64))) # E: numpy.dtype[{float64}]
# Parameterized dtypes
reveal_type(np.dtype("S8")) # E: numpy.dtype
# Void
reveal_type(np.dtype(("U", 10))) # E: numpy.dtype[numpy.void]
+
+# Methods and attributes
+reveal_type(dtype_U.base) # E: numpy.dtype[Any]
+reveal_type(dtype_U.subdtype) # E: Union[None, Tuple[numpy.dtype[Any], builtins.tuple[builtins.int]]]
+reveal_type(dtype_U.newbyteorder()) # E: numpy.dtype[numpy.str_]
+reveal_type(dtype_U.type) # E: Type[numpy.str_]
+reveal_type(dtype_U.name) # E: str
+reveal_type(dtype_U.names) # E: Union[None, builtins.tuple[builtins.str]]
+
+reveal_type(dtype_U * 0) # E: numpy.dtype[numpy.str_]
+reveal_type(dtype_U * 1) # E: numpy.dtype[numpy.str_]
+reveal_type(dtype_U * 2) # E: numpy.dtype[numpy.str_]
+
+reveal_type(dtype_i8 * 0) # E: numpy.dtype[numpy.void]
+reveal_type(dtype_i8 * 1) # E: numpy.dtype[{int64}]
+reveal_type(dtype_i8 * 2) # E: numpy.dtype[numpy.void]
+
+reveal_type(0 * dtype_U) # E: numpy.dtype[numpy.str_]
+reveal_type(1 * dtype_U) # E: numpy.dtype[numpy.str_]
+reveal_type(2 * dtype_U) # E: numpy.dtype[numpy.str_]
+
+reveal_type(0 * dtype_i8) # E: numpy.dtype[Any]
+reveal_type(1 * dtype_i8) # E: numpy.dtype[Any]
+reveal_type(2 * dtype_i8) # E: numpy.dtype[Any]
+
+reveal_type(dtype_V["f0"]) # E: numpy.dtype[Any]
+reveal_type(dtype_V[0]) # E: numpy.dtype[Any]
+reveal_type(dtype_V[["f0", "f1"]]) # E: numpy.dtype[numpy.void]
+reveal_type(dtype_V[["f0"]]) # E: numpy.dtype[numpy.void]
diff --git a/numpy/typing/tests/data/reveal/einsumfunc.py b/numpy/typing/tests/data/reveal/einsumfunc.py
new file mode 100644
index 000000000..f1a90428d
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/einsumfunc.py
@@ -0,0 +1,32 @@
+from typing import List, Any
+import numpy as np
+
+AR_LIKE_b: List[bool]
+AR_LIKE_u: List[np.uint32]
+AR_LIKE_i: List[int]
+AR_LIKE_f: List[float]
+AR_LIKE_c: List[complex]
+AR_LIKE_U: List[str]
+
+OUT_f: np.ndarray[Any, np.dtype[np.float64]]
+
+reveal_type(np.einsum("i,i->i", AR_LIKE_b, AR_LIKE_b)) # E: Any
+reveal_type(np.einsum("i,i->i", AR_LIKE_u, AR_LIKE_u)) # E: Any
+reveal_type(np.einsum("i,i->i", AR_LIKE_i, AR_LIKE_i)) # E: Any
+reveal_type(np.einsum("i,i->i", AR_LIKE_f, AR_LIKE_f)) # E: Any
+reveal_type(np.einsum("i,i->i", AR_LIKE_c, AR_LIKE_c)) # E: Any
+reveal_type(np.einsum("i,i->i", AR_LIKE_b, AR_LIKE_i)) # E: Any
+reveal_type(np.einsum("i,i,i,i->i", AR_LIKE_b, AR_LIKE_u, AR_LIKE_i, AR_LIKE_c)) # E: Any
+
+reveal_type(np.einsum("i,i->i", AR_LIKE_c, AR_LIKE_c, out=OUT_f)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]
+reveal_type(np.einsum("i,i->i", AR_LIKE_U, AR_LIKE_U, dtype=bool, casting="unsafe", out=OUT_f)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]
+reveal_type(np.einsum("i,i->i", AR_LIKE_f, AR_LIKE_f, dtype="c16")) # E: Any
+reveal_type(np.einsum("i,i->i", AR_LIKE_U, AR_LIKE_U, dtype=bool, casting="unsafe")) # E: Any
+
+reveal_type(np.einsum_path("i,i->i", AR_LIKE_b, AR_LIKE_b)) # E: Tuple[builtins.list[Any], builtins.str]
+reveal_type(np.einsum_path("i,i->i", AR_LIKE_u, AR_LIKE_u)) # E: Tuple[builtins.list[Any], builtins.str]
+reveal_type(np.einsum_path("i,i->i", AR_LIKE_i, AR_LIKE_i)) # E: Tuple[builtins.list[Any], builtins.str]
+reveal_type(np.einsum_path("i,i->i", AR_LIKE_f, AR_LIKE_f)) # E: Tuple[builtins.list[Any], builtins.str]
+reveal_type(np.einsum_path("i,i->i", AR_LIKE_c, AR_LIKE_c)) # E: Tuple[builtins.list[Any], builtins.str]
+reveal_type(np.einsum_path("i,i->i", AR_LIKE_b, AR_LIKE_i)) # E: Tuple[builtins.list[Any], builtins.str]
+reveal_type(np.einsum_path("i,i,i,i->i", AR_LIKE_b, AR_LIKE_u, AR_LIKE_i, AR_LIKE_c)) # E: Tuple[builtins.list[Any], builtins.str]
diff --git a/numpy/typing/tests/data/reveal/flatiter.py b/numpy/typing/tests/data/reveal/flatiter.py
index 56cdc7a0e..97776dd9f 100644
--- a/numpy/typing/tests/data/reveal/flatiter.py
+++ b/numpy/typing/tests/data/reveal/flatiter.py
@@ -1,14 +1,17 @@
+from typing import Any
import numpy as np
-a: "np.flatiter[np.ndarray]"
+a: np.flatiter[np.ndarray[Any, np.dtype[np.str_]]]
-reveal_type(a.base) # E: numpy.ndarray*
-reveal_type(a.copy()) # E: numpy.ndarray*
+reveal_type(a.base) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
+reveal_type(a.copy()) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
reveal_type(a.coords) # E: tuple[builtins.int]
reveal_type(a.index) # E: int
-reveal_type(iter(a)) # E: Iterator[numpy.generic*]
-reveal_type(next(a)) # E: numpy.generic
-reveal_type(a[0]) # E: numpy.generic
-reveal_type(a[[0, 1, 2]]) # E: numpy.ndarray*
-reveal_type(a[...]) # E: numpy.ndarray*
-reveal_type(a[:]) # E: numpy.ndarray*
+reveal_type(iter(a)) # E: Iterator[numpy.str_]
+reveal_type(next(a)) # E: numpy.str_
+reveal_type(a[0]) # E: numpy.str_
+reveal_type(a[[0, 1, 2]]) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
+reveal_type(a[...]) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
+reveal_type(a[:]) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
+reveal_type(a.__array__()) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
+reveal_type(a.__array__(np.dtype(np.float64))) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
diff --git a/numpy/typing/tests/data/reveal/fromnumeric.py b/numpy/typing/tests/data/reveal/fromnumeric.py
index 75865c285..bbcfbb85a 100644
--- a/numpy/typing/tests/data/reveal/fromnumeric.py
+++ b/numpy/typing/tests/data/reveal/fromnumeric.py
@@ -12,116 +12,102 @@ b = np.float32(1.0)
c = 1.0
d = np.array(1.0, dtype=np.float32) # writeable
-reveal_type(np.take(a, 0)) # E: numpy.bool_
-reveal_type(np.take(b, 0)) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(
- np.take(c, 0) # E: Union[numpy.generic, datetime.datetime, datetime.timedelta]
-)
-reveal_type(
- np.take(A, 0) # E: Union[numpy.generic, datetime.datetime, datetime.timedelta]
-)
-reveal_type(
- np.take(B, 0) # E: Union[numpy.generic, datetime.datetime, datetime.timedelta]
-)
-reveal_type(
- np.take( # E: Union[Union[numpy.generic, datetime.datetime, datetime.timedelta], numpy.ndarray]
- A, [0]
- )
-)
-reveal_type(
- np.take( # E: Union[Union[numpy.generic, datetime.datetime, datetime.timedelta], numpy.ndarray]
- B, [0]
- )
-)
-
-reveal_type(np.reshape(a, 1)) # E: numpy.ndarray
-reveal_type(np.reshape(b, 1)) # E: numpy.ndarray
-reveal_type(np.reshape(c, 1)) # E: numpy.ndarray
-reveal_type(np.reshape(A, 1)) # E: numpy.ndarray
-reveal_type(np.reshape(B, 1)) # E: numpy.ndarray
-
-reveal_type(np.choose(a, [True, True])) # E: numpy.bool_
-reveal_type(np.choose(A, [True, True])) # E: numpy.ndarray
-
-reveal_type(np.repeat(a, 1)) # E: numpy.ndarray
-reveal_type(np.repeat(b, 1)) # E: numpy.ndarray
-reveal_type(np.repeat(c, 1)) # E: numpy.ndarray
-reveal_type(np.repeat(A, 1)) # E: numpy.ndarray
-reveal_type(np.repeat(B, 1)) # E: numpy.ndarray
+reveal_type(np.take(a, 0)) # E: Any
+reveal_type(np.take(b, 0)) # E: Any
+reveal_type(np.take(c, 0)) # E: Any
+reveal_type(np.take(A, 0)) # E: Any
+reveal_type(np.take(B, 0)) # E: Any
+reveal_type(np.take(A, [0])) # E: Any
+reveal_type(np.take(B, [0])) # E: Any
+
+reveal_type(np.reshape(a, 1)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.reshape(b, 1)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.reshape(c, 1)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.reshape(A, 1)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.reshape(B, 1)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.choose(a, [True, True])) # E: Any
+reveal_type(np.choose(A, [True, True])) # E: Any
+
+reveal_type(np.repeat(a, 1)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.repeat(b, 1)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.repeat(c, 1)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.repeat(A, 1)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.repeat(B, 1)) # E: numpy.ndarray[Any, Any]
# TODO: Add tests for np.put()
-reveal_type(np.swapaxes(A, 0, 0)) # E: numpy.ndarray
-reveal_type(np.swapaxes(B, 0, 0)) # E: numpy.ndarray
-
-reveal_type(np.transpose(a)) # E: numpy.ndarray
-reveal_type(np.transpose(b)) # E: numpy.ndarray
-reveal_type(np.transpose(c)) # E: numpy.ndarray
-reveal_type(np.transpose(A)) # E: numpy.ndarray
-reveal_type(np.transpose(B)) # E: numpy.ndarray
-
-reveal_type(np.partition(a, 0, axis=None)) # E: numpy.ndarray
-reveal_type(np.partition(b, 0, axis=None)) # E: numpy.ndarray
-reveal_type(np.partition(c, 0, axis=None)) # E: numpy.ndarray
-reveal_type(np.partition(A, 0)) # E: numpy.ndarray
-reveal_type(np.partition(B, 0)) # E: numpy.ndarray
-
-reveal_type(np.argpartition(a, 0)) # E: numpy.integer[Any]
-reveal_type(np.argpartition(b, 0)) # E: numpy.integer[Any]
-reveal_type(np.argpartition(c, 0)) # E: numpy.ndarray
-reveal_type(np.argpartition(A, 0)) # E: numpy.ndarray
-reveal_type(np.argpartition(B, 0)) # E: numpy.ndarray
-
-reveal_type(np.sort(A, 0)) # E: numpy.ndarray
-reveal_type(np.sort(B, 0)) # E: numpy.ndarray
-
-reveal_type(np.argsort(A, 0)) # E: numpy.ndarray
-reveal_type(np.argsort(B, 0)) # E: numpy.ndarray
-
-reveal_type(np.argmax(A)) # E: numpy.integer[Any]
-reveal_type(np.argmax(B)) # E: numpy.integer[Any]
-reveal_type(np.argmax(A, axis=0)) # E: Union[numpy.integer[Any], numpy.ndarray]
-reveal_type(np.argmax(B, axis=0)) # E: Union[numpy.integer[Any], numpy.ndarray]
-
-reveal_type(np.argmin(A)) # E: numpy.integer[Any]
-reveal_type(np.argmin(B)) # E: numpy.integer[Any]
-reveal_type(np.argmin(A, axis=0)) # E: Union[numpy.integer[Any], numpy.ndarray]
-reveal_type(np.argmin(B, axis=0)) # E: Union[numpy.integer[Any], numpy.ndarray]
-
-reveal_type(np.searchsorted(A[0], 0)) # E: numpy.integer[Any]
-reveal_type(np.searchsorted(B[0], 0)) # E: numpy.integer[Any]
-reveal_type(np.searchsorted(A[0], [0])) # E: numpy.ndarray
-reveal_type(np.searchsorted(B[0], [0])) # E: numpy.ndarray
-
-reveal_type(np.resize(a, (5, 5))) # E: numpy.ndarray
-reveal_type(np.resize(b, (5, 5))) # E: numpy.ndarray
-reveal_type(np.resize(c, (5, 5))) # E: numpy.ndarray
-reveal_type(np.resize(A, (5, 5))) # E: numpy.ndarray
-reveal_type(np.resize(B, (5, 5))) # E: numpy.ndarray
+reveal_type(np.swapaxes(A, 0, 0)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.swapaxes(B, 0, 0)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.transpose(a)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.transpose(b)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.transpose(c)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.transpose(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.transpose(B)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.partition(a, 0, axis=None)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.partition(b, 0, axis=None)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.partition(c, 0, axis=None)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.partition(A, 0)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.partition(B, 0)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.argpartition(a, 0)) # E: Any
+reveal_type(np.argpartition(b, 0)) # E: Any
+reveal_type(np.argpartition(c, 0)) # E: Any
+reveal_type(np.argpartition(A, 0)) # E: Any
+reveal_type(np.argpartition(B, 0)) # E: Any
+
+reveal_type(np.sort(A, 0)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.sort(B, 0)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.argsort(A, 0)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.argsort(B, 0)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.argmax(A)) # E: {intp}
+reveal_type(np.argmax(B)) # E: {intp}
+reveal_type(np.argmax(A, axis=0)) # E: Any
+reveal_type(np.argmax(B, axis=0)) # E: Any
+
+reveal_type(np.argmin(A)) # E: {intp}
+reveal_type(np.argmin(B)) # E: {intp}
+reveal_type(np.argmin(A, axis=0)) # E: Any
+reveal_type(np.argmin(B, axis=0)) # E: Any
+
+reveal_type(np.searchsorted(A[0], 0)) # E: {intp}
+reveal_type(np.searchsorted(B[0], 0)) # E: {intp}
+reveal_type(np.searchsorted(A[0], [0])) # E: numpy.ndarray[Any, Any]
+reveal_type(np.searchsorted(B[0], [0])) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.resize(a, (5, 5))) # E: numpy.ndarray[Any, Any]
+reveal_type(np.resize(b, (5, 5))) # E: numpy.ndarray[Any, Any]
+reveal_type(np.resize(c, (5, 5))) # E: numpy.ndarray[Any, Any]
+reveal_type(np.resize(A, (5, 5))) # E: numpy.ndarray[Any, Any]
+reveal_type(np.resize(B, (5, 5))) # E: numpy.ndarray[Any, Any]
reveal_type(np.squeeze(a)) # E: numpy.bool_
-reveal_type(np.squeeze(b)) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(np.squeeze(c)) # E: numpy.ndarray
-reveal_type(np.squeeze(A)) # E: numpy.ndarray
-reveal_type(np.squeeze(B)) # E: numpy.ndarray
+reveal_type(np.squeeze(b)) # E: {float32}
+reveal_type(np.squeeze(c)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.squeeze(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.squeeze(B)) # E: numpy.ndarray[Any, Any]
-reveal_type(np.diagonal(A)) # E: numpy.ndarray
-reveal_type(np.diagonal(B)) # E: numpy.ndarray
+reveal_type(np.diagonal(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.diagonal(B)) # E: numpy.ndarray[Any, Any]
-reveal_type(np.trace(A)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.trace(B)) # E: Union[numpy.number[Any], numpy.ndarray]
+reveal_type(np.trace(A)) # E: Any
+reveal_type(np.trace(B)) # E: Any
-reveal_type(np.ravel(a)) # E: numpy.ndarray
-reveal_type(np.ravel(b)) # E: numpy.ndarray
-reveal_type(np.ravel(c)) # E: numpy.ndarray
-reveal_type(np.ravel(A)) # E: numpy.ndarray
-reveal_type(np.ravel(B)) # E: numpy.ndarray
+reveal_type(np.ravel(a)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.ravel(b)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.ravel(c)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.ravel(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.ravel(B)) # E: numpy.ndarray[Any, Any]
-reveal_type(np.nonzero(a)) # E: tuple[numpy.ndarray]
-reveal_type(np.nonzero(b)) # E: tuple[numpy.ndarray]
-reveal_type(np.nonzero(c)) # E: tuple[numpy.ndarray]
-reveal_type(np.nonzero(A)) # E: tuple[numpy.ndarray]
-reveal_type(np.nonzero(B)) # E: tuple[numpy.ndarray]
+reveal_type(np.nonzero(a)) # E: tuple[numpy.ndarray[Any, Any]]
+reveal_type(np.nonzero(b)) # E: tuple[numpy.ndarray[Any, Any]]
+reveal_type(np.nonzero(c)) # E: tuple[numpy.ndarray[Any, Any]]
+reveal_type(np.nonzero(A)) # E: tuple[numpy.ndarray[Any, Any]]
+reveal_type(np.nonzero(B)) # E: tuple[numpy.ndarray[Any, Any]]
reveal_type(np.shape(a)) # E: tuple[builtins.int]
reveal_type(np.shape(b)) # E: tuple[builtins.int]
@@ -129,99 +115,99 @@ reveal_type(np.shape(c)) # E: tuple[builtins.int]
reveal_type(np.shape(A)) # E: tuple[builtins.int]
reveal_type(np.shape(B)) # E: tuple[builtins.int]
-reveal_type(np.compress([True], a)) # E: numpy.ndarray
-reveal_type(np.compress([True], b)) # E: numpy.ndarray
-reveal_type(np.compress([True], c)) # E: numpy.ndarray
-reveal_type(np.compress([True], A)) # E: numpy.ndarray
-reveal_type(np.compress([True], B)) # E: numpy.ndarray
-
-reveal_type(np.clip(a, 0, 1.0)) # E: numpy.number[Any]
-reveal_type(np.clip(b, -1, 1)) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(np.clip(c, 0, 1)) # E: numpy.number[Any]
-reveal_type(np.clip(A, 0, 1)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.clip(B, 0, 1)) # E: Union[numpy.number[Any], numpy.ndarray]
-
-reveal_type(np.sum(a)) # E: numpy.number[Any]
-reveal_type(np.sum(b)) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(np.sum(c)) # E: numpy.number[Any]
-reveal_type(np.sum(A)) # E: numpy.number[Any]
-reveal_type(np.sum(B)) # E: numpy.number[Any]
-reveal_type(np.sum(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.sum(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
+reveal_type(np.compress([True], a)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.compress([True], b)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.compress([True], c)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.compress([True], A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.compress([True], B)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.clip(a, 0, 1.0)) # E: Any
+reveal_type(np.clip(b, -1, 1)) # E: Any
+reveal_type(np.clip(c, 0, 1)) # E: Any
+reveal_type(np.clip(A, 0, 1)) # E: Any
+reveal_type(np.clip(B, 0, 1)) # E: Any
+
+reveal_type(np.sum(a)) # E: Any
+reveal_type(np.sum(b)) # E: Any
+reveal_type(np.sum(c)) # E: Any
+reveal_type(np.sum(A)) # E: Any
+reveal_type(np.sum(B)) # E: Any
+reveal_type(np.sum(A, axis=0)) # E: Any
+reveal_type(np.sum(B, axis=0)) # E: Any
reveal_type(np.all(a)) # E: numpy.bool_
reveal_type(np.all(b)) # E: numpy.bool_
reveal_type(np.all(c)) # E: numpy.bool_
reveal_type(np.all(A)) # E: numpy.bool_
reveal_type(np.all(B)) # E: numpy.bool_
-reveal_type(np.all(A, axis=0)) # E: Union[numpy.bool_, numpy.ndarray]
-reveal_type(np.all(B, axis=0)) # E: Union[numpy.bool_, numpy.ndarray]
-reveal_type(np.all(A, keepdims=True)) # E: Union[numpy.bool_, numpy.ndarray]
-reveal_type(np.all(B, keepdims=True)) # E: Union[numpy.bool_, numpy.ndarray]
+reveal_type(np.all(A, axis=0)) # E: Any
+reveal_type(np.all(B, axis=0)) # E: Any
+reveal_type(np.all(A, keepdims=True)) # E: Any
+reveal_type(np.all(B, keepdims=True)) # E: Any
reveal_type(np.any(a)) # E: numpy.bool_
reveal_type(np.any(b)) # E: numpy.bool_
reveal_type(np.any(c)) # E: numpy.bool_
reveal_type(np.any(A)) # E: numpy.bool_
reveal_type(np.any(B)) # E: numpy.bool_
-reveal_type(np.any(A, axis=0)) # E: Union[numpy.bool_, numpy.ndarray]
-reveal_type(np.any(B, axis=0)) # E: Union[numpy.bool_, numpy.ndarray]
-reveal_type(np.any(A, keepdims=True)) # E: Union[numpy.bool_, numpy.ndarray]
-reveal_type(np.any(B, keepdims=True)) # E: Union[numpy.bool_, numpy.ndarray]
-
-reveal_type(np.cumsum(a)) # E: numpy.ndarray
-reveal_type(np.cumsum(b)) # E: numpy.ndarray
-reveal_type(np.cumsum(c)) # E: numpy.ndarray
-reveal_type(np.cumsum(A)) # E: numpy.ndarray
-reveal_type(np.cumsum(B)) # E: numpy.ndarray
-
-reveal_type(np.ptp(a)) # E: numpy.number[Any]
-reveal_type(np.ptp(b)) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(np.ptp(c)) # E: numpy.number[Any]
-reveal_type(np.ptp(A)) # E: numpy.number[Any]
-reveal_type(np.ptp(B)) # E: numpy.number[Any]
-reveal_type(np.ptp(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.ptp(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.ptp(A, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.ptp(B, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray]
-
-reveal_type(np.amax(a)) # E: numpy.number[Any]
-reveal_type(np.amax(b)) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(np.amax(c)) # E: numpy.number[Any]
-reveal_type(np.amax(A)) # E: numpy.number[Any]
-reveal_type(np.amax(B)) # E: numpy.number[Any]
-reveal_type(np.amax(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.amax(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.amax(A, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.amax(B, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray]
-
-reveal_type(np.amin(a)) # E: numpy.number[Any]
-reveal_type(np.amin(b)) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(np.amin(c)) # E: numpy.number[Any]
-reveal_type(np.amin(A)) # E: numpy.number[Any]
-reveal_type(np.amin(B)) # E: numpy.number[Any]
-reveal_type(np.amin(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.amin(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.amin(A, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.amin(B, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray]
-
-reveal_type(np.prod(a)) # E: numpy.number[Any]
-reveal_type(np.prod(b)) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(np.prod(c)) # E: numpy.number[Any]
-reveal_type(np.prod(A)) # E: numpy.number[Any]
-reveal_type(np.prod(B)) # E: numpy.number[Any]
-reveal_type(np.prod(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.prod(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.prod(A, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.prod(B, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.prod(b, out=d)) # E: numpy.ndarray
-reveal_type(np.prod(B, out=d)) # E: numpy.ndarray
-
-reveal_type(np.cumprod(a)) # E: numpy.ndarray
-reveal_type(np.cumprod(b)) # E: numpy.ndarray
-reveal_type(np.cumprod(c)) # E: numpy.ndarray
-reveal_type(np.cumprod(A)) # E: numpy.ndarray
-reveal_type(np.cumprod(B)) # E: numpy.ndarray
+reveal_type(np.any(A, axis=0)) # E: Any
+reveal_type(np.any(B, axis=0)) # E: Any
+reveal_type(np.any(A, keepdims=True)) # E: Any
+reveal_type(np.any(B, keepdims=True)) # E: Any
+
+reveal_type(np.cumsum(a)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.cumsum(b)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.cumsum(c)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.cumsum(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.cumsum(B)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(np.ptp(a)) # E: Any
+reveal_type(np.ptp(b)) # E: Any
+reveal_type(np.ptp(c)) # E: Any
+reveal_type(np.ptp(A)) # E: Any
+reveal_type(np.ptp(B)) # E: Any
+reveal_type(np.ptp(A, axis=0)) # E: Any
+reveal_type(np.ptp(B, axis=0)) # E: Any
+reveal_type(np.ptp(A, keepdims=True)) # E: Any
+reveal_type(np.ptp(B, keepdims=True)) # E: Any
+
+reveal_type(np.amax(a)) # E: Any
+reveal_type(np.amax(b)) # E: Any
+reveal_type(np.amax(c)) # E: Any
+reveal_type(np.amax(A)) # E: Any
+reveal_type(np.amax(B)) # E: Any
+reveal_type(np.amax(A, axis=0)) # E: Any
+reveal_type(np.amax(B, axis=0)) # E: Any
+reveal_type(np.amax(A, keepdims=True)) # E: Any
+reveal_type(np.amax(B, keepdims=True)) # E: Any
+
+reveal_type(np.amin(a)) # E: Any
+reveal_type(np.amin(b)) # E: Any
+reveal_type(np.amin(c)) # E: Any
+reveal_type(np.amin(A)) # E: Any
+reveal_type(np.amin(B)) # E: Any
+reveal_type(np.amin(A, axis=0)) # E: Any
+reveal_type(np.amin(B, axis=0)) # E: Any
+reveal_type(np.amin(A, keepdims=True)) # E: Any
+reveal_type(np.amin(B, keepdims=True)) # E: Any
+
+reveal_type(np.prod(a)) # E: Any
+reveal_type(np.prod(b)) # E: Any
+reveal_type(np.prod(c)) # E: Any
+reveal_type(np.prod(A)) # E: Any
+reveal_type(np.prod(B)) # E: Any
+reveal_type(np.prod(A, axis=0)) # E: Any
+reveal_type(np.prod(B, axis=0)) # E: Any
+reveal_type(np.prod(A, keepdims=True)) # E: Any
+reveal_type(np.prod(B, keepdims=True)) # E: Any
+reveal_type(np.prod(b, out=d)) # E: Any
+reveal_type(np.prod(B, out=d)) # E: Any
+
+reveal_type(np.cumprod(a)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.cumprod(b)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.cumprod(c)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.cumprod(A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.cumprod(B)) # E: numpy.ndarray[Any, Any]
reveal_type(np.ndim(a)) # E: int
reveal_type(np.ndim(b)) # E: int
@@ -235,44 +221,44 @@ reveal_type(np.size(c)) # E: int
reveal_type(np.size(A)) # E: int
reveal_type(np.size(B)) # E: int
-reveal_type(np.around(a)) # E: numpy.number[Any]
-reveal_type(np.around(b)) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(np.around(c)) # E: numpy.number[Any]
-reveal_type(np.around(A)) # E: numpy.ndarray
-reveal_type(np.around(B)) # E: numpy.ndarray
-
-reveal_type(np.mean(a)) # E: numpy.number[Any]
-reveal_type(np.mean(b)) # E: numpy.number[Any]
-reveal_type(np.mean(c)) # E: numpy.number[Any]
-reveal_type(np.mean(A)) # E: numpy.number[Any]
-reveal_type(np.mean(B)) # E: numpy.number[Any]
-reveal_type(np.mean(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.mean(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.mean(A, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.mean(B, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.mean(b, out=d)) # E: numpy.ndarray
-reveal_type(np.mean(B, out=d)) # E: numpy.ndarray
-
-reveal_type(np.std(a)) # E: numpy.number[Any]
-reveal_type(np.std(b)) # E: numpy.number[Any]
-reveal_type(np.std(c)) # E: numpy.number[Any]
-reveal_type(np.std(A)) # E: numpy.number[Any]
-reveal_type(np.std(B)) # E: numpy.number[Any]
-reveal_type(np.std(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.std(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.std(A, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.std(B, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.std(b, out=d)) # E: numpy.ndarray
-reveal_type(np.std(B, out=d)) # E: numpy.ndarray
-
-reveal_type(np.var(a)) # E: numpy.number[Any]
-reveal_type(np.var(b)) # E: numpy.number[Any]
-reveal_type(np.var(c)) # E: numpy.number[Any]
-reveal_type(np.var(A)) # E: numpy.number[Any]
-reveal_type(np.var(B)) # E: numpy.number[Any]
-reveal_type(np.var(A, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.var(B, axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.var(A, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.var(B, keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(np.var(b, out=d)) # E: numpy.ndarray
-reveal_type(np.var(B, out=d)) # E: numpy.ndarray
+reveal_type(np.around(a)) # E: Any
+reveal_type(np.around(b)) # E: Any
+reveal_type(np.around(c)) # E: Any
+reveal_type(np.around(A)) # E: Any
+reveal_type(np.around(B)) # E: Any
+
+reveal_type(np.mean(a)) # E: Any
+reveal_type(np.mean(b)) # E: Any
+reveal_type(np.mean(c)) # E: Any
+reveal_type(np.mean(A)) # E: Any
+reveal_type(np.mean(B)) # E: Any
+reveal_type(np.mean(A, axis=0)) # E: Any
+reveal_type(np.mean(B, axis=0)) # E: Any
+reveal_type(np.mean(A, keepdims=True)) # E: Any
+reveal_type(np.mean(B, keepdims=True)) # E: Any
+reveal_type(np.mean(b, out=d)) # E: Any
+reveal_type(np.mean(B, out=d)) # E: Any
+
+reveal_type(np.std(a)) # E: Any
+reveal_type(np.std(b)) # E: Any
+reveal_type(np.std(c)) # E: Any
+reveal_type(np.std(A)) # E: Any
+reveal_type(np.std(B)) # E: Any
+reveal_type(np.std(A, axis=0)) # E: Any
+reveal_type(np.std(B, axis=0)) # E: Any
+reveal_type(np.std(A, keepdims=True)) # E: Any
+reveal_type(np.std(B, keepdims=True)) # E: Any
+reveal_type(np.std(b, out=d)) # E: Any
+reveal_type(np.std(B, out=d)) # E: Any
+
+reveal_type(np.var(a)) # E: Any
+reveal_type(np.var(b)) # E: Any
+reveal_type(np.var(c)) # E: Any
+reveal_type(np.var(A)) # E: Any
+reveal_type(np.var(B)) # E: Any
+reveal_type(np.var(A, axis=0)) # E: Any
+reveal_type(np.var(B, axis=0)) # E: Any
+reveal_type(np.var(A, keepdims=True)) # E: Any
+reveal_type(np.var(B, keepdims=True)) # E: Any
+reveal_type(np.var(b, out=d)) # E: Any
+reveal_type(np.var(B, out=d)) # E: Any
diff --git a/numpy/typing/tests/data/reveal/getlimits.py b/numpy/typing/tests/data/reveal/getlimits.py
new file mode 100644
index 000000000..e12723bfe
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/getlimits.py
@@ -0,0 +1,73 @@
+import numpy as np
+from numpy.typing import _32Bit
+
+f: float
+f8: np.float64
+c8: np.complex64
+
+i: int
+i8: np.int64
+u4: np.uint32
+
+finfo_f8: np.finfo[np.float64]
+iinfo_i8: np.iinfo[np.int64]
+machar_f4: np.core.getlimits.MachArLike[_32Bit]
+
+reveal_type(np.finfo(f)) # E: numpy.finfo[{double}]
+reveal_type(np.finfo(f8)) # E: numpy.finfo[{float64}]
+reveal_type(np.finfo(c8)) # E: numpy.finfo[{float32}]
+reveal_type(np.finfo('f2')) # E: numpy.finfo[numpy.floating[Any]]
+
+reveal_type(finfo_f8.dtype) # E: numpy.dtype[{float64}]
+reveal_type(finfo_f8.bits) # E: int
+reveal_type(finfo_f8.eps) # E: {float64}
+reveal_type(finfo_f8.epsneg) # E: {float64}
+reveal_type(finfo_f8.iexp) # E: int
+reveal_type(finfo_f8.machep) # E: int
+reveal_type(finfo_f8.max) # E: {float64}
+reveal_type(finfo_f8.maxexp) # E: int
+reveal_type(finfo_f8.min) # E: {float64}
+reveal_type(finfo_f8.minexp) # E: int
+reveal_type(finfo_f8.negep) # E: int
+reveal_type(finfo_f8.nexp) # E: int
+reveal_type(finfo_f8.nmant) # E: int
+reveal_type(finfo_f8.precision) # E: int
+reveal_type(finfo_f8.resolution) # E: {float64}
+reveal_type(finfo_f8.tiny) # E: {float64}
+reveal_type(finfo_f8.smallest_normal) # E: {float64}
+reveal_type(finfo_f8.smallest_subnormal) # E: {float64}
+reveal_type(finfo_f8.machar) # E: MachArLike[numpy.typing._64Bit]
+
+reveal_type(np.iinfo(i)) # E: iinfo[{int_}]
+reveal_type(np.iinfo(i8)) # E: iinfo[{int64}]
+reveal_type(np.iinfo(u4)) # E: iinfo[{uint32}]
+reveal_type(np.iinfo('i2')) # E: iinfo[Any]
+
+reveal_type(iinfo_i8.dtype) # E: numpy.dtype[{int64}]
+reveal_type(iinfo_i8.kind) # E: str
+reveal_type(iinfo_i8.bits) # E: int
+reveal_type(iinfo_i8.key) # E: str
+reveal_type(iinfo_i8.min) # E: int
+reveal_type(iinfo_i8.max) # E: int
+
+reveal_type(machar_f4.eps) # E: numpy.ndarray[Any, numpy.dtype[{float32}]]
+reveal_type(machar_f4.epsilon) # E: numpy.ndarray[Any, numpy.dtype[{float32}]]
+reveal_type(machar_f4.epsneg) # E: numpy.ndarray[Any, numpy.dtype[{float32}]]
+reveal_type(machar_f4.huge) # E: numpy.ndarray[Any, numpy.dtype[{float32}]]
+reveal_type(machar_f4.resolution) # E: numpy.ndarray[Any, numpy.dtype[{float32}]]
+reveal_type(machar_f4.tiny) # E: numpy.ndarray[Any, numpy.dtype[{float32}]]
+reveal_type(machar_f4.xmax) # E: numpy.ndarray[Any, numpy.dtype[{float32}]]
+reveal_type(machar_f4.xmin) # E: numpy.ndarray[Any, numpy.dtype[{float32}]]
+reveal_type(machar_f4.smallest_subnormal) # E: numpy.ndarray[Any, numpy.dtype[{float32}]]
+reveal_type(machar_f4.smallest_normal) # E: numpy.ndarray[Any, numpy.dtype[{float32}]]
+reveal_type(machar_f4.iexp) # E: int
+reveal_type(machar_f4.irnd) # E: int
+reveal_type(machar_f4.it) # E: int
+reveal_type(machar_f4.machep) # E: int
+reveal_type(machar_f4.maxexp) # E: int
+reveal_type(machar_f4.minexp) # E: int
+reveal_type(machar_f4.negep) # E: int
+reveal_type(machar_f4.ngrd) # E: int
+reveal_type(machar_f4.precision) # E: int
+reveal_type(machar_f4.ibeta) # E: {int32}
+reveal_type(machar_f4.title) # E: str
diff --git a/numpy/typing/tests/data/reveal/index_tricks.py b/numpy/typing/tests/data/reveal/index_tricks.py
new file mode 100644
index 000000000..863d60220
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/index_tricks.py
@@ -0,0 +1,64 @@
+from typing import Any, List
+import numpy as np
+
+AR_LIKE_b: List[bool]
+AR_LIKE_i: List[int]
+AR_LIKE_f: List[float]
+AR_LIKE_U: List[str]
+
+AR_i8: np.ndarray[Any, np.dtype[np.int64]]
+
+reveal_type(np.ndenumerate(AR_i8)) # E: numpy.ndenumerate[{int64}]
+reveal_type(np.ndenumerate(AR_LIKE_f)) # E: numpy.ndenumerate[{double}]
+reveal_type(np.ndenumerate(AR_LIKE_U)) # E: numpy.ndenumerate[numpy.str_]
+
+reveal_type(np.ndenumerate(AR_i8).iter) # E: numpy.flatiter[numpy.ndarray[Any, numpy.dtype[{int64}]]]
+reveal_type(np.ndenumerate(AR_LIKE_f).iter) # E: numpy.flatiter[numpy.ndarray[Any, numpy.dtype[{double}]]]
+reveal_type(np.ndenumerate(AR_LIKE_U).iter) # E: numpy.flatiter[numpy.ndarray[Any, numpy.dtype[numpy.str_]]]
+
+reveal_type(next(np.ndenumerate(AR_i8))) # E: Tuple[builtins.tuple[builtins.int], {int64}]
+reveal_type(next(np.ndenumerate(AR_LIKE_f))) # E: Tuple[builtins.tuple[builtins.int], {double}]
+reveal_type(next(np.ndenumerate(AR_LIKE_U))) # E: Tuple[builtins.tuple[builtins.int], numpy.str_]
+
+reveal_type(iter(np.ndenumerate(AR_i8))) # E: Iterator[Tuple[builtins.tuple[builtins.int], {int64}]]
+reveal_type(iter(np.ndenumerate(AR_LIKE_f))) # E: Iterator[Tuple[builtins.tuple[builtins.int], {double}]]
+reveal_type(iter(np.ndenumerate(AR_LIKE_U))) # E: Iterator[Tuple[builtins.tuple[builtins.int], numpy.str_]]
+
+reveal_type(iter(np.ndindex(1, 2, 3))) # E: Iterator[builtins.tuple[builtins.int]]
+reveal_type(next(np.ndindex(1, 2, 3))) # E: builtins.tuple[builtins.int]
+
+reveal_type(np.unravel_index([22, 41, 37], (7, 6))) # E: tuple[numpy.ndarray[Any, numpy.dtype[{intp}]]]
+reveal_type(np.unravel_index([31, 41, 13], (7, 6), order="F")) # E: tuple[numpy.ndarray[Any, numpy.dtype[{intp}]]]
+reveal_type(np.unravel_index(1621, (6, 7, 8, 9))) # E: tuple[{intp}]
+
+reveal_type(np.ravel_multi_index([[1]], (7, 6))) # E: numpy.ndarray[Any, numpy.dtype[{intp}]]
+reveal_type(np.ravel_multi_index(AR_LIKE_i, (7, 6))) # E: {intp}
+reveal_type(np.ravel_multi_index(AR_LIKE_i, (7, 6), order="F")) # E: {intp}
+reveal_type(np.ravel_multi_index(AR_LIKE_i, (4, 6), mode="clip")) # E: {intp}
+reveal_type(np.ravel_multi_index(AR_LIKE_i, (4, 4), mode=("clip", "wrap"))) # E: {intp}
+reveal_type(np.ravel_multi_index((3, 1, 4, 1), (6, 7, 8, 9))) # E: {intp}
+
+reveal_type(np.mgrid[1:1:2]) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.mgrid[1:1:2, None:10]) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.ogrid[1:1:2]) # E: list[numpy.ndarray[Any, numpy.dtype[Any]]]
+reveal_type(np.ogrid[1:1:2, None:10]) # E: list[numpy.ndarray[Any, numpy.dtype[Any]]]
+
+reveal_type(np.index_exp[0:1]) # E: Tuple[builtins.slice]
+reveal_type(np.index_exp[0:1, None:3]) # E: Tuple[builtins.slice, builtins.slice]
+reveal_type(np.index_exp[0, 0:1, ..., [0, 1, 3]]) # E: Tuple[Literal[0]?, builtins.slice, builtins.ellipsis, builtins.list[builtins.int]]
+
+reveal_type(np.s_[0:1]) # E: builtins.slice
+reveal_type(np.s_[0:1, None:3]) # E: Tuple[builtins.slice, builtins.slice]
+reveal_type(np.s_[0, 0:1, ..., [0, 1, 3]]) # E: Tuple[Literal[0]?, builtins.slice, builtins.ellipsis, builtins.list[builtins.int]]
+
+reveal_type(np.ix_(AR_LIKE_b)) # E: tuple[numpy.ndarray[Any, numpy.dtype[numpy.bool_]]]
+reveal_type(np.ix_(AR_LIKE_i, AR_LIKE_f)) # E: tuple[numpy.ndarray[Any, numpy.dtype[{double}]]]
+reveal_type(np.ix_(AR_i8)) # E: tuple[numpy.ndarray[Any, numpy.dtype[{int64}]]]
+
+reveal_type(np.fill_diagonal(AR_i8, 5)) # E: None
+
+reveal_type(np.diag_indices(4)) # E: tuple[numpy.ndarray[Any, numpy.dtype[{int_}]]]
+reveal_type(np.diag_indices(2, 3)) # E: tuple[numpy.ndarray[Any, numpy.dtype[{int_}]]]
+
+reveal_type(np.diag_indices_from(AR_i8)) # E: tuple[numpy.ndarray[Any, numpy.dtype[{int_}]]]
diff --git a/numpy/typing/tests/data/reveal/lib_utils.py b/numpy/typing/tests/data/reveal/lib_utils.py
new file mode 100644
index 000000000..d82012707
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/lib_utils.py
@@ -0,0 +1,30 @@
+from io import StringIO
+from typing import Any, Dict
+
+import numpy as np
+
+AR: np.ndarray[Any, np.dtype[np.float64]]
+AR_DICT: Dict[str, np.ndarray[Any, np.dtype[np.float64]]]
+FILE: StringIO
+
+def func(a: int) -> bool: ...
+
+reveal_type(np.deprecate(func)) # E: def (a: builtins.int) -> builtins.bool
+reveal_type(np.deprecate()) # E: _Deprecate
+
+reveal_type(np.deprecate_with_doc("test")) # E: _Deprecate
+reveal_type(np.deprecate_with_doc(None)) # E: _Deprecate
+
+reveal_type(np.byte_bounds(AR)) # E: Tuple[builtins.int, builtins.int]
+reveal_type(np.byte_bounds(np.float64())) # E: Tuple[builtins.int, builtins.int]
+
+reveal_type(np.who(None)) # E: None
+reveal_type(np.who(AR_DICT)) # E: None
+
+reveal_type(np.info(1, output=FILE)) # E: None
+
+reveal_type(np.source(np.interp, output=FILE)) # E: None
+
+reveal_type(np.lookfor("binary representation", output=FILE)) # E: None
+
+reveal_type(np.safe_eval("1 + 1")) # E: Any
diff --git a/numpy/typing/tests/data/reveal/lib_version.py b/numpy/typing/tests/data/reveal/lib_version.py
new file mode 100644
index 000000000..e6f695558
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/lib_version.py
@@ -0,0 +1,18 @@
+from numpy.lib import NumpyVersion
+
+version = NumpyVersion("1.8.0")
+
+reveal_type(version.vstring) # E: str
+reveal_type(version.version) # E: str
+reveal_type(version.major) # E: int
+reveal_type(version.minor) # E: int
+reveal_type(version.bugfix) # E: int
+reveal_type(version.pre_release) # E: str
+reveal_type(version.is_devversion) # E: bool
+
+reveal_type(version == version) # E: bool
+reveal_type(version != version) # E: bool
+reveal_type(version < "1.8.0") # E: bool
+reveal_type(version <= version) # E: bool
+reveal_type(version > version) # E: bool
+reveal_type(version >= "1.8.0") # E: bool
diff --git a/numpy/typing/tests/data/reveal/mod.py b/numpy/typing/tests/data/reveal/mod.py
index 4292041f8..bf45b8c58 100644
--- a/numpy/typing/tests/data/reveal/mod.py
+++ b/numpy/typing/tests/data/reveal/mod.py
@@ -1,3 +1,4 @@
+from typing import Any
import numpy as np
f8 = np.float64()
@@ -15,135 +16,132 @@ b = bool()
f = float()
i = int()
-AR = np.array([1], dtype=np.bool_)
-AR.setflags(write=False)
-
-AR2 = np.array([1], dtype=np.timedelta64)
-AR2.setflags(write=False)
+AR_b: np.ndarray[Any, np.dtype[np.bool_]]
+AR_m: np.ndarray[Any, np.dtype[np.timedelta64]]
# Time structures
reveal_type(td % td) # E: numpy.timedelta64
-reveal_type(AR2 % td) # E: Any
-reveal_type(td % AR2) # E: Any
+reveal_type(AR_m % td) # E: Any
+reveal_type(td % AR_m) # E: Any
-reveal_type(divmod(td, td)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.timedelta64]
-reveal_type(divmod(AR2, td)) # E: Tuple[Any, Any]
-reveal_type(divmod(td, AR2)) # E: Tuple[Any, Any]
+reveal_type(divmod(td, td)) # E: Tuple[{int64}, numpy.timedelta64]
+reveal_type(divmod(AR_m, td)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]], numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]]
+reveal_type(divmod(td, AR_m)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]], numpy.ndarray[Any, numpy.dtype[numpy.timedelta64]]]
# Bool
-reveal_type(b_ % b) # E: numpy.signedinteger[numpy.typing._8Bit]
-reveal_type(b_ % i) # E: numpy.signedinteger[Any]
-reveal_type(b_ % f) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(b_ % b_) # E: numpy.signedinteger[numpy.typing._8Bit]
-reveal_type(b_ % i8) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(b_ % u8) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(b_ % f8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(b_ % AR) # E: Any
-
-reveal_type(divmod(b_, b)) # E: Tuple[numpy.signedinteger[numpy.typing._8Bit], numpy.signedinteger[numpy.typing._8Bit]]
-reveal_type(divmod(b_, i)) # E: Tuple[numpy.signedinteger[Any], numpy.signedinteger[Any]]
-reveal_type(divmod(b_, f)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
-reveal_type(divmod(b_, b_)) # E: Tuple[numpy.signedinteger[numpy.typing._8Bit], numpy.signedinteger[numpy.typing._8Bit]]
-reveal_type(divmod(b_, i8)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]]
-reveal_type(divmod(b_, u8)) # E: Tuple[numpy.unsignedinteger[numpy.typing._64Bit], numpy.unsignedinteger[numpy.typing._64Bit]]
-reveal_type(divmod(b_, f8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
-reveal_type(divmod(b_, AR)) # E: Tuple[Any, Any]
-
-reveal_type(b % b_) # E: numpy.signedinteger[numpy.typing._8Bit]
-reveal_type(i % b_) # E: numpy.signedinteger[Any]
-reveal_type(f % b_) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(b_ % b_) # E: numpy.signedinteger[numpy.typing._8Bit]
-reveal_type(i8 % b_) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(u8 % b_) # E: numpy.unsignedinteger[numpy.typing._64Bit]
-reveal_type(f8 % b_) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(AR % b_) # E: Any
-
-reveal_type(divmod(b, b_)) # E: Tuple[numpy.signedinteger[numpy.typing._8Bit], numpy.signedinteger[numpy.typing._8Bit]]
-reveal_type(divmod(i, b_)) # E: Tuple[numpy.signedinteger[Any], numpy.signedinteger[Any]]
-reveal_type(divmod(f, b_)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
-reveal_type(divmod(b_, b_)) # E: Tuple[numpy.signedinteger[numpy.typing._8Bit], numpy.signedinteger[numpy.typing._8Bit]]
-reveal_type(divmod(i8, b_)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]]
-reveal_type(divmod(u8, b_)) # E: Tuple[numpy.unsignedinteger[numpy.typing._64Bit], numpy.unsignedinteger[numpy.typing._64Bit]]
-reveal_type(divmod(f8, b_)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
-reveal_type(divmod(AR, b_)) # E: Tuple[Any, Any]
+reveal_type(b_ % b) # E: {int8}
+reveal_type(b_ % i) # E: {int_}
+reveal_type(b_ % f) # E: {float64}
+reveal_type(b_ % b_) # E: {int8}
+reveal_type(b_ % i8) # E: {int64}
+reveal_type(b_ % u8) # E: {uint64}
+reveal_type(b_ % f8) # E: {float64}
+reveal_type(b_ % AR_b) # E: numpy.ndarray[Any, numpy.dtype[{int8}]]
+
+reveal_type(divmod(b_, b)) # E: Tuple[{int8}, {int8}]
+reveal_type(divmod(b_, i)) # E: Tuple[{int_}, {int_}]
+reveal_type(divmod(b_, f)) # E: Tuple[{float64}, {float64}]
+reveal_type(divmod(b_, b_)) # E: Tuple[{int8}, {int8}]
+reveal_type(divmod(b_, i8)) # E: Tuple[{int64}, {int64}]
+reveal_type(divmod(b_, u8)) # E: Tuple[{uint64}, {uint64}]
+reveal_type(divmod(b_, f8)) # E: Tuple[{float64}, {float64}]
+reveal_type(divmod(b_, AR_b)) # E: numpy.ndarray[Any, numpy.dtype[{int8}]], numpy.ndarray[Any, numpy.dtype[{int8}]]]
+
+reveal_type(b % b_) # E: {int8}
+reveal_type(i % b_) # E: {int_}
+reveal_type(f % b_) # E: {float64}
+reveal_type(b_ % b_) # E: {int8}
+reveal_type(i8 % b_) # E: {int64}
+reveal_type(u8 % b_) # E: {uint64}
+reveal_type(f8 % b_) # E: {float64}
+reveal_type(AR_b % b_) # E: numpy.ndarray[Any, numpy.dtype[{int8}]]
+
+reveal_type(divmod(b, b_)) # E: Tuple[{int8}, {int8}]
+reveal_type(divmod(i, b_)) # E: Tuple[{int_}, {int_}]
+reveal_type(divmod(f, b_)) # E: Tuple[{float64}, {float64}]
+reveal_type(divmod(b_, b_)) # E: Tuple[{int8}, {int8}]
+reveal_type(divmod(i8, b_)) # E: Tuple[{int64}, {int64}]
+reveal_type(divmod(u8, b_)) # E: Tuple[{uint64}, {uint64}]
+reveal_type(divmod(f8, b_)) # E: Tuple[{float64}, {float64}]
+reveal_type(divmod(AR_b, b_)) # E: numpy.ndarray[Any, numpy.dtype[{int8}]], numpy.ndarray[Any, numpy.dtype[{int8}]]]
# int
-reveal_type(i8 % b) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i8 % i) # E: numpy.signedinteger[Any]
-reveal_type(i8 % f) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(i8 % i8) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i8 % f8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(i4 % i8) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i4 % f8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(i4 % i4) # E: numpy.signedinteger[numpy.typing._32Bit]
-reveal_type(i4 % f4) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(i8 % AR) # E: Any
-
-reveal_type(divmod(i8, b)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]]
-reveal_type(divmod(i8, i)) # E: Tuple[numpy.signedinteger[Any], numpy.signedinteger[Any]]
-reveal_type(divmod(i8, f)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
-reveal_type(divmod(i8, i8)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]]
-reveal_type(divmod(i8, f8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
-reveal_type(divmod(i8, i4)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]]
-reveal_type(divmod(i8, f4)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
-reveal_type(divmod(i4, i4)) # E: Tuple[numpy.signedinteger[numpy.typing._32Bit], numpy.signedinteger[numpy.typing._32Bit]]
-reveal_type(divmod(i4, f4)) # E: Tuple[numpy.floating[numpy.typing._32Bit], numpy.floating[numpy.typing._32Bit]]
-reveal_type(divmod(i8, AR)) # E: Tuple[Any, Any]
-
-reveal_type(b % i8) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(i % i8) # E: numpy.signedinteger[Any]
-reveal_type(f % i8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(i8 % i8) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(f8 % i8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(i8 % i4) # E: numpy.signedinteger[numpy.typing._64Bit]
-reveal_type(f8 % i4) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(i4 % i4) # E: numpy.signedinteger[numpy.typing._32Bit]
-reveal_type(f4 % i4) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(AR % i8) # E: Any
-
-reveal_type(divmod(b, i8)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]]
-reveal_type(divmod(i, i8)) # E: Tuple[numpy.signedinteger[Any], numpy.signedinteger[Any]]
-reveal_type(divmod(f, i8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
-reveal_type(divmod(i8, i8)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]]
-reveal_type(divmod(f8, i8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
-reveal_type(divmod(i4, i8)) # E: Tuple[numpy.signedinteger[numpy.typing._64Bit], numpy.signedinteger[numpy.typing._64Bit]]
-reveal_type(divmod(f4, i8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
-reveal_type(divmod(i4, i4)) # E: Tuple[numpy.signedinteger[numpy.typing._32Bit], numpy.signedinteger[numpy.typing._32Bit]]
-reveal_type(divmod(f4, i4)) # E: Tuple[numpy.floating[numpy.typing._32Bit], numpy.floating[numpy.typing._32Bit]]
-reveal_type(divmod(AR, i8)) # E: Tuple[Any, Any]
+reveal_type(i8 % b) # E: {int64}
+reveal_type(i8 % i) # E: {int64}
+reveal_type(i8 % f) # E: {float64}
+reveal_type(i8 % i8) # E: {int64}
+reveal_type(i8 % f8) # E: {float64}
+reveal_type(i4 % i8) # E: {int64}
+reveal_type(i4 % f8) # E: {float64}
+reveal_type(i4 % i4) # E: {int32}
+reveal_type(i4 % f4) # E: {float32}
+reveal_type(i8 % AR_b) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+
+reveal_type(divmod(i8, b)) # E: Tuple[{int64}, {int64}]
+reveal_type(divmod(i8, i)) # E: Tuple[{int64}, {int64}]
+reveal_type(divmod(i8, f)) # E: Tuple[{float64}, {float64}]
+reveal_type(divmod(i8, i8)) # E: Tuple[{int64}, {int64}]
+reveal_type(divmod(i8, f8)) # E: Tuple[{float64}, {float64}]
+reveal_type(divmod(i8, i4)) # E: Tuple[{int64}, {int64}]
+reveal_type(divmod(i8, f4)) # E: Tuple[{float64}, {float64}]
+reveal_type(divmod(i4, i4)) # E: Tuple[{int32}, {int32}]
+reveal_type(divmod(i4, f4)) # E: Tuple[{float32}, {float32}]
+reveal_type(divmod(i8, AR_b)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]], numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]]
+
+reveal_type(b % i8) # E: {int64}
+reveal_type(i % i8) # E: {int64}
+reveal_type(f % i8) # E: {float64}
+reveal_type(i8 % i8) # E: {int64}
+reveal_type(f8 % i8) # E: {float64}
+reveal_type(i8 % i4) # E: {int64}
+reveal_type(f8 % i4) # E: {float64}
+reveal_type(i4 % i4) # E: {int32}
+reveal_type(f4 % i4) # E: {float32}
+reveal_type(AR_b % i8) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+
+reveal_type(divmod(b, i8)) # E: Tuple[{int64}, {int64}]
+reveal_type(divmod(i, i8)) # E: Tuple[{int64}, {int64}]
+reveal_type(divmod(f, i8)) # E: Tuple[{float64}, {float64}]
+reveal_type(divmod(i8, i8)) # E: Tuple[{int64}, {int64}]
+reveal_type(divmod(f8, i8)) # E: Tuple[{float64}, {float64}]
+reveal_type(divmod(i4, i8)) # E: Tuple[{int64}, {int64}]
+reveal_type(divmod(f4, i8)) # E: Tuple[{float64}, {float64}]
+reveal_type(divmod(i4, i4)) # E: Tuple[{int32}, {int32}]
+reveal_type(divmod(f4, i4)) # E: Tuple[{float32}, {float32}]
+reveal_type(divmod(AR_b, i8)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]], numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]]
# float
-reveal_type(f8 % b) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(f8 % i) # E: numpy.floating[Any]
-reveal_type(f8 % f) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(i8 % f4) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(f4 % f4) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(f8 % AR) # E: Any
-
-reveal_type(divmod(f8, b)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
-reveal_type(divmod(f8, i)) # E: Tuple[numpy.floating[Any], numpy.floating[Any]]
-reveal_type(divmod(f8, f)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
-reveal_type(divmod(f8, f8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
-reveal_type(divmod(f8, f4)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
-reveal_type(divmod(f4, f4)) # E: Tuple[numpy.floating[numpy.typing._32Bit], numpy.floating[numpy.typing._32Bit]]
-reveal_type(divmod(f8, AR)) # E: Tuple[Any, Any]
-
-reveal_type(b % f8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(i % f8) # E: numpy.floating[Any]
-reveal_type(f % f8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(f8 % f8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(f8 % f8) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(f4 % f4) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(AR % f8) # E: Any
-
-reveal_type(divmod(b, f8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
-reveal_type(divmod(i, f8)) # E: Tuple[numpy.floating[Any], numpy.floating[Any]]
-reveal_type(divmod(f, f8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
-reveal_type(divmod(f8, f8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
-reveal_type(divmod(f4, f8)) # E: Tuple[numpy.floating[numpy.typing._64Bit], numpy.floating[numpy.typing._64Bit]]
-reveal_type(divmod(f4, f4)) # E: Tuple[numpy.floating[numpy.typing._32Bit], numpy.floating[numpy.typing._32Bit]]
-reveal_type(divmod(AR, f8)) # E: Tuple[Any, Any]
+reveal_type(f8 % b) # E: {float64}
+reveal_type(f8 % i) # E: {float64}
+reveal_type(f8 % f) # E: {float64}
+reveal_type(i8 % f4) # E: {float64}
+reveal_type(f4 % f4) # E: {float32}
+reveal_type(f8 % AR_b) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+
+reveal_type(divmod(f8, b)) # E: Tuple[{float64}, {float64}]
+reveal_type(divmod(f8, i)) # E: Tuple[{float64}, {float64}]
+reveal_type(divmod(f8, f)) # E: Tuple[{float64}, {float64}]
+reveal_type(divmod(f8, f8)) # E: Tuple[{float64}, {float64}]
+reveal_type(divmod(f8, f4)) # E: Tuple[{float64}, {float64}]
+reveal_type(divmod(f4, f4)) # E: Tuple[{float32}, {float32}]
+reveal_type(divmod(f8, AR_b)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]], numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]]
+
+reveal_type(b % f8) # E: {float64}
+reveal_type(i % f8) # E: {float64}
+reveal_type(f % f8) # E: {float64}
+reveal_type(f8 % f8) # E: {float64}
+reveal_type(f8 % f8) # E: {float64}
+reveal_type(f4 % f4) # E: {float32}
+reveal_type(AR_b % f8) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+
+reveal_type(divmod(b, f8)) # E: Tuple[{float64}, {float64}]
+reveal_type(divmod(i, f8)) # E: Tuple[{float64}, {float64}]
+reveal_type(divmod(f, f8)) # E: Tuple[{float64}, {float64}]
+reveal_type(divmod(f8, f8)) # E: Tuple[{float64}, {float64}]
+reveal_type(divmod(f4, f8)) # E: Tuple[{float64}, {float64}]
+reveal_type(divmod(f4, f4)) # E: Tuple[{float32}, {float32}]
+reveal_type(divmod(AR_b, f8)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]], numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]]
diff --git a/numpy/typing/tests/data/reveal/modules.py b/numpy/typing/tests/data/reveal/modules.py
index 406463152..7e695433e 100644
--- a/numpy/typing/tests/data/reveal/modules.py
+++ b/numpy/typing/tests/data/reveal/modules.py
@@ -1,4 +1,5 @@
import numpy as np
+from numpy import f2py
reveal_type(np) # E: ModuleType
@@ -16,5 +17,31 @@ reveal_type(np.rec) # E: ModuleType
reveal_type(np.testing) # E: ModuleType
reveal_type(np.version) # E: ModuleType
-# TODO: Remove when annotations have been added to `np.testing.assert_equal`
-reveal_type(np.testing.assert_equal) # E: Any
+reveal_type(np.lib.format) # E: ModuleType
+reveal_type(np.lib.mixins) # E: ModuleType
+reveal_type(np.lib.scimath) # E: ModuleType
+reveal_type(np.lib.stride_tricks) # E: ModuleType
+reveal_type(np.ma.extras) # E: ModuleType
+reveal_type(np.polynomial.chebyshev) # E: ModuleType
+reveal_type(np.polynomial.hermite) # E: ModuleType
+reveal_type(np.polynomial.hermite_e) # E: ModuleType
+reveal_type(np.polynomial.laguerre) # E: ModuleType
+reveal_type(np.polynomial.legendre) # E: ModuleType
+reveal_type(np.polynomial.polynomial) # E: ModuleType
+
+reveal_type(np.__path__) # E: list[builtins.str]
+reveal_type(np.__version__) # E: str
+reveal_type(np.__git_version__) # E: str
+reveal_type(np.test) # E: numpy._pytesttester.PytestTester
+reveal_type(np.test.module_name) # E: str
+
+reveal_type(np.__all__) # E: list[builtins.str]
+reveal_type(np.char.__all__) # E: list[builtins.str]
+reveal_type(np.ctypeslib.__all__) # E: list[builtins.str]
+reveal_type(np.emath.__all__) # E: list[builtins.str]
+reveal_type(np.lib.__all__) # E: list[builtins.str]
+reveal_type(np.ma.__all__) # E: list[builtins.str]
+reveal_type(np.random.__all__) # E: list[builtins.str]
+reveal_type(np.rec.__all__) # E: list[builtins.str]
+reveal_type(np.testing.__all__) # E: list[builtins.str]
+reveal_type(f2py.__all__) # E: list[builtins.str]
diff --git a/numpy/typing/tests/data/reveal/multiarray.py b/numpy/typing/tests/data/reveal/multiarray.py
new file mode 100644
index 000000000..cee51975e
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/multiarray.py
@@ -0,0 +1,125 @@
+from typing import Any, List, TypeVar
+from pathlib import Path
+
+import numpy as np
+import numpy.typing as npt
+
+_SCT = TypeVar("_SCT", bound=np.generic, covariant=True)
+
+class SubClass(np.ndarray[Any, np.dtype[_SCT]]): ...
+
+subclass: SubClass[np.float64]
+
+AR_f8: npt.NDArray[np.float64]
+AR_i8: npt.NDArray[np.int64]
+AR_u1: npt.NDArray[np.uint8]
+AR_m: npt.NDArray[np.timedelta64]
+AR_M: npt.NDArray[np.datetime64]
+
+AR_LIKE_f: List[float]
+AR_LIKE_i: List[int]
+
+m: np.timedelta64
+M: np.datetime64
+
+b_f8 = np.broadcast(AR_f8)
+b_i8_f8_f8 = np.broadcast(AR_i8, AR_f8, AR_f8)
+
+def func(a: int) -> bool: ...
+
+reveal_type(next(b_f8)) # E: tuple[Any]
+reveal_type(b_f8.reset()) # E: None
+reveal_type(b_f8.index) # E: int
+reveal_type(b_f8.iters) # E: tuple[numpy.flatiter[Any]]
+reveal_type(b_f8.nd) # E: int
+reveal_type(b_f8.ndim) # E: int
+reveal_type(b_f8.numiter) # E: int
+reveal_type(b_f8.shape) # E: tuple[builtins.int]
+reveal_type(b_f8.size) # E: int
+
+reveal_type(next(b_i8_f8_f8)) # E: tuple[Any]
+reveal_type(b_i8_f8_f8.reset()) # E: None
+reveal_type(b_i8_f8_f8.index) # E: int
+reveal_type(b_i8_f8_f8.iters) # E: tuple[numpy.flatiter[Any]]
+reveal_type(b_i8_f8_f8.nd) # E: int
+reveal_type(b_i8_f8_f8.ndim) # E: int
+reveal_type(b_i8_f8_f8.numiter) # E: int
+reveal_type(b_i8_f8_f8.shape) # E: tuple[builtins.int]
+reveal_type(b_i8_f8_f8.size) # E: int
+
+reveal_type(np.inner(AR_f8, AR_i8)) # E: Any
+
+reveal_type(np.where([True, True, False])) # E: tuple[numpy.ndarray[Any, numpy.dtype[{intp}]]]
+reveal_type(np.where([True, True, False], 1, 0)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.lexsort([0, 1, 2])) # E: Any
+
+reveal_type(np.can_cast(np.dtype("i8"), int)) # E: bool
+reveal_type(np.can_cast(AR_f8, "f8")) # E: bool
+reveal_type(np.can_cast(AR_f8, np.complex128, casting="unsafe")) # E: bool
+
+reveal_type(np.min_scalar_type([1])) # E: numpy.dtype[Any]
+reveal_type(np.min_scalar_type(AR_f8)) # E: numpy.dtype[Any]
+
+reveal_type(np.result_type(int, [1])) # E: numpy.dtype[Any]
+reveal_type(np.result_type(AR_f8, AR_u1)) # E: numpy.dtype[Any]
+reveal_type(np.result_type(AR_f8, np.complex128)) # E: numpy.dtype[Any]
+
+reveal_type(np.dot(AR_LIKE_f, AR_i8)) # E: Any
+reveal_type(np.dot(AR_u1, 1)) # E: Any
+reveal_type(np.dot(1.5j, 1)) # E: Any
+reveal_type(np.dot(AR_u1, 1, out=AR_f8)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+
+reveal_type(np.vdot(AR_LIKE_f, AR_i8)) # E: numpy.floating[Any]
+reveal_type(np.vdot(AR_u1, 1)) # E: numpy.signedinteger[Any]
+reveal_type(np.vdot(1.5j, 1)) # E: numpy.complexfloating[Any, Any]
+
+reveal_type(np.bincount(AR_i8)) # E: numpy.ndarray[Any, numpy.dtype[{intp}]]
+
+reveal_type(np.copyto(AR_f8, [1., 1.5, 1.6])) # E: None
+
+reveal_type(np.putmask(AR_f8, [True, True, False], 1.5)) # E: None
+
+reveal_type(np.packbits(AR_i8)) # numpy.ndarray[Any, numpy.dtype[{uint8}]]
+reveal_type(np.packbits(AR_u1)) # numpy.ndarray[Any, numpy.dtype[{uint8}]]
+
+reveal_type(np.unpackbits(AR_u1)) # numpy.ndarray[Any, numpy.dtype[{uint8}]]
+
+reveal_type(np.shares_memory(1, 2)) # E: bool
+reveal_type(np.shares_memory(AR_f8, AR_f8, max_work=1)) # E: bool
+
+reveal_type(np.may_share_memory(1, 2)) # E: bool
+reveal_type(np.may_share_memory(AR_f8, AR_f8, max_work=1)) # E: bool
+
+reveal_type(np.geterrobj()) # E: list[Any]
+
+reveal_type(np.seterrobj([8192, 521, None])) # E: None
+
+reveal_type(np.promote_types(np.int32, np.int64)) # E: numpy.dtype[Any]
+reveal_type(np.promote_types("f4", float)) # E: numpy.dtype[Any]
+
+reveal_type(np.frompyfunc(func, 1, 1, identity=None)) # numpy.ufunc
+
+reveal_type(np.datetime_data("m8[D]")) # E: Tuple[builtins.str, builtins.int]
+reveal_type(np.datetime_data(np.datetime64)) # E: Tuple[builtins.str, builtins.int]
+reveal_type(np.datetime_data(np.dtype(np.timedelta64))) # E: Tuple[builtins.str, builtins.int]
+
+reveal_type(np.busday_count("2011-01", "2011-02")) # E: {int_}
+reveal_type(np.busday_count(["2011-01"], "2011-02")) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+
+reveal_type(np.busday_offset(M, m)) # E: numpy.datetime64
+reveal_type(np.busday_offset(M, 5)) # E: numpy.datetime64
+reveal_type(np.busday_offset(AR_M, m)) # E: numpy.ndarray[Any, numpy.dtype[numpy.datetime64]]
+reveal_type(np.busday_offset("2011-01", "2011-02", roll="forward")) # E: numpy.datetime64
+reveal_type(np.busday_offset(["2011-01"], "2011-02", roll="forward")) # E: numpy.ndarray[Any, numpy.dtype[numpy.datetime64]]
+
+reveal_type(np.is_busday("2012")) # E: numpy.bool_
+reveal_type(np.is_busday(["2012"])) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+
+reveal_type(np.datetime_as_string(M)) # E: numpy.str_
+reveal_type(np.datetime_as_string(AR_M)) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
+
+reveal_type(np.compare_chararrays("a", "b", "!=", rstrip=False)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.compare_chararrays(b"a", b"a", "==", True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+
+reveal_type(np.add_docstring(func, "test")) # E: None
diff --git a/numpy/typing/tests/data/reveal/nbit_base_example.py b/numpy/typing/tests/data/reveal/nbit_base_example.py
index 0c4c53f9b..d34f6f69a 100644
--- a/numpy/typing/tests/data/reveal/nbit_base_example.py
+++ b/numpy/typing/tests/data/reveal/nbit_base_example.py
@@ -2,9 +2,10 @@ from typing import TypeVar, Union
import numpy as np
import numpy.typing as npt
-T = TypeVar("T", bound=npt.NBitBase)
+T1 = TypeVar("T1", bound=npt.NBitBase)
+T2 = TypeVar("T2", bound=npt.NBitBase)
-def add(a: np.floating[T], b: np.integer[T]) -> np.floating[T]:
+def add(a: np.floating[T1], b: np.integer[T2]) -> np.floating[Union[T1, T2]]:
return a + b
i8: np.int64
@@ -12,7 +13,7 @@ i4: np.int32
f8: np.float64
f4: np.float32
-reveal_type(add(f8, i8)) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(add(f4, i8)) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(add(f8, i4)) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(add(f4, i4)) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(add(f8, i8)) # E: {float64}
+reveal_type(add(f4, i8)) # E: {float64}
+reveal_type(add(f8, i4)) # E: {float64}
+reveal_type(add(f4, i4)) # E: {float32}
diff --git a/numpy/typing/tests/data/reveal/ndarray_conversion.py b/numpy/typing/tests/data/reveal/ndarray_conversion.py
index 4ee637b75..03f2faf43 100644
--- a/numpy/typing/tests/data/reveal/ndarray_conversion.py
+++ b/numpy/typing/tests/data/reveal/ndarray_conversion.py
@@ -1,12 +1,13 @@
import numpy as np
+import numpy.typing as npt
-nd = np.array([[1, 2], [3, 4]])
+nd: npt.NDArray[np.int_] = np.array([[1, 2], [3, 4]])
# item
-reveal_type(nd.item()) # E: Any
-reveal_type(nd.item(1)) # E: Any
-reveal_type(nd.item(0, 1)) # E: Any
-reveal_type(nd.item((0, 1))) # E: Any
+reveal_type(nd.item()) # E: int
+reveal_type(nd.item(1)) # E: int
+reveal_type(nd.item(0, 1)) # E: int
+reveal_type(nd.item((0, 1))) # E: int
# tolist
reveal_type(nd.tolist()) # E: Any
@@ -19,36 +20,32 @@ reveal_type(nd.tolist()) # E: Any
# dumps is pretty simple
# astype
-reveal_type(nd.astype("float")) # E: numpy.ndarray
-reveal_type(nd.astype(float)) # E: numpy.ndarray
-reveal_type(nd.astype(float, "K")) # E: numpy.ndarray
-reveal_type(nd.astype(float, "K", "unsafe")) # E: numpy.ndarray
-reveal_type(nd.astype(float, "K", "unsafe", True)) # E: numpy.ndarray
-reveal_type(nd.astype(float, "K", "unsafe", True, True)) # E: numpy.ndarray
+reveal_type(nd.astype("float")) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(nd.astype(float)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(nd.astype(np.float64)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(nd.astype(np.float64, "K")) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(nd.astype(np.float64, "K", "unsafe")) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(nd.astype(np.float64, "K", "unsafe", True)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(nd.astype(np.float64, "K", "unsafe", True, True)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
# byteswap
-reveal_type(nd.byteswap()) # E: numpy.ndarray
-reveal_type(nd.byteswap(True)) # E: numpy.ndarray
+reveal_type(nd.byteswap()) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(nd.byteswap(True)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
# copy
-reveal_type(nd.copy()) # E: numpy.ndarray
-reveal_type(nd.copy("C")) # E: numpy.ndarray
+reveal_type(nd.copy()) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(nd.copy("C")) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
-# view
-class SubArray(np.ndarray):
- pass
-
-
-reveal_type(nd.view()) # E: numpy.ndarray
-reveal_type(nd.view(np.int64)) # E: numpy.ndarray
-# replace `Any` with `numpy.matrix` when `matrix` will be added to stubs
-reveal_type(nd.view(np.int64, np.matrix)) # E: Any
-reveal_type(nd.view(np.int64, SubArray)) # E: SubArray
+reveal_type(nd.view()) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(nd.view(np.float64)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(nd.view(float)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(nd.view(np.float64, np.matrix)) # E: numpy.matrix[Any, Any]
# getfield
-reveal_type(nd.getfield("float")) # E: numpy.ndarray
-reveal_type(nd.getfield(float)) # E: numpy.ndarray
-reveal_type(nd.getfield(float, 8)) # E: numpy.ndarray
+reveal_type(nd.getfield("float")) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(nd.getfield(float)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(nd.getfield(np.float64)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(nd.getfield(np.float64, 8)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
# setflags does not return a value
# fill does not return a value
diff --git a/numpy/typing/tests/data/reveal/ndarray_misc.py b/numpy/typing/tests/data/reveal/ndarray_misc.py
index 826c8aaa6..050b82cdc 100644
--- a/numpy/typing/tests/data/reveal/ndarray_misc.py
+++ b/numpy/typing/tests/data/reveal/ndarray_misc.py
@@ -6,145 +6,190 @@ function-based counterpart in `../from_numeric.py`.
"""
+import operator
+import ctypes as ct
+from typing import Any
+
import numpy as np
+from numpy.typing import NDArray
-class SubClass(np.ndarray): ...
+class SubClass(NDArray[np.object_]): ...
f8: np.float64
-A: np.ndarray
B: SubClass
+AR_f8: NDArray[np.float64]
+AR_i8: NDArray[np.int64]
+AR_U: NDArray[np.str_]
+
+ctypes_obj = AR_f8.ctypes
+
+reveal_type(ctypes_obj.data) # E: int
+reveal_type(ctypes_obj.shape) # E: ctypes.Array[{c_intp}]
+reveal_type(ctypes_obj.strides) # E: ctypes.Array[{c_intp}]
+reveal_type(ctypes_obj._as_parameter_) # E: ctypes.c_void_p
+
+reveal_type(ctypes_obj.data_as(ct.c_void_p)) # E: ctypes.c_void_p
+reveal_type(ctypes_obj.shape_as(ct.c_longlong)) # E: ctypes.Array[ctypes.c_longlong]
+reveal_type(ctypes_obj.strides_as(ct.c_ubyte)) # E: ctypes.Array[ctypes.c_ubyte]
reveal_type(f8.all()) # E: numpy.bool_
-reveal_type(A.all()) # E: numpy.bool_
-reveal_type(A.all(axis=0)) # E: Union[numpy.bool_, numpy.ndarray]
-reveal_type(A.all(keepdims=True)) # E: Union[numpy.bool_, numpy.ndarray]
-reveal_type(A.all(out=B)) # E: SubClass
+reveal_type(AR_f8.all()) # E: numpy.bool_
+reveal_type(AR_f8.all(axis=0)) # E: Any
+reveal_type(AR_f8.all(keepdims=True)) # E: Any
+reveal_type(AR_f8.all(out=B)) # E: SubClass
reveal_type(f8.any()) # E: numpy.bool_
-reveal_type(A.any()) # E: numpy.bool_
-reveal_type(A.any(axis=0)) # E: Union[numpy.bool_, numpy.ndarray]
-reveal_type(A.any(keepdims=True)) # E: Union[numpy.bool_, numpy.ndarray]
-reveal_type(A.any(out=B)) # E: SubClass
-
-reveal_type(f8.argmax()) # E: numpy.signedinteger[Any]
-reveal_type(A.argmax()) # E: numpy.signedinteger[Any]
-reveal_type(A.argmax(axis=0)) # E: Union[numpy.signedinteger[Any], numpy.ndarray]
-reveal_type(A.argmax(out=B)) # E: SubClass
-
-reveal_type(f8.argmin()) # E: numpy.signedinteger[Any]
-reveal_type(A.argmin()) # E: numpy.signedinteger[Any]
-reveal_type(A.argmin(axis=0)) # E: Union[numpy.signedinteger[Any], numpy.ndarray]
-reveal_type(A.argmin(out=B)) # E: SubClass
-
-reveal_type(f8.argsort()) # E: numpy.ndarray
-reveal_type(A.argsort()) # E: numpy.ndarray
-
-reveal_type(f8.astype(np.int64).choose([()])) # E: numpy.ndarray
-reveal_type(A.choose([0])) # E: numpy.ndarray
-reveal_type(A.choose([0], out=B)) # E: SubClass
-
-reveal_type(f8.clip(1)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(A.clip(1)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(A.clip(None, 1)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(A.clip(1, out=B)) # E: SubClass
-reveal_type(A.clip(None, 1, out=B)) # E: SubClass
-
-reveal_type(f8.compress([0])) # E: numpy.ndarray
-reveal_type(A.compress([0])) # E: numpy.ndarray
-reveal_type(A.compress([0], out=B)) # E: SubClass
-
-reveal_type(f8.conj()) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(A.conj()) # E: numpy.ndarray
+reveal_type(AR_f8.any()) # E: numpy.bool_
+reveal_type(AR_f8.any(axis=0)) # E: Any
+reveal_type(AR_f8.any(keepdims=True)) # E: Any
+reveal_type(AR_f8.any(out=B)) # E: SubClass
+
+reveal_type(f8.argmax()) # E: {intp}
+reveal_type(AR_f8.argmax()) # E: {intp}
+reveal_type(AR_f8.argmax(axis=0)) # E: Any
+reveal_type(AR_f8.argmax(out=B)) # E: SubClass
+
+reveal_type(f8.argmin()) # E: {intp}
+reveal_type(AR_f8.argmin()) # E: {intp}
+reveal_type(AR_f8.argmin(axis=0)) # E: Any
+reveal_type(AR_f8.argmin(out=B)) # E: SubClass
+
+reveal_type(f8.argsort()) # E: numpy.ndarray[Any, Any]
+reveal_type(AR_f8.argsort()) # E: numpy.ndarray[Any, Any]
+
+reveal_type(f8.astype(np.int64).choose([()])) # E: numpy.ndarray[Any, Any]
+reveal_type(AR_f8.choose([0])) # E: numpy.ndarray[Any, Any]
+reveal_type(AR_f8.choose([0], out=B)) # E: SubClass
+
+reveal_type(f8.clip(1)) # E: Any
+reveal_type(AR_f8.clip(1)) # E: Any
+reveal_type(AR_f8.clip(None, 1)) # E: Any
+reveal_type(AR_f8.clip(1, out=B)) # E: SubClass
+reveal_type(AR_f8.clip(None, 1, out=B)) # E: SubClass
+
+reveal_type(f8.compress([0])) # E: numpy.ndarray[Any, Any]
+reveal_type(AR_f8.compress([0])) # E: numpy.ndarray[Any, Any]
+reveal_type(AR_f8.compress([0], out=B)) # E: SubClass
+
+reveal_type(f8.conj()) # E: {float64}
+reveal_type(AR_f8.conj()) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
reveal_type(B.conj()) # E: SubClass
-reveal_type(f8.conjugate()) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(A.conjugate()) # E: numpy.ndarray
+reveal_type(f8.conjugate()) # E: {float64}
+reveal_type(AR_f8.conjugate()) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
reveal_type(B.conjugate()) # E: SubClass
-reveal_type(f8.cumprod()) # E: numpy.ndarray
-reveal_type(A.cumprod()) # E: numpy.ndarray
-reveal_type(A.cumprod(out=B)) # E: SubClass
-
-reveal_type(f8.cumsum()) # E: numpy.ndarray
-reveal_type(A.cumsum()) # E: numpy.ndarray
-reveal_type(A.cumsum(out=B)) # E: SubClass
-
-reveal_type(f8.max()) # E: numpy.number[Any]
-reveal_type(A.max()) # E: numpy.number[Any]
-reveal_type(A.max(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(A.max(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(A.max(out=B)) # E: SubClass
-
-reveal_type(f8.mean()) # E: numpy.number[Any]
-reveal_type(A.mean()) # E: numpy.number[Any]
-reveal_type(A.mean(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(A.mean(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(A.mean(out=B)) # E: SubClass
-
-reveal_type(f8.min()) # E: numpy.number[Any]
-reveal_type(A.min()) # E: numpy.number[Any]
-reveal_type(A.min(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(A.min(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(A.min(out=B)) # E: SubClass
-
-reveal_type(f8.newbyteorder()) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(A.newbyteorder()) # E: numpy.ndarray
+reveal_type(f8.cumprod()) # E: numpy.ndarray[Any, Any]
+reveal_type(AR_f8.cumprod()) # E: numpy.ndarray[Any, Any]
+reveal_type(AR_f8.cumprod(out=B)) # E: SubClass
+
+reveal_type(f8.cumsum()) # E: numpy.ndarray[Any, Any]
+reveal_type(AR_f8.cumsum()) # E: numpy.ndarray[Any, Any]
+reveal_type(AR_f8.cumsum(out=B)) # E: SubClass
+
+reveal_type(f8.max()) # E: Any
+reveal_type(AR_f8.max()) # E: Any
+reveal_type(AR_f8.max(axis=0)) # E: Any
+reveal_type(AR_f8.max(keepdims=True)) # E: Any
+reveal_type(AR_f8.max(out=B)) # E: SubClass
+
+reveal_type(f8.mean()) # E: Any
+reveal_type(AR_f8.mean()) # E: Any
+reveal_type(AR_f8.mean(axis=0)) # E: Any
+reveal_type(AR_f8.mean(keepdims=True)) # E: Any
+reveal_type(AR_f8.mean(out=B)) # E: SubClass
+
+reveal_type(f8.min()) # E: Any
+reveal_type(AR_f8.min()) # E: Any
+reveal_type(AR_f8.min(axis=0)) # E: Any
+reveal_type(AR_f8.min(keepdims=True)) # E: Any
+reveal_type(AR_f8.min(out=B)) # E: SubClass
+
+reveal_type(f8.newbyteorder()) # E: {float64}
+reveal_type(AR_f8.newbyteorder()) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
reveal_type(B.newbyteorder('|')) # E: SubClass
-reveal_type(f8.prod()) # E: numpy.number[Any]
-reveal_type(A.prod()) # E: numpy.number[Any]
-reveal_type(A.prod(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(A.prod(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(A.prod(out=B)) # E: SubClass
+reveal_type(f8.prod()) # E: Any
+reveal_type(AR_f8.prod()) # E: Any
+reveal_type(AR_f8.prod(axis=0)) # E: Any
+reveal_type(AR_f8.prod(keepdims=True)) # E: Any
+reveal_type(AR_f8.prod(out=B)) # E: SubClass
+
+reveal_type(f8.ptp()) # E: Any
+reveal_type(AR_f8.ptp()) # E: Any
+reveal_type(AR_f8.ptp(axis=0)) # E: Any
+reveal_type(AR_f8.ptp(keepdims=True)) # E: Any
+reveal_type(AR_f8.ptp(out=B)) # E: SubClass
+
+reveal_type(f8.round()) # E: {float64}
+reveal_type(AR_f8.round()) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(AR_f8.round(out=B)) # E: SubClass
+
+reveal_type(f8.repeat(1)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(AR_f8.repeat(1)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(B.repeat(1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.object_]]
+
+reveal_type(f8.std()) # E: Any
+reveal_type(AR_f8.std()) # E: Any
+reveal_type(AR_f8.std(axis=0)) # E: Any
+reveal_type(AR_f8.std(keepdims=True)) # E: Any
+reveal_type(AR_f8.std(out=B)) # E: SubClass
+
+reveal_type(f8.sum()) # E: Any
+reveal_type(AR_f8.sum()) # E: Any
+reveal_type(AR_f8.sum(axis=0)) # E: Any
+reveal_type(AR_f8.sum(keepdims=True)) # E: Any
+reveal_type(AR_f8.sum(out=B)) # E: SubClass
+
+reveal_type(f8.take(0)) # E: {float64}
+reveal_type(AR_f8.take(0)) # E: {float64}
+reveal_type(AR_f8.take([0])) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(AR_f8.take(0, out=B)) # E: SubClass
+reveal_type(AR_f8.take([0], out=B)) # E: SubClass
+
+reveal_type(f8.var()) # E: Any
+reveal_type(AR_f8.var()) # E: Any
+reveal_type(AR_f8.var(axis=0)) # E: Any
+reveal_type(AR_f8.var(keepdims=True)) # E: Any
+reveal_type(AR_f8.var(out=B)) # E: SubClass
+
+reveal_type(AR_f8.argpartition([0])) # E: numpy.ndarray[Any, numpy.dtype[{intp}]]
+
+reveal_type(AR_f8.diagonal()) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
-reveal_type(f8.ptp()) # E: numpy.number[Any]
-reveal_type(A.ptp()) # E: numpy.number[Any]
-reveal_type(A.ptp(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(A.ptp(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(A.ptp(out=B)) # E: SubClass
+reveal_type(AR_f8.dot(1)) # E: numpy.ndarray[Any, Any]
+reveal_type(AR_f8.dot([1])) # E: Any
+reveal_type(AR_f8.dot(1, out=B)) # E: SubClass
-reveal_type(f8.round()) # E: numpy.floating[numpy.typing._64Bit]
-reveal_type(A.round()) # E: numpy.ndarray
-reveal_type(A.round(out=B)) # E: SubClass
+reveal_type(AR_f8.nonzero()) # E: tuple[numpy.ndarray[Any, numpy.dtype[{intp}]]]
-reveal_type(f8.repeat(1)) # E: numpy.ndarray
-reveal_type(A.repeat(1)) # E: numpy.ndarray
-reveal_type(B.repeat(1)) # E: numpy.ndarray
+reveal_type(AR_f8.searchsorted(1)) # E: {intp}
+reveal_type(AR_f8.searchsorted([1])) # E: numpy.ndarray[Any, numpy.dtype[{intp}]]
-reveal_type(f8.std()) # E: numpy.number[Any]
-reveal_type(A.std()) # E: numpy.number[Any]
-reveal_type(A.std(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(A.std(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(A.std(out=B)) # E: SubClass
+reveal_type(AR_f8.trace()) # E: Any
+reveal_type(AR_f8.trace(out=B)) # E: SubClass
-reveal_type(f8.sum()) # E: numpy.number[Any]
-reveal_type(A.sum()) # E: numpy.number[Any]
-reveal_type(A.sum(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(A.sum(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(A.sum(out=B)) # E: SubClass
+reveal_type(AR_f8.item()) # E: float
+reveal_type(AR_U.item()) # E: str
-reveal_type(f8.take(0)) # E: numpy.generic
-reveal_type(A.take(0)) # E: numpy.generic
-reveal_type(A.take([0])) # E: numpy.ndarray
-reveal_type(A.take(0, out=B)) # E: SubClass
-reveal_type(A.take([0], out=B)) # E: SubClass
+reveal_type(AR_f8.ravel()) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(AR_U.ravel()) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
-reveal_type(f8.var()) # E: numpy.number[Any]
-reveal_type(A.var()) # E: numpy.number[Any]
-reveal_type(A.var(axis=0)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(A.var(keepdims=True)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(A.var(out=B)) # E: SubClass
+reveal_type(AR_f8.flatten()) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(AR_U.flatten()) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
-reveal_type(A.argpartition([0])) # E: numpy.ndarray
+reveal_type(AR_f8.reshape(1)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(AR_U.reshape(1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
-reveal_type(A.diagonal()) # E: numpy.ndarray
+reveal_type(int(AR_f8)) # E: int
+reveal_type(int(AR_U)) # E: int
-reveal_type(A.dot(1)) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(A.dot(1, out=B)) # E: SubClass
+reveal_type(float(AR_f8)) # E: float
+reveal_type(float(AR_U)) # E: float
-reveal_type(A.nonzero()) # E: tuple[numpy.ndarray]
+reveal_type(complex(AR_f8)) # E: complex
-reveal_type(A.searchsorted([1])) # E: numpy.ndarray
+reveal_type(operator.index(AR_i8)) # E: int
-reveal_type(A.trace()) # E: Union[numpy.number[Any], numpy.ndarray]
-reveal_type(A.trace(out=B)) # E: SubClass
+reveal_type(AR_f8.__array_prepare__(B)) # E: numpy.ndarray[Any, numpy.dtype[numpy.object_]]
+reveal_type(AR_f8.__array_wrap__(B)) # E: numpy.ndarray[Any, numpy.dtype[numpy.object_]]
diff --git a/numpy/typing/tests/data/reveal/nditer.py b/numpy/typing/tests/data/reveal/nditer.py
new file mode 100644
index 000000000..de2a4b5ed
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/nditer.py
@@ -0,0 +1,19 @@
+import copy
+import numpy as np
+
+nditer_obj: np.nditer
+
+with nditer_obj as context:
+ reveal_type(context) # E: numpy.nditer
+
+reveal_type(len(nditer_obj)) # E: builtins.int
+reveal_type(copy.copy(nditer_obj)) # E: numpy.nditer
+reveal_type(next(nditer_obj)) # E: Any
+reveal_type(iter(nditer_obj)) # E: typing.Iterator[Any]
+reveal_type(nditer_obj[1]) # E: Any
+reveal_type(nditer_obj[1:5]) # E: Any
+
+nditer_obj[1] = 1
+nditer_obj[1:5] = 1
+del nditer_obj[1]
+del nditer_obj[1:5]
diff --git a/numpy/typing/tests/data/reveal/numeric.py b/numpy/typing/tests/data/reveal/numeric.py
index 5cbfa4ac7..ec6e47ca0 100644
--- a/numpy/typing/tests/data/reveal/numeric.py
+++ b/numpy/typing/tests/data/reveal/numeric.py
@@ -20,53 +20,53 @@ C: SubClass
reveal_type(np.count_nonzero(i8)) # E: int
reveal_type(np.count_nonzero(A)) # E: int
reveal_type(np.count_nonzero(B)) # E: int
-reveal_type(np.count_nonzero(A, keepdims=True)) # E: Union[numpy.signedinteger[Any], numpy.ndarray]
-reveal_type(np.count_nonzero(A, axis=0)) # E: Union[numpy.signedinteger[Any], numpy.ndarray]
+reveal_type(np.count_nonzero(A, keepdims=True)) # E: Any
+reveal_type(np.count_nonzero(A, axis=0)) # E: Any
reveal_type(np.isfortran(i8)) # E: bool
reveal_type(np.isfortran(A)) # E: bool
-reveal_type(np.argwhere(i8)) # E: numpy.ndarray
-reveal_type(np.argwhere(A)) # E: numpy.ndarray
+reveal_type(np.argwhere(i8)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.argwhere(A)) # E: numpy.ndarray[Any, Any]
-reveal_type(np.flatnonzero(i8)) # E: numpy.ndarray
-reveal_type(np.flatnonzero(A)) # E: numpy.ndarray
+reveal_type(np.flatnonzero(i8)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.flatnonzero(A)) # E: numpy.ndarray[Any, Any]
-reveal_type(np.correlate(B, A, mode="valid")) # E: numpy.ndarray
-reveal_type(np.correlate(A, A, mode="same")) # E: numpy.ndarray
+reveal_type(np.correlate(B, A, mode="valid")) # E: numpy.ndarray[Any, Any]
+reveal_type(np.correlate(A, A, mode="same")) # E: numpy.ndarray[Any, Any]
-reveal_type(np.convolve(B, A, mode="valid")) # E: numpy.ndarray
-reveal_type(np.convolve(A, A, mode="same")) # E: numpy.ndarray
+reveal_type(np.convolve(B, A, mode="valid")) # E: numpy.ndarray[Any, Any]
+reveal_type(np.convolve(A, A, mode="same")) # E: numpy.ndarray[Any, Any]
-reveal_type(np.outer(i8, A)) # E: numpy.ndarray
-reveal_type(np.outer(B, A)) # E: numpy.ndarray
-reveal_type(np.outer(A, A)) # E: numpy.ndarray
+reveal_type(np.outer(i8, A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.outer(B, A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.outer(A, A)) # E: numpy.ndarray[Any, Any]
reveal_type(np.outer(A, A, out=C)) # E: SubClass
-reveal_type(np.tensordot(B, A)) # E: numpy.ndarray
-reveal_type(np.tensordot(A, A)) # E: numpy.ndarray
-reveal_type(np.tensordot(A, A, axes=0)) # E: numpy.ndarray
-reveal_type(np.tensordot(A, A, axes=(0, 1))) # E: numpy.ndarray
+reveal_type(np.tensordot(B, A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.tensordot(A, A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.tensordot(A, A, axes=0)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.tensordot(A, A, axes=(0, 1))) # E: numpy.ndarray[Any, Any]
reveal_type(np.isscalar(i8)) # E: bool
reveal_type(np.isscalar(A)) # E: bool
reveal_type(np.isscalar(B)) # E: bool
-reveal_type(np.roll(A, 1)) # E: numpy.ndarray
-reveal_type(np.roll(A, (1, 2))) # E: numpy.ndarray
-reveal_type(np.roll(B, 1)) # E: numpy.ndarray
+reveal_type(np.roll(A, 1)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.roll(A, (1, 2))) # E: numpy.ndarray[Any, Any]
+reveal_type(np.roll(B, 1)) # E: numpy.ndarray[Any, Any]
-reveal_type(np.rollaxis(A, 0, 1)) # E: numpy.ndarray
+reveal_type(np.rollaxis(A, 0, 1)) # E: numpy.ndarray[Any, Any]
-reveal_type(np.moveaxis(A, 0, 1)) # E: numpy.ndarray
-reveal_type(np.moveaxis(A, (0, 1), (1, 2))) # E: numpy.ndarray
+reveal_type(np.moveaxis(A, 0, 1)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.moveaxis(A, (0, 1), (1, 2))) # E: numpy.ndarray[Any, Any]
-reveal_type(np.cross(B, A)) # E: numpy.ndarray
-reveal_type(np.cross(A, A)) # E: numpy.ndarray
+reveal_type(np.cross(B, A)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.cross(A, A)) # E: numpy.ndarray[Any, Any]
-reveal_type(np.indices([0, 1, 2])) # E: numpy.ndarray
-reveal_type(np.indices([0, 1, 2], sparse=False)) # E: numpy.ndarray
-reveal_type(np.indices([0, 1, 2], sparse=True)) # E: tuple[numpy.ndarray]
+reveal_type(np.indices([0, 1, 2])) # E: numpy.ndarray[Any, Any]
+reveal_type(np.indices([0, 1, 2], sparse=False)) # E: numpy.ndarray[Any, Any]
+reveal_type(np.indices([0, 1, 2], sparse=True)) # E: tuple[numpy.ndarray[Any, Any]]
reveal_type(np.binary_repr(1)) # E: str
@@ -76,9 +76,9 @@ reveal_type(np.allclose(i8, A)) # E: bool
reveal_type(np.allclose(B, A)) # E: bool
reveal_type(np.allclose(A, A)) # E: bool
-reveal_type(np.isclose(i8, A)) # E: Union[numpy.bool_, numpy.ndarray]
-reveal_type(np.isclose(B, A)) # E: Union[numpy.bool_, numpy.ndarray]
-reveal_type(np.isclose(A, A)) # E: Union[numpy.bool_, numpy.ndarray]
+reveal_type(np.isclose(i8, A)) # E: Any
+reveal_type(np.isclose(B, A)) # E: Any
+reveal_type(np.isclose(A, A)) # E: Any
reveal_type(np.array_equal(i8, A)) # E: bool
reveal_type(np.array_equal(B, A)) # E: bool
diff --git a/numpy/typing/tests/data/reveal/numerictypes.py b/numpy/typing/tests/data/reveal/numerictypes.py
index e026158cd..c50a3a3d6 100644
--- a/numpy/typing/tests/data/reveal/numerictypes.py
+++ b/numpy/typing/tests/data/reveal/numerictypes.py
@@ -1,18 +1,42 @@
import numpy as np
-reveal_type(np.issctype(np.generic)) # E: bool
-reveal_type(np.issctype("foo")) # E: bool
+reveal_type(np.maximum_sctype(np.float64)) # E: Type[{float64}]
+reveal_type(np.maximum_sctype("f8")) # E: Type[Any]
-reveal_type(np.obj2sctype("S8")) # E: Union[numpy.generic, None]
-reveal_type(np.obj2sctype("S8", default=None)) # E: Union[numpy.generic, None]
-reveal_type(
- np.obj2sctype("foo", default=int) # E: Union[numpy.generic, Type[builtins.int*]]
-)
+reveal_type(np.issctype(np.float64)) # E: bool
+reveal_type(np.issctype("foo")) # E: Literal[False]
+
+reveal_type(np.obj2sctype(np.float64)) # E: Union[None, Type[{float64}]]
+reveal_type(np.obj2sctype(np.float64, default=False)) # E: Union[builtins.bool, Type[{float64}]]
+reveal_type(np.obj2sctype("S8")) # E: Union[None, Type[Any]]
+reveal_type(np.obj2sctype("S8", default=None)) # E: Union[None, Type[Any]]
+reveal_type(np.obj2sctype("foo", default=False)) # E: Union[builtins.bool, Type[Any]]
+reveal_type(np.obj2sctype(1)) # E: None
+reveal_type(np.obj2sctype(1, default=False)) # E: bool
reveal_type(np.issubclass_(np.float64, float)) # E: bool
reveal_type(np.issubclass_(np.float64, (int, float))) # E: bool
+reveal_type(np.issubclass_(1, 1)) # E: Literal[False]
reveal_type(np.sctype2char("S8")) # E: str
reveal_type(np.sctype2char(list)) # E: str
-reveal_type(np.find_common_type([np.int64], [np.int64])) # E: numpy.dtype
+reveal_type(np.find_common_type([np.int64], [np.int64])) # E: numpy.dtype[Any]
+
+reveal_type(np.cast[int]) # E: _CastFunc
+reveal_type(np.cast["i8"]) # E: _CastFunc
+reveal_type(np.cast[np.int64]) # E: _CastFunc
+
+reveal_type(np.nbytes[int]) # E: int
+reveal_type(np.nbytes["i8"]) # E: int
+reveal_type(np.nbytes[np.int64]) # E: int
+
+reveal_type(np.ScalarType) # E: Tuple
+reveal_type(np.ScalarType[0]) # E: Type[builtins.int]
+reveal_type(np.ScalarType[4]) # E: Type[builtins.bool]
+reveal_type(np.ScalarType[9]) # E: Type[{csingle}]
+reveal_type(np.ScalarType[11]) # E: Type[{clongdouble}]
+
+reveal_type(np.typecodes["Character"]) # E: Literal['c']
+reveal_type(np.typecodes["Complex"]) # E: Literal['FDG']
+reveal_type(np.typecodes["All"]) # E: Literal['?bhilqpBHILQPefdgFDGSUVOMm']
diff --git a/numpy/typing/tests/data/reveal/random.py b/numpy/typing/tests/data/reveal/random.py
new file mode 100644
index 000000000..6fc35aced
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/random.py
@@ -0,0 +1,1539 @@
+from __future__ import annotations
+
+from typing import Any, List
+
+import numpy as np
+
+def_rng = np.random.default_rng()
+seed_seq = np.random.SeedSequence()
+mt19937 = np.random.MT19937()
+pcg64 = np.random.PCG64()
+sfc64 = np.random.SFC64()
+philox = np.random.Philox()
+seedless_seq = np.random.bit_generator.SeedlessSeedSequence()
+
+reveal_type(def_rng) # E: numpy.random._generator.Generator
+reveal_type(mt19937) # E: numpy.random._mt19937.MT19937
+reveal_type(pcg64) # E: numpy.random._pcg64.PCG64
+reveal_type(sfc64) # E: numpy.random._sfc64.SFC64
+reveal_type(philox) # E: numpy.random._philox.Philox
+reveal_type(seed_seq) # E: numpy.random.bit_generator.SeedSequence
+reveal_type(seedless_seq) # E: numpy.random.bit_generator.SeedlessSeedSequence
+
+mt19937_jumped = mt19937.jumped()
+mt19937_jumped3 = mt19937.jumped(3)
+mt19937_raw = mt19937.random_raw()
+mt19937_raw_arr = mt19937.random_raw(5)
+
+reveal_type(mt19937_jumped) # E: numpy.random._mt19937.MT19937
+reveal_type(mt19937_jumped3) # E: numpy.random._mt19937.MT19937
+reveal_type(mt19937_raw) # E: int
+reveal_type(mt19937_raw_arr) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(mt19937.lock) # E: threading.Lock
+
+pcg64_jumped = pcg64.jumped()
+pcg64_jumped3 = pcg64.jumped(3)
+pcg64_adv = pcg64.advance(3)
+pcg64_raw = pcg64.random_raw()
+pcg64_raw_arr = pcg64.random_raw(5)
+
+reveal_type(pcg64_jumped) # E: numpy.random._pcg64.PCG64
+reveal_type(pcg64_jumped3) # E: numpy.random._pcg64.PCG64
+reveal_type(pcg64_adv) # E: numpy.random._pcg64.PCG64
+reveal_type(pcg64_raw) # E: int
+reveal_type(pcg64_raw_arr) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(pcg64.lock) # E: threading.Lock
+
+philox_jumped = philox.jumped()
+philox_jumped3 = philox.jumped(3)
+philox_adv = philox.advance(3)
+philox_raw = philox.random_raw()
+philox_raw_arr = philox.random_raw(5)
+
+reveal_type(philox_jumped) # E: numpy.random._philox.Philox
+reveal_type(philox_jumped3) # E: numpy.random._philox.Philox
+reveal_type(philox_adv) # E: numpy.random._philox.Philox
+reveal_type(philox_raw) # E: int
+reveal_type(philox_raw_arr) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(philox.lock) # E: threading.Lock
+
+sfc64_raw = sfc64.random_raw()
+sfc64_raw_arr = sfc64.random_raw(5)
+
+reveal_type(sfc64_raw) # E: int
+reveal_type(sfc64_raw_arr) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(sfc64.lock) # E: threading.Lock
+
+reveal_type(seed_seq.pool) # numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(seed_seq.entropy) # E:Union[None, int, Sequence[int]]
+reveal_type(seed_seq.spawn(1)) # E: list[numpy.random.bit_generator.SeedSequence]
+reveal_type(seed_seq.generate_state(8, "uint32")) # E: numpy.ndarray[Any, numpy.dtype[Union[numpy.unsignedinteger[numpy.typing._32Bit], numpy.unsignedinteger[numpy.typing._64Bit]]]]
+reveal_type(seed_seq.generate_state(8, "uint64")) # E: numpy.ndarray[Any, numpy.dtype[Union[numpy.unsignedinteger[numpy.typing._32Bit], numpy.unsignedinteger[numpy.typing._64Bit]]]]
+
+
+def_gen: np.random.Generator = np.random.default_rng()
+
+D_arr_0p1: np.ndarray[Any, np.dtype[np.float64]] = np.array([0.1])
+D_arr_0p5: np.ndarray[Any, np.dtype[np.float64]] = np.array([0.5])
+D_arr_0p9: np.ndarray[Any, np.dtype[np.float64]] = np.array([0.9])
+D_arr_1p5: np.ndarray[Any, np.dtype[np.float64]] = np.array([1.5])
+I_arr_10: np.ndarray[Any, np.dtype[np.int_]] = np.array([10], dtype=np.int_)
+I_arr_20: np.ndarray[Any, np.dtype[np.int_]] = np.array([20], dtype=np.int_)
+D_arr_like_0p1: List[float] = [0.1]
+D_arr_like_0p5: List[float] = [0.5]
+D_arr_like_0p9: List[float] = [0.9]
+D_arr_like_1p5: List[float] = [1.5]
+I_arr_like_10: List[int] = [10]
+I_arr_like_20: List[int] = [20]
+D_2D_like: List[List[float]] = [[1, 2], [2, 3], [3, 4], [4, 5.1]]
+D_2D: np.ndarray[Any, np.dtype[np.float64]] = np.array(D_2D_like)
+S_out: np.ndarray[Any, np.dtype[np.float32]] = np.empty(1, dtype=np.float32)
+D_out: np.ndarray[Any, np.dtype[np.float64]] = np.empty(1)
+
+reveal_type(def_gen.standard_normal()) # E: float
+reveal_type(def_gen.standard_normal(dtype=np.float32)) # E: float
+reveal_type(def_gen.standard_normal(dtype="float32")) # E: float
+reveal_type(def_gen.standard_normal(dtype="double")) # E: float
+reveal_type(def_gen.standard_normal(dtype=np.float64)) # E: float
+reveal_type(def_gen.standard_normal(size=None)) # E: float
+reveal_type(def_gen.standard_normal(size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.standard_normal(size=1, dtype=np.float32)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._32Bit]]]
+reveal_type(def_gen.standard_normal(size=1, dtype="f4")) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._32Bit]]]
+reveal_type(def_gen.standard_normal(size=1, dtype="float32", out=S_out)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._32Bit]]]
+reveal_type(def_gen.standard_normal(dtype=np.float32, out=S_out)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._32Bit]]]
+reveal_type(def_gen.standard_normal(size=1, dtype=np.float64)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.standard_normal(size=1, dtype="float64")) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.standard_normal(size=1, dtype="f8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.standard_normal(out=D_out)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.standard_normal(size=1, dtype="float64")) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.standard_normal(size=1, dtype="float64", out=D_out)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+
+reveal_type(def_gen.random()) # E: float
+reveal_type(def_gen.random(dtype=np.float32)) # E: float
+reveal_type(def_gen.random(dtype="float32")) # E: float
+reveal_type(def_gen.random(dtype="double")) # E: float
+reveal_type(def_gen.random(dtype=np.float64)) # E: float
+reveal_type(def_gen.random(size=None)) # E: float
+reveal_type(def_gen.random(size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.random(size=1, dtype=np.float32)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._32Bit]]]
+reveal_type(def_gen.random(size=1, dtype="f4")) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._32Bit]]]
+reveal_type(def_gen.random(size=1, dtype="float32", out=S_out)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._32Bit]]]
+reveal_type(def_gen.random(dtype=np.float32, out=S_out)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._32Bit]]]
+reveal_type(def_gen.random(size=1, dtype=np.float64)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.random(size=1, dtype="float64")) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.random(size=1, dtype="f8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.random(out=D_out)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.random(size=1, dtype="float64")) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.random(size=1, dtype="float64", out=D_out)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+
+reveal_type(def_gen.standard_cauchy()) # E: float
+reveal_type(def_gen.standard_cauchy(size=None)) # E: float
+reveal_type(def_gen.standard_cauchy(size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.standard_exponential()) # E: float
+reveal_type(def_gen.standard_exponential(method="inv")) # E: float
+reveal_type(def_gen.standard_exponential(dtype=np.float32)) # E: float
+reveal_type(def_gen.standard_exponential(dtype="float32")) # E: float
+reveal_type(def_gen.standard_exponential(dtype="double")) # E: float
+reveal_type(def_gen.standard_exponential(dtype=np.float64)) # E: float
+reveal_type(def_gen.standard_exponential(size=None)) # E: float
+reveal_type(def_gen.standard_exponential(size=None, method="inv")) # E: float
+reveal_type(def_gen.standard_exponential(size=1, method="inv")) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.standard_exponential(size=1, dtype=np.float32)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._32Bit]]]
+reveal_type(def_gen.standard_exponential(size=1, dtype="f4", method="inv")) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._32Bit]]]
+reveal_type(def_gen.standard_exponential(size=1, dtype="float32", out=S_out)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._32Bit]]]
+reveal_type(def_gen.standard_exponential(dtype=np.float32, out=S_out)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._32Bit]]]
+reveal_type(def_gen.standard_exponential(size=1, dtype=np.float64, method="inv")) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.standard_exponential(size=1, dtype="float64")) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.standard_exponential(size=1, dtype="f8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.standard_exponential(out=D_out)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.standard_exponential(size=1, dtype="float64")) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.standard_exponential(size=1, dtype="float64", out=D_out)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+
+reveal_type(def_gen.zipf(1.5)) # E: int
+reveal_type(def_gen.zipf(1.5, size=None)) # E: int
+reveal_type(def_gen.zipf(1.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.zipf(D_arr_1p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.zipf(D_arr_1p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.zipf(D_arr_like_1p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.zipf(D_arr_like_1p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+
+reveal_type(def_gen.weibull(0.5)) # E: float
+reveal_type(def_gen.weibull(0.5, size=None)) # E: float
+reveal_type(def_gen.weibull(0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.weibull(D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.weibull(D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.weibull(D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.weibull(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.standard_t(0.5)) # E: float
+reveal_type(def_gen.standard_t(0.5, size=None)) # E: float
+reveal_type(def_gen.standard_t(0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.standard_t(D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.standard_t(D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.standard_t(D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.standard_t(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.poisson(0.5)) # E: int
+reveal_type(def_gen.poisson(0.5, size=None)) # E: int
+reveal_type(def_gen.poisson(0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.poisson(D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.poisson(D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.poisson(D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.poisson(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+
+reveal_type(def_gen.power(0.5)) # E: float
+reveal_type(def_gen.power(0.5, size=None)) # E: float
+reveal_type(def_gen.power(0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.power(D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.power(D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.power(D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.power(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.pareto(0.5)) # E: float
+reveal_type(def_gen.pareto(0.5, size=None)) # E: float
+reveal_type(def_gen.pareto(0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.pareto(D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.pareto(D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.pareto(D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.pareto(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.chisquare(0.5)) # E: float
+reveal_type(def_gen.chisquare(0.5, size=None)) # E: float
+reveal_type(def_gen.chisquare(0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.chisquare(D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.chisquare(D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.chisquare(D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.chisquare(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.exponential(0.5)) # E: float
+reveal_type(def_gen.exponential(0.5, size=None)) # E: float
+reveal_type(def_gen.exponential(0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.exponential(D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.exponential(D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.exponential(D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.exponential(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.geometric(0.5)) # E: int
+reveal_type(def_gen.geometric(0.5, size=None)) # E: int
+reveal_type(def_gen.geometric(0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.geometric(D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.geometric(D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.geometric(D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.geometric(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+
+reveal_type(def_gen.logseries(0.5)) # E: int
+reveal_type(def_gen.logseries(0.5, size=None)) # E: int
+reveal_type(def_gen.logseries(0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.logseries(D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.logseries(D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.logseries(D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.logseries(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+
+reveal_type(def_gen.rayleigh(0.5)) # E: float
+reveal_type(def_gen.rayleigh(0.5, size=None)) # E: float
+reveal_type(def_gen.rayleigh(0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.rayleigh(D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.rayleigh(D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.rayleigh(D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.rayleigh(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.standard_gamma(0.5)) # E: float
+reveal_type(def_gen.standard_gamma(0.5, size=None)) # E: float
+reveal_type(def_gen.standard_gamma(0.5, dtype="float32")) # E: float
+reveal_type(def_gen.standard_gamma(0.5, size=None, dtype="float32")) # E: float
+reveal_type(def_gen.standard_gamma(0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.standard_gamma(D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.standard_gamma(D_arr_0p5, dtype="f4")) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._32Bit]]]
+reveal_type(def_gen.standard_gamma(0.5, size=1, dtype="float32", out=S_out)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._32Bit]]]
+reveal_type(def_gen.standard_gamma(D_arr_0p5, dtype=np.float32, out=S_out)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._32Bit]]]
+reveal_type(def_gen.standard_gamma(D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.standard_gamma(D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.standard_gamma(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.standard_gamma(0.5, out=D_out)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.standard_gamma(D_arr_like_0p5, out=D_out)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.standard_gamma(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(def_gen.standard_gamma(D_arr_like_0p5, size=1, out=D_out, dtype=np.float64)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+
+reveal_type(def_gen.vonmises(0.5, 0.5)) # E: float
+reveal_type(def_gen.vonmises(0.5, 0.5, size=None)) # E: float
+reveal_type(def_gen.vonmises(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.vonmises(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.vonmises(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.vonmises(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.vonmises(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.vonmises(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.vonmises(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.vonmises(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.vonmises(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.vonmises(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.vonmises(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.wald(0.5, 0.5)) # E: float
+reveal_type(def_gen.wald(0.5, 0.5, size=None)) # E: float
+reveal_type(def_gen.wald(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.wald(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.wald(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.wald(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.wald(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.wald(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.wald(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.wald(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.wald(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.wald(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.wald(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.uniform(0.5, 0.5)) # E: float
+reveal_type(def_gen.uniform(0.5, 0.5, size=None)) # E: float
+reveal_type(def_gen.uniform(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.uniform(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.uniform(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.uniform(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.uniform(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.uniform(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.uniform(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.uniform(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.uniform(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.uniform(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.uniform(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.beta(0.5, 0.5)) # E: float
+reveal_type(def_gen.beta(0.5, 0.5, size=None)) # E: float
+reveal_type(def_gen.beta(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.beta(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.beta(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.beta(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.beta(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.beta(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.beta(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.beta(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.beta(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.beta(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.beta(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.f(0.5, 0.5)) # E: float
+reveal_type(def_gen.f(0.5, 0.5, size=None)) # E: float
+reveal_type(def_gen.f(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.f(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.f(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.f(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.f(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.f(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.f(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.f(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.f(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.f(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.f(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.gamma(0.5, 0.5)) # E: float
+reveal_type(def_gen.gamma(0.5, 0.5, size=None)) # E: float
+reveal_type(def_gen.gamma(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.gamma(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.gamma(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.gamma(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.gamma(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.gamma(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.gamma(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.gamma(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.gamma(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.gamma(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.gamma(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.gumbel(0.5, 0.5)) # E: float
+reveal_type(def_gen.gumbel(0.5, 0.5, size=None)) # E: float
+reveal_type(def_gen.gumbel(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.gumbel(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.gumbel(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.gumbel(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.gumbel(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.gumbel(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.gumbel(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.gumbel(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.gumbel(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.gumbel(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.gumbel(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.laplace(0.5, 0.5)) # E: float
+reveal_type(def_gen.laplace(0.5, 0.5, size=None)) # E: float
+reveal_type(def_gen.laplace(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.laplace(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.laplace(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.laplace(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.laplace(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.laplace(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.laplace(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.laplace(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.laplace(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.laplace(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.laplace(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.logistic(0.5, 0.5)) # E: float
+reveal_type(def_gen.logistic(0.5, 0.5, size=None)) # E: float
+reveal_type(def_gen.logistic(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.logistic(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.logistic(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.logistic(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.logistic(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.logistic(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.logistic(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.logistic(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.logistic(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.logistic(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.logistic(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.lognormal(0.5, 0.5)) # E: float
+reveal_type(def_gen.lognormal(0.5, 0.5, size=None)) # E: float
+reveal_type(def_gen.lognormal(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.lognormal(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.lognormal(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.lognormal(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.lognormal(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.lognormal(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.lognormal(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.lognormal(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.lognormal(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.lognormal(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.lognormal(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.noncentral_chisquare(0.5, 0.5)) # E: float
+reveal_type(def_gen.noncentral_chisquare(0.5, 0.5, size=None)) # E: float
+reveal_type(def_gen.noncentral_chisquare(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.noncentral_chisquare(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.noncentral_chisquare(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.noncentral_chisquare(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.noncentral_chisquare(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.noncentral_chisquare(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.noncentral_chisquare(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.noncentral_chisquare(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.noncentral_chisquare(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.noncentral_chisquare(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.noncentral_chisquare(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.normal(0.5, 0.5)) # E: float
+reveal_type(def_gen.normal(0.5, 0.5, size=None)) # E: float
+reveal_type(def_gen.normal(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.normal(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.normal(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.normal(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.normal(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.normal(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.normal(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.normal(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.normal(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.normal(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.normal(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.triangular(0.1, 0.5, 0.9)) # E: float
+reveal_type(def_gen.triangular(0.1, 0.5, 0.9, size=None)) # E: float
+reveal_type(def_gen.triangular(0.1, 0.5, 0.9, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.triangular(D_arr_0p1, 0.5, 0.9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.triangular(0.1, D_arr_0p5, 0.9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.triangular(D_arr_0p1, 0.5, D_arr_like_0p9, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.triangular(0.1, D_arr_0p5, 0.9, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.triangular(D_arr_like_0p1, 0.5, D_arr_0p9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.triangular(0.5, D_arr_like_0p5, 0.9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.triangular(D_arr_0p1, D_arr_0p5, 0.9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.triangular(D_arr_like_0p1, D_arr_like_0p5, 0.9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.triangular(D_arr_0p1, D_arr_0p5, D_arr_0p9, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.triangular(D_arr_like_0p1, D_arr_like_0p5, D_arr_like_0p9, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.noncentral_f(0.1, 0.5, 0.9)) # E: float
+reveal_type(def_gen.noncentral_f(0.1, 0.5, 0.9, size=None)) # E: float
+reveal_type(def_gen.noncentral_f(0.1, 0.5, 0.9, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.noncentral_f(D_arr_0p1, 0.5, 0.9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.noncentral_f(0.1, D_arr_0p5, 0.9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.noncentral_f(D_arr_0p1, 0.5, D_arr_like_0p9, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.noncentral_f(0.1, D_arr_0p5, 0.9, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.noncentral_f(D_arr_like_0p1, 0.5, D_arr_0p9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.noncentral_f(0.5, D_arr_like_0p5, 0.9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.noncentral_f(D_arr_0p1, D_arr_0p5, 0.9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.noncentral_f(D_arr_like_0p1, D_arr_like_0p5, 0.9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.noncentral_f(D_arr_0p1, D_arr_0p5, D_arr_0p9, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.noncentral_f(D_arr_like_0p1, D_arr_like_0p5, D_arr_like_0p9, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.binomial(10, 0.5)) # E: int
+reveal_type(def_gen.binomial(10, 0.5, size=None)) # E: int
+reveal_type(def_gen.binomial(10, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.binomial(I_arr_10, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.binomial(10, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.binomial(I_arr_10, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.binomial(10, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.binomial(I_arr_like_10, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.binomial(10, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.binomial(I_arr_10, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.binomial(I_arr_like_10, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.binomial(I_arr_10, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.binomial(I_arr_like_10, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+
+reveal_type(def_gen.negative_binomial(10, 0.5)) # E: int
+reveal_type(def_gen.negative_binomial(10, 0.5, size=None)) # E: int
+reveal_type(def_gen.negative_binomial(10, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.negative_binomial(I_arr_10, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.negative_binomial(10, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.negative_binomial(I_arr_10, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.negative_binomial(10, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.negative_binomial(I_arr_like_10, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.negative_binomial(10, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.negative_binomial(I_arr_10, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.negative_binomial(I_arr_like_10, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.negative_binomial(I_arr_10, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.negative_binomial(I_arr_like_10, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+
+reveal_type(def_gen.hypergeometric(20, 20, 10)) # E: int
+reveal_type(def_gen.hypergeometric(20, 20, 10, size=None)) # E: int
+reveal_type(def_gen.hypergeometric(20, 20, 10, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.hypergeometric(I_arr_20, 20, 10)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.hypergeometric(20, I_arr_20, 10)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.hypergeometric(I_arr_20, 20, I_arr_like_10, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.hypergeometric(20, I_arr_20, 10, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.hypergeometric(I_arr_like_20, 20, I_arr_10)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.hypergeometric(20, I_arr_like_20, 10)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.hypergeometric(I_arr_20, I_arr_20, 10)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.hypergeometric(I_arr_like_20, I_arr_like_20, 10)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.hypergeometric(I_arr_20, I_arr_20, I_arr_10, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.hypergeometric(I_arr_like_20, I_arr_like_20, I_arr_like_10, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+
+I_int64_100: np.ndarray[Any, np.dtype[np.int64]] = np.array([100], dtype=np.int64)
+
+reveal_type(def_gen.integers(0, 100)) # E: int
+reveal_type(def_gen.integers(100)) # E: int
+reveal_type(def_gen.integers([100])) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(0, [100])) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+
+I_bool_low: np.ndarray[Any, np.dtype[np.bool_]] = np.array([0], dtype=np.bool_)
+I_bool_low_like: List[int] = [0]
+I_bool_high_open: np.ndarray[Any, np.dtype[np.bool_]] = np.array([1], dtype=np.bool_)
+I_bool_high_closed: np.ndarray[Any, np.dtype[np.bool_]] = np.array([1], dtype=np.bool_)
+
+reveal_type(def_gen.integers(2, dtype=bool)) # E: builtins.bool
+reveal_type(def_gen.integers(0, 2, dtype=bool)) # E: builtins.bool
+reveal_type(def_gen.integers(1, dtype=bool, endpoint=True)) # E: builtins.bool
+reveal_type(def_gen.integers(0, 1, dtype=bool, endpoint=True)) # E: builtins.bool
+reveal_type(def_gen.integers(I_bool_low_like, 1, dtype=bool, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]
+reveal_type(def_gen.integers(I_bool_high_open, dtype=bool)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]
+reveal_type(def_gen.integers(I_bool_low, I_bool_high_open, dtype=bool)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]
+reveal_type(def_gen.integers(0, I_bool_high_open, dtype=bool)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]
+reveal_type(def_gen.integers(I_bool_high_closed, dtype=bool, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]
+reveal_type(def_gen.integers(I_bool_low, I_bool_high_closed, dtype=bool, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]
+reveal_type(def_gen.integers(0, I_bool_high_closed, dtype=bool, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]
+
+reveal_type(def_gen.integers(2, dtype=np.bool_)) # E: builtins.bool
+reveal_type(def_gen.integers(0, 2, dtype=np.bool_)) # E: builtins.bool
+reveal_type(def_gen.integers(1, dtype=np.bool_, endpoint=True)) # E: builtins.bool
+reveal_type(def_gen.integers(0, 1, dtype=np.bool_, endpoint=True)) # E: builtins.bool
+reveal_type(def_gen.integers(I_bool_low_like, 1, dtype=np.bool_, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]
+reveal_type(def_gen.integers(I_bool_high_open, dtype=np.bool_)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]
+reveal_type(def_gen.integers(I_bool_low, I_bool_high_open, dtype=np.bool_)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]
+reveal_type(def_gen.integers(0, I_bool_high_open, dtype=np.bool_)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]
+reveal_type(def_gen.integers(I_bool_high_closed, dtype=np.bool_, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]
+reveal_type(def_gen.integers(I_bool_low, I_bool_high_closed, dtype=np.bool_, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]
+reveal_type(def_gen.integers(0, I_bool_high_closed, dtype=np.bool_, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]
+
+I_u1_low: np.ndarray[Any, np.dtype[np.uint8]] = np.array([0], dtype=np.uint8)
+I_u1_low_like: List[int] = [0]
+I_u1_high_open: np.ndarray[Any, np.dtype[np.uint8]] = np.array([255], dtype=np.uint8)
+I_u1_high_closed: np.ndarray[Any, np.dtype[np.uint8]] = np.array([255], dtype=np.uint8)
+
+reveal_type(def_gen.integers(256, dtype="u1")) # E: int
+reveal_type(def_gen.integers(0, 256, dtype="u1")) # E: int
+reveal_type(def_gen.integers(255, dtype="u1", endpoint=True)) # E: int
+reveal_type(def_gen.integers(0, 255, dtype="u1", endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_u1_low_like, 255, dtype="u1", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_u1_high_open, dtype="u1")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_u1_low, I_u1_high_open, dtype="u1")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(0, I_u1_high_open, dtype="u1")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_u1_high_closed, dtype="u1", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_u1_low, I_u1_high_closed, dtype="u1", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(0, I_u1_high_closed, dtype="u1", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+
+reveal_type(def_gen.integers(256, dtype="uint8")) # E: int
+reveal_type(def_gen.integers(0, 256, dtype="uint8")) # E: int
+reveal_type(def_gen.integers(255, dtype="uint8", endpoint=True)) # E: int
+reveal_type(def_gen.integers(0, 255, dtype="uint8", endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_u1_low_like, 255, dtype="uint8", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_u1_high_open, dtype="uint8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_u1_low, I_u1_high_open, dtype="uint8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(0, I_u1_high_open, dtype="uint8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_u1_high_closed, dtype="uint8", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_u1_low, I_u1_high_closed, dtype="uint8", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(0, I_u1_high_closed, dtype="uint8", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+
+reveal_type(def_gen.integers(256, dtype=np.uint8)) # E: int
+reveal_type(def_gen.integers(0, 256, dtype=np.uint8)) # E: int
+reveal_type(def_gen.integers(255, dtype=np.uint8, endpoint=True)) # E: int
+reveal_type(def_gen.integers(0, 255, dtype=np.uint8, endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_u1_low_like, 255, dtype=np.uint8, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_u1_high_open, dtype=np.uint8)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_u1_low, I_u1_high_open, dtype=np.uint8)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(0, I_u1_high_open, dtype=np.uint8)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_u1_high_closed, dtype=np.uint8, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_u1_low, I_u1_high_closed, dtype=np.uint8, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(0, I_u1_high_closed, dtype=np.uint8, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+
+I_u2_low: np.ndarray[Any, np.dtype[np.uint16]] = np.array([0], dtype=np.uint16)
+I_u2_low_like: List[int] = [0]
+I_u2_high_open: np.ndarray[Any, np.dtype[np.uint16]] = np.array([65535], dtype=np.uint16)
+I_u2_high_closed: np.ndarray[Any, np.dtype[np.uint16]] = np.array([65535], dtype=np.uint16)
+
+reveal_type(def_gen.integers(65536, dtype="u2")) # E: int
+reveal_type(def_gen.integers(0, 65536, dtype="u2")) # E: int
+reveal_type(def_gen.integers(65535, dtype="u2", endpoint=True)) # E: int
+reveal_type(def_gen.integers(0, 65535, dtype="u2", endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_u2_low_like, 65535, dtype="u2", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_u2_high_open, dtype="u2")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_u2_low, I_u2_high_open, dtype="u2")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(0, I_u2_high_open, dtype="u2")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_u2_high_closed, dtype="u2", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_u2_low, I_u2_high_closed, dtype="u2", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(0, I_u2_high_closed, dtype="u2", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+
+reveal_type(def_gen.integers(65536, dtype="uint16")) # E: int
+reveal_type(def_gen.integers(0, 65536, dtype="uint16")) # E: int
+reveal_type(def_gen.integers(65535, dtype="uint16", endpoint=True)) # E: int
+reveal_type(def_gen.integers(0, 65535, dtype="uint16", endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_u2_low_like, 65535, dtype="uint16", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_u2_high_open, dtype="uint16")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_u2_low, I_u2_high_open, dtype="uint16")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(0, I_u2_high_open, dtype="uint16")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_u2_high_closed, dtype="uint16", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_u2_low, I_u2_high_closed, dtype="uint16", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(0, I_u2_high_closed, dtype="uint16", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+
+reveal_type(def_gen.integers(65536, dtype=np.uint16)) # E: int
+reveal_type(def_gen.integers(0, 65536, dtype=np.uint16)) # E: int
+reveal_type(def_gen.integers(65535, dtype=np.uint16, endpoint=True)) # E: int
+reveal_type(def_gen.integers(0, 65535, dtype=np.uint16, endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_u2_low_like, 65535, dtype=np.uint16, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_u2_high_open, dtype=np.uint16)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_u2_low, I_u2_high_open, dtype=np.uint16)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(0, I_u2_high_open, dtype=np.uint16)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_u2_high_closed, dtype=np.uint16, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_u2_low, I_u2_high_closed, dtype=np.uint16, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(0, I_u2_high_closed, dtype=np.uint16, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+
+I_u4_low: np.ndarray[Any, np.dtype[np.uint32]] = np.array([0], dtype=np.uint32)
+I_u4_low_like: List[int] = [0]
+I_u4_high_open: np.ndarray[Any, np.dtype[np.uint32]] = np.array([4294967295], dtype=np.uint32)
+I_u4_high_closed: np.ndarray[Any, np.dtype[np.uint32]] = np.array([4294967295], dtype=np.uint32)
+
+reveal_type(def_gen.integers(4294967296, dtype=np.int_)) # E: int
+reveal_type(def_gen.integers(0, 4294967296, dtype=np.int_)) # E: int
+reveal_type(def_gen.integers(4294967295, dtype=np.int_, endpoint=True)) # E: int
+reveal_type(def_gen.integers(0, 4294967295, dtype=np.int_, endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_u4_low_like, 4294967295, dtype=np.int_, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(def_gen.integers(I_u4_high_open, dtype=np.int_)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(def_gen.integers(I_u4_low, I_u4_high_open, dtype=np.int_)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(def_gen.integers(0, I_u4_high_open, dtype=np.int_)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(def_gen.integers(I_u4_high_closed, dtype=np.int_, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(def_gen.integers(I_u4_low, I_u4_high_closed, dtype=np.int_, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(def_gen.integers(0, I_u4_high_closed, dtype=np.int_, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+
+
+reveal_type(def_gen.integers(4294967296, dtype="u4")) # E: int
+reveal_type(def_gen.integers(0, 4294967296, dtype="u4")) # E: int
+reveal_type(def_gen.integers(4294967295, dtype="u4", endpoint=True)) # E: int
+reveal_type(def_gen.integers(0, 4294967295, dtype="u4", endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_u4_low_like, 4294967295, dtype="u4", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_u4_high_open, dtype="u4")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_u4_low, I_u4_high_open, dtype="u4")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(0, I_u4_high_open, dtype="u4")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_u4_high_closed, dtype="u4", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_u4_low, I_u4_high_closed, dtype="u4", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(0, I_u4_high_closed, dtype="u4", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+
+reveal_type(def_gen.integers(4294967296, dtype="uint32")) # E: int
+reveal_type(def_gen.integers(0, 4294967296, dtype="uint32")) # E: int
+reveal_type(def_gen.integers(4294967295, dtype="uint32", endpoint=True)) # E: int
+reveal_type(def_gen.integers(0, 4294967295, dtype="uint32", endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_u4_low_like, 4294967295, dtype="uint32", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_u4_high_open, dtype="uint32")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_u4_low, I_u4_high_open, dtype="uint32")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(0, I_u4_high_open, dtype="uint32")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_u4_high_closed, dtype="uint32", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_u4_low, I_u4_high_closed, dtype="uint32", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(0, I_u4_high_closed, dtype="uint32", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+
+reveal_type(def_gen.integers(4294967296, dtype=np.uint32)) # E: int
+reveal_type(def_gen.integers(0, 4294967296, dtype=np.uint32)) # E: int
+reveal_type(def_gen.integers(4294967295, dtype=np.uint32, endpoint=True)) # E: int
+reveal_type(def_gen.integers(0, 4294967295, dtype=np.uint32, endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_u4_low_like, 4294967295, dtype=np.uint32, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_u4_high_open, dtype=np.uint32)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_u4_low, I_u4_high_open, dtype=np.uint32)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(0, I_u4_high_open, dtype=np.uint32)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_u4_high_closed, dtype=np.uint32, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_u4_low, I_u4_high_closed, dtype=np.uint32, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(0, I_u4_high_closed, dtype=np.uint32, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+
+reveal_type(def_gen.integers(4294967296, dtype=np.uint)) # E: int
+reveal_type(def_gen.integers(0, 4294967296, dtype=np.uint)) # E: int
+reveal_type(def_gen.integers(4294967295, dtype=np.uint, endpoint=True)) # E: int
+reveal_type(def_gen.integers(0, 4294967295, dtype=np.uint, endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_u4_low_like, 4294967295, dtype=np.uint, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[{uint}]]
+reveal_type(def_gen.integers(I_u4_high_open, dtype=np.uint)) # E: numpy.ndarray[Any, numpy.dtype[{uint}]]
+reveal_type(def_gen.integers(I_u4_low, I_u4_high_open, dtype=np.uint)) # E: numpy.ndarray[Any, numpy.dtype[{uint}]]
+reveal_type(def_gen.integers(0, I_u4_high_open, dtype=np.uint)) # E: numpy.ndarray[Any, numpy.dtype[{uint}]]
+reveal_type(def_gen.integers(I_u4_high_closed, dtype=np.uint, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[{uint}]]
+reveal_type(def_gen.integers(I_u4_low, I_u4_high_closed, dtype=np.uint, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[{uint}]]
+reveal_type(def_gen.integers(0, I_u4_high_closed, dtype=np.uint, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[{uint}]]
+
+I_u8_low: np.ndarray[Any, np.dtype[np.uint64]] = np.array([0], dtype=np.uint64)
+I_u8_low_like: List[int] = [0]
+I_u8_high_open: np.ndarray[Any, np.dtype[np.uint64]] = np.array([18446744073709551615], dtype=np.uint64)
+I_u8_high_closed: np.ndarray[Any, np.dtype[np.uint64]] = np.array([18446744073709551615], dtype=np.uint64)
+
+reveal_type(def_gen.integers(18446744073709551616, dtype="u8")) # E: int
+reveal_type(def_gen.integers(0, 18446744073709551616, dtype="u8")) # E: int
+reveal_type(def_gen.integers(18446744073709551615, dtype="u8", endpoint=True)) # E: int
+reveal_type(def_gen.integers(0, 18446744073709551615, dtype="u8", endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_u8_low_like, 18446744073709551615, dtype="u8", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_u8_high_open, dtype="u8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_u8_low, I_u8_high_open, dtype="u8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(0, I_u8_high_open, dtype="u8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_u8_high_closed, dtype="u8", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_u8_low, I_u8_high_closed, dtype="u8", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(0, I_u8_high_closed, dtype="u8", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+
+reveal_type(def_gen.integers(18446744073709551616, dtype="uint64")) # E: int
+reveal_type(def_gen.integers(0, 18446744073709551616, dtype="uint64")) # E: int
+reveal_type(def_gen.integers(18446744073709551615, dtype="uint64", endpoint=True)) # E: int
+reveal_type(def_gen.integers(0, 18446744073709551615, dtype="uint64", endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_u8_low_like, 18446744073709551615, dtype="uint64", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_u8_high_open, dtype="uint64")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_u8_low, I_u8_high_open, dtype="uint64")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(0, I_u8_high_open, dtype="uint64")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_u8_high_closed, dtype="uint64", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_u8_low, I_u8_high_closed, dtype="uint64", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(0, I_u8_high_closed, dtype="uint64", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+
+reveal_type(def_gen.integers(18446744073709551616, dtype=np.uint64)) # E: int
+reveal_type(def_gen.integers(0, 18446744073709551616, dtype=np.uint64)) # E: int
+reveal_type(def_gen.integers(18446744073709551615, dtype=np.uint64, endpoint=True)) # E: int
+reveal_type(def_gen.integers(0, 18446744073709551615, dtype=np.uint64, endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_u8_low_like, 18446744073709551615, dtype=np.uint64, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_u8_high_open, dtype=np.uint64)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_u8_low, I_u8_high_open, dtype=np.uint64)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(0, I_u8_high_open, dtype=np.uint64)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_u8_high_closed, dtype=np.uint64, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_u8_low, I_u8_high_closed, dtype=np.uint64, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(0, I_u8_high_closed, dtype=np.uint64, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+
+I_i1_low: np.ndarray[Any, np.dtype[np.int8]] = np.array([-128], dtype=np.int8)
+I_i1_low_like: List[int] = [-128]
+I_i1_high_open: np.ndarray[Any, np.dtype[np.int8]] = np.array([127], dtype=np.int8)
+I_i1_high_closed: np.ndarray[Any, np.dtype[np.int8]] = np.array([127], dtype=np.int8)
+
+reveal_type(def_gen.integers(128, dtype="i1")) # E: int
+reveal_type(def_gen.integers(-128, 128, dtype="i1")) # E: int
+reveal_type(def_gen.integers(127, dtype="i1", endpoint=True)) # E: int
+reveal_type(def_gen.integers(-128, 127, dtype="i1", endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_i1_low_like, 127, dtype="i1", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_i1_high_open, dtype="i1")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_i1_low, I_i1_high_open, dtype="i1")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(-128, I_i1_high_open, dtype="i1")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_i1_high_closed, dtype="i1", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_i1_low, I_i1_high_closed, dtype="i1", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(-128, I_i1_high_closed, dtype="i1", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+
+reveal_type(def_gen.integers(128, dtype="int8")) # E: int
+reveal_type(def_gen.integers(-128, 128, dtype="int8")) # E: int
+reveal_type(def_gen.integers(127, dtype="int8", endpoint=True)) # E: int
+reveal_type(def_gen.integers(-128, 127, dtype="int8", endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_i1_low_like, 127, dtype="int8", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_i1_high_open, dtype="int8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_i1_low, I_i1_high_open, dtype="int8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(-128, I_i1_high_open, dtype="int8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_i1_high_closed, dtype="int8", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_i1_low, I_i1_high_closed, dtype="int8", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(-128, I_i1_high_closed, dtype="int8", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+
+reveal_type(def_gen.integers(128, dtype=np.int8)) # E: int
+reveal_type(def_gen.integers(-128, 128, dtype=np.int8)) # E: int
+reveal_type(def_gen.integers(127, dtype=np.int8, endpoint=True)) # E: int
+reveal_type(def_gen.integers(-128, 127, dtype=np.int8, endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_i1_low_like, 127, dtype=np.int8, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_i1_high_open, dtype=np.int8)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_i1_low, I_i1_high_open, dtype=np.int8)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(-128, I_i1_high_open, dtype=np.int8)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_i1_high_closed, dtype=np.int8, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(I_i1_low, I_i1_high_closed, dtype=np.int8, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(def_gen.integers(-128, I_i1_high_closed, dtype=np.int8, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+
+I_i2_low: np.ndarray[Any, np.dtype[np.int16]] = np.array([-32768], dtype=np.int16)
+I_i2_low_like: List[int] = [-32768]
+I_i2_high_open: np.ndarray[Any, np.dtype[np.int16]] = np.array([32767], dtype=np.int16)
+I_i2_high_closed: np.ndarray[Any, np.dtype[np.int16]] = np.array([32767], dtype=np.int16)
+
+reveal_type(def_gen.integers(32768, dtype="i2")) # E: int
+reveal_type(def_gen.integers(-32768, 32768, dtype="i2")) # E: int
+reveal_type(def_gen.integers(32767, dtype="i2", endpoint=True)) # E: int
+reveal_type(def_gen.integers(-32768, 32767, dtype="i2", endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_i2_low_like, 32767, dtype="i2", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_i2_high_open, dtype="i2")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_i2_low, I_i2_high_open, dtype="i2")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(-32768, I_i2_high_open, dtype="i2")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_i2_high_closed, dtype="i2", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_i2_low, I_i2_high_closed, dtype="i2", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(-32768, I_i2_high_closed, dtype="i2", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+
+reveal_type(def_gen.integers(32768, dtype="int16")) # E: int
+reveal_type(def_gen.integers(-32768, 32768, dtype="int16")) # E: int
+reveal_type(def_gen.integers(32767, dtype="int16", endpoint=True)) # E: int
+reveal_type(def_gen.integers(-32768, 32767, dtype="int16", endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_i2_low_like, 32767, dtype="int16", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_i2_high_open, dtype="int16")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_i2_low, I_i2_high_open, dtype="int16")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(-32768, I_i2_high_open, dtype="int16")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_i2_high_closed, dtype="int16", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_i2_low, I_i2_high_closed, dtype="int16", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(-32768, I_i2_high_closed, dtype="int16", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+
+reveal_type(def_gen.integers(32768, dtype=np.int16)) # E: int
+reveal_type(def_gen.integers(-32768, 32768, dtype=np.int16)) # E: int
+reveal_type(def_gen.integers(32767, dtype=np.int16, endpoint=True)) # E: int
+reveal_type(def_gen.integers(-32768, 32767, dtype=np.int16, endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_i2_low_like, 32767, dtype=np.int16, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_i2_high_open, dtype=np.int16)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_i2_low, I_i2_high_open, dtype=np.int16)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(-32768, I_i2_high_open, dtype=np.int16)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_i2_high_closed, dtype=np.int16, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(I_i2_low, I_i2_high_closed, dtype=np.int16, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(def_gen.integers(-32768, I_i2_high_closed, dtype=np.int16, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+
+I_i4_low: np.ndarray[Any, np.dtype[np.int32]] = np.array([-2147483648], dtype=np.int32)
+I_i4_low_like: List[int] = [-2147483648]
+I_i4_high_open: np.ndarray[Any, np.dtype[np.int32]] = np.array([2147483647], dtype=np.int32)
+I_i4_high_closed: np.ndarray[Any, np.dtype[np.int32]] = np.array([2147483647], dtype=np.int32)
+
+reveal_type(def_gen.integers(2147483648, dtype="i4")) # E: int
+reveal_type(def_gen.integers(-2147483648, 2147483648, dtype="i4")) # E: int
+reveal_type(def_gen.integers(2147483647, dtype="i4", endpoint=True)) # E: int
+reveal_type(def_gen.integers(-2147483648, 2147483647, dtype="i4", endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_i4_low_like, 2147483647, dtype="i4", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_i4_high_open, dtype="i4")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_i4_low, I_i4_high_open, dtype="i4")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(-2147483648, I_i4_high_open, dtype="i4")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_i4_high_closed, dtype="i4", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_i4_low, I_i4_high_closed, dtype="i4", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(-2147483648, I_i4_high_closed, dtype="i4", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+
+reveal_type(def_gen.integers(2147483648, dtype="int32")) # E: int
+reveal_type(def_gen.integers(-2147483648, 2147483648, dtype="int32")) # E: int
+reveal_type(def_gen.integers(2147483647, dtype="int32", endpoint=True)) # E: int
+reveal_type(def_gen.integers(-2147483648, 2147483647, dtype="int32", endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_i4_low_like, 2147483647, dtype="int32", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_i4_high_open, dtype="int32")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_i4_low, I_i4_high_open, dtype="int32")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(-2147483648, I_i4_high_open, dtype="int32")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_i4_high_closed, dtype="int32", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_i4_low, I_i4_high_closed, dtype="int32", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(-2147483648, I_i4_high_closed, dtype="int32", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+
+reveal_type(def_gen.integers(2147483648, dtype=np.int32)) # E: int
+reveal_type(def_gen.integers(-2147483648, 2147483648, dtype=np.int32)) # E: int
+reveal_type(def_gen.integers(2147483647, dtype=np.int32, endpoint=True)) # E: int
+reveal_type(def_gen.integers(-2147483648, 2147483647, dtype=np.int32, endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_i4_low_like, 2147483647, dtype=np.int32, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_i4_high_open, dtype=np.int32)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_i4_low, I_i4_high_open, dtype=np.int32)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(-2147483648, I_i4_high_open, dtype=np.int32)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_i4_high_closed, dtype=np.int32, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(I_i4_low, I_i4_high_closed, dtype=np.int32, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(def_gen.integers(-2147483648, I_i4_high_closed, dtype=np.int32, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+
+I_i8_low: np.ndarray[Any, np.dtype[np.int64]] = np.array([-9223372036854775808], dtype=np.int64)
+I_i8_low_like: List[int] = [-9223372036854775808]
+I_i8_high_open: np.ndarray[Any, np.dtype[np.int64]] = np.array([9223372036854775807], dtype=np.int64)
+I_i8_high_closed: np.ndarray[Any, np.dtype[np.int64]] = np.array([9223372036854775807], dtype=np.int64)
+
+reveal_type(def_gen.integers(9223372036854775808, dtype="i8")) # E: int
+reveal_type(def_gen.integers(-9223372036854775808, 9223372036854775808, dtype="i8")) # E: int
+reveal_type(def_gen.integers(9223372036854775807, dtype="i8", endpoint=True)) # E: int
+reveal_type(def_gen.integers(-9223372036854775808, 9223372036854775807, dtype="i8", endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_i8_low_like, 9223372036854775807, dtype="i8", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_i8_high_open, dtype="i8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_i8_low, I_i8_high_open, dtype="i8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(-9223372036854775808, I_i8_high_open, dtype="i8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_i8_high_closed, dtype="i8", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_i8_low, I_i8_high_closed, dtype="i8", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(-9223372036854775808, I_i8_high_closed, dtype="i8", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+
+reveal_type(def_gen.integers(9223372036854775808, dtype="int64")) # E: int
+reveal_type(def_gen.integers(-9223372036854775808, 9223372036854775808, dtype="int64")) # E: int
+reveal_type(def_gen.integers(9223372036854775807, dtype="int64", endpoint=True)) # E: int
+reveal_type(def_gen.integers(-9223372036854775808, 9223372036854775807, dtype="int64", endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_i8_low_like, 9223372036854775807, dtype="int64", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_i8_high_open, dtype="int64")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_i8_low, I_i8_high_open, dtype="int64")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(-9223372036854775808, I_i8_high_open, dtype="int64")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_i8_high_closed, dtype="int64", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_i8_low, I_i8_high_closed, dtype="int64", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(-9223372036854775808, I_i8_high_closed, dtype="int64", endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+
+reveal_type(def_gen.integers(9223372036854775808, dtype=np.int64)) # E: int
+reveal_type(def_gen.integers(-9223372036854775808, 9223372036854775808, dtype=np.int64)) # E: int
+reveal_type(def_gen.integers(9223372036854775807, dtype=np.int64, endpoint=True)) # E: int
+reveal_type(def_gen.integers(-9223372036854775808, 9223372036854775807, dtype=np.int64, endpoint=True)) # E: int
+reveal_type(def_gen.integers(I_i8_low_like, 9223372036854775807, dtype=np.int64, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_i8_high_open, dtype=np.int64)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_i8_low, I_i8_high_open, dtype=np.int64)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(-9223372036854775808, I_i8_high_open, dtype=np.int64)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_i8_high_closed, dtype=np.int64, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(I_i8_low, I_i8_high_closed, dtype=np.int64, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.integers(-9223372036854775808, I_i8_high_closed, dtype=np.int64, endpoint=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+
+
+reveal_type(def_gen.bit_generator) # E: BitGenerator
+
+reveal_type(def_gen.bytes(2)) # E: bytes
+
+reveal_type(def_gen.choice(5)) # E: int
+reveal_type(def_gen.choice(5, 3)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.choice(5, 3, replace=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.choice(5, 3, p=[1 / 5] * 5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.choice(5, 3, p=[1 / 5] * 5, replace=False)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+
+reveal_type(def_gen.choice(["pooh", "rabbit", "piglet", "Christopher"])) # E: Any
+reveal_type(def_gen.choice(["pooh", "rabbit", "piglet", "Christopher"], 3)) # E: numpy.ndarray[Any, Any]
+reveal_type(def_gen.choice(["pooh", "rabbit", "piglet", "Christopher"], 3, p=[1 / 4] * 4)) # E: numpy.ndarray[Any, Any]
+reveal_type(def_gen.choice(["pooh", "rabbit", "piglet", "Christopher"], 3, replace=True)) # E: numpy.ndarray[Any, Any]
+reveal_type(def_gen.choice(["pooh", "rabbit", "piglet", "Christopher"], 3, replace=False, p=np.array([1 / 8, 1 / 8, 1 / 2, 1 / 4]))) # E: numpy.ndarray[Any, Any]
+
+reveal_type(def_gen.dirichlet([0.5, 0.5])) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.dirichlet(np.array([0.5, 0.5]))) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.dirichlet(np.array([0.5, 0.5]), size=3)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.multinomial(20, [1 / 6.0] * 6)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.multinomial(20, np.array([0.5, 0.5]))) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.multinomial(20, [1 / 6.0] * 6, size=2)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.multinomial([[10], [20]], [1 / 6.0] * 6, size=(2, 2))) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.multinomial(np.array([[10], [20]]), np.array([0.5, 0.5]), size=(2, 2))) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+
+reveal_type(def_gen.multivariate_hypergeometric([3, 5, 7], 2)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.multivariate_hypergeometric(np.array([3, 5, 7]), 2)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.multivariate_hypergeometric(np.array([3, 5, 7]), 2, size=4)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.multivariate_hypergeometric(np.array([3, 5, 7]), 2, size=(4, 7))) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.multivariate_hypergeometric([3, 5, 7], 2, method="count")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.multivariate_hypergeometric(np.array([3, 5, 7]), 2, method="marginals")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+
+reveal_type(def_gen.multivariate_normal([0.0], [[1.0]])) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.multivariate_normal([0.0], np.array([[1.0]]))) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.multivariate_normal(np.array([0.0]), [[1.0]])) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(def_gen.multivariate_normal([0.0], np.array([[1.0]]))) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(def_gen.permutation(10)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(def_gen.permutation([1, 2, 3, 4])) # E: numpy.ndarray[Any, Any]
+reveal_type(def_gen.permutation(np.array([1, 2, 3, 4]))) # E: numpy.ndarray[Any, Any]
+reveal_type(def_gen.permutation(D_2D, axis=1)) # E: numpy.ndarray[Any, Any]
+reveal_type(def_gen.permuted(D_2D)) # E: numpy.ndarray[Any, Any]
+reveal_type(def_gen.permuted(D_2D_like)) # E: numpy.ndarray[Any, Any]
+reveal_type(def_gen.permuted(D_2D, axis=1)) # E: numpy.ndarray[Any, Any]
+reveal_type(def_gen.permuted(D_2D, out=D_2D)) # E: numpy.ndarray[Any, Any]
+reveal_type(def_gen.permuted(D_2D_like, out=D_2D)) # E: numpy.ndarray[Any, Any]
+reveal_type(def_gen.permuted(D_2D_like, out=D_2D)) # E: numpy.ndarray[Any, Any]
+reveal_type(def_gen.permuted(D_2D, axis=1, out=D_2D)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(def_gen.shuffle(np.arange(10))) # E: None
+reveal_type(def_gen.shuffle([1, 2, 3, 4, 5])) # E: None
+reveal_type(def_gen.shuffle(D_2D, axis=1)) # E: None
+
+reveal_type(np.random.Generator(pcg64)) # E: Generator
+reveal_type(def_gen.__str__()) # E: str
+reveal_type(def_gen.__repr__()) # E: str
+def_gen_state = def_gen.__getstate__()
+reveal_type(def_gen_state) # E: builtins.dict[builtins.str, Any]
+reveal_type(def_gen.__setstate__(def_gen_state)) # E: None
+
+# RandomState
+random_st: np.random.RandomState = np.random.RandomState()
+
+reveal_type(random_st.standard_normal()) # E: float
+reveal_type(random_st.standard_normal(size=None)) # E: float
+reveal_type(random_st.standard_normal(size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+
+reveal_type(random_st.random()) # E: float
+reveal_type(random_st.random(size=None)) # E: float
+reveal_type(random_st.random(size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+
+reveal_type(random_st.standard_cauchy()) # E: float
+reveal_type(random_st.standard_cauchy(size=None)) # E: float
+reveal_type(random_st.standard_cauchy(size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.standard_exponential()) # E: float
+reveal_type(random_st.standard_exponential(size=None)) # E: float
+reveal_type(random_st.standard_exponential(size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+
+reveal_type(random_st.zipf(1.5)) # E: int
+reveal_type(random_st.zipf(1.5, size=None)) # E: int
+reveal_type(random_st.zipf(1.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.zipf(D_arr_1p5)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.zipf(D_arr_1p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.zipf(D_arr_like_1p5)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.zipf(D_arr_like_1p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+
+reveal_type(random_st.weibull(0.5)) # E: float
+reveal_type(random_st.weibull(0.5, size=None)) # E: float
+reveal_type(random_st.weibull(0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.weibull(D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.weibull(D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.weibull(D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.weibull(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.standard_t(0.5)) # E: float
+reveal_type(random_st.standard_t(0.5, size=None)) # E: float
+reveal_type(random_st.standard_t(0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.standard_t(D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.standard_t(D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.standard_t(D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.standard_t(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.poisson(0.5)) # E: int
+reveal_type(random_st.poisson(0.5, size=None)) # E: int
+reveal_type(random_st.poisson(0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.poisson(D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.poisson(D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.poisson(D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.poisson(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+
+reveal_type(random_st.power(0.5)) # E: float
+reveal_type(random_st.power(0.5, size=None)) # E: float
+reveal_type(random_st.power(0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.power(D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.power(D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.power(D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.power(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.pareto(0.5)) # E: float
+reveal_type(random_st.pareto(0.5, size=None)) # E: float
+reveal_type(random_st.pareto(0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.pareto(D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.pareto(D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.pareto(D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.pareto(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.chisquare(0.5)) # E: float
+reveal_type(random_st.chisquare(0.5, size=None)) # E: float
+reveal_type(random_st.chisquare(0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.chisquare(D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.chisquare(D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.chisquare(D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.chisquare(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.exponential(0.5)) # E: float
+reveal_type(random_st.exponential(0.5, size=None)) # E: float
+reveal_type(random_st.exponential(0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.exponential(D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.exponential(D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.exponential(D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.exponential(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.geometric(0.5)) # E: int
+reveal_type(random_st.geometric(0.5, size=None)) # E: int
+reveal_type(random_st.geometric(0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.geometric(D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.geometric(D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.geometric(D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.geometric(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+
+reveal_type(random_st.logseries(0.5)) # E: int
+reveal_type(random_st.logseries(0.5, size=None)) # E: int
+reveal_type(random_st.logseries(0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.logseries(D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.logseries(D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.logseries(D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.logseries(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+
+reveal_type(random_st.rayleigh(0.5)) # E: float
+reveal_type(random_st.rayleigh(0.5, size=None)) # E: float
+reveal_type(random_st.rayleigh(0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.rayleigh(D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.rayleigh(D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.rayleigh(D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.rayleigh(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.standard_gamma(0.5)) # E: float
+reveal_type(random_st.standard_gamma(0.5, size=None)) # E: float
+reveal_type(random_st.standard_gamma(0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(random_st.standard_gamma(D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(random_st.standard_gamma(D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(random_st.standard_gamma(D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(random_st.standard_gamma(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+reveal_type(random_st.standard_gamma(D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]]
+
+reveal_type(random_st.vonmises(0.5, 0.5)) # E: float
+reveal_type(random_st.vonmises(0.5, 0.5, size=None)) # E: float
+reveal_type(random_st.vonmises(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.vonmises(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.vonmises(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.vonmises(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.vonmises(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.vonmises(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.vonmises(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.vonmises(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.vonmises(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.vonmises(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.vonmises(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.wald(0.5, 0.5)) # E: float
+reveal_type(random_st.wald(0.5, 0.5, size=None)) # E: float
+reveal_type(random_st.wald(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.wald(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.wald(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.wald(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.wald(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.wald(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.wald(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.wald(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.wald(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.wald(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.wald(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.uniform(0.5, 0.5)) # E: float
+reveal_type(random_st.uniform(0.5, 0.5, size=None)) # E: float
+reveal_type(random_st.uniform(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.uniform(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.uniform(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.uniform(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.uniform(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.uniform(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.uniform(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.uniform(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.uniform(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.uniform(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.uniform(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.beta(0.5, 0.5)) # E: float
+reveal_type(random_st.beta(0.5, 0.5, size=None)) # E: float
+reveal_type(random_st.beta(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.beta(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.beta(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.beta(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.beta(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.beta(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.beta(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.beta(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.beta(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.beta(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.beta(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.f(0.5, 0.5)) # E: float
+reveal_type(random_st.f(0.5, 0.5, size=None)) # E: float
+reveal_type(random_st.f(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.f(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.f(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.f(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.f(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.f(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.f(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.f(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.f(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.f(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.f(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.gamma(0.5, 0.5)) # E: float
+reveal_type(random_st.gamma(0.5, 0.5, size=None)) # E: float
+reveal_type(random_st.gamma(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.gamma(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.gamma(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.gamma(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.gamma(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.gamma(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.gamma(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.gamma(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.gamma(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.gamma(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.gamma(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.gumbel(0.5, 0.5)) # E: float
+reveal_type(random_st.gumbel(0.5, 0.5, size=None)) # E: float
+reveal_type(random_st.gumbel(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.gumbel(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.gumbel(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.gumbel(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.gumbel(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.gumbel(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.gumbel(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.gumbel(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.gumbel(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.gumbel(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.gumbel(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.laplace(0.5, 0.5)) # E: float
+reveal_type(random_st.laplace(0.5, 0.5, size=None)) # E: float
+reveal_type(random_st.laplace(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.laplace(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.laplace(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.laplace(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.laplace(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.laplace(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.laplace(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.laplace(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.laplace(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.laplace(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.laplace(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.logistic(0.5, 0.5)) # E: float
+reveal_type(random_st.logistic(0.5, 0.5, size=None)) # E: float
+reveal_type(random_st.logistic(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.logistic(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.logistic(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.logistic(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.logistic(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.logistic(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.logistic(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.logistic(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.logistic(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.logistic(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.logistic(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.lognormal(0.5, 0.5)) # E: float
+reveal_type(random_st.lognormal(0.5, 0.5, size=None)) # E: float
+reveal_type(random_st.lognormal(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.lognormal(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.lognormal(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.lognormal(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.lognormal(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.lognormal(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.lognormal(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.lognormal(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.lognormal(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.lognormal(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.lognormal(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.noncentral_chisquare(0.5, 0.5)) # E: float
+reveal_type(random_st.noncentral_chisquare(0.5, 0.5, size=None)) # E: float
+reveal_type(random_st.noncentral_chisquare(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.noncentral_chisquare(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.noncentral_chisquare(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.noncentral_chisquare(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.noncentral_chisquare(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.noncentral_chisquare(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.noncentral_chisquare(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.noncentral_chisquare(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.noncentral_chisquare(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.noncentral_chisquare(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.noncentral_chisquare(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.normal(0.5, 0.5)) # E: float
+reveal_type(random_st.normal(0.5, 0.5, size=None)) # E: float
+reveal_type(random_st.normal(0.5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.normal(D_arr_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.normal(0.5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.normal(D_arr_0p5, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.normal(0.5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.normal(D_arr_like_0p5, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.normal(0.5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.normal(D_arr_0p5, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.normal(D_arr_like_0p5, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.normal(D_arr_0p5, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.normal(D_arr_like_0p5, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.triangular(0.1, 0.5, 0.9)) # E: float
+reveal_type(random_st.triangular(0.1, 0.5, 0.9, size=None)) # E: float
+reveal_type(random_st.triangular(0.1, 0.5, 0.9, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.triangular(D_arr_0p1, 0.5, 0.9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.triangular(0.1, D_arr_0p5, 0.9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.triangular(D_arr_0p1, 0.5, D_arr_like_0p9, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.triangular(0.1, D_arr_0p5, 0.9, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.triangular(D_arr_like_0p1, 0.5, D_arr_0p9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.triangular(0.5, D_arr_like_0p5, 0.9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.triangular(D_arr_0p1, D_arr_0p5, 0.9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.triangular(D_arr_like_0p1, D_arr_like_0p5, 0.9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.triangular(D_arr_0p1, D_arr_0p5, D_arr_0p9, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.triangular(D_arr_like_0p1, D_arr_like_0p5, D_arr_like_0p9, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.noncentral_f(0.1, 0.5, 0.9)) # E: float
+reveal_type(random_st.noncentral_f(0.1, 0.5, 0.9, size=None)) # E: float
+reveal_type(random_st.noncentral_f(0.1, 0.5, 0.9, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.noncentral_f(D_arr_0p1, 0.5, 0.9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.noncentral_f(0.1, D_arr_0p5, 0.9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.noncentral_f(D_arr_0p1, 0.5, D_arr_like_0p9, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.noncentral_f(0.1, D_arr_0p5, 0.9, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.noncentral_f(D_arr_like_0p1, 0.5, D_arr_0p9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.noncentral_f(0.5, D_arr_like_0p5, 0.9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.noncentral_f(D_arr_0p1, D_arr_0p5, 0.9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.noncentral_f(D_arr_like_0p1, D_arr_like_0p5, 0.9)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.noncentral_f(D_arr_0p1, D_arr_0p5, D_arr_0p9, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.noncentral_f(D_arr_like_0p1, D_arr_like_0p5, D_arr_like_0p9, size=1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.binomial(10, 0.5)) # E: int
+reveal_type(random_st.binomial(10, 0.5, size=None)) # E: int
+reveal_type(random_st.binomial(10, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.binomial(I_arr_10, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.binomial(10, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.binomial(I_arr_10, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.binomial(10, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.binomial(I_arr_like_10, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.binomial(10, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.binomial(I_arr_10, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.binomial(I_arr_like_10, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.binomial(I_arr_10, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.binomial(I_arr_like_10, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+
+reveal_type(random_st.negative_binomial(10, 0.5)) # E: int
+reveal_type(random_st.negative_binomial(10, 0.5, size=None)) # E: int
+reveal_type(random_st.negative_binomial(10, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.negative_binomial(I_arr_10, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.negative_binomial(10, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.negative_binomial(I_arr_10, 0.5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.negative_binomial(10, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.negative_binomial(I_arr_like_10, 0.5)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.negative_binomial(10, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.negative_binomial(I_arr_10, D_arr_0p5)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.negative_binomial(I_arr_like_10, D_arr_like_0p5)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.negative_binomial(I_arr_10, D_arr_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.negative_binomial(I_arr_like_10, D_arr_like_0p5, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+
+reveal_type(random_st.hypergeometric(20, 20, 10)) # E: int
+reveal_type(random_st.hypergeometric(20, 20, 10, size=None)) # E: int
+reveal_type(random_st.hypergeometric(20, 20, 10, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.hypergeometric(I_arr_20, 20, 10)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.hypergeometric(20, I_arr_20, 10)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.hypergeometric(I_arr_20, 20, I_arr_like_10, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.hypergeometric(20, I_arr_20, 10, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.hypergeometric(I_arr_like_20, 20, I_arr_10)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.hypergeometric(20, I_arr_like_20, 10)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.hypergeometric(I_arr_20, I_arr_20, 10)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.hypergeometric(I_arr_like_20, I_arr_like_20, 10)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.hypergeometric(I_arr_20, I_arr_20, I_arr_10, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.hypergeometric(I_arr_like_20, I_arr_like_20, I_arr_like_10, size=1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+
+reveal_type(random_st.randint(0, 100)) # E: int
+reveal_type(random_st.randint(100)) # E: int
+reveal_type(random_st.randint([100])) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.randint(0, [100])) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+
+reveal_type(random_st.randint(2, dtype=bool)) # E: builtins.bool
+reveal_type(random_st.randint(0, 2, dtype=bool)) # E: builtins.bool
+reveal_type(random_st.randint(I_bool_high_open, dtype=bool)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]
+reveal_type(random_st.randint(I_bool_low, I_bool_high_open, dtype=bool)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]
+reveal_type(random_st.randint(0, I_bool_high_open, dtype=bool)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]
+
+reveal_type(random_st.randint(2, dtype=np.bool_)) # E: builtins.bool
+reveal_type(random_st.randint(0, 2, dtype=np.bool_)) # E: builtins.bool
+reveal_type(random_st.randint(I_bool_high_open, dtype=np.bool_)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]
+reveal_type(random_st.randint(I_bool_low, I_bool_high_open, dtype=np.bool_)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]
+reveal_type(random_st.randint(0, I_bool_high_open, dtype=np.bool_)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]
+
+reveal_type(random_st.randint(256, dtype="u1")) # E: int
+reveal_type(random_st.randint(0, 256, dtype="u1")) # E: int
+reveal_type(random_st.randint(I_u1_high_open, dtype="u1")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(random_st.randint(I_u1_low, I_u1_high_open, dtype="u1")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(random_st.randint(0, I_u1_high_open, dtype="u1")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+
+reveal_type(random_st.randint(256, dtype="uint8")) # E: int
+reveal_type(random_st.randint(0, 256, dtype="uint8")) # E: int
+reveal_type(random_st.randint(I_u1_high_open, dtype="uint8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(random_st.randint(I_u1_low, I_u1_high_open, dtype="uint8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(random_st.randint(0, I_u1_high_open, dtype="uint8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+
+reveal_type(random_st.randint(256, dtype=np.uint8)) # E: int
+reveal_type(random_st.randint(0, 256, dtype=np.uint8)) # E: int
+reveal_type(random_st.randint(I_u1_high_open, dtype=np.uint8)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(random_st.randint(I_u1_low, I_u1_high_open, dtype=np.uint8)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+reveal_type(random_st.randint(0, I_u1_high_open, dtype=np.uint8)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._8Bit]]]
+
+reveal_type(random_st.randint(65536, dtype="u2")) # E: int
+reveal_type(random_st.randint(0, 65536, dtype="u2")) # E: int
+reveal_type(random_st.randint(I_u2_high_open, dtype="u2")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(random_st.randint(I_u2_low, I_u2_high_open, dtype="u2")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(random_st.randint(0, I_u2_high_open, dtype="u2")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+
+reveal_type(random_st.randint(65536, dtype="uint16")) # E: int
+reveal_type(random_st.randint(0, 65536, dtype="uint16")) # E: int
+reveal_type(random_st.randint(I_u2_high_open, dtype="uint16")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(random_st.randint(I_u2_low, I_u2_high_open, dtype="uint16")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(random_st.randint(0, I_u2_high_open, dtype="uint16")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+
+reveal_type(random_st.randint(65536, dtype=np.uint16)) # E: int
+reveal_type(random_st.randint(0, 65536, dtype=np.uint16)) # E: int
+reveal_type(random_st.randint(I_u2_high_open, dtype=np.uint16)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(random_st.randint(I_u2_low, I_u2_high_open, dtype=np.uint16)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+reveal_type(random_st.randint(0, I_u2_high_open, dtype=np.uint16)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._16Bit]]]
+
+reveal_type(random_st.randint(4294967296, dtype="u4")) # E: int
+reveal_type(random_st.randint(0, 4294967296, dtype="u4")) # E: int
+reveal_type(random_st.randint(I_u4_high_open, dtype="u4")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(random_st.randint(I_u4_low, I_u4_high_open, dtype="u4")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(random_st.randint(0, I_u4_high_open, dtype="u4")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+
+reveal_type(random_st.randint(4294967296, dtype="uint32")) # E: int
+reveal_type(random_st.randint(0, 4294967296, dtype="uint32")) # E: int
+reveal_type(random_st.randint(I_u4_high_open, dtype="uint32")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(random_st.randint(I_u4_low, I_u4_high_open, dtype="uint32")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(random_st.randint(0, I_u4_high_open, dtype="uint32")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+
+reveal_type(random_st.randint(4294967296, dtype=np.uint32)) # E: int
+reveal_type(random_st.randint(0, 4294967296, dtype=np.uint32)) # E: int
+reveal_type(random_st.randint(I_u4_high_open, dtype=np.uint32)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(random_st.randint(I_u4_low, I_u4_high_open, dtype=np.uint32)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+reveal_type(random_st.randint(0, I_u4_high_open, dtype=np.uint32)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]]
+
+reveal_type(random_st.randint(4294967296, dtype=np.uint)) # E: int
+reveal_type(random_st.randint(0, 4294967296, dtype=np.uint)) # E: int
+reveal_type(random_st.randint(I_u4_high_open, dtype=np.uint)) # E: numpy.ndarray[Any, numpy.dtype[{uint}]]
+reveal_type(random_st.randint(I_u4_low, I_u4_high_open, dtype=np.uint)) # E: numpy.ndarray[Any, numpy.dtype[{uint}]]
+reveal_type(random_st.randint(0, I_u4_high_open, dtype=np.uint)) # E: numpy.ndarray[Any, numpy.dtype[{uint}]]
+
+reveal_type(random_st.randint(18446744073709551616, dtype="u8")) # E: int
+reveal_type(random_st.randint(0, 18446744073709551616, dtype="u8")) # E: int
+reveal_type(random_st.randint(I_u8_high_open, dtype="u8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(random_st.randint(I_u8_low, I_u8_high_open, dtype="u8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(random_st.randint(0, I_u8_high_open, dtype="u8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+
+reveal_type(random_st.randint(18446744073709551616, dtype="uint64")) # E: int
+reveal_type(random_st.randint(0, 18446744073709551616, dtype="uint64")) # E: int
+reveal_type(random_st.randint(I_u8_high_open, dtype="uint64")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(random_st.randint(I_u8_low, I_u8_high_open, dtype="uint64")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(random_st.randint(0, I_u8_high_open, dtype="uint64")) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+
+reveal_type(random_st.randint(18446744073709551616, dtype=np.uint64)) # E: int
+reveal_type(random_st.randint(0, 18446744073709551616, dtype=np.uint64)) # E: int
+reveal_type(random_st.randint(I_u8_high_open, dtype=np.uint64)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(random_st.randint(I_u8_low, I_u8_high_open, dtype=np.uint64)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+reveal_type(random_st.randint(0, I_u8_high_open, dtype=np.uint64)) # E: numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._64Bit]]]
+
+reveal_type(random_st.randint(128, dtype="i1")) # E: int
+reveal_type(random_st.randint(-128, 128, dtype="i1")) # E: int
+reveal_type(random_st.randint(I_i1_high_open, dtype="i1")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(random_st.randint(I_i1_low, I_i1_high_open, dtype="i1")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(random_st.randint(-128, I_i1_high_open, dtype="i1")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+
+reveal_type(random_st.randint(128, dtype="int8")) # E: int
+reveal_type(random_st.randint(-128, 128, dtype="int8")) # E: int
+reveal_type(random_st.randint(I_i1_high_open, dtype="int8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(random_st.randint(I_i1_low, I_i1_high_open, dtype="int8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(random_st.randint(-128, I_i1_high_open, dtype="int8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+
+reveal_type(random_st.randint(128, dtype=np.int8)) # E: int
+reveal_type(random_st.randint(-128, 128, dtype=np.int8)) # E: int
+reveal_type(random_st.randint(I_i1_high_open, dtype=np.int8)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(random_st.randint(I_i1_low, I_i1_high_open, dtype=np.int8)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+reveal_type(random_st.randint(-128, I_i1_high_open, dtype=np.int8)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._8Bit]]]
+
+reveal_type(random_st.randint(32768, dtype="i2")) # E: int
+reveal_type(random_st.randint(-32768, 32768, dtype="i2")) # E: int
+reveal_type(random_st.randint(I_i2_high_open, dtype="i2")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(random_st.randint(I_i2_low, I_i2_high_open, dtype="i2")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(random_st.randint(-32768, I_i2_high_open, dtype="i2")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(random_st.randint(32768, dtype="int16")) # E: int
+reveal_type(random_st.randint(-32768, 32768, dtype="int16")) # E: int
+reveal_type(random_st.randint(I_i2_high_open, dtype="int16")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(random_st.randint(I_i2_low, I_i2_high_open, dtype="int16")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(random_st.randint(-32768, I_i2_high_open, dtype="int16")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(random_st.randint(32768, dtype=np.int16)) # E: int
+reveal_type(random_st.randint(-32768, 32768, dtype=np.int16)) # E: int
+reveal_type(random_st.randint(I_i2_high_open, dtype=np.int16)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(random_st.randint(I_i2_low, I_i2_high_open, dtype=np.int16)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+reveal_type(random_st.randint(-32768, I_i2_high_open, dtype=np.int16)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._16Bit]]]
+
+reveal_type(random_st.randint(2147483648, dtype="i4")) # E: int
+reveal_type(random_st.randint(-2147483648, 2147483648, dtype="i4")) # E: int
+reveal_type(random_st.randint(I_i4_high_open, dtype="i4")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(random_st.randint(I_i4_low, I_i4_high_open, dtype="i4")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(random_st.randint(-2147483648, I_i4_high_open, dtype="i4")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+
+reveal_type(random_st.randint(2147483648, dtype="int32")) # E: int
+reveal_type(random_st.randint(-2147483648, 2147483648, dtype="int32")) # E: int
+reveal_type(random_st.randint(I_i4_high_open, dtype="int32")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(random_st.randint(I_i4_low, I_i4_high_open, dtype="int32")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(random_st.randint(-2147483648, I_i4_high_open, dtype="int32")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+
+reveal_type(random_st.randint(2147483648, dtype=np.int32)) # E: int
+reveal_type(random_st.randint(-2147483648, 2147483648, dtype=np.int32)) # E: int
+reveal_type(random_st.randint(I_i4_high_open, dtype=np.int32)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(random_st.randint(I_i4_low, I_i4_high_open, dtype=np.int32)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+reveal_type(random_st.randint(-2147483648, I_i4_high_open, dtype=np.int32)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._32Bit]]]
+
+reveal_type(random_st.randint(2147483648, dtype=np.int_)) # E: int
+reveal_type(random_st.randint(-2147483648, 2147483648, dtype=np.int_)) # E: int
+reveal_type(random_st.randint(I_i4_high_open, dtype=np.int_)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.randint(I_i4_low, I_i4_high_open, dtype=np.int_)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.randint(-2147483648, I_i4_high_open, dtype=np.int_)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+
+reveal_type(random_st.randint(9223372036854775808, dtype="i8")) # E: int
+reveal_type(random_st.randint(-9223372036854775808, 9223372036854775808, dtype="i8")) # E: int
+reveal_type(random_st.randint(I_i8_high_open, dtype="i8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(random_st.randint(I_i8_low, I_i8_high_open, dtype="i8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(random_st.randint(-9223372036854775808, I_i8_high_open, dtype="i8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+
+reveal_type(random_st.randint(9223372036854775808, dtype="int64")) # E: int
+reveal_type(random_st.randint(-9223372036854775808, 9223372036854775808, dtype="int64")) # E: int
+reveal_type(random_st.randint(I_i8_high_open, dtype="int64")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(random_st.randint(I_i8_low, I_i8_high_open, dtype="int64")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(random_st.randint(-9223372036854775808, I_i8_high_open, dtype="int64")) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+
+reveal_type(random_st.randint(9223372036854775808, dtype=np.int64)) # E: int
+reveal_type(random_st.randint(-9223372036854775808, 9223372036854775808, dtype=np.int64)) # E: int
+reveal_type(random_st.randint(I_i8_high_open, dtype=np.int64)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(random_st.randint(I_i8_low, I_i8_high_open, dtype=np.int64)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+reveal_type(random_st.randint(-9223372036854775808, I_i8_high_open, dtype=np.int64)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[numpy.typing._64Bit]]]
+
+reveal_type(random_st._bit_generator) # E: BitGenerator
+
+reveal_type(random_st.bytes(2)) # E: bytes
+
+reveal_type(random_st.choice(5)) # E: int
+reveal_type(random_st.choice(5, 3)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.choice(5, 3, replace=True)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.choice(5, 3, p=[1 / 5] * 5)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.choice(5, 3, p=[1 / 5] * 5, replace=False)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+
+reveal_type(random_st.choice(["pooh", "rabbit", "piglet", "Christopher"])) # E: Any
+reveal_type(random_st.choice(["pooh", "rabbit", "piglet", "Christopher"], 3)) # E: numpy.ndarray[Any, Any]
+reveal_type(random_st.choice(["pooh", "rabbit", "piglet", "Christopher"], 3, p=[1 / 4] * 4)) # E: numpy.ndarray[Any, Any]
+reveal_type(random_st.choice(["pooh", "rabbit", "piglet", "Christopher"], 3, replace=True)) # E: numpy.ndarray[Any, Any]
+reveal_type(random_st.choice(["pooh", "rabbit", "piglet", "Christopher"], 3, replace=False, p=np.array([1 / 8, 1 / 8, 1 / 2, 1 / 4]))) # E: numpy.ndarray[Any, Any]
+
+reveal_type(random_st.dirichlet([0.5, 0.5])) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.dirichlet(np.array([0.5, 0.5]))) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.dirichlet(np.array([0.5, 0.5]), size=3)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.multinomial(20, [1 / 6.0] * 6)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.multinomial(20, np.array([0.5, 0.5]))) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.multinomial(20, [1 / 6.0] * 6, size=2)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+
+reveal_type(random_st.multivariate_normal([0.0], [[1.0]])) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.multivariate_normal([0.0], np.array([[1.0]]))) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.multivariate_normal(np.array([0.0]), [[1.0]])) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.multivariate_normal([0.0], np.array([[1.0]]))) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.permutation(10)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.permutation([1, 2, 3, 4])) # E: numpy.ndarray[Any, Any]
+reveal_type(random_st.permutation(np.array([1, 2, 3, 4]))) # E: numpy.ndarray[Any, Any]
+reveal_type(random_st.permutation(D_2D)) # E: numpy.ndarray[Any, Any]
+
+reveal_type(random_st.shuffle(np.arange(10))) # E: None
+reveal_type(random_st.shuffle([1, 2, 3, 4, 5])) # E: None
+reveal_type(random_st.shuffle(D_2D)) # E: None
+
+reveal_type(np.random.RandomState(pcg64)) # E: RandomState
+reveal_type(np.random.RandomState(0)) # E: RandomState
+reveal_type(np.random.RandomState([0, 1, 2])) # E: RandomState
+reveal_type(random_st.__str__()) # E: str
+reveal_type(random_st.__repr__()) # E: str
+random_st_state = random_st.__getstate__()
+reveal_type(random_st_state) # E: builtins.dict[builtins.str, Any]
+reveal_type(random_st.__setstate__(random_st_state)) # E: None
+reveal_type(random_st.seed()) # E: None
+reveal_type(random_st.seed(1)) # E: None
+reveal_type(random_st.seed([0, 1])) # E: None
+random_st_get_state = random_st.get_state()
+reveal_type(random_st_state) # E: builtins.dict[builtins.str, Any]
+random_st_get_state_legacy = random_st.get_state(legacy=True)
+reveal_type(random_st_get_state_legacy) # E: Union[builtins.dict[builtins.str, Any], Tuple[builtins.str, numpy.ndarray[Any, numpy.dtype[numpy.unsignedinteger[numpy.typing._32Bit]]], builtins.int, builtins.int, builtins.float]]
+reveal_type(random_st.set_state(random_st_get_state)) # E: None
+
+reveal_type(random_st.rand()) # E: float
+reveal_type(random_st.rand(1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.rand(1, 2)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.randn()) # E: float
+reveal_type(random_st.randn(1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.randn(1, 2)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.random_sample()) # E: float
+reveal_type(random_st.random_sample(1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+reveal_type(random_st.random_sample(size=(1, 2))) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[numpy.typing._64Bit]]
+
+reveal_type(random_st.tomaxint()) # E: int
+reveal_type(random_st.tomaxint(1)) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
+reveal_type(random_st.tomaxint((1,))) # E: numpy.ndarray[Any, numpy.dtype[{int_}]]
diff --git a/numpy/typing/tests/data/reveal/scalars.py b/numpy/typing/tests/data/reveal/scalars.py
index e887e302d..c36813004 100644
--- a/numpy/typing/tests/data/reveal/scalars.py
+++ b/numpy/typing/tests/data/reveal/scalars.py
@@ -1,28 +1,158 @@
+import sys
import numpy as np
-x = np.complex64(3 + 2j)
+b: np.bool_
+u8: np.uint64
+i8: np.int64
+f8: np.float64
+c8: np.complex64
+c16: np.complex128
+m: np.timedelta64
+U: np.str_
+S: np.bytes_
-reveal_type(x.real) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(x.imag) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(c8.real) # E: {float32}
+reveal_type(c8.imag) # E: {float32}
-reveal_type(x.real.real) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(x.real.imag) # E: numpy.floating[numpy.typing._32Bit]
+reveal_type(c8.real.real) # E: {float32}
+reveal_type(c8.real.imag) # E: {float32}
-reveal_type(x.itemsize) # E: int
-reveal_type(x.shape) # E: Tuple[]
-reveal_type(x.strides) # E: Tuple[]
+reveal_type(c8.itemsize) # E: int
+reveal_type(c8.shape) # E: Tuple[]
+reveal_type(c8.strides) # E: Tuple[]
-reveal_type(x.ndim) # E: Literal[0]
-reveal_type(x.size) # E: Literal[1]
+reveal_type(c8.ndim) # E: Literal[0]
+reveal_type(c8.size) # E: Literal[1]
-reveal_type(x.squeeze()) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
-reveal_type(x.byteswap()) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
-reveal_type(x.transpose()) # E: numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]
+reveal_type(c8.squeeze()) # E: {complex64}
+reveal_type(c8.byteswap()) # E: {complex64}
+reveal_type(c8.transpose()) # E: {complex64}
-reveal_type(x.dtype) # E: numpy.dtype[numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]]
+reveal_type(c8.dtype) # E: numpy.dtype[{complex64}]
-reveal_type(np.complex64().real) # E: numpy.floating[numpy.typing._32Bit]
-reveal_type(np.complex128().imag) # E: numpy.floating[numpy.typing._64Bit]
+reveal_type(c8.real) # E: {float32}
+reveal_type(c16.imag) # E: {float64}
reveal_type(np.unicode_('foo')) # E: numpy.str_
reveal_type(np.str0('foo')) # E: numpy.str_
+
+# Aliases
+reveal_type(np.unicode_()) # E: numpy.str_
+reveal_type(np.str0()) # E: numpy.str_
+reveal_type(np.bool8()) # E: numpy.bool_
+reveal_type(np.bytes0()) # E: numpy.bytes_
+reveal_type(np.string_()) # E: numpy.bytes_
+reveal_type(np.object0()) # E: numpy.object_
+reveal_type(np.void0(0)) # E: numpy.void
+
+reveal_type(np.byte()) # E: {byte}
+reveal_type(np.short()) # E: {short}
+reveal_type(np.intc()) # E: {intc}
+reveal_type(np.intp()) # E: {intp}
+reveal_type(np.int0()) # E: {intp}
+reveal_type(np.int_()) # E: {int_}
+reveal_type(np.longlong()) # E: {longlong}
+
+reveal_type(np.ubyte()) # E: {ubyte}
+reveal_type(np.ushort()) # E: {ushort}
+reveal_type(np.uintc()) # E: {uintc}
+reveal_type(np.uintp()) # E: {uintp}
+reveal_type(np.uint0()) # E: {uintp}
+reveal_type(np.uint()) # E: {uint}
+reveal_type(np.ulonglong()) # E: {ulonglong}
+
+reveal_type(np.half()) # E: {half}
+reveal_type(np.single()) # E: {single}
+reveal_type(np.double()) # E: {double}
+reveal_type(np.float_()) # E: {double}
+reveal_type(np.longdouble()) # E: {longdouble}
+reveal_type(np.longfloat()) # E: {longdouble}
+
+reveal_type(np.csingle()) # E: {csingle}
+reveal_type(np.singlecomplex()) # E: {csingle}
+reveal_type(np.cdouble()) # E: {cdouble}
+reveal_type(np.complex_()) # E: {cdouble}
+reveal_type(np.cfloat()) # E: {cdouble}
+reveal_type(np.clongdouble()) # E: {clongdouble}
+reveal_type(np.clongfloat()) # E: {clongdouble}
+reveal_type(np.longcomplex()) # E: {clongdouble}
+
+reveal_type(b.item()) # E: bool
+reveal_type(i8.item()) # E: int
+reveal_type(u8.item()) # E: int
+reveal_type(f8.item()) # E: float
+reveal_type(c16.item()) # E: complex
+reveal_type(U.item()) # E: str
+reveal_type(S.item()) # E: bytes
+
+reveal_type(b.tolist()) # E: bool
+reveal_type(i8.tolist()) # E: int
+reveal_type(u8.tolist()) # E: int
+reveal_type(f8.tolist()) # E: float
+reveal_type(c16.tolist()) # E: complex
+reveal_type(U.tolist()) # E: str
+reveal_type(S.tolist()) # E: bytes
+
+reveal_type(b.ravel()) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(i8.ravel()) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(u8.ravel()) # E: numpy.ndarray[Any, numpy.dtype[{uint64}]]
+reveal_type(f8.ravel()) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(c16.ravel()) # E: numpy.ndarray[Any, numpy.dtype[{complex128}]]
+reveal_type(U.ravel()) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
+reveal_type(S.ravel()) # E: numpy.ndarray[Any, numpy.dtype[numpy.bytes_]]
+
+reveal_type(b.flatten()) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(i8.flatten()) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(u8.flatten()) # E: numpy.ndarray[Any, numpy.dtype[{uint64}]]
+reveal_type(f8.flatten()) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(c16.flatten()) # E: numpy.ndarray[Any, numpy.dtype[{complex128}]]
+reveal_type(U.flatten()) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
+reveal_type(S.flatten()) # E: numpy.ndarray[Any, numpy.dtype[numpy.bytes_]]
+
+reveal_type(b.reshape(1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(i8.reshape(1)) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(u8.reshape(1)) # E: numpy.ndarray[Any, numpy.dtype[{uint64}]]
+reveal_type(f8.reshape(1)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(c16.reshape(1)) # E: numpy.ndarray[Any, numpy.dtype[{complex128}]]
+reveal_type(U.reshape(1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
+reveal_type(S.reshape(1)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bytes_]]
+
+reveal_type(i8.astype(float)) # E: Any
+reveal_type(i8.astype(np.float64)) # E: {float64}
+
+reveal_type(i8.view()) # E: {int64}
+reveal_type(i8.view(np.float64)) # E: {float64}
+reveal_type(i8.view(float)) # E: Any
+reveal_type(i8.view(np.float64, np.ndarray)) # E: {float64}
+
+reveal_type(i8.getfield(float)) # E: Any
+reveal_type(i8.getfield(np.float64)) # E: {float64}
+reveal_type(i8.getfield(np.float64, 8)) # E: {float64}
+
+reveal_type(f8.as_integer_ratio()) # E: Tuple[builtins.int, builtins.int]
+reveal_type(f8.is_integer()) # E: bool
+reveal_type(f8.__trunc__()) # E: int
+reveal_type(f8.__getformat__("float")) # E: str
+reveal_type(f8.hex()) # E: str
+reveal_type(np.float64.fromhex("0x0.0p+0")) # E: {float64}
+
+reveal_type(f8.__getnewargs__()) # E: Tuple[builtins.float]
+reveal_type(c16.__getnewargs__()) # E: Tuple[builtins.float, builtins.float]
+
+reveal_type(i8.numerator) # E: {int64}
+reveal_type(i8.denominator) # E: Literal[1]
+reveal_type(u8.numerator) # E: {uint64}
+reveal_type(u8.denominator) # E: Literal[1]
+reveal_type(m.numerator) # E: numpy.timedelta64
+reveal_type(m.denominator) # E: Literal[1]
+
+reveal_type(round(i8)) # E: int
+reveal_type(round(i8, 3)) # E: {int64}
+reveal_type(round(u8)) # E: int
+reveal_type(round(u8, 3)) # E: {uint64}
+reveal_type(round(f8)) # E: int
+reveal_type(round(f8, 3)) # E: {float64}
+
+if sys.version_info >= (3, 9):
+ reveal_type(f8.__ceil__()) # E: int
+ reveal_type(f8.__floor__()) # E: int
diff --git a/numpy/typing/tests/data/reveal/shape_base.py b/numpy/typing/tests/data/reveal/shape_base.py
new file mode 100644
index 000000000..57633defb
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/shape_base.py
@@ -0,0 +1,57 @@
+import numpy as np
+from numpy.typing import NDArray
+from typing import Any, List
+
+i8: np.int64
+f8: np.float64
+
+AR_b: NDArray[np.bool_]
+AR_i8: NDArray[np.int64]
+AR_f8: NDArray[np.float64]
+
+AR_LIKE_f8: List[float]
+
+reveal_type(np.take_along_axis(AR_f8, AR_i8, axis=1)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.take_along_axis(f8, AR_i8, axis=None)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+
+reveal_type(np.put_along_axis(AR_f8, AR_i8, "1.0", axis=1)) # E: None
+
+reveal_type(np.expand_dims(AR_i8, 2)) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.expand_dims(AR_LIKE_f8, 2)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.column_stack([AR_i8])) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.column_stack([AR_LIKE_f8])) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.dstack([AR_i8])) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.dstack([AR_LIKE_f8])) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.row_stack([AR_i8])) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.row_stack([AR_LIKE_f8])) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.array_split(AR_i8, [3, 5, 6, 10])) # E: list[numpy.ndarray[Any, numpy.dtype[{int64}]]]
+reveal_type(np.array_split(AR_LIKE_f8, [3, 5, 6, 10])) # E: list[numpy.ndarray[Any, numpy.dtype[Any]]]
+
+reveal_type(np.split(AR_i8, [3, 5, 6, 10])) # E: list[numpy.ndarray[Any, numpy.dtype[{int64}]]]
+reveal_type(np.split(AR_LIKE_f8, [3, 5, 6, 10])) # E: list[numpy.ndarray[Any, numpy.dtype[Any]]]
+
+reveal_type(np.hsplit(AR_i8, [3, 5, 6, 10])) # E: list[numpy.ndarray[Any, numpy.dtype[{int64}]]]
+reveal_type(np.hsplit(AR_LIKE_f8, [3, 5, 6, 10])) # E: list[numpy.ndarray[Any, numpy.dtype[Any]]]
+
+reveal_type(np.vsplit(AR_i8, [3, 5, 6, 10])) # E: list[numpy.ndarray[Any, numpy.dtype[{int64}]]]
+reveal_type(np.vsplit(AR_LIKE_f8, [3, 5, 6, 10])) # E: list[numpy.ndarray[Any, numpy.dtype[Any]]]
+
+reveal_type(np.dsplit(AR_i8, [3, 5, 6, 10])) # E: list[numpy.ndarray[Any, numpy.dtype[{int64}]]]
+reveal_type(np.dsplit(AR_LIKE_f8, [3, 5, 6, 10])) # E: list[numpy.ndarray[Any, numpy.dtype[Any]]]
+
+reveal_type(np.lib.shape_base.get_array_prepare(AR_i8)) # E: numpy.lib.shape_base._ArrayPrepare
+reveal_type(np.lib.shape_base.get_array_prepare(AR_i8, 1)) # E: Union[None, numpy.lib.shape_base._ArrayPrepare]
+
+reveal_type(np.get_array_wrap(AR_i8)) # E: numpy.lib.shape_base._ArrayWrap
+reveal_type(np.get_array_wrap(AR_i8, 1)) # E: Union[None, numpy.lib.shape_base._ArrayWrap]
+
+reveal_type(np.kron(AR_b, AR_b)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.kron(AR_b, AR_i8)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(np.kron(AR_f8, AR_f8)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+
+reveal_type(np.tile(AR_i8, 5)) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.tile(AR_LIKE_f8, [2, 2])) # E: numpy.ndarray[Any, numpy.dtype[Any]]
diff --git a/numpy/typing/tests/data/reveal/testing.py b/numpy/typing/tests/data/reveal/testing.py
new file mode 100644
index 000000000..2b040ff60
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/testing.py
@@ -0,0 +1,173 @@
+from __future__ import annotations
+
+import re
+import sys
+from typing import Any, Callable, TypeVar
+from pathlib import Path
+
+import numpy as np
+import numpy.typing as npt
+
+AR_f8: npt.NDArray[np.float64]
+AR_i8: npt.NDArray[np.int64]
+
+bool_obj: bool
+suppress_obj: np.testing.suppress_warnings
+FT = TypeVar("FT", bound=Callable[..., Any])
+
+def func() -> int: ...
+
+def func2(
+ x: npt.NDArray[np.number[Any]],
+ y: npt.NDArray[np.number[Any]],
+) -> npt.NDArray[np.bool_]: ...
+
+reveal_type(np.testing.KnownFailureException()) # E: KnownFailureException
+reveal_type(np.testing.IgnoreException()) # E: IgnoreException
+
+reveal_type(np.testing.clear_and_catch_warnings(modules=[np.testing])) # E: _clear_and_catch_warnings_without_records
+reveal_type(np.testing.clear_and_catch_warnings(True)) # E: _clear_and_catch_warnings_with_records
+reveal_type(np.testing.clear_and_catch_warnings(False)) # E: _clear_and_catch_warnings_without_records
+reveal_type(np.testing.clear_and_catch_warnings(bool_obj)) # E: clear_and_catch_warnings
+reveal_type(np.testing.clear_and_catch_warnings.class_modules) # E: tuple[types.ModuleType]
+reveal_type(np.testing.clear_and_catch_warnings.modules) # E: set[types.ModuleType]
+
+with np.testing.clear_and_catch_warnings(True) as c1:
+ reveal_type(c1) # E: builtins.list[warnings.WarningMessage]
+with np.testing.clear_and_catch_warnings() as c2:
+ reveal_type(c2) # E: None
+
+reveal_type(np.testing.suppress_warnings("once")) # E: suppress_warnings
+reveal_type(np.testing.suppress_warnings()(func)) # E: def () -> builtins.int
+reveal_type(suppress_obj.filter(RuntimeWarning)) # E: None
+reveal_type(suppress_obj.record(RuntimeWarning)) # E: list[warnings.WarningMessage]
+with suppress_obj as c3:
+ reveal_type(c3) # E: suppress_warnings
+
+reveal_type(np.testing.verbose) # E: int
+reveal_type(np.testing.IS_PYPY) # E: bool
+reveal_type(np.testing.HAS_REFCOUNT) # E: bool
+reveal_type(np.testing.HAS_LAPACK64) # E: bool
+
+reveal_type(np.testing.assert_(1, msg="test")) # E: None
+reveal_type(np.testing.assert_(2, msg=lambda: "test")) # E: None
+
+if sys.platform == "win32" or sys.platform == "cygwin":
+ reveal_type(np.testing.memusage()) # E: builtins.int
+elif sys.platform == "linux":
+ reveal_type(np.testing.memusage()) # E: Union[None, builtins.int]
+else:
+ reveal_type(np.testing.memusage()) # E: <nothing>
+
+reveal_type(np.testing.jiffies()) # E: builtins.int
+
+reveal_type(np.testing.build_err_msg([0, 1, 2], "test")) # E: str
+reveal_type(np.testing.build_err_msg(range(2), "test", header="header")) # E: str
+reveal_type(np.testing.build_err_msg(np.arange(9).reshape(3, 3), "test", verbose=False)) # E: str
+reveal_type(np.testing.build_err_msg("abc", "test", names=["x", "y"])) # E: str
+reveal_type(np.testing.build_err_msg([1.0, 2.0], "test", precision=5)) # E: str
+
+reveal_type(np.testing.assert_equal({1}, {1})) # E: None
+reveal_type(np.testing.assert_equal([1, 2, 3], [1, 2, 3], err_msg="fail")) # E: None
+reveal_type(np.testing.assert_equal(1, 1.0, verbose=True)) # E: None
+
+reveal_type(np.testing.print_assert_equal('Test XYZ of func xyz', [0, 1], [0, 1])) # E: None
+
+reveal_type(np.testing.assert_almost_equal(1.0, 1.1)) # E: None
+reveal_type(np.testing.assert_almost_equal([1, 2, 3], [1, 2, 3], err_msg="fail")) # E: None
+reveal_type(np.testing.assert_almost_equal(1, 1.0, verbose=True)) # E: None
+reveal_type(np.testing.assert_almost_equal(1, 1.0001, decimal=2)) # E: None
+
+reveal_type(np.testing.assert_approx_equal(1.0, 1.1)) # E: None
+reveal_type(np.testing.assert_approx_equal("1", "2", err_msg="fail")) # E: None
+reveal_type(np.testing.assert_approx_equal(1, 1.0, verbose=True)) # E: None
+reveal_type(np.testing.assert_approx_equal(1, 1.0001, significant=2)) # E: None
+
+reveal_type(np.testing.assert_array_compare(func2, AR_i8, AR_f8, err_msg="test")) # E: None
+reveal_type(np.testing.assert_array_compare(func2, AR_i8, AR_f8, verbose=True)) # E: None
+reveal_type(np.testing.assert_array_compare(func2, AR_i8, AR_f8, header="header")) # E: None
+reveal_type(np.testing.assert_array_compare(func2, AR_i8, AR_f8, precision=np.int64())) # E: None
+reveal_type(np.testing.assert_array_compare(func2, AR_i8, AR_f8, equal_nan=False)) # E: None
+reveal_type(np.testing.assert_array_compare(func2, AR_i8, AR_f8, equal_inf=True)) # E: None
+
+reveal_type(np.testing.assert_array_equal(AR_i8, AR_f8)) # E: None
+reveal_type(np.testing.assert_array_equal(AR_i8, AR_f8, err_msg="test")) # E: None
+reveal_type(np.testing.assert_array_equal(AR_i8, AR_f8, verbose=True)) # E: None
+
+reveal_type(np.testing.assert_array_almost_equal(AR_i8, AR_f8)) # E: None
+reveal_type(np.testing.assert_array_almost_equal(AR_i8, AR_f8, err_msg="test")) # E: None
+reveal_type(np.testing.assert_array_almost_equal(AR_i8, AR_f8, verbose=True)) # E: None
+reveal_type(np.testing.assert_array_almost_equal(AR_i8, AR_f8, decimal=1)) # E: None
+
+reveal_type(np.testing.assert_array_less(AR_i8, AR_f8)) # E: None
+reveal_type(np.testing.assert_array_less(AR_i8, AR_f8, err_msg="test")) # E: None
+reveal_type(np.testing.assert_array_less(AR_i8, AR_f8, verbose=True)) # E: None
+
+reveal_type(np.testing.runstring("1 + 1", {})) # E: Any
+reveal_type(np.testing.runstring("int64() + 1", {"int64": np.int64})) # E: Any
+
+reveal_type(np.testing.assert_string_equal("1", "1")) # E: None
+
+reveal_type(np.testing.rundocs()) # E: None
+reveal_type(np.testing.rundocs("test.py")) # E: None
+reveal_type(np.testing.rundocs(Path("test.py"), raise_on_error=True)) # E: None
+
+@np.testing.raises(RuntimeError, RuntimeWarning)
+def func3(a: int) -> bool: ...
+
+reveal_type(func3) # E: def (a: builtins.int) -> builtins.bool
+
+reveal_type(np.testing.assert_raises(RuntimeWarning)) # E: _AssertRaisesContext[builtins.RuntimeWarning]
+reveal_type(np.testing.assert_raises(RuntimeWarning, func3, 5)) # E: None
+
+reveal_type(np.testing.assert_raises_regex(RuntimeWarning, r"test")) # E: _AssertRaisesContext[builtins.RuntimeWarning]
+reveal_type(np.testing.assert_raises_regex(RuntimeWarning, b"test", func3, 5)) # E: None
+reveal_type(np.testing.assert_raises_regex(RuntimeWarning, re.compile(b"test"), func3, 5)) # E: None
+
+class Test: ...
+
+def decorate(a: FT) -> FT:
+ return a
+
+reveal_type(np.testing.decorate_methods(Test, decorate)) # E: None
+reveal_type(np.testing.decorate_methods(Test, decorate, None)) # E: None
+reveal_type(np.testing.decorate_methods(Test, decorate, "test")) # E: None
+reveal_type(np.testing.decorate_methods(Test, decorate, b"test")) # E: None
+reveal_type(np.testing.decorate_methods(Test, decorate, re.compile("test"))) # E: None
+
+reveal_type(np.testing.measure("for i in range(1000): np.sqrt(i**2)")) # E: float
+reveal_type(np.testing.measure(b"for i in range(1000): np.sqrt(i**2)", times=5)) # E: float
+
+reveal_type(np.testing.assert_allclose(AR_i8, AR_f8)) # E: None
+reveal_type(np.testing.assert_allclose(AR_i8, AR_f8, rtol=0.005)) # E: None
+reveal_type(np.testing.assert_allclose(AR_i8, AR_f8, atol=1)) # E: None
+reveal_type(np.testing.assert_allclose(AR_i8, AR_f8, equal_nan=True)) # E: None
+reveal_type(np.testing.assert_allclose(AR_i8, AR_f8, err_msg="err")) # E: None
+reveal_type(np.testing.assert_allclose(AR_i8, AR_f8, verbose=False)) # E: None
+
+reveal_type(np.testing.assert_array_almost_equal_nulp(AR_i8, AR_f8, nulp=2)) # E: None
+
+reveal_type(np.testing.assert_array_max_ulp(AR_i8, AR_f8, maxulp=2)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+reveal_type(np.testing.assert_array_max_ulp(AR_i8, AR_f8, dtype=np.float32)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.testing.assert_warns(RuntimeWarning)) # E: _GeneratorContextManager[None]
+reveal_type(np.testing.assert_warns(RuntimeWarning, func3, 5)) # E: bool
+
+reveal_type(np.testing.assert_no_warnings()) # E: _GeneratorContextManager[None]
+reveal_type(np.testing.assert_no_warnings(func3, 5)) # E: bool
+
+reveal_type(np.testing.tempdir("test_dir")) # E: _GeneratorContextManager[builtins.str]
+reveal_type(np.testing.tempdir(prefix=b"test")) # E: _GeneratorContextManager[builtins.bytes]
+reveal_type(np.testing.tempdir("test_dir", dir=Path("here"))) # E: _GeneratorContextManager[builtins.str]
+
+reveal_type(np.testing.temppath("test_dir", text=True)) # E: _GeneratorContextManager[builtins.str]
+reveal_type(np.testing.temppath(prefix=b"test")) # E: _GeneratorContextManager[builtins.bytes]
+reveal_type(np.testing.temppath("test_dir", dir=Path("here"))) # E: _GeneratorContextManager[builtins.str]
+
+reveal_type(np.testing.assert_no_gc_cycles()) # E: _GeneratorContextManager[None]
+reveal_type(np.testing.assert_no_gc_cycles(func3, 5)) # E: None
+
+reveal_type(np.testing.break_cycles()) # E: None
+
+reveal_type(np.testing.TestCase()) # E: unittest.case.TestCase
+reveal_type(np.testing.run_module_suite(file_to_run="numpy/tests/test_matlib.py")) # E: None
diff --git a/numpy/typing/tests/data/reveal/twodim_base.py b/numpy/typing/tests/data/reveal/twodim_base.py
new file mode 100644
index 000000000..b95fbc71e
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/twodim_base.py
@@ -0,0 +1,72 @@
+from typing import Any, List, TypeVar
+
+import numpy as np
+import numpy.typing as npt
+
+_SCT = TypeVar("_SCT", bound=np.generic)
+
+
+def func1(ar: npt.NDArray[_SCT], a: int) -> npt.NDArray[_SCT]:
+ pass
+
+
+def func2(ar: npt.NDArray[np.number[Any]], a: str) -> npt.NDArray[np.float64]:
+ pass
+
+
+AR_b: npt.NDArray[np.bool_]
+AR_u: npt.NDArray[np.uint64]
+AR_i: npt.NDArray[np.int64]
+AR_f: npt.NDArray[np.float64]
+AR_c: npt.NDArray[np.complex128]
+AR_O: npt.NDArray[np.object_]
+
+AR_LIKE_b: List[bool]
+
+reveal_type(np.fliplr(AR_b)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.fliplr(AR_LIKE_b)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.flipud(AR_b)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.flipud(AR_LIKE_b)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.eye(10)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.eye(10, M=20, dtype=np.int64)) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.eye(10, k=2, dtype=int)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.diag(AR_b)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.diag(AR_LIKE_b, k=0)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.diagflat(AR_b)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.diagflat(AR_LIKE_b, k=0)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.tri(10)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.tri(10, M=20, dtype=np.int64)) # E: numpy.ndarray[Any, numpy.dtype[{int64}]]
+reveal_type(np.tri(10, k=2, dtype=int)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.tril(AR_b)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.tril(AR_LIKE_b, k=0)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.triu(AR_b)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.triu(AR_LIKE_b, k=0)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.vander(AR_b)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(np.vander(AR_u)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(np.vander(AR_i, N=2)) # E: numpy.ndarray[Any, numpy.dtype[numpy.signedinteger[Any]]]
+reveal_type(np.vander(AR_f, increasing=True)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(np.vander(AR_c)) # E: numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]
+reveal_type(np.vander(AR_O)) # E: numpy.ndarray[Any, numpy.dtype[numpy.object_]]
+
+reveal_type(np.histogram2d(AR_i, AR_b)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[{float64}]], numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]], numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]]
+reveal_type(np.histogram2d(AR_f, AR_f)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[{float64}]], numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]], numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]]
+reveal_type(np.histogram2d(AR_f, AR_c, weights=AR_LIKE_b)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[{float64}]], numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]], numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]]
+
+reveal_type(np.mask_indices(10, func1)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[{intp}]], numpy.ndarray[Any, numpy.dtype[{intp}]]]
+reveal_type(np.mask_indices(8, func2, "0")) # E: Tuple[numpy.ndarray[Any, numpy.dtype[{intp}]], numpy.ndarray[Any, numpy.dtype[{intp}]]]
+
+reveal_type(np.tril_indices(10)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[{int_}]], numpy.ndarray[Any, numpy.dtype[{int_}]]]
+
+reveal_type(np.tril_indices_from(AR_b)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[{int_}]], numpy.ndarray[Any, numpy.dtype[{int_}]]]
+
+reveal_type(np.triu_indices(10)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[{int_}]], numpy.ndarray[Any, numpy.dtype[{int_}]]]
+
+reveal_type(np.triu_indices_from(AR_b)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[{int_}]], numpy.ndarray[Any, numpy.dtype[{int_}]]]
diff --git a/numpy/typing/tests/data/reveal/type_check.py b/numpy/typing/tests/data/reveal/type_check.py
new file mode 100644
index 000000000..416dd42a8
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/type_check.py
@@ -0,0 +1,73 @@
+from typing import List
+import numpy as np
+import numpy.typing as npt
+
+f8: np.float64
+f: float
+
+# NOTE: Avoid importing the platform specific `np.float128` type
+AR_i8: npt.NDArray[np.int64]
+AR_i4: npt.NDArray[np.int32]
+AR_f2: npt.NDArray[np.float16]
+AR_f8: npt.NDArray[np.float64]
+AR_f16: npt.NDArray[np.floating[npt._128Bit]]
+AR_c8: npt.NDArray[np.complex64]
+AR_c16: npt.NDArray[np.complex128]
+
+AR_LIKE_f: List[float]
+
+class RealObj:
+ real: slice
+
+class ImagObj:
+ imag: slice
+
+reveal_type(np.mintypecode(["f8"], typeset="qfQF"))
+
+reveal_type(np.asfarray(AR_f8)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.asfarray(AR_LIKE_f)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.asfarray(AR_f8, dtype="c16")) # E: numpy.ndarray[Any, numpy.dtype[numpy.complexfloating[Any, Any]]]
+reveal_type(np.asfarray(AR_f8, dtype="i8")) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+
+reveal_type(np.real(RealObj())) # E: slice
+reveal_type(np.real(AR_f8)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.real(AR_c16)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.real(AR_LIKE_f)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.imag(ImagObj())) # E: slice
+reveal_type(np.imag(AR_f8)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.imag(AR_c16)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.imag(AR_LIKE_f)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.iscomplex(f8)) # E: numpy.bool_
+reveal_type(np.iscomplex(AR_f8)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.iscomplex(AR_LIKE_f)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+
+reveal_type(np.isreal(f8)) # E: numpy.bool_
+reveal_type(np.isreal(AR_f8)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.isreal(AR_LIKE_f)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+
+reveal_type(np.iscomplexobj(f8)) # E: bool
+reveal_type(np.isrealobj(f8)) # E: bool
+
+reveal_type(np.nan_to_num(f8)) # E: {float64}
+reveal_type(np.nan_to_num(f, copy=True)) # E: Any
+reveal_type(np.nan_to_num(AR_f8, nan=1.5)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.nan_to_num(AR_LIKE_f, posinf=9999)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.real_if_close(AR_f8)) # E: numpy.ndarray[Any, numpy.dtype[{float64}]]
+reveal_type(np.real_if_close(AR_c16)) # E: Union[numpy.ndarray[Any, numpy.dtype[{float64}]], numpy.ndarray[Any, numpy.dtype[{complex128}]]]
+reveal_type(np.real_if_close(AR_c8)) # E: Union[numpy.ndarray[Any, numpy.dtype[{float32}]], numpy.ndarray[Any, numpy.dtype[{complex64}]]]
+reveal_type(np.real_if_close(AR_LIKE_f)) # E: numpy.ndarray[Any, numpy.dtype[Any]]
+
+reveal_type(np.typename("h")) # E: Literal['short']
+reveal_type(np.typename("B")) # E: Literal['unsigned char']
+reveal_type(np.typename("V")) # E: Literal['void']
+reveal_type(np.typename("S1")) # E: Literal['character']
+
+reveal_type(np.common_type(AR_i4)) # E: Type[{float64}]
+reveal_type(np.common_type(AR_f2)) # E: Type[{float16}]
+reveal_type(np.common_type(AR_f2, AR_i4)) # E: Type[{float64}]
+reveal_type(np.common_type(AR_f16, AR_i4)) # E: Type[{float128}]
+reveal_type(np.common_type(AR_c8, AR_f2)) # E: Type[{complex64}]
+reveal_type(np.common_type(AR_f2, AR_c8, AR_i4)) # E: Type[{complex128}]
diff --git a/numpy/typing/tests/data/reveal/ufunclike.py b/numpy/typing/tests/data/reveal/ufunclike.py
new file mode 100644
index 000000000..8b3aea7ce
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/ufunclike.py
@@ -0,0 +1,29 @@
+from typing import List, Any
+import numpy as np
+
+AR_LIKE_b: List[bool]
+AR_LIKE_u: List[np.uint32]
+AR_LIKE_i: List[int]
+AR_LIKE_f: List[float]
+AR_LIKE_O: List[np.object_]
+
+AR_U: np.ndarray[Any, np.dtype[np.str_]]
+
+reveal_type(np.fix(AR_LIKE_b)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(np.fix(AR_LIKE_u)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(np.fix(AR_LIKE_i)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(np.fix(AR_LIKE_f)) # E: numpy.ndarray[Any, numpy.dtype[numpy.floating[Any]]]
+reveal_type(np.fix(AR_LIKE_O)) # E: Any
+reveal_type(np.fix(AR_LIKE_f, out=AR_U)) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
+
+reveal_type(np.isposinf(AR_LIKE_b)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.isposinf(AR_LIKE_u)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.isposinf(AR_LIKE_i)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.isposinf(AR_LIKE_f)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.isposinf(AR_LIKE_f, out=AR_U)) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
+
+reveal_type(np.isneginf(AR_LIKE_b)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.isneginf(AR_LIKE_u)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.isneginf(AR_LIKE_i)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.isneginf(AR_LIKE_f)) # E: numpy.ndarray[Any, numpy.dtype[numpy.bool_]]
+reveal_type(np.isneginf(AR_LIKE_f, out=AR_U)) # E: numpy.ndarray[Any, numpy.dtype[numpy.str_]]
diff --git a/numpy/typing/tests/data/reveal/ufuncs.py b/numpy/typing/tests/data/reveal/ufuncs.py
new file mode 100644
index 000000000..ade45577c
--- /dev/null
+++ b/numpy/typing/tests/data/reveal/ufuncs.py
@@ -0,0 +1,68 @@
+import numpy as np
+import numpy.typing as npt
+
+f8: np.float64
+AR_f8: npt.NDArray[np.float64]
+AR_i8: npt.NDArray[np.int64]
+
+reveal_type(np.absolute.__doc__) # E: str
+reveal_type(np.absolute.types) # E: builtins.list[builtins.str]
+
+reveal_type(np.absolute.__name__) # E: Literal['absolute']
+reveal_type(np.absolute.ntypes) # E: Literal[20]
+reveal_type(np.absolute.identity) # E: None
+reveal_type(np.absolute.nin) # E: Literal[1]
+reveal_type(np.absolute.nin) # E: Literal[1]
+reveal_type(np.absolute.nout) # E: Literal[1]
+reveal_type(np.absolute.nargs) # E: Literal[2]
+reveal_type(np.absolute.signature) # E: None
+reveal_type(np.absolute(f8)) # E: Any
+reveal_type(np.absolute(AR_f8)) # E: numpy.ndarray
+reveal_type(np.absolute.at(AR_f8, AR_i8)) # E: None
+
+reveal_type(np.add.__name__) # E: Literal['add']
+reveal_type(np.add.ntypes) # E: Literal[22]
+reveal_type(np.add.identity) # E: Literal[0]
+reveal_type(np.add.nin) # E: Literal[2]
+reveal_type(np.add.nout) # E: Literal[1]
+reveal_type(np.add.nargs) # E: Literal[3]
+reveal_type(np.add.signature) # E: None
+reveal_type(np.add(f8, f8)) # E: Any
+reveal_type(np.add(AR_f8, f8)) # E: numpy.ndarray
+reveal_type(np.add.at(AR_f8, AR_i8, f8)) # E: None
+reveal_type(np.add.reduce(AR_f8, axis=0)) # E: Any
+reveal_type(np.add.accumulate(AR_f8)) # E: numpy.ndarray
+reveal_type(np.add.reduceat(AR_f8, AR_i8)) # E: numpy.ndarray
+reveal_type(np.add.outer(f8, f8)) # E: Any
+reveal_type(np.add.outer(AR_f8, f8)) # E: numpy.ndarray
+
+reveal_type(np.frexp.__name__) # E: Literal['frexp']
+reveal_type(np.frexp.ntypes) # E: Literal[4]
+reveal_type(np.frexp.identity) # E: None
+reveal_type(np.frexp.nin) # E: Literal[1]
+reveal_type(np.frexp.nout) # E: Literal[2]
+reveal_type(np.frexp.nargs) # E: Literal[3]
+reveal_type(np.frexp.signature) # E: None
+reveal_type(np.frexp(f8)) # E: Tuple[Any, Any]
+reveal_type(np.frexp(AR_f8)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[Any]], numpy.ndarray[Any, numpy.dtype[Any]]]
+
+reveal_type(np.divmod.__name__) # E: Literal['divmod']
+reveal_type(np.divmod.ntypes) # E: Literal[15]
+reveal_type(np.divmod.identity) # E: None
+reveal_type(np.divmod.nin) # E: Literal[2]
+reveal_type(np.divmod.nout) # E: Literal[2]
+reveal_type(np.divmod.nargs) # E: Literal[4]
+reveal_type(np.divmod.signature) # E: None
+reveal_type(np.divmod(f8, f8)) # E: Tuple[Any, Any]
+reveal_type(np.divmod(AR_f8, f8)) # E: Tuple[numpy.ndarray[Any, numpy.dtype[Any]], numpy.ndarray[Any, numpy.dtype[Any]]]
+
+reveal_type(np.matmul.__name__) # E: Literal['matmul']
+reveal_type(np.matmul.ntypes) # E: Literal[19]
+reveal_type(np.matmul.identity) # E: None
+reveal_type(np.matmul.nin) # E: Literal[2]
+reveal_type(np.matmul.nout) # E: Literal[1]
+reveal_type(np.matmul.nargs) # E: Literal[3]
+reveal_type(np.matmul.signature) # E: Literal['(n?,k),(k,m?)->(n?,m?)']
+reveal_type(np.matmul.identity) # E: None
+reveal_type(np.matmul(AR_f8, AR_f8)) # E: Any
+reveal_type(np.matmul(AR_f8, AR_f8, axes=[(0, 1), (0, 1), (0, 1)])) # E: Any
diff --git a/numpy/typing/tests/data/reveal/warnings_and_errors.py b/numpy/typing/tests/data/reveal/warnings_and_errors.py
index c428deb7a..3f20a0135 100644
--- a/numpy/typing/tests/data/reveal/warnings_and_errors.py
+++ b/numpy/typing/tests/data/reveal/warnings_and_errors.py
@@ -7,4 +7,5 @@ reveal_type(np.VisibleDeprecationWarning()) # E: numpy.VisibleDeprecationWarnin
reveal_type(np.ComplexWarning()) # E: numpy.ComplexWarning
reveal_type(np.RankWarning()) # E: numpy.RankWarning
reveal_type(np.TooHardError()) # E: numpy.TooHardError
-reveal_type(np.AxisError(1)) # E: numpy.AxisError
+reveal_type(np.AxisError("test")) # E: numpy.AxisError
+reveal_type(np.AxisError(5, 1)) # E: numpy.AxisError
diff --git a/numpy/typing/tests/test_generic_alias.py b/numpy/typing/tests/test_generic_alias.py
new file mode 100644
index 000000000..3021d9859
--- /dev/null
+++ b/numpy/typing/tests/test_generic_alias.py
@@ -0,0 +1,128 @@
+from __future__ import annotations
+
+import sys
+import types
+import pickle
+import weakref
+from typing import TypeVar, Any, Callable, Tuple, Type, Union
+
+import pytest
+import numpy as np
+from numpy.typing._generic_alias import _GenericAlias
+
+ScalarType = TypeVar("ScalarType", bound=np.generic, covariant=True)
+T1 = TypeVar("T1")
+T2 = TypeVar("T2")
+DType = _GenericAlias(np.dtype, (ScalarType,))
+NDArray = _GenericAlias(np.ndarray, (Any, DType))
+
+if sys.version_info >= (3, 9):
+ DType_ref = types.GenericAlias(np.dtype, (ScalarType,))
+ NDArray_ref = types.GenericAlias(np.ndarray, (Any, DType_ref))
+ FuncType = Callable[[Union[_GenericAlias, types.GenericAlias]], Any]
+else:
+ DType_ref = Any
+ NDArray_ref = Any
+ FuncType = Callable[[_GenericAlias], Any]
+
+GETATTR_NAMES = sorted(set(dir(np.ndarray)) - _GenericAlias._ATTR_EXCEPTIONS)
+
+BUFFER = np.array([1], dtype=np.int64)
+BUFFER.setflags(write=False)
+
+def _get_subclass_mro(base: type) -> Tuple[type, ...]:
+ class Subclass(base): # type: ignore[misc,valid-type]
+ pass
+ return Subclass.__mro__[1:]
+
+
+class TestGenericAlias:
+ """Tests for `numpy.typing._generic_alias._GenericAlias`."""
+
+ @pytest.mark.parametrize("name,func", [
+ ("__init__", lambda n: n),
+ ("__init__", lambda n: _GenericAlias(np.ndarray, Any)),
+ ("__init__", lambda n: _GenericAlias(np.ndarray, (Any,))),
+ ("__init__", lambda n: _GenericAlias(np.ndarray, (Any, Any))),
+ ("__init__", lambda n: _GenericAlias(np.ndarray, T1)),
+ ("__init__", lambda n: _GenericAlias(np.ndarray, (T1,))),
+ ("__init__", lambda n: _GenericAlias(np.ndarray, (T1, T2))),
+ ("__origin__", lambda n: n.__origin__),
+ ("__args__", lambda n: n.__args__),
+ ("__parameters__", lambda n: n.__parameters__),
+ ("__reduce__", lambda n: n.__reduce__()[1:]),
+ ("__reduce_ex__", lambda n: n.__reduce_ex__(1)[1:]),
+ ("__mro_entries__", lambda n: n.__mro_entries__([object])),
+ ("__hash__", lambda n: hash(n)),
+ ("__repr__", lambda n: repr(n)),
+ ("__getitem__", lambda n: n[np.float64]),
+ ("__getitem__", lambda n: n[ScalarType][np.float64]),
+ ("__getitem__", lambda n: n[Union[np.int64, ScalarType]][np.float64]),
+ ("__getitem__", lambda n: n[Union[T1, T2]][np.float32, np.float64]),
+ ("__eq__", lambda n: n == n),
+ ("__ne__", lambda n: n != np.ndarray),
+ ("__dir__", lambda n: dir(n)),
+ ("__call__", lambda n: n((1,), np.int64, BUFFER)),
+ ("__call__", lambda n: n(shape=(1,), dtype=np.int64, buffer=BUFFER)),
+ ("subclassing", lambda n: _get_subclass_mro(n)),
+ ("pickle", lambda n: n == pickle.loads(pickle.dumps(n))),
+ ])
+ def test_pass(self, name: str, func: FuncType) -> None:
+ """Compare `types.GenericAlias` with its numpy-based backport.
+
+ Checker whether ``func`` runs as intended and that both `GenericAlias`
+ and `_GenericAlias` return the same result.
+
+ """
+ value = func(NDArray)
+
+ if sys.version_info >= (3, 9):
+ value_ref = func(NDArray_ref)
+ assert value == value_ref
+
+ def test_weakref(self) -> None:
+ """Test ``__weakref__``."""
+ value = weakref.ref(NDArray)()
+
+ if sys.version_info >= (3, 9, 1): # xref bpo-42332
+ value_ref = weakref.ref(NDArray_ref)()
+ assert value == value_ref
+
+ @pytest.mark.parametrize("name", GETATTR_NAMES)
+ def test_getattr(self, name: str) -> None:
+ """Test that `getattr` wraps around the underlying type,
+ aka ``__origin__``.
+
+ """
+ value = getattr(NDArray, name)
+ value_ref1 = getattr(np.ndarray, name)
+
+ if sys.version_info >= (3, 9):
+ value_ref2 = getattr(NDArray_ref, name)
+ assert value == value_ref1 == value_ref2
+ else:
+ assert value == value_ref1
+
+ @pytest.mark.parametrize("name,exc_type,func", [
+ ("__getitem__", TypeError, lambda n: n[()]),
+ ("__getitem__", TypeError, lambda n: n[Any, Any]),
+ ("__getitem__", TypeError, lambda n: n[Any][Any]),
+ ("isinstance", TypeError, lambda n: isinstance(np.array(1), n)),
+ ("issublass", TypeError, lambda n: issubclass(np.ndarray, n)),
+ ("setattr", AttributeError, lambda n: setattr(n, "__origin__", int)),
+ ("setattr", AttributeError, lambda n: setattr(n, "test", int)),
+ ("getattr", AttributeError, lambda n: getattr(n, "test")),
+ ])
+ def test_raise(
+ self,
+ name: str,
+ exc_type: Type[BaseException],
+ func: FuncType,
+ ) -> None:
+ """Test operations that are supposed to raise."""
+ with pytest.raises(exc_type):
+ func(NDArray)
+
+ if sys.version_info >= (3, 9):
+ with pytest.raises(exc_type):
+ func(NDArray_ref)
diff --git a/numpy/typing/tests/test_isfile.py b/numpy/typing/tests/test_isfile.py
index 569f05435..b617b3873 100644
--- a/numpy/typing/tests/test_isfile.py
+++ b/numpy/typing/tests/test_isfile.py
@@ -10,7 +10,6 @@ FILES = [
ROOT / "__init__.pyi",
ROOT / "char.pyi",
ROOT / "ctypeslib.pyi",
- ROOT / "emath.pyi",
ROOT / "rec.pyi",
ROOT / "core" / "__init__.pyi",
ROOT / "distutils" / "__init__.pyi",
diff --git a/numpy/typing/tests/test_runtime.py b/numpy/typing/tests/test_runtime.py
new file mode 100644
index 000000000..e82b08ac2
--- /dev/null
+++ b/numpy/typing/tests/test_runtime.py
@@ -0,0 +1,90 @@
+"""Test the runtime usage of `numpy.typing`."""
+
+from __future__ import annotations
+
+import sys
+from typing import get_type_hints, Union, Tuple, NamedTuple
+
+import pytest
+import numpy as np
+import numpy.typing as npt
+
+try:
+ from typing_extensions import get_args, get_origin
+ SKIP = False
+except ImportError:
+ SKIP = True
+
+
+class TypeTup(NamedTuple):
+ typ: type
+ args: Tuple[type, ...]
+ origin: None | type
+
+
+if sys.version_info >= (3, 9):
+ NDArrayTup = TypeTup(npt.NDArray, npt.NDArray.__args__, np.ndarray)
+else:
+ NDArrayTup = TypeTup(npt.NDArray, (), None)
+
+TYPES = {
+ "ArrayLike": TypeTup(npt.ArrayLike, npt.ArrayLike.__args__, Union),
+ "DTypeLike": TypeTup(npt.DTypeLike, npt.DTypeLike.__args__, Union),
+ "NBitBase": TypeTup(npt.NBitBase, (), None),
+ "NDArray": NDArrayTup,
+}
+
+
+@pytest.mark.parametrize("name,tup", TYPES.items(), ids=TYPES.keys())
+@pytest.mark.skipif(SKIP, reason="requires typing-extensions")
+def test_get_args(name: type, tup: TypeTup) -> None:
+ """Test `typing.get_args`."""
+ typ, ref = tup.typ, tup.args
+ out = get_args(typ)
+ assert out == ref
+
+
+@pytest.mark.parametrize("name,tup", TYPES.items(), ids=TYPES.keys())
+@pytest.mark.skipif(SKIP, reason="requires typing-extensions")
+def test_get_origin(name: type, tup: TypeTup) -> None:
+ """Test `typing.get_origin`."""
+ typ, ref = tup.typ, tup.origin
+ out = get_origin(typ)
+ assert out == ref
+
+
+@pytest.mark.parametrize("name,tup", TYPES.items(), ids=TYPES.keys())
+def test_get_type_hints(name: type, tup: TypeTup) -> None:
+ """Test `typing.get_type_hints`."""
+ typ = tup.typ
+
+ # Explicitly set `__annotations__` in order to circumvent the
+ # stringification performed by `from __future__ import annotations`
+ def func(a): pass
+ func.__annotations__ = {"a": typ, "return": None}
+
+ out = get_type_hints(func)
+ ref = {"a": typ, "return": type(None)}
+ assert out == ref
+
+
+@pytest.mark.parametrize("name,tup", TYPES.items(), ids=TYPES.keys())
+def test_get_type_hints_str(name: type, tup: TypeTup) -> None:
+ """Test `typing.get_type_hints` with string-representation of types."""
+ typ_str, typ = f"npt.{name}", tup.typ
+
+ # Explicitly set `__annotations__` in order to circumvent the
+ # stringification performed by `from __future__ import annotations`
+ def func(a): pass
+ func.__annotations__ = {"a": typ_str, "return": None}
+
+ out = get_type_hints(func)
+ ref = {"a": typ, "return": type(None)}
+ assert out == ref
+
+
+def test_keys() -> None:
+ """Test that ``TYPES.keys()`` and ``numpy.typing.__all__`` are synced."""
+ keys = TYPES.keys()
+ ref = set(npt.__all__)
+ assert keys == ref
diff --git a/numpy/typing/tests/test_typing.py b/numpy/typing/tests/test_typing.py
index 90de4fd6d..35558c880 100644
--- a/numpy/typing/tests/test_typing.py
+++ b/numpy/typing/tests/test_typing.py
@@ -2,10 +2,18 @@ import importlib.util
import itertools
import os
import re
+import shutil
from collections import defaultdict
-from typing import Optional
+from typing import Optional, IO, Dict, List
import pytest
+import numpy as np
+from numpy.typing.mypy_plugin import (
+ _PRECISION_DICT,
+ _EXTENDED_PRECISION_LIST,
+ _C_INTP,
+)
+
try:
from mypy import api
except ImportError:
@@ -18,9 +26,64 @@ DATA_DIR = os.path.join(os.path.dirname(__file__), "data")
PASS_DIR = os.path.join(DATA_DIR, "pass")
FAIL_DIR = os.path.join(DATA_DIR, "fail")
REVEAL_DIR = os.path.join(DATA_DIR, "reveal")
+MISC_DIR = os.path.join(DATA_DIR, "misc")
MYPY_INI = os.path.join(DATA_DIR, "mypy.ini")
CACHE_DIR = os.path.join(DATA_DIR, ".mypy_cache")
+#: A dictionary with file names as keys and lists of the mypy stdout as values.
+#: To-be populated by `run_mypy`.
+OUTPUT_MYPY: Dict[str, List[str]] = {}
+
+
+def _key_func(key: str) -> str:
+ """Split at the first occurance of the ``:`` character.
+
+ Windows drive-letters (*e.g.* ``C:``) are ignored herein.
+ """
+ drive, tail = os.path.splitdrive(key)
+ return os.path.join(drive, tail.split(":", 1)[0])
+
+
+def _strip_filename(msg: str) -> str:
+ """Strip the filename from a mypy message."""
+ _, tail = os.path.splitdrive(msg)
+ return tail.split(":", 1)[-1]
+
+
+@pytest.mark.slow
+@pytest.mark.skipif(NO_MYPY, reason="Mypy is not installed")
+@pytest.fixture(scope="module", autouse=True)
+def run_mypy() -> None:
+ """Clears the cache and run mypy before running any of the typing tests.
+
+ The mypy results are cached in `OUTPUT_MYPY` for further use.
+
+ The cache refresh can be skipped using
+
+ NUMPY_TYPING_TEST_CLEAR_CACHE=0 pytest numpy/typing/tests
+ """
+ if os.path.isdir(CACHE_DIR) and bool(os.environ.get("NUMPY_TYPING_TEST_CLEAR_CACHE", True)):
+ shutil.rmtree(CACHE_DIR)
+
+ for directory in (PASS_DIR, REVEAL_DIR, FAIL_DIR, MISC_DIR):
+ # Run mypy
+ stdout, stderr, exit_code = api.run([
+ "--config-file",
+ MYPY_INI,
+ "--cache-dir",
+ CACHE_DIR,
+ directory,
+ ])
+ if stderr:
+ pytest.fail(f"Unexpected mypy standard error\n\n{stderr}")
+ elif exit_code not in {0, 1}:
+ pytest.fail(f"Unexpected mypy exit code: {exit_code}\n\n{stdout}")
+ stdout = stdout.replace('*', '')
+
+ # Parse the output
+ iterator = itertools.groupby(stdout.split("\n"), key=_key_func)
+ OUTPUT_MYPY.update((k, list(v)) for k, v in iterator if k)
+
def get_test_cases(directory):
for root, _, files in os.walk(directory):
@@ -41,15 +104,12 @@ def get_test_cases(directory):
@pytest.mark.skipif(NO_MYPY, reason="Mypy is not installed")
@pytest.mark.parametrize("path", get_test_cases(PASS_DIR))
def test_success(path):
- stdout, stderr, exitcode = api.run([
- "--config-file",
- MYPY_INI,
- "--cache-dir",
- CACHE_DIR,
- path,
- ])
- assert exitcode == 0, stdout
- assert re.match(r"Success: no issues found in \d+ source files?", stdout.strip())
+ # Alias `OUTPUT_MYPY` so that it appears in the local namespace
+ output_mypy = OUTPUT_MYPY
+ if path in output_mypy:
+ msg = "Unexpected mypy output\n\n"
+ msg += "\n".join(_strip_filename(v) for v in output_mypy[path])
+ raise AssertionError(msg)
@pytest.mark.slow
@@ -58,37 +118,23 @@ def test_success(path):
def test_fail(path):
__tracebackhide__ = True
- stdout, stderr, exitcode = api.run([
- "--config-file",
- MYPY_INI,
- "--cache-dir",
- CACHE_DIR,
- path,
- ])
- assert exitcode != 0
-
with open(path) as fin:
lines = fin.readlines()
errors = defaultdict(lambda: "")
- error_lines = stdout.rstrip("\n").split("\n")
- assert re.match(
- r"Found \d+ errors? in \d+ files? \(checked \d+ source files?\)",
- error_lines[-1].strip(),
- )
- for error_line in error_lines[:-1]:
- error_line = error_line.strip()
- if not error_line:
- continue
+ output_mypy = OUTPUT_MYPY
+ assert path in output_mypy
+ for error_line in output_mypy[path]:
+ error_line = _strip_filename(error_line)
match = re.match(
- r"^.+\.py:(?P<lineno>\d+): (error|note): .+$",
+ r"(?P<lineno>\d+): (error|note): .+$",
error_line,
)
if match is None:
raise ValueError(f"Unexpected error line format: {error_line}")
lineno = int(match.group('lineno'))
- errors[lineno] += error_line
+ errors[lineno] += f'{error_line}\n'
for i, line in enumerate(lines):
lineno = i + 1
@@ -101,7 +147,7 @@ def test_fail(path):
expected_error = errors.get(lineno)
_test_fail(path, marker, expected_error, lineno)
else:
- pytest.fail(f"Error {repr(errors[lineno])} not found")
+ pytest.fail(f"Unexpected mypy output\n\n{errors[lineno]}")
_FAIL_MSG1 = """Extra error at line {}
@@ -123,31 +169,109 @@ def _test_fail(path: str, error: str, expected_error: Optional[str], lineno: int
raise AssertionError(_FAIL_MSG2.format(lineno, expected_error, error))
+def _construct_format_dict():
+ dct = {k.split(".")[-1]: v.replace("numpy", "numpy.typing") for
+ k, v in _PRECISION_DICT.items()}
+
+ return {
+ "uint8": "numpy.unsignedinteger[numpy.typing._8Bit]",
+ "uint16": "numpy.unsignedinteger[numpy.typing._16Bit]",
+ "uint32": "numpy.unsignedinteger[numpy.typing._32Bit]",
+ "uint64": "numpy.unsignedinteger[numpy.typing._64Bit]",
+ "uint128": "numpy.unsignedinteger[numpy.typing._128Bit]",
+ "uint256": "numpy.unsignedinteger[numpy.typing._256Bit]",
+ "int8": "numpy.signedinteger[numpy.typing._8Bit]",
+ "int16": "numpy.signedinteger[numpy.typing._16Bit]",
+ "int32": "numpy.signedinteger[numpy.typing._32Bit]",
+ "int64": "numpy.signedinteger[numpy.typing._64Bit]",
+ "int128": "numpy.signedinteger[numpy.typing._128Bit]",
+ "int256": "numpy.signedinteger[numpy.typing._256Bit]",
+ "float16": "numpy.floating[numpy.typing._16Bit]",
+ "float32": "numpy.floating[numpy.typing._32Bit]",
+ "float64": "numpy.floating[numpy.typing._64Bit]",
+ "float80": "numpy.floating[numpy.typing._80Bit]",
+ "float96": "numpy.floating[numpy.typing._96Bit]",
+ "float128": "numpy.floating[numpy.typing._128Bit]",
+ "float256": "numpy.floating[numpy.typing._256Bit]",
+ "complex64": "numpy.complexfloating[numpy.typing._32Bit, numpy.typing._32Bit]",
+ "complex128": "numpy.complexfloating[numpy.typing._64Bit, numpy.typing._64Bit]",
+ "complex160": "numpy.complexfloating[numpy.typing._80Bit, numpy.typing._80Bit]",
+ "complex192": "numpy.complexfloating[numpy.typing._96Bit, numpy.typing._96Bit]",
+ "complex256": "numpy.complexfloating[numpy.typing._128Bit, numpy.typing._128Bit]",
+ "complex512": "numpy.complexfloating[numpy.typing._256Bit, numpy.typing._256Bit]",
+
+ "ubyte": f"numpy.unsignedinteger[{dct['_NBitByte']}]",
+ "ushort": f"numpy.unsignedinteger[{dct['_NBitShort']}]",
+ "uintc": f"numpy.unsignedinteger[{dct['_NBitIntC']}]",
+ "uintp": f"numpy.unsignedinteger[{dct['_NBitIntP']}]",
+ "uint": f"numpy.unsignedinteger[{dct['_NBitInt']}]",
+ "ulonglong": f"numpy.unsignedinteger[{dct['_NBitLongLong']}]",
+ "byte": f"numpy.signedinteger[{dct['_NBitByte']}]",
+ "short": f"numpy.signedinteger[{dct['_NBitShort']}]",
+ "intc": f"numpy.signedinteger[{dct['_NBitIntC']}]",
+ "intp": f"numpy.signedinteger[{dct['_NBitIntP']}]",
+ "int_": f"numpy.signedinteger[{dct['_NBitInt']}]",
+ "longlong": f"numpy.signedinteger[{dct['_NBitLongLong']}]",
+
+ "half": f"numpy.floating[{dct['_NBitHalf']}]",
+ "single": f"numpy.floating[{dct['_NBitSingle']}]",
+ "double": f"numpy.floating[{dct['_NBitDouble']}]",
+ "longdouble": f"numpy.floating[{dct['_NBitLongDouble']}]",
+ "csingle": f"numpy.complexfloating[{dct['_NBitSingle']}, {dct['_NBitSingle']}]",
+ "cdouble": f"numpy.complexfloating[{dct['_NBitDouble']}, {dct['_NBitDouble']}]",
+ "clongdouble": f"numpy.complexfloating[{dct['_NBitLongDouble']}, {dct['_NBitLongDouble']}]",
+
+ # numpy.typing
+ "_NBitInt": dct['_NBitInt'],
+
+ # numpy.ctypeslib
+ "c_intp": f"ctypes.{_C_INTP}"
+ }
+
+
+#: A dictionary with all supported format keys (as keys)
+#: and matching values
+FORMAT_DICT: Dict[str, str] = _construct_format_dict()
+
+
+def _parse_reveals(file: IO[str]) -> List[str]:
+ """Extract and parse all ``" # E: "`` comments from the passed file-like object.
+
+ All format keys will be substituted for their respective value from `FORMAT_DICT`,
+ *e.g.* ``"{float64}"`` becomes ``"numpy.floating[numpy.typing._64Bit]"``.
+ """
+ string = file.read().replace("*", "")
+
+ # Grab all `# E:`-based comments
+ comments_array = np.char.partition(string.split("\n"), sep=" # E: ")[:, 2]
+ comments = "/n".join(comments_array)
+
+ # Only search for the `{*}` pattern within comments,
+ # otherwise there is the risk of accidently grabbing dictionaries and sets
+ key_set = set(re.findall(r"\{(.*?)\}", comments))
+ kwargs = {
+ k: FORMAT_DICT.get(k, f"<UNRECOGNIZED FORMAT KEY {k!r}>") for k in key_set
+ }
+ fmt_str = comments.format(**kwargs)
+
+ return fmt_str.split("/n")
+
+
@pytest.mark.slow
@pytest.mark.skipif(NO_MYPY, reason="Mypy is not installed")
@pytest.mark.parametrize("path", get_test_cases(REVEAL_DIR))
def test_reveal(path):
__tracebackhide__ = True
- stdout, stderr, exitcode = api.run([
- "--config-file",
- MYPY_INI,
- "--cache-dir",
- CACHE_DIR,
- path,
- ])
-
with open(path) as fin:
- lines = fin.read().replace('*', '').split("\n")
-
- stdout_list = stdout.replace('*', '').split("\n")
- for error_line in stdout_list:
- error_line = error_line.strip()
- if not error_line:
- continue
+ lines = _parse_reveals(fin)
+ output_mypy = OUTPUT_MYPY
+ assert path in output_mypy
+ for error_line in output_mypy[path]:
+ error_line = _strip_filename(error_line)
match = re.match(
- r"^.+\.py:(?P<lineno>\d+): note: .+$",
+ r"(?P<lineno>\d+): note: .+$",
error_line,
)
if match is None:
@@ -155,7 +279,7 @@ def test_reveal(path):
lineno = int(match.group('lineno')) - 1
assert "Revealed type is" in error_line
- marker = lines[lineno].split("# E:")[-1].strip()
+ marker = lines[lineno]
_test_reveal(path, marker, error_line, 1 + lineno)
@@ -180,3 +304,46 @@ def test_code_runs(path):
spec = importlib.util.spec_from_file_location(f"{dirname}.{filename}", path)
test_module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(test_module)
+
+
+LINENO_MAPPING = {
+ 3: "uint128",
+ 4: "uint256",
+ 6: "int128",
+ 7: "int256",
+ 9: "float80",
+ 10: "float96",
+ 11: "float128",
+ 12: "float256",
+ 14: "complex160",
+ 15: "complex192",
+ 16: "complex256",
+ 17: "complex512",
+}
+
+
+@pytest.mark.slow
+@pytest.mark.skipif(NO_MYPY, reason="Mypy is not installed")
+def test_extended_precision() -> None:
+ path = os.path.join(MISC_DIR, "extended_precision.py")
+ output_mypy = OUTPUT_MYPY
+ assert path in output_mypy
+
+ for _msg in output_mypy[path]:
+ *_, _lineno, msg_typ, msg = _msg.split(":")
+
+ msg = _strip_filename(msg)
+ lineno = int(_lineno)
+ msg_typ = msg_typ.strip()
+ assert msg_typ in {"error", "note"}
+
+ if LINENO_MAPPING[lineno] in _EXTENDED_PRECISION_LIST:
+ if msg_typ == "error":
+ raise ValueError(f"Unexpected reveal line format: {lineno}")
+ else:
+ marker = FORMAT_DICT[LINENO_MAPPING[lineno]]
+ _test_reveal(path, marker, msg, lineno)
+ else:
+ if msg_typ == "error":
+ marker = "Module has no attribute"
+ _test_fail(path, marker, msg, lineno)
diff --git a/numpy/typing/tests/test_typing_extensions.py b/numpy/typing/tests/test_typing_extensions.py
new file mode 100644
index 000000000..f59f222fb
--- /dev/null
+++ b/numpy/typing/tests/test_typing_extensions.py
@@ -0,0 +1,35 @@
+"""Tests for the optional typing-extensions dependency."""
+
+import sys
+import textwrap
+import subprocess
+
+CODE = textwrap.dedent(r"""
+ import sys
+ import importlib
+
+ assert "typing_extensions" not in sys.modules
+ assert "numpy.typing" not in sys.modules
+
+ # Importing `typing_extensions` will now raise an `ImportError`
+ sys.modules["typing_extensions"] = None
+ assert importlib.import_module("numpy.typing")
+""")
+
+
+def test_no_typing_extensions() -> None:
+ """Import `numpy.typing` in the absence of typing-extensions.
+
+ Notes
+ -----
+ Ideally, we'd just run the normal typing tests in an environment where
+ typing-extensions is not installed, but unfortunatelly this is currently
+ impossible as it is an indirect hard dependency of pytest.
+
+ """
+ p = subprocess.run([sys.executable, '-c', CODE], capture_output=True)
+ if p.returncode:
+ raise AssertionError(
+ f"Non-zero return code: {p.returncode!r}\n\n{p.stderr.decode()}"
+ )
+
diff --git a/numpy/version.py b/numpy/version.py
new file mode 100644
index 000000000..4159a1c0e
--- /dev/null
+++ b/numpy/version.py
@@ -0,0 +1,12 @@
+from ._version import get_versions
+
+__ALL__ = ['version', 'full_version', 'git_revision', 'release']
+
+vinfo = get_versions()
+version: str = vinfo["version"]
+full_version: str = vinfo['version']
+git_revision: str = vinfo['full-revisionid']
+release = 'dev0' not in version and '+' not in version
+short_version: str = vinfo['version'].split("+")[0]
+
+del get_versions, vinfo
diff --git a/pavement.py b/pavement.py
index 373354432..43ed14a51 100644
--- a/pavement.py
+++ b/pavement.py
@@ -26,6 +26,7 @@ import os
import sys
import shutil
import hashlib
+import textwrap
# The paver package needs to be installed to run tasks
import paver
@@ -37,7 +38,7 @@ from paver.easy import Bunch, options, task, sh
#-----------------------------------
# Path to the release notes
-RELEASE_NOTES = 'doc/source/release/1.21.0-notes.rst'
+RELEASE_NOTES = 'doc/source/release/1.22.0-notes.rst'
#-------------------------------------------------------
@@ -49,25 +50,13 @@ options(installers=Bunch(releasedir="release",
installersdir=os.path.join("release", "installers")),)
-#-----------------------------
-# Generate the release version
-#-----------------------------
+#------------------------
+# Get the release version
+#------------------------
sys.path.insert(0, os.path.dirname(__file__))
try:
- setup_py = __import__("setup")
- FULLVERSION = setup_py.VERSION
- # This is duplicated from setup.py
- if os.path.exists('.git'):
- GIT_REVISION = setup_py.git_version()
- elif os.path.exists('numpy/version.py'):
- # must be a source distribution, use existing version file
- from numpy.version import git_revision as GIT_REVISION
- else:
- GIT_REVISION = "Unknown"
-
- if not setup_py.ISRELEASED:
- FULLVERSION += '.dev0+' + GIT_REVISION[:7]
+ from setup import FULLVERSION
finally:
sys.path.pop(0)
@@ -210,22 +199,25 @@ def write_release_task(options, filename='README'):
with open(notes) as fnotes:
freadme.write(fnotes.read())
- freadme.writelines("""
-Checksums
-=========
+ freadme.writelines(textwrap.dedent(
+ """
+ Checksums
+ =========
-MD5
----
-::
+ MD5
+ ---
+ ::
-""")
+ """))
freadme.writelines([f' {c}\n' for c in compute_md5(idirs)])
- freadme.writelines("""
-SHA256
-------
-::
-""")
+ freadme.writelines(textwrap.dedent(
+ """
+ SHA256
+ ------
+ ::
+
+ """))
freadme.writelines([f' {c}\n' for c in compute_sha256(idirs)])
# generate md file using pandoc before signing
diff --git a/pyproject.toml b/pyproject.toml
index 2526842fa..14f275e97 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,8 +1,9 @@
[build-system]
# Minimum requirements for the build system to execute.
requires = [
+ "packaging==20.5; platform_machine=='arm64'", # macos M1
"setuptools<49.2.0",
- "wheel<=0.35.1",
+ "wheel==0.36.2",
"Cython>=0.29.21,<3.0", # Note: keep in sync with tools/cythonize.py
]
@@ -73,4 +74,3 @@ requires = [
directory = "change"
name = "Changes"
showcontent = true
-
diff --git a/pytest.ini b/pytest.ini
index 149af04b8..dfad538c2 100644
--- a/pytest.ini
+++ b/pytest.ini
@@ -14,4 +14,5 @@ filterwarnings =
# Matrix PendingDeprecationWarning.
ignore:the matrix subclass is not
ignore:Importing from numpy.matlib is
-
+# pytest warning when using PYTHONOPTIMIZE
+ ignore:assertions not in test modules or plugins:pytest.PytestConfigWarning
diff --git a/runtests.py b/runtests.py
index 87e26768b..452ccbc64 100755
--- a/runtests.py
+++ b/runtests.py
@@ -8,7 +8,10 @@ Examples::
$ python runtests.py
$ python runtests.py -s {SAMPLE_SUBMODULE}
+ $ # Run a standalone test function:
$ python runtests.py -t {SAMPLE_TEST}
+ $ # Run a test defined as a method of a TestXXX class:
+ $ python runtests.py -t {SAMPLE_TEST2}
$ python runtests.py --ipython
$ python runtests.py --python somescript.py
$ python runtests.py --bench
@@ -28,6 +31,12 @@ Generate C code coverage listing under build/lcov/:
$ python runtests.py --gcov [...other args...]
$ python runtests.py --lcov-html
+Run lint checks.
+Provide target branch name or `uncommitted` to check before committing:
+
+ $ python runtests.py --lint main
+ $ python runtests.py --lint uncommitted
+
"""
#
# This is a generic test runner script for projects using NumPy's test
@@ -37,6 +46,7 @@ Generate C code coverage listing under build/lcov/:
PROJECT_MODULE = "numpy"
PROJECT_ROOT_FILES = ['numpy', 'LICENSE.txt', 'setup.py']
SAMPLE_TEST = "numpy/linalg/tests/test_linalg.py::test_byteorder_check"
+SAMPLE_TEST2 = "numpy/core/tests/test_memmap.py::TestMemmap::test_open_with_filename"
SAMPLE_SUBMODULE = "linalg"
EXTRA_PATH = ['/usr/lib/ccache', '/usr/lib/f90cache',
@@ -68,36 +78,44 @@ ROOT_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__)))
def main(argv):
parser = ArgumentParser(usage=__doc__.lstrip())
parser.add_argument("--verbose", "-v", action="count", default=1,
- help="more verbosity")
+ help="Add one verbosity level to pytest. Default is 0")
parser.add_argument("--debug-info", action="store_true",
- help=("add --verbose-cfg to build_src to show compiler "
- "configuration output while creating "
+ help=("Add --verbose-cfg to build_src to show "
+ "compiler configuration output while creating "
"_numpyconfig.h and config.h"))
parser.add_argument("--no-build", "-n", action="store_true", default=False,
- help="do not build the project (use system installed version)")
- parser.add_argument("--build-only", "-b", action="store_true", default=False,
- help="just build, do not run any tests")
+ help="Do not build the project (use system installed "
+ "version)")
+ parser.add_argument("--build-only", "-b", action="store_true",
+ default=False, help="Just build, do not run any tests")
parser.add_argument("--doctests", action="store_true", default=False,
help="Run doctests in module")
parser.add_argument("--refguide-check", action="store_true", default=False,
- help="Run refguide (doctest) check (do not run regular tests.)")
+ help="Run refguide (doctest) check (do not run "
+ "regular tests.)")
parser.add_argument("--coverage", action="store_true", default=False,
- help=("report coverage of project code. HTML output goes "
- "under build/coverage"))
+ help=("Report coverage of project code. HTML output "
+ "goes under build/coverage"))
+ parser.add_argument("--lint", default=None,
+ help="'<Target Branch>' or 'uncommitted', passed to "
+ "tools/linter.py [--branch BRANCH] "
+ "[--uncommitted]")
parser.add_argument("--durations", action="store", default=-1, type=int,
- help=("Time N slowest tests, time all if 0, time none if < 0"))
+ help=("Time N slowest tests, time all if 0, time none "
+ "if < 0"))
parser.add_argument("--gcov", action="store_true", default=False,
- help=("enable C code coverage via gcov (requires GCC). "
- "gcov output goes to build/**/*.gc*"))
+ help=("Enable C code coverage via gcov (requires "
+ "GCC). gcov output goes to build/**/*.gc*"))
parser.add_argument("--lcov-html", action="store_true", default=False,
- help=("produce HTML for C code coverage information "
+ help=("Produce HTML for C code coverage information "
"from a previous run with --gcov. "
"HTML output goes to build/lcov/"))
parser.add_argument("--mode", "-m", default="fast",
help="'fast', 'full', or something that could be "
"passed to nosetests -A [default: fast]")
parser.add_argument("--submodule", "-s", default=None,
- help="Submodule whose tests to run (cluster, constants, ...)")
+ help="Submodule whose tests to run (cluster, "
+ "constants, ...)")
parser.add_argument("--pythonpath", "-p", default=None,
help="Paths to prepend to PYTHONPATH")
parser.add_argument("--tests", "-t", action='append',
@@ -115,13 +133,16 @@ def main(argv):
parser.add_argument("--parallel", "-j", type=int, default=0,
help="Number of parallel jobs during build")
parser.add_argument("--warn-error", action="store_true",
- help="Set -Werror to convert all compiler warnings to errors")
+ help="Set -Werror to convert all compiler warnings to "
+ "errors")
parser.add_argument("--cpu-baseline", default=None,
- help="Specify a list of enabled baseline CPU optimizations"),
+ help="Specify a list of enabled baseline CPU "
+ "optimizations"),
parser.add_argument("--cpu-dispatch", default=None,
help="Specify a list of dispatched CPU optimizations"),
parser.add_argument("--disable-optimization", action="store_true",
- help="Disable CPU optimized code(dispatch,simd,fast...)"),
+ help="Disable CPU optimized code (dispatch, simd, "
+ "fast, ...)"),
parser.add_argument("--simd-test", default=None,
help="Specify a list of CPU optimizations to be "
"tested against NumPy SIMD interface"),
@@ -136,7 +157,8 @@ def main(argv):
"COMMIT. Note that you need to commit your "
"changes first!"))
parser.add_argument("args", metavar="ARGS", default=[], nargs=REMAINDER,
- help="Arguments to pass to pytest, asv, mypy, Python or shell")
+ help="Arguments to pass to pytest, asv, mypy, Python "
+ "or shell")
args = parser.parse_args(argv)
if args.durations < 0:
@@ -162,6 +184,9 @@ def main(argv):
print("*** Benchmarks should not be run against debug "
"version; remove -g flag ***")
+ if args.lint:
+ check_lint(args.lint)
+
if not args.no_build:
# we need the noarch path in case the package is pure python.
site_dir, site_dir_noarch = build_project(args)
@@ -432,8 +457,6 @@ def build_project(args):
cmd += ["build"]
if args.parallel > 1:
cmd += ["-j", str(args.parallel)]
- if args.debug_info:
- cmd += ["build_src", "--verbose-cfg"]
if args.warn_error:
cmd += ["--warn-error"]
if args.cpu_baseline:
@@ -444,6 +467,8 @@ def build_project(args):
cmd += ["--disable-optimization"]
if args.simd_test is not None:
cmd += ["--simd-test", args.simd_test]
+ if args.debug_info:
+ cmd += ["build_src", "--verbose-cfg"]
# Install; avoid producing eggs so numpy can be imported from dst_dir.
cmd += ['install', '--prefix=' + dst_dir,
'--single-version-externally-managed',
@@ -524,6 +549,7 @@ def asv_compare_config(bench_path, args, h_commits):
is_cached = asv_substitute_config(conf_path, nconf_path,
numpy_build_options = ' '.join([f'\\"{v}\\"' for v in build]),
+ numpy_global_options= ' '.join([f'--global-option=\\"{v}\\"' for v in ["build"] + build])
)
if not is_cached:
asv_clear_cache(bench_path, h_commits)
@@ -538,7 +564,7 @@ def asv_clear_cache(bench_path, h_commits, env_dir="env"):
for asv_build_cache in glob.glob(asv_build_pattern, recursive=True):
for c in h_commits:
try: shutil.rmtree(os.path.join(asv_build_cache, c))
- except OSError: pass
+ except OSError: pass
def asv_substitute_config(in_config, out_config, **custom_vars):
"""
@@ -636,6 +662,24 @@ def lcov_generate():
else:
print("HTML output generated under build/lcov/")
+def check_lint(lint_args):
+ """
+ Adds ROOT_DIR to path and performs lint checks.
+ This functions exits the program with status code of lint check.
+ """
+ sys.path.append(ROOT_DIR)
+ try:
+ from tools.linter import DiffLinter
+ except ModuleNotFoundError as e:
+ print(f"Error: {e.msg}. "
+ "Install using linter_requirements.txt.")
+ sys.exit(1)
+
+ uncommitted = lint_args == "uncommitted"
+ branch = "main" if uncommitted else lint_args
+
+ DiffLinter(branch).run_lint(uncommitted)
+
if __name__ == "__main__":
main(argv=sys.argv[1:])
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 000000000..5bca14ba0
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,11 @@
+# See the docstring in versioneer.py for instructions. Note that you must
+# re-run 'versioneer.py setup' after changing this section, and commit the
+# resulting files.
+
+[versioneer]
+VCS = git
+style = pep440
+versionfile_source = numpy/_version.py
+versionfile_build = numpy/_version.py
+tag_prefix = v
+parentdir_prefix = numpy-
diff --git a/setup.py b/setup.py
index 326d34e7a..826610466 100755
--- a/setup.py
+++ b/setup.py
@@ -24,13 +24,63 @@ import sys
import subprocess
import textwrap
import warnings
+import builtins
+import re
-if sys.version_info[:2] < (3, 6):
- raise RuntimeError("Python version >= 3.6 required.")
+# Python supported version checks. Keep right after stdlib imports to ensure we
+# get a sensible error for older Python versions
+if sys.version_info[:2] < (3, 7):
+ raise RuntimeError("Python version >= 3.7 required.")
-import builtins
+import versioneer
+
+
+# This is a bit hackish: we are setting a global variable so that the main
+# numpy __init__ can detect if it is being loaded by the setup routine, to
+# avoid attempting to load components that aren't built yet. While ugly, it's
+# a lot more robust than what was previously being used.
+builtins.__NUMPY_SETUP__ = True
+
+# Needed for backwards code compatibility below and in some CI scripts.
+# The version components are changed from ints to strings, but only VERSION
+# seems to matter outside of this module and it was already a str.
+FULLVERSION = versioneer.get_version()
+
+# Capture the version string:
+# 1.22.0.dev0+ ... -> ISRELEASED == False, VERSION == 1.22.0
+# 1.22.0rc1+ ... -> ISRELEASED == False, VERSION == 1.22.0
+# 1.22.0 ... -> ISRELEASED == True, VERSION == 1.22.0
+# 1.22.0rc1 ... -> ISRELEASED == True, VERSION == 1.22.0
+ISRELEASED = re.search(r'(dev|\+)', FULLVERSION) is None
+MAJOR, MINOR, MICRO = re.match(r'(\d+)\.(\d+)\.(\d+)', FULLVERSION).groups()
+VERSION = '{}.{}.{}'.format(MAJOR, MINOR, MICRO)
+
+# The first version not in the `Programming Language :: Python :: ...` classifiers above
+if sys.version_info >= (3, 10):
+ fmt = "NumPy {} may not yet support Python {}.{}."
+ warnings.warn(
+ fmt.format(VERSION, *sys.version_info[:2]),
+ RuntimeWarning)
+ del fmt
+
+# BEFORE importing setuptools, remove MANIFEST. Otherwise it may not be
+# properly updated when the contents of directories change (true for distutils,
+# not sure about setuptools).
+if os.path.exists('MANIFEST'):
+ os.remove('MANIFEST')
+
+# We need to import setuptools here in order for it to persist in sys.modules.
+# Its presence/absence is used in subclassing setup in numpy/distutils/core.py.
+# However, we need to run the distutils version of sdist, so import that first
+# so that it is in sys.modules
+import numpy.distutils.command.sdist
+import setuptools
+
+# Initialize cmdclass from versioneer
+from numpy.distutils.core import numpy_cmdclass
+cmdclass = versioneer.get_cmdclass(numpy_cmdclass)
CLASSIFIERS = """\
Development Status :: 5 - Production/Stable
@@ -40,7 +90,6 @@ License :: OSI Approved :: BSD License
Programming Language :: C
Programming Language :: Python
Programming Language :: Python :: 3
-Programming Language :: Python :: 3.6
Programming Language :: Python :: 3.7
Programming Language :: Python :: 3.8
Programming Language :: Python :: 3.9
@@ -55,114 +104,6 @@ Operating System :: Unix
Operating System :: MacOS
"""
-MAJOR = 1
-MINOR = 21
-MICRO = 0
-ISRELEASED = False
-VERSION = '%d.%d.%d' % (MAJOR, MINOR, MICRO)
-
-# The first version not in the `Programming Language :: Python :: ...` classifiers above
-if sys.version_info >= (3, 10):
- warnings.warn(
- f"NumPy {VERSION} may not yet support Python "
- f"{sys.version_info.major}.{sys.version_info.minor}.",
- RuntimeWarning,
- )
-
-
-# Return the git revision as a string
-def git_version():
- def _minimal_ext_cmd(cmd):
- # construct minimal environment
- env = {}
- for k in ['SYSTEMROOT', 'PATH', 'HOME']:
- v = os.environ.get(k)
- if v is not None:
- env[k] = v
- # LANGUAGE is used on win32
- env['LANGUAGE'] = 'C'
- env['LANG'] = 'C'
- env['LC_ALL'] = 'C'
- out = subprocess.check_output(cmd, stderr=subprocess.STDOUT, env=env)
- return out
-
- try:
- out = _minimal_ext_cmd(['git', 'rev-parse', 'HEAD'])
- GIT_REVISION = out.strip().decode('ascii')
- except (subprocess.SubprocessError, OSError):
- GIT_REVISION = "Unknown"
-
- if not GIT_REVISION:
- # this shouldn't happen but apparently can (see gh-8512)
- GIT_REVISION = "Unknown"
-
- return GIT_REVISION
-
-
-# BEFORE importing setuptools, remove MANIFEST. Otherwise it may not be
-# properly updated when the contents of directories change (true for distutils,
-# not sure about setuptools).
-if os.path.exists('MANIFEST'):
- os.remove('MANIFEST')
-
-# This is a bit hackish: we are setting a global variable so that the main
-# numpy __init__ can detect if it is being loaded by the setup routine, to
-# avoid attempting to load components that aren't built yet. While ugly, it's
-# a lot more robust than what was previously being used.
-builtins.__NUMPY_SETUP__ = True
-
-
-def get_version_info():
- # Adding the git rev number needs to be done inside write_version_py(),
- # otherwise the import of numpy.version messes up the build under Python 3.
- FULLVERSION = VERSION
- if os.path.exists('.git'):
- GIT_REVISION = git_version()
- elif os.path.exists('numpy/version.py'):
- # must be a source distribution, use existing version file
- try:
- from numpy.version import git_revision as GIT_REVISION
- except ImportError:
- raise ImportError("Unable to import git_revision. Try removing "
- "numpy/version.py and the build directory "
- "before building.")
- else:
- GIT_REVISION = "Unknown"
-
- if not ISRELEASED:
- import time
-
- time_stamp = time.strftime("%Y%m%d%H%M%S", time.localtime())
- FULLVERSION += f'.dev0+{time_stamp}_{GIT_REVISION[:7]}'
-
- return FULLVERSION, GIT_REVISION
-
-
-def write_version_py(filename='numpy/version.py'):
- cnt = """
-# THIS FILE IS GENERATED FROM NUMPY SETUP.PY
-#
-# To compare versions robustly, use `numpy.lib.NumpyVersion`
-short_version: str = '%(version)s'
-version: str = '%(version)s'
-full_version: str = '%(full_version)s'
-git_revision: str = '%(git_revision)s'
-release: bool = %(isrelease)s
-
-if not release:
- version = full_version
-"""
- FULLVERSION, GIT_REVISION = get_version_info()
-
- a = open(filename, 'w')
- try:
- a.write(cnt % {'version': VERSION,
- 'full_version': FULLVERSION,
- 'git_revision': GIT_REVISION,
- 'isrelease': str(ISRELEASED)})
- finally:
- a.close()
-
def configuration(parent_package='', top_path=None):
from numpy.distutils.misc_util import Configuration
@@ -231,13 +172,14 @@ class concat_license_files():
f.write(self.bsd_text)
-from distutils.command.sdist import sdist
-class sdist_checked(sdist):
+# Need to inherit from versioneer version of sdist to get the encoded
+# version information.
+class sdist_checked(cmdclass['sdist']):
""" check submodules on sdist to prevent incomplete tarballs """
def run(self):
check_submodules()
with concat_license_files():
- sdist.run(self)
+ super().run()
def get_build_overrides():
@@ -310,7 +252,8 @@ def parse_setuppy_commands():
'--maintainer', '--maintainer-email', '--contact',
'--contact-email', '--url', '--license', '--description',
'--long-description', '--platforms', '--classifiers',
- '--keywords', '--provides', '--requires', '--obsoletes']
+ '--keywords', '--provides', '--requires', '--obsoletes',
+ 'version',]
for command in info_commands:
if command in args:
@@ -321,7 +264,8 @@ def parse_setuppy_commands():
# below and not standalone. Hence they're not added to good_commands.
good_commands = ('develop', 'sdist', 'build', 'build_ext', 'build_py',
'build_clib', 'build_scripts', 'bdist_wheel', 'bdist_rpm',
- 'bdist_wininst', 'bdist_msi', 'bdist_mpkg', 'build_src')
+ 'bdist_wininst', 'bdist_msi', 'bdist_mpkg', 'build_src',
+ 'bdist_egg')
for command in good_commands:
if command in args:
@@ -376,8 +320,6 @@ def parse_setuppy_commands():
Instead, build what you want to upload and upload those files
with `twine upload -s <filenames>` instead.
""",
- upload_docs="`setup.py upload_docs` is not supported",
- easy_install="`setup.py easy_install` is not supported",
clean="""
`setup.py clean` is not supported, use one of the following instead:
@@ -385,10 +327,6 @@ def parse_setuppy_commands():
- `git clean -Xdf` (cleans all versioned files, doesn't touch
files that aren't checked into the git repo)
""",
- check="`setup.py check` is not supported",
- register="`setup.py register` is not supported",
- bdist_dumb="`setup.py bdist_dumb` is not supported",
- bdist="`setup.py bdist` is not supported",
build_sphinx="""
`setup.py build_sphinx` is not supported, use the
Makefile under doc/""",
@@ -409,21 +347,17 @@ def parse_setuppy_commands():
# Commands that do more than print info, but also don't need Cython and
# template parsing.
- other_commands = ['egg_info', 'install_egg_info', 'rotate']
+ other_commands = ['egg_info', 'install_egg_info', 'rotate', 'dist_info']
for command in other_commands:
if command in args:
return False
# If we got here, we didn't detect what setup.py command was given
- import warnings
- warnings.warn("Unrecognized setuptools command, proceeding with "
- "generating Cython sources and expanding templates",
- stacklevel=2)
- return True
+ raise RuntimeError("Unrecognized setuptools command: {}".format(args))
def get_docs_url():
- if not ISRELEASED:
+ if 'dev' in VERSION:
return "https://numpy.org/devdocs"
else:
# For releases, this URL ends up on pypi.
@@ -438,9 +372,6 @@ def setup_package():
os.chdir(src_path)
sys.path.insert(0, src_path)
- # Rewrite the version file every time
- write_version_py()
-
# The f2py scripts that will be installed
if sys.platform == 'win32':
f2py_cmds = [
@@ -453,7 +384,7 @@ def setup_package():
'f2py%s.%s = numpy.f2py.f2py2e:main' % sys.version_info[:2],
]
- cmdclass = {"sdist": sdist_checked, }
+ cmdclass["sdist"] = sdist_checked
metadata = dict(
name='numpy',
maintainer="NumPy Developers",
@@ -472,8 +403,9 @@ def setup_package():
classifiers=[_f for _f in CLASSIFIERS.split('\n') if _f],
platforms=["Windows", "Linux", "Solaris", "Mac OS-X", "Unix"],
test_suite='pytest',
+ version=versioneer.get_version(),
cmdclass=cmdclass,
- python_requires='>=3.6',
+ python_requires='>=3.7',
zip_safe=False,
entry_points={
'console_scripts': f2py_cmds
@@ -489,8 +421,9 @@ def setup_package():
if run_build:
# patches distutils, even though we don't use it
- import setuptools # noqa: F401
+ #from setuptools import setup
from numpy.distutils.core import setup
+
if 'sdist' not in sys.argv:
# Generate Cython sources, unless we're generating an sdist
generate_cython()
@@ -499,10 +432,8 @@ def setup_package():
# Customize extension building
cmdclass['build_clib'], cmdclass['build_ext'] = get_build_overrides()
else:
+ #from numpy.distutils.core import setup
from setuptools import setup
- # Version number is added to metadata inside configuration() if build
- # is run.
- metadata['version'] = get_version_info()[0]
try:
setup(**metadata)
diff --git a/shippable.yml b/shippable.yml
deleted file mode 100644
index 2843377e2..000000000
--- a/shippable.yml
+++ /dev/null
@@ -1,67 +0,0 @@
-branches:
- only:
- - master
- - maintenance/*
-
-language: python
-
-python:
- # use versions available for job image
- # aarch64_u16pytall:v6.7.4
- # (what we currently have access to by default)
- # this is a bit restrictive in terms
- # of version availability / control,
- # but it is convenient
- - 3.7
-
-runtime:
- # use the free open source pool of nodes
- # only for ARM platform
- nodePool: shippable_shared_aarch64
-
-build:
- ci:
- # install dependencies and newer toolchain for gfortran5
- - sudo add-apt-repository ppa:ubuntu-toolchain-r/test
- - sudo apt-get update
- - sudo apt-get install gcc gfortran libgfortran5
- - target=$(python tools/openblas_support.py)
- - ls -lR "${target}"
- - sudo cp -r "${target}"/lib/* /usr/lib
- - sudo cp "${target}"/include/* /usr/include
- - python -m pip install --upgrade pip
-
- # we will pay the ~13 minute cost of compiling Cython only when a new
- # version is scraped in by pip; otherwise, use the cached
- # wheel shippable places on Amazon S3 after we build it once
- - python -m pip install -r test_requirements.txt --cache-dir=/root/.cache/pip/wheels/$SHIPPABLE_PYTHON_VERSION
- # install pytest-xdist to leverage a second core
- # for unit tests
- - python -m pip install pytest-xdist
-
- # build and test numpy
- - export PATH=$PATH:$SHIPPABLE_REPO_DIR
- # build first and adjust PATH so f2py is found in scripts dir
- # use > 1 core for build sometimes slows down a fair bit,
- # other times modestly speeds up, so avoid for now
- - python -m pip install .
- - extra_directories=($SHIPPABLE_REPO_DIR/build/*scripts*)
- - extra_path=$(printf "%s:" "${extra_directories[@]}")
- - export PATH="${extra_path}${PATH}"
- # check OpenBLAS version
- - python tools/openblas_support.py --check_version
- # run the test suite
- - python runtests.py -n --debug-info --show-build-log -- -rsx --junit-xml=$SHIPPABLE_REPO_DIR/shippable/testresults/tests.xml -n 2 --durations=10
-
- cache: false
-
-# disable email notification
-# of CI job result
-integrations:
- notifications:
- - integrationName: email
- type: email
- on_success: never
- on_failure: never
- on_cancel: never
- on_pull_request: never
diff --git a/site.cfg.example b/site.cfg.example
index c809303a2..1a6b36d2c 100644
--- a/site.cfg.example
+++ b/site.cfg.example
@@ -28,7 +28,7 @@
# extensions with this dependency. Use the character given by os.pathsep
# to separate the items in the list. Note that this character is known to
# vary on some unix-like systems; if a colon does not work, try a comma.
-# This also applies to include_dirs and src_dirs (see below).
+# This also applies to include_dirs.
# On UN*X-type systems (OS X, most BSD and Linux systems):
# library_dirs = /usr/lib:/usr/local/lib
# On Windows:
@@ -40,15 +40,6 @@
# List of directories to add to the header file search path.
# include_dirs = /usr/include:/usr/local/include
#
-# src_dirs
-# List of directories that contain extracted source code for the
-# dependency. For some dependencies, numpy.distutils will be able to build
-# them from source if binaries cannot be found. The FORTRAN BLAS and
-# LAPACK libraries are one example. However, most dependencies are more
-# complicated and require actual installation that you need to do
-# yourself.
-# src_dirs = /home/username/src/BLAS_SRC:/home/username/src/LAPACK_SRC
-#
# search_static_first
# Boolean (one of (0, false, no, off) for False or (1, true, yes, on) for
# True) to tell numpy.distutils to prefer static libraries (.a) over
diff --git a/test_requirements.txt b/test_requirements.txt
index 97d06a0cf..9f2ee2001 100644
--- a/test_requirements.txt
+++ b/test_requirements.txt
@@ -1,17 +1,15 @@
-cython==0.29.21
-wheel
+cython==0.29.24
+wheel<0.36.3
setuptools<49.2.0
-hypothesis==5.41.4
-pytest==6.0.2
-pytz==2020.4
-pytest-cov==2.10.1
+hypothesis==6.14.5
+pytest==6.2.4
+pytz==2021.1
+pytest-cov==2.12.1
pickle5; python_version == '3.7' and platform_python_implementation != 'PyPy'
-pickle5; python_version == '3.6' and platform_python_implementation != 'PyPy'
# for numpy.random.test.test_extending
cffi
# For testing types. Notes on the restrictions:
# - Mypy relies on C API features not present in PyPy
-# - Mypy doesn't currently work on Python 3.9
-# - Python 3.6 doesn't work because it doesn't understand py.typed
-mypy==0.790; platform_python_implementation != "PyPy" and python_version > "3.6"
-typing_extensions
+# - There is no point in installing typing_extensions without mypy
+mypy==0.910; platform_python_implementation != "PyPy"
+typing_extensions==3.10.0.0; platform_python_implementation != "PyPy"
diff --git a/tools/changelog.py b/tools/changelog.py
index 920f5b87f..2bd7cde08 100755
--- a/tools/changelog.py
+++ b/tools/changelog.py
@@ -22,6 +22,7 @@ Dependencies
- gitpython
- pygithub
+- git >= 2.29.0
Some code was copied from scipy `tools/gh_list.py` and `tools/authors.py`.
@@ -57,21 +58,29 @@ A total of %d pull requests were merged for this release.
def get_authors(revision_range):
- pat = u'^.*\\t(.*)$'
lst_release, cur_release = [r.strip() for r in revision_range.split('..')]
+ authors_pat = r'^.*\t(.*)$'
- # authors, in current release and previous to current release.
- cur = set(re.findall(pat, this_repo.git.shortlog('-s', revision_range),
- re.M))
- pre = set(re.findall(pat, this_repo.git.shortlog('-s', lst_release),
- re.M))
+ # authors and co-authors in current and previous releases.
+ grp1 = '--group=author'
+ grp2 = '--group=trailer:co-authored-by'
+ cur = this_repo.git.shortlog('-s', grp1, grp2, revision_range)
+ pre = this_repo.git.shortlog('-s', grp1, grp2, lst_release)
+ authors_cur = set(re.findall(authors_pat, cur, re.M))
+ authors_pre = set(re.findall(authors_pat, pre, re.M))
- # Homu is the author of auto merges, clean him out.
- cur.discard('Homu')
- pre.discard('Homu')
+ # Ignore the bot Homu.
+ authors_cur.discard('Homu')
+ authors_pre.discard('Homu')
+
+ # Ignore the bot dependabot-preview
+ authors_cur.discard('dependabot-preview')
+ authors_pre.discard('dependabot-preview')
# Append '+' to new authors.
- authors = [s + u' +' for s in cur - pre] + [s for s in cur & pre]
+ authors_new = [s + ' +' for s in authors_cur - authors_pre]
+ authors_old = [s for s in authors_cur & authors_pre]
+ authors = authors_new + authors_old
authors.sort()
return authors
@@ -82,18 +91,18 @@ def get_pull_requests(repo, revision_range):
# From regular merges
merges = this_repo.git.log(
'--oneline', '--merges', revision_range)
- issues = re.findall(u"Merge pull request \\#(\\d*)", merges)
+ issues = re.findall(r"Merge pull request \#(\d*)", merges)
prnums.extend(int(s) for s in issues)
# From Homu merges (Auto merges)
- issues = re. findall(u"Auto merge of \\#(\\d*)", merges)
+ issues = re. findall(r"Auto merge of \#(\d*)", merges)
prnums.extend(int(s) for s in issues)
# From fast forward squash-merges
commits = this_repo.git.log(
'--oneline', '--no-merges', '--first-parent', revision_range)
- issues = re.findall(u'^.*\\(\\#(\\d+)\\)$', commits, re.M)
- prnums.extend(int(s) for s in issues)
+ issues = re.findall(r'^.*\((\#|gh-|gh-\#)(\d+)\)$', commits, re.M)
+ prnums.extend(int(s[1]) for s in issues)
# get PR data from github repo
prnums.sort()
@@ -109,31 +118,31 @@ def main(token, revision_range):
# document authors
authors = get_authors(revision_range)
- heading = u"Contributors"
+ heading = "Contributors"
print()
print(heading)
- print(u"="*len(heading))
+ print("="*len(heading))
print(author_msg % len(authors))
for s in authors:
- print(u'* ' + s)
+ print('* ' + s)
# document pull requests
pull_requests = get_pull_requests(github_repo, revision_range)
- heading = u"Pull requests merged"
- pull_msg = u"* `#{0} <{1}>`__: {2}"
+ heading = "Pull requests merged"
+ pull_msg = "* `#{0} <{1}>`__: {2}"
print()
print(heading)
- print(u"="*len(heading))
+ print("="*len(heading))
print(pull_request_msg % len(pull_requests))
for pull in pull_requests:
- title = re.sub(u"\\s+", u" ", pull.title.strip())
+ title = re.sub(r"\s+", " ", pull.title.strip())
if len(title) > 60:
- remainder = re.sub(u"\\s.*$", u"...", title[60:])
+ remainder = re.sub(r"\s.*$", "...", title[60:])
if len(remainder) > 20:
- remainder = title[:80] + u"..."
+ remainder = title[:80] + "..."
else:
title = title[:60] + remainder
print(pull_msg.format(pull.number, pull.html_url, title))
diff --git a/tools/ci/push_docs_to_repo.py b/tools/ci/push_docs_to_repo.py
index ae5305484..058f748ec 100755
--- a/tools/ci/push_docs_to_repo.py
+++ b/tools/ci/push_docs_to_repo.py
@@ -45,6 +45,9 @@ workdir = tempfile.mkdtemp()
os.chdir(workdir)
run(['git', 'init'])
+# ensure the working branch is called "main"
+# (`--initial-branch=main` appared to have failed on older git versions):
+run(['git', 'checkout', '-b', 'main'])
run(['git', 'remote', 'add', 'origin', args.remote])
run(['git', 'config', '--local', 'user.name', args.committer])
run(['git', 'config', '--local', 'user.email', args.email])
@@ -56,7 +59,7 @@ run(['git', 'commit', '--allow-empty', '-m', args.message], stdout=False)
print('- uploading as %s <%s>' % (args.committer, args.email))
if args.force:
- run(['git', 'push', 'origin', 'master', '--force'])
+ run(['git', 'push', 'origin', 'main', '--force'])
else:
print('\n!! No `--force` argument specified; aborting')
print('!! Before enabling that flag, make sure you know what it does\n')
diff --git a/tools/ci/test_all_newsfragments_used.py b/tools/ci/test_all_newsfragments_used.py
index c2e031549..62c9a05f9 100755
--- a/tools/ci/test_all_newsfragments_used.py
+++ b/tools/ci/test_all_newsfragments_used.py
@@ -12,5 +12,5 @@ fragments.remove("template.rst")
if fragments:
print("The following files were not found by towncrier:")
- print(" " + " \n".join(fragments))
+ print(" " + "\n ".join(fragments))
sys.exit(1)
diff --git a/tools/commitstats.py b/tools/commitstats.py
index 14c37d4d2..534f0a1b8 100644
--- a/tools/commitstats.py
+++ b/tools/commitstats.py
@@ -4,7 +4,7 @@ import re
import numpy as np
import os
-names = re.compile(r'r\d+\s[|]\s(.*)\s[|]\s200')
+names = re.compile(r'r\d+\s\|\s(.*)\s\|\s200')
def get_count(filename, repo):
mystr = open(filename).read()
diff --git a/tools/cythonize.py b/tools/cythonize.py
index 6cebf0f72..06cf54c9a 100755
--- a/tools/cythonize.py
+++ b/tools/cythonize.py
@@ -56,12 +56,14 @@ def process_pyx(fromfile, tofile):
try:
# try the cython in the installed python first (somewhat related to scipy/scipy#2397)
+ import Cython
from Cython.Compiler.Version import version as cython_version
- except ImportError:
+ except ImportError as e:
# The `cython` command need not point to the version installed in the
# Python running this script, so raise an error to avoid the chance of
# using the wrong version of Cython.
- raise OSError('Cython needs to be installed in Python as a module')
+ msg = 'Cython needs to be installed in Python as a module'
+ raise OSError(msg) from e
else:
# check the version, and invoke through python
from distutils.version import LooseVersion
@@ -73,7 +75,9 @@ def process_pyx(fromfile, tofile):
required_version = LooseVersion('0.29.21')
if LooseVersion(cython_version) < required_version:
- raise RuntimeError(f'Building {VENDOR} requires Cython >= {required_version}')
+ cython_path = Cython.__file__
+ raise RuntimeError(f'Building {VENDOR} requires Cython >= {required_version}'
+ f', found {cython_version} at {cython_path}')
subprocess.check_call(
[sys.executable, '-m', 'cython'] + flags + ["-o", tofile, fromfile])
diff --git a/tools/functions_missing_types.py b/tools/functions_missing_types.py
index c2fe156f0..0461aabd3 100755
--- a/tools/functions_missing_types.py
+++ b/tools/functions_missing_types.py
@@ -41,10 +41,12 @@ EXCLUDE_LIST = {
"fastCopyAndTranspose",
"get_array_wrap",
"int_asbuffer",
+ "numarray",
"oldnumeric",
"safe_eval",
"set_numeric_ops",
"test",
+ "typeDict",
# Builtins
"bool",
"complex",
diff --git a/tools/gitpod/Dockerfile b/tools/gitpod/Dockerfile
new file mode 100644
index 000000000..e2e0e1bc9
--- /dev/null
+++ b/tools/gitpod/Dockerfile
@@ -0,0 +1,101 @@
+#
+# Dockerfile for NumPy development
+#
+# Usage:
+# -------
+#
+# To make a local build of the container, from the 'Docker-dev' directory:
+# docker build --rm -f "Dockerfile" -t <build-tag> "."
+#
+# To use the container use the following command. It assumes that you are in
+# the root folder of the NumPy git repository, making it available as
+# /home/numpy in the container. Whatever changes you make to that directory
+# are visible in the host and container.
+# The docker image is retrieved from the NumPy dockerhub repository
+#
+# docker run --rm -it -v $(pwd):/home/numpy numpy/numpy-dev:<image-tag>
+#
+# By default the container will activate the conda environment numpy-dev
+# which contains all the dependencies needed for NumPy development
+#
+# To build NumPy run: python setup.py build_ext --inplace
+#
+# To run the tests use: python runtests.py
+#
+# This image is based on: Ubuntu 20.04 (focal)
+# https://hub.docker.com/_/ubuntu/?tab=tags&name=focal
+# OS/ARCH: linux/amd64
+FROM gitpod/workspace-base:latest
+
+ARG MAMBAFORGE_VERSION="4.10.0-0"
+ARG CONDA_ENV=numpy-dev
+
+
+# ---- Configure environment ----
+ENV CONDA_DIR=/home/gitpod/mambaforge3 \
+ SHELL=/bin/bash
+ENV PATH=${CONDA_DIR}/bin:$PATH \
+ WORKSPACE=/workspace/numpy
+
+
+# -----------------------------------------------------------------------------
+# ---- Creating as root - note: make sure to change to gitpod in the end ----
+USER root
+
+# hadolint ignore=DL3008
+RUN apt-get update && \
+ apt-get install -yq --no-install-recommends \
+ ca-certificates \
+ dirmngr \
+ dvisvgm \
+ gnupg \
+ gpg-agent \
+ texlive-latex-extra \
+ vim && \
+ # this needs to be done after installing dirmngr
+ apt-key adv --keyserver keyserver.ubuntu.com --recv-key C99B11DEB97541F0 && \
+ apt-add-repository https://cli.github.com/packages && \
+ apt-get install -yq --no-install-recommends \
+ gh && \
+ locale-gen en_US.UTF-8 && \
+ apt-get clean && \
+ rm -rf /var/cache/apt/* &&\
+ rm -rf /var/lib/apt/lists/* &&\
+ rm -rf /tmp/*
+
+# Allows this Dockerfile to activate conda environments
+SHELL ["/bin/bash", "--login", "-o", "pipefail", "-c"]
+
+# -----------------------------------------------------------------------------
+# ---- Installing mamba ----
+RUN wget -q -O mambaforge3.sh \
+ "https://github.com/conda-forge/miniforge/releases/download/$MAMBAFORGE_VERSION/Mambaforge-$MAMBAFORGE_VERSION-Linux-x86_64.sh" && \
+ bash mambaforge3.sh -p ${CONDA_DIR} -b && \
+ rm mambaforge3.sh
+
+# -----------------------------------------------------------------------------
+# ---- Copy needed files ----
+# basic workspace configurations
+COPY ./tools/gitpod/workspace_config /usr/local/bin/workspace_config
+
+RUN chmod a+rx /usr/local/bin/workspace_config && \
+ workspace_config
+
+# Copy conda environment file into the container - this needs to exists inside
+# the container to create a conda environment from it
+COPY environment.yml /tmp/environment.yml
+
+# -----------------------------------------------------------------------------
+# ---- Create conda environment ----
+# Install NumPy dependencies
+RUN mamba env create -f /tmp/environment.yml && \
+ conda activate ${CONDA_ENV} && \
+ mamba install ccache -y && \
+ # needed for docs rendering later on
+ python -m pip install --no-cache-dir sphinx-autobuild && \
+ conda clean --all -f -y && \
+ rm -rf /tmp/*
+
+# -----------------------------------------------------------------------------
+# Always make sure we are not root
+USER gitpod \ No newline at end of file
diff --git a/tools/gitpod/gitpod.Dockerfile b/tools/gitpod/gitpod.Dockerfile
new file mode 100644
index 000000000..7791df191
--- /dev/null
+++ b/tools/gitpod/gitpod.Dockerfile
@@ -0,0 +1,47 @@
+# Doing a local shallow clone - keeps the container secure
+# and much slimmer than using COPY directly or making a
+# remote clone
+ARG BASE_CONTAINER="numpy/numpy-dev:latest"
+FROM gitpod/workspace-base:latest as clone
+
+COPY --chown=gitpod . /tmp/numpy_repo
+
+# the clone should be deep enough for versioneer to work
+RUN git clone --shallow-since=2021-05-22 file:////tmp/numpy_repo /tmp/numpy
+
+# -----------------------------------------------------------------------------
+# Using the numpy-dev Docker image as a base
+# This way, we ensure we have all the needed compilers and dependencies
+# while reducing the build time
+FROM ${BASE_CONTAINER} as build
+
+# -----------------------------------------------------------------------------
+USER root
+
+# -----------------------------------------------------------------------------
+# ---- ENV variables ----
+# ---- Directories needed ----
+ENV WORKSPACE=/workspace/numpy/ \
+ CONDA_ENV=numpy-dev
+
+# Allows this Dockerfile to activate conda environments
+SHELL ["/bin/bash", "--login", "-o", "pipefail", "-c"]
+
+# Copy over the shallow clone
+COPY --from=clone --chown=gitpod /tmp/numpy ${WORKSPACE}
+
+# Everything happens in the /workspace/numpy directory
+WORKDIR ${WORKSPACE}
+
+# Build numpy to populate the cache used by ccache
+RUN conda activate ${CONDA_ENV} && \
+ python setup.py build_ext --inplace && \
+ ccache -s
+
+# Gitpod will load the repository into /workspace/numpy. We remove the
+# directoy from the image to prevent conflicts
+RUN rm -rf ${WORKSPACE}
+
+# -----------------------------------------------------------------------------
+# Always return to non privileged user
+USER gitpod
diff --git a/tools/gitpod/settings.json b/tools/gitpod/settings.json
new file mode 100644
index 000000000..8f070c04c
--- /dev/null
+++ b/tools/gitpod/settings.json
@@ -0,0 +1,9 @@
+{
+ "restructuredtext.languageServer.disabled": true,
+ "restructuredtext.builtDocumentationPath": "${workspaceRoot}/doc/build/html",
+ "restructuredtext.confPath": "",
+ "restructuredtext.updateOnTextChanged": "true",
+ "restructuredtext.updateDelay": 300,
+ "restructuredtext.linter.disabled": true,
+ "python.pythonPath": "/home/gitpod/mambaforge3/envs/numpy-dev/bin/python"
+} \ No newline at end of file
diff --git a/tools/gitpod/workspace_config b/tools/gitpod/workspace_config
new file mode 100644
index 000000000..aa859c9be
--- /dev/null
+++ b/tools/gitpod/workspace_config
@@ -0,0 +1,58 @@
+#!/bin/bash
+# Basic configurations for the workspace
+
+set -e
+
+# gitpod/workspace-base needs at least one file here
+touch /home/gitpod/.bashrc.d/empty
+
+# Add git aliases
+git config --global alias.co checkout
+git config --global alias.ci commit
+git config --global alias.st status
+git config --global alias.br branch
+git config --global alias.hist "log --pretty=format:'%h %ad | %s%d [%an]' --graph --date=short"
+git config --global alias.type 'cat-file -t'
+git config --global alias.dump 'cat-file -p'
+
+# Enable basic vim defaults in ~/.vimrc
+echo "filetype plugin indent on" >>~/.vimrc
+echo "set colorcolumn=80" >>~/.vimrc
+echo "set number" >>~/.vimrc
+echo "syntax enable" >>~/.vimrc
+
+# Vanity custom bash prompt - makes it more legible
+echo "PS1='\[\e]0;\u \w\a\]\[\033[01;36m\]\u\[\033[m\] > \[\033[38;5;141m\]\w\[\033[m\] \\$ '" >>~/.bashrc
+
+# Enable prompt color in the skeleton .bashrc
+# hadolint ignore=SC2016
+sed -i 's/^#force_color_prompt=yes/force_color_prompt=yes/' /etc/skel/.bashrc
+
+# .gitpod.yml is configured to install NumPy from /workspace/numpy
+echo "export PYTHONPATH=${WORKSPACE}" >>~/.bashrc
+
+# make conda activate command available from /bin/bash (login and interactive)
+if [[ ! -f "/etc/profile.d/conda.sh" ]]; then
+ ln -s ${CONDA_DIR}/etc/profile.d/conda.sh /etc/profile.d/conda.sh
+fi
+echo ". ${CONDA_DIR}/etc/profile.d/conda.sh" >>~/.bashrc
+echo "conda activate numpy-dev" >>~/.bashrc
+
+# Enable prompt color in the skeleton .bashrc
+# hadolint ignore=SC2016
+sed -i 's/^#force_color_prompt=yes/force_color_prompt=yes/' /etc/skel/.bashrc
+
+# .gitpod.yml is configured to install numpy from /workspace/numpy
+echo "export PYTHONPATH=/workspace/numpy" >>~/.bashrc
+
+# Set up ccache for compilers for this Dockerfile
+# REF: https://github.com/conda-forge/compilers-feedstock/issues/31
+echo "conda activate numpy-dev" >>~/.startuprc
+echo "export CC=\"ccache \$CC\"" >>~/.startuprc
+echo "export CXX=\"ccache \$CXX\"" >>~/.startuprc
+echo "export F77=\"ccache \$F77\"" >>~/.startuprc
+echo "export F90=\"ccache \$F90\"" >>~/.startuprc
+echo "export GFORTRAN=\"ccache \$GFORTRAN\"" >>~/.startuprc
+echo "export FC=\"ccache \$FC\"" >>~/.startuprc
+echo "source ~/.startuprc" >>~/.profile
+echo "source ~/.startuprc" >>~/.bashrc
diff --git a/tools/lint_diff.ini b/tools/lint_diff.ini
new file mode 100644
index 000000000..3b66d3c3e
--- /dev/null
+++ b/tools/lint_diff.ini
@@ -0,0 +1,4 @@
+[pycodestyle]
+max_line_length = 79
+statistics = True
+ignore = E121,E122,E123,E125,E126,E127,E128,E226,E251,E265,E266,E302,E402,E704,E712,E721,E731,E741,W291,W293,W391,W503,W504
diff --git a/tools/linter.py b/tools/linter.py
new file mode 100644
index 000000000..fd229dbef
--- /dev/null
+++ b/tools/linter.py
@@ -0,0 +1,83 @@
+import os
+import sys
+import subprocess
+from argparse import ArgumentParser
+from git import Repo, exc
+
+CONFIG = os.path.join(
+ os.path.abspath(os.path.dirname(__file__)),
+ 'lint_diff.ini',
+)
+
+# NOTE: The `diff` and `exclude` options of pycodestyle seem to be
+# incompatible, so instead just exclude the necessary files when
+# computing the diff itself.
+EXCLUDE = (
+ "numpy/typing/tests/data/",
+ "numpy/__config__.py",
+)
+
+
+class DiffLinter:
+ def __init__(self, branch):
+ self.branch = branch
+ self.repo = Repo('.')
+ self.head = self.repo.head.commit
+
+ def get_branch_diff(self, uncommitted = False):
+ """
+ Determine the first common ancestor commit.
+ Find diff between branch and FCA commit.
+ Note: if `uncommitted` is set, check only
+ uncommitted changes
+ """
+ try:
+ commit = self.repo.merge_base(self.branch, self.head)[0]
+ except exc.GitCommandError:
+ print(f"Branch with name `{self.branch}` does not exist")
+ sys.exit(1)
+
+ exclude = [f':(exclude){i}' for i in EXCLUDE]
+ if uncommitted:
+ diff = self.repo.git.diff(
+ self.head, '--unified=0', '***.py', *exclude
+ )
+ else:
+ diff = self.repo.git.diff(
+ commit, self.head, '--unified=0', '***.py', *exclude
+ )
+ return diff
+
+ def run_pycodestyle(self, diff):
+ """
+ Original Author: Josh Wilson (@person142)
+ Source:
+ https://github.com/scipy/scipy/blob/main/tools/lint_diff.py
+ Run pycodestyle on the given diff.
+ """
+ res = subprocess.run(
+ ['pycodestyle', '--diff', '--config', CONFIG],
+ input=diff,
+ stdout=subprocess.PIPE,
+ encoding='utf-8',
+ )
+ return res.returncode, res.stdout
+
+ def run_lint(self, uncommitted):
+ diff = self.get_branch_diff(uncommitted)
+ retcode, errors = self.run_pycodestyle(diff)
+
+ errors and print(errors)
+
+ sys.exit(retcode)
+
+
+if __name__ == '__main__':
+ parser = ArgumentParser()
+ parser.add_argument("--branch", type=str, default='main',
+ help="The branch to diff against")
+ parser.add_argument("--uncommitted", action='store_true',
+ help="Check only uncommitted changes")
+ args = parser.parse_args()
+
+ DiffLinter(args.branch).run_lint(args.uncommitted)
diff --git a/tools/list_installed_dll_dependencies_cygwin.sh b/tools/list_installed_dll_dependencies_cygwin.sh
new file mode 100644
index 000000000..5b81998db
--- /dev/null
+++ b/tools/list_installed_dll_dependencies_cygwin.sh
@@ -0,0 +1,38 @@
+#!/bin/dash
+# Check permissions and dependencies on installed DLLs
+# DLLs need execute permissions to be used
+# DLLs must be able to find their dependencies
+# This checks both of those, then does a direct test
+# The best way of checking whether a C extension module is importable
+# is trying to import it. The rest is trying to give reasons why it
+# isn't importing.
+#
+# One of the tools and the extension for shared libraries are
+# Cygwin-specific, but the rest should work on most platforms with
+# /bin/sh
+
+py_ver=3.7
+site_packages=$(python${py_ver} -m pip show numpy | \
+ grep Location | cut -d " " -f 2 -);
+dll_list=$(for name in $(python${py_ver} -m pip show -f numpy | \
+ grep -F .dll); do echo ${site_packages}/${name}; done)
+echo "Checks for existence, permissions and file type"
+ls -l ${dll_list}
+file ${dll_list}
+echo "Dependency checks"
+ldd ${dll_list} | grep -F -e " => not found" && exit 1
+cygcheck ${dll_list} >cygcheck_dll_list 2>cygcheck_missing_deps
+grep -F -e "cygcheck: track_down: could not find " cygcheck_missing_deps && exit 1
+echo "Import tests"
+mkdir -p dist/
+cd dist/
+for name in ${dll_list};
+do
+ echo ${name}
+ ext_module=$(echo ${name} | \
+ sed -E \
+ -e "s/^\/+(home|usr).*?site-packages\/+//" \
+ -e "s/.cpython-3.m?-x86(_64)?-cygwin.dll$//" \
+ -e "s/\//./g")
+ python${py_ver} -c "import ${ext_module}"
+done
diff --git a/tools/npy_tempita/__init__.py b/tools/npy_tempita/__init__.py
index 50a995104..fedcd91f4 100644
--- a/tools/npy_tempita/__init__.py
+++ b/tools/npy_tempita/__init__.py
@@ -705,7 +705,7 @@ lead_whitespace_re = re.compile(r'^[\t ]*\n')
def trim_lex(tokens):
r"""
- Takes a lexed set of tokens, and removes whitespace when there is
+ Takes a lexed list of tokens, and removes whitespace when there is
a directive on a line by itself:
>>> tokens = lex('{{if x}}\nx\n{{endif}}\ny', trim_whitespace=False)
diff --git a/tools/openblas_support.py b/tools/openblas_support.py
index 50837177b..9ab964e6f 100644
--- a/tools/openblas_support.py
+++ b/tools/openblas_support.py
@@ -2,6 +2,7 @@ import glob
import hashlib
import os
import platform
+import sysconfig
import sys
import shutil
import tarfile
@@ -12,97 +13,36 @@ from tempfile import mkstemp, gettempdir
from urllib.request import urlopen, Request
from urllib.error import HTTPError
-OPENBLAS_V = '0.3.12'
-# Temporary build of OpenBLAS to test a fix for dynamic detection of CPU
-OPENBLAS_LONG = 'v0.3.12-buffersize20'
+OPENBLAS_V = '0.3.17'
+OPENBLAS_LONG = 'v0.3.17'
BASE_LOC = 'https://anaconda.org/multibuild-wheels-staging/openblas-libs'
BASEURL = f'{BASE_LOC}/{OPENBLAS_LONG}/download'
-ARCHITECTURES = ['', 'windows', 'darwin', 'aarch64', 'x86_64',
- 'i686', 'ppc64le', 's390x']
-sha256_vals = {
- "openblas-v0.3.7-527-g79fd006c-win_amd64-gcc_7_1_0.zip":
- "7249d68c02e6b6339e06edfeab1fecddf29ee1e67a3afaa77917c320c43de840",
- "openblas64_-v0.3.7-527-g79fd006c-win_amd64-gcc_7_1_0.zip":
- "6488e0961a5926e47242f63b63b41cfdd661e6f1d267e8e313e397cde4775c17",
- "openblas-v0.3.7-527-g79fd006c-win32-gcc_7_1_0.zip":
- "5fb0867ca70b1d0fdbf68dd387c0211f26903d74631420e4aabb49e94aa3930d",
- "openblas-v0.3.7-527-g79fd006c-macosx_10_9_x86_64-gf_1becaaa.tar.gz":
- "69434bd626bbc495da9ce8c36b005d140c75e3c47f94e88c764a199e820f9259",
- "openblas64_-v0.3.7-527-g79fd006c-macosx_10_9_x86_64-gf_1becaaa.tar.gz":
- "093f6d953e3fa76a86809be67bd1f0b27656671b5a55b233169cfaa43fd63e22",
- "openblas-v0.3.7-527-g79fd006c-manylinux2014_aarch64.tar.gz":
- "42676c69dc48cd6e412251b39da6b955a5a0e00323ddd77f9137f7c259d35319",
- "openblas64_-v0.3.7-527-g79fd006c-manylinux2014_aarch64.tar.gz":
- "5aec167af4052cf5e9e3e416c522d9794efabf03a2aea78b9bb3adc94f0b73d8",
- "openblas-v0.3.7-527-g79fd006c-manylinux2010_x86_64.tar.gz":
- "fa67c6cc29d4cc5c70a147c80526243239a6f95fc3feadcf83a78176cd9c526b",
- "openblas64_-v0.3.7-527-g79fd006c-manylinux2010_x86_64.tar.gz":
- "9ad34e89a5307dcf5823bf5c020580d0559a0c155fe85b44fc219752e61852b0",
- "openblas-v0.3.7-527-g79fd006c-manylinux2010_i686.tar.gz":
- "0b8595d316c8b7be84ab1f1d5a0c89c1b35f7c987cdaf61d441bcba7ab4c7439",
- "openblas-v0.3.7-527-g79fd006c-manylinux2014_ppc64le.tar.gz":
- "3e1c7d6472c34e7210e3605be4bac9ddd32f613d44297dc50cf2d067e720c4a9",
- "openblas64_-v0.3.7-527-g79fd006c-manylinux2014_ppc64le.tar.gz":
- "a0885873298e21297a04be6cb7355a585df4fa4873e436b4c16c0a18fc9073ea",
- "openblas-v0.3.7-527-g79fd006c-manylinux2014_s390x.tar.gz":
- "79b454320817574e20499d58f05259ed35213bea0158953992b910607b17f240",
- "openblas64_-v0.3.7-527-g79fd006c-manylinux2014_s390x.tar.gz":
- "9fddbebf5301518fc4a5d2022a61886544a0566868c8c014359a1ee6b17f2814",
- "openblas-v0.3.7-527-g79fd006c-manylinux1_i686.tar.gz":
- "24fb92684ec4676185fff5c9340f50c3db6075948bcef760e9c715a8974e4680",
- "openblas-v0.3.7-527-g79fd006c-manylinux1_x86_64.tar.gz":
- "ebb8236b57a1b4075fd5cdc3e9246d2900c133a42482e5e714d1e67af5d00e62",
- "openblas-v0.3.10-win_amd64-gcc_7_1_0.zip":
- "e5356a2aa4aa7ed9233b2ca199fdd445f55ba227f004ebc63071dfa2426e9b09",
- "openblas64_-v0.3.10-win_amd64-gcc_7_1_0.zip":
- "aea3f9c8bdfe0b837f0d2739a6c755b12b6838f6c983e4ede71b4e1b576e6e77",
- "openblas-v0.3.10-win32-gcc_7_1_0.zip":
- "af1ad3172b23f7c6ef2234151a71d3be4d92010dad4dfb25d07cf5a20f009202",
- "openblas64_-v0.3.10-macosx_10_9_x86_64-gf_1becaaa.tar.gz":
- "38b61c58d63048731d6884fea7b63f8cbd610e85b138c6bac0e39fd77cd4699b",
- "openblas-v0.3.10-manylinux2014_aarch64.tar.gz":
- "c4444b9836ec26f7772fae02851961bf73177ff2aa436470e56fab8a1ef8d405",
- "openblas-v0.3.10-manylinux2010_x86_64.tar.gz":
- "cb7988c4a015aece9c49b1169f51c4ac2287fb9aab8114c8ab67792138ffc85e",
- "openblas-v0.3.10-manylinux2010_i686.tar.gz":
- "dc637801dd80ebd6394ea8b4a97f8858e4224870ea9214de08bebbdddd8e206e",
- "openblas-v0.3.10-manylinux1_x86_64.tar.gz":
- "ec1f9e9b2a62d5cb9e2634b88ee2da7cb6b07702d5a0e8b190d680a31adfa23a",
- "openblas-v0.3.10-manylinux1_i686.tar.gz":
- "b13d9d14e6bd452c0fbadb5cd5fda05b98b1e14043edb13ead90694d4cc07f0e",
- "openblas-v0.3.10-manylinux2014_ppc64le.tar.gz":
- "1cbc8176986099cf0cbb8f64968d5a14880d602d4b3c59a91d75b69b8760cde3",
- "openblas-v0.3.10-manylinux2014_s390x.tar.gz":
- "fa6722f0b12507ab0a65f38501ed8435b573df0adc0b979f47cdc4c9e9599475",
- "openblas-v0.3.10-macosx_10_9_x86_64-gf_1becaaa.tar.gz":
- "c6940b5133e687ae7a4f9c7c794f6a6d92b619cf41e591e5db07aab5da118199",
- "openblas64_-v0.3.10-manylinux2014_s390x.tar.gz":
- "e0347dd6f3f3a27d2f5e76d382e8a4a68e2e92f5f6a10e54ef65c7b14b44d0e8",
- "openblas64_-v0.3.10-manylinux2014_ppc64le.tar.gz":
- "4b96a51ac767ec0aabb821c61bcd3420e82e987fc93f7e1f85aebb2a845694eb",
- "openblas64_-v0.3.10-manylinux2010_x86_64.tar.gz":
- "f68fea21fbc73d06b7566057cad2ed8c7c0eb71fabf9ed8a609f86e5bc60ce5e",
- "openblas64_-v0.3.10-manylinux2014_aarch64.tar.gz":
- "15e6eed8cb0df8b88e52baa136ffe1769c517e9de7bcdfd81ec56420ae1069e9",
-}
-
-
+SUPPORTED_PLATFORMS = [
+ 'linux-aarch64',
+ 'linux-x86_64',
+ 'linux-i686',
+ 'linux-ppc64le',
+ 'linux-s390x',
+ 'win-amd64',
+ 'win-32',
+ 'macosx-x86_64',
+ 'macosx-arm64',
+]
IS_32BIT = sys.maxsize < 2**32
-def get_arch():
- if platform.system() == 'Windows':
- ret = 'windows'
- elif platform.system() == 'Darwin':
- ret = 'darwin'
- else:
- ret = platform.uname().machine
- # What do 32 bit machines report?
- # If they are a docker, they can report x86_64
- if 'x86' in ret and IS_32BIT:
- ret = 'i686'
- assert ret in ARCHITECTURES, f'invalid architecture {ret}'
- return ret
+def get_plat():
+ plat = sysconfig.get_platform()
+ plat_split = plat.split("-")
+ arch = plat_split[-1]
+ if arch == "win32":
+ plat = "win-32"
+ elif arch in ["universal2", "intel"]:
+ plat = f"macosx-{platform.uname().machine}"
+ elif len(plat_split) > 2:
+ plat = f"{plat_split[0]}-{arch}"
+ assert plat in SUPPORTED_PLATFORMS, f'invalid platform {plat}'
+ return plat
def get_ilp64():
@@ -120,34 +60,38 @@ def get_manylinux(arch):
default = '2014'
ret = os.environ.get("MB_ML_VER", default)
# XXX For PEP 600 this can be a glibc version
- assert ret in ('1', '2010', '2014'), f'invalid MB_ML_VER {ret}'
+ assert ret in ('1', '2010', '2014', '_2_24'), f'invalid MB_ML_VER {ret}'
return ret
-def download_openblas(target, arch, ilp64, is_32bit):
- ml_ver = get_manylinux(arch)
+def download_openblas(target, plat, ilp64):
+ osname, arch = plat.split("-")
fnsuffix = {None: "", "64_": "64_"}[ilp64]
filename = ''
headers = {'User-Agent':
('Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 ; '
'(KHTML, like Gecko) Chrome/41.0.2228.0 Safari/537.3')}
- if arch in ('aarch64', 'ppc64le', 's390x', 'x86_64', 'i686'):
+ suffix = None
+ if osname == "linux":
+ ml_ver = get_manylinux(arch)
suffix = f'manylinux{ml_ver}_{arch}.tar.gz'
- filename = f'{BASEURL}/openblas{fnsuffix}-{OPENBLAS_LONG}-{suffix}'
typ = 'tar.gz'
- elif arch == 'darwin':
+ elif plat == 'macosx-x86_64':
suffix = 'macosx_10_9_x86_64-gf_1becaaa.tar.gz'
- filename = f'{BASEURL}/openblas{fnsuffix}-{OPENBLAS_LONG}-{suffix}'
typ = 'tar.gz'
- elif arch == 'windows':
- if is_32bit:
+ elif plat == 'macosx-arm64':
+ suffix = 'macosx_11_0_arm64-gf_f26990f.tar.gz'
+ typ = 'tar.gz'
+ elif osname == 'win':
+ if plat == "win-32":
suffix = 'win32-gcc_8_1_0.zip'
else:
suffix = 'win_amd64-gcc_8_1_0.zip'
- filename = f'{BASEURL}/openblas{fnsuffix}-{OPENBLAS_LONG}-{suffix}'
typ = 'zip'
- if not filename:
+
+ if not suffix:
return None
+ filename = f'{BASEURL}/openblas{fnsuffix}-{OPENBLAS_LONG}-{suffix}'
req = Request(url=filename, headers=headers)
try:
response = urlopen(req)
@@ -162,22 +106,13 @@ def download_openblas(target, arch, ilp64, is_32bit):
data = response.read()
# Verify hash
key = os.path.basename(filename)
- sha256_returned = hashlib.sha256(data).hexdigest()
- if 0:
- if key not in sha256_vals:
- raise ValueError(
- f'\nkey "{key}" with hash "{sha256_returned}" not in sha256_vals\n')
- sha256_expected = sha256_vals[key]
- if sha256_returned != sha256_expected:
- # print(f'\nkey "{key}" with hash "{sha256_returned}" mismatch\n')
- raise ValueError(f'sha256 hash mismatch for filename {filename}')
print("Saving to file", file=sys.stderr)
with open(target, 'wb') as fid:
fid.write(data)
return typ
-def setup_openblas(arch=get_arch(), ilp64=get_ilp64(), is_32bit=IS_32BIT):
+def setup_openblas(plat=get_plat(), ilp64=get_ilp64()):
'''
Download and setup an openblas library for building. If successful,
the configuration script will find it automatically.
@@ -189,12 +124,13 @@ def setup_openblas(arch=get_arch(), ilp64=get_ilp64(), is_32bit=IS_32BIT):
To determine success, do ``os.path.exists(msg)``
'''
_, tmp = mkstemp()
- if not arch:
- raise ValueError('unknown architecture')
- typ = download_openblas(tmp, arch, ilp64, is_32bit)
+ if not plat:
+ raise ValueError('unknown platform')
+ typ = download_openblas(tmp, plat, ilp64)
if not typ:
return ''
- if arch == 'windows':
+ osname, arch = plat.split("-")
+ if osname == 'win':
if not typ == 'zip':
return f'expecting to download zipfile on windows, not {typ}'
return unpack_windows_zip(tmp)
@@ -213,7 +149,10 @@ def unpack_windows_zip(fname):
if not lib:
return 'could not find libopenblas_%s*.a ' \
'in downloaded zipfile' % OPENBLAS_LONG
- target = os.path.join(gettempdir(), 'openblas.a')
+ if get_ilp64() is None:
+ target = os.path.join(gettempdir(), 'openblas.a')
+ else:
+ target = os.path.join(gettempdir(), 'openblas64_.a')
with open(target, 'wb') as fid:
fid.write(zf.read(lib[0]))
return target
@@ -294,23 +233,22 @@ def make_init(dirname):
"""))
-def test_setup(arches):
+def test_setup(plats):
'''
Make sure all the downloadable files exist and can be opened
'''
def items():
- """ yields all combinations of arch, ilp64, is_32bit
+ """ yields all combinations of arch, ilp64
"""
- for arch in arches:
- yield arch, None, False
- if arch not in ('i686',):
- yield arch, '64_', False
- if arch in ('windows',):
- yield arch, None, True
- if arch in ('i686', 'x86_64'):
+ for plat in plats:
+ yield plat, None
+ osname, arch = plat.split("-")
+ if arch not in ('i686', 'arm64', '32'):
+ yield plat, '64_'
+ if osname == "linux" and arch in ('i686', 'x86_64'):
oldval = os.environ.get('MB_ML_VER', None)
os.environ['MB_ML_VER'] = '1'
- yield arch, None, False
+ yield plat, None
# Once we create x86_64 and i686 manylinux2014 wheels...
# os.environ['MB_ML_VER'] = '2014'
# yield arch, None, False
@@ -320,25 +258,23 @@ def test_setup(arches):
os.environ.pop('MB_ML_VER')
errs = []
- for arch, ilp64, is_32bit in items():
- if arch == '':
- continue
- if arch not in arches:
+ for plat, ilp64 in items():
+ osname, _ = plat.split("-")
+ if plat not in plats:
continue
target = None
try:
try:
- target = setup_openblas(arch, ilp64, is_32bit)
+ target = setup_openblas(plat, ilp64)
except Exception as e:
- print(f'Could not setup {arch} with ilp64 {ilp64}, '
- f'32bit {is_32bit}:')
+ print(f'Could not setup {plat} with ilp64 {ilp64}, ')
print(e)
errs.append(e)
continue
if not target:
- raise RuntimeError(f'Could not setup {arch}')
+ raise RuntimeError(f'Could not setup {plat}')
print(target)
- if arch == 'windows':
+ if osname == 'win':
if not target.endswith('.a'):
raise RuntimeError("Not .a extracted!")
else:
@@ -389,7 +325,7 @@ if __name__ == '__main__':
'architecture')
parser.add_argument('--test', nargs='*', default=None,
help='Test different architectures. "all", or any of '
- f'{ARCHITECTURES}')
+ f'{SUPPORTED_PLATFORMS}')
parser.add_argument('--check_version', nargs='?', default='',
help='Check provided OpenBLAS version string '
'against available OpenBLAS')
@@ -400,6 +336,6 @@ if __name__ == '__main__':
print(setup_openblas())
else:
if len(args.test) == 0 or 'all' in args.test:
- test_setup(ARCHITECTURES)
+ test_setup(SUPPORTED_PLATFORMS)
else:
test_setup(args.test)
diff --git a/tools/refguide_check.py b/tools/refguide_check.py
index 138e0ece7..9a6d1c9f8 100644
--- a/tools/refguide_check.py
+++ b/tools/refguide_check.py
@@ -19,11 +19,12 @@ another function, or deprecated, or ...)
Another use of this helper script is to check validity of code samples
in docstrings::
- $ python refguide_check.py --doctests ma
+ $ python tools/refguide_check.py --doctests ma
or in RST-based documentations::
- $ python refguide_check.py --rst docs
+ $ python tools/refguide_check.py --rst doc/source
+
"""
import copy
import doctest
@@ -165,9 +166,8 @@ def short_path(path, cwd=None):
Parameters
----------
- path: str or None
-
- cwd: str or None
+ path : str or None
+ cwd : str or None
Returns
-------
@@ -304,7 +304,7 @@ def compare(all_dict, others, names, module_name):
List of non deprecated sub modules for module_name
others : list
List of sub modules for module_name
- names : set
+ names : set
Set of function names or special directives present in
docstring of module_name
module_name : ModuleType
@@ -343,8 +343,8 @@ def is_deprecated(f):
"""
Check if module `f` is deprecated
- Parameter
- ---------
+ Parameters
+ ----------
f : ModuleType
Returns
@@ -779,13 +779,12 @@ def _run_doctests(tests, full_name, verbose, doctest_warnings):
Parameters
----------
- tests: list
+ tests : list
full_name : str
verbose : bool
-
- doctest_warning : bool
+ doctest_warnings : bool
Returns
-------
diff --git a/tools/swig/numpy.i b/tools/swig/numpy.i
index 60930c098..99ed073ab 100644
--- a/tools/swig/numpy.i
+++ b/tools/swig/numpy.i
@@ -2887,158 +2887,6 @@
}
%typemap(argout,
fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities")
- (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3)
-{
- npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
- PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
- PyArrayObject* array = (PyArrayObject*) obj;
-
- if (!array || !require_fortran(array)) SWIG_fail;
-
-%#ifdef SWIGPY_USE_CAPSULE
- PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
-%#else
- PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
-%#endif
-
-%#if NPY_API_VERSION < 0x00000007
- PyArray_BASE(array) = cap;
-%#else
- PyArray_SetBaseObject(array,cap);
-%#endif
-
- $result = SWIG_Python_AppendOutput($result,obj);
-}
-
-/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
- DATA_TYPE** ARGOUTVIEWM_FARRAY4)
- */
-%typemap(in,numinputs=0)
- (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEWM_FARRAY4)
- (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL )
-{
- $1 = &dim1_temp;
- $2 = &dim2_temp;
- $3 = &dim3_temp;
- $4 = &dim4_temp;
- $5 = &data_temp;
-}
-%typemap(argout,
- fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities")
- (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_FARRAY4)
-{
- npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
- PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
- PyArrayObject* array = (PyArrayObject*) obj;
-
- if (!array || !require_fortran(array)) SWIG_fail;
-
-%#ifdef SWIGPY_USE_CAPSULE
- PyObject* cap = PyCapsule_New((void*)(*$5), SWIGPY_CAPSULE_NAME, free_cap);
-%#else
- PyObject* cap = PyCObject_FromVoidPtr((void*)(*$5), free);
-%#endif
-
-%#if NPY_API_VERSION < 0x00000007
- PyArray_BASE(array) = cap;
-%#else
- PyArray_SetBaseObject(array,cap);
-%#endif
-
- $result = SWIG_Python_AppendOutput($result,obj);
-}
-
-/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
- DIM_TYPE* DIM3, DIM_TYPE* DIM4)
- */
-%typemap(in,numinputs=0)
- (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 )
- (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
-{
- $1 = &data_temp;
- $2 = &dim1_temp;
- $3 = &dim2_temp;
- $4 = &dim3_temp;
- $5 = &dim4_temp;
-}
-%typemap(argout,
- fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
- (DATA_TYPE** ARGOUTVIEWM_ARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
-{
- npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
- PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$1));
- PyArrayObject* array = (PyArrayObject*) obj;
-
- if (!array) SWIG_fail;
-
-%#ifdef SWIGPY_USE_CAPSULE
- PyObject* cap = PyCapsule_New((void*)(*$1), SWIGPY_CAPSULE_NAME, free_cap);
-%#else
- PyObject* cap = PyCObject_FromVoidPtr((void*)(*$1), free);
-%#endif
-
-%#if NPY_API_VERSION < 0x00000007
- PyArray_BASE(array) = cap;
-%#else
- PyArray_SetBaseObject(array,cap);
-%#endif
-
- $result = SWIG_Python_AppendOutput($result,obj);
-}
-
-/* Typemap suite for (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4,
- DATA_TYPE** ARGOUTVIEWM_ARRAY4)
- */
-%typemap(in,numinputs=0)
- (DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 , DATA_TYPE** ARGOUTVIEWM_ARRAY4)
- (DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp, DATA_TYPE* data_temp = NULL )
-{
- $1 = &dim1_temp;
- $2 = &dim2_temp;
- $3 = &dim3_temp;
- $4 = &dim4_temp;
- $5 = &data_temp;
-}
-%typemap(argout,
- fragment="NumPy_Backward_Compatibility,NumPy_Utilities")
- (DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4, DATA_TYPE** ARGOUTVIEWM_ARRAY4)
-{
- npy_intp dims[4] = { *$1, *$2, *$3 , *$4 };
- PyObject* obj = PyArray_SimpleNewFromData(4, dims, DATA_TYPECODE, (void*)(*$5));
- PyArrayObject* array = (PyArrayObject*) obj;
-
- if (!array) SWIG_fail;
-
-%#ifdef SWIGPY_USE_CAPSULE
- PyObject* cap = PyCapsule_New((void*)(*$5), SWIGPY_CAPSULE_NAME, free_cap);
-%#else
- PyObject* cap = PyCObject_FromVoidPtr((void*)(*$5), free);
-%#endif
-
-%#if NPY_API_VERSION < 0x00000007
- PyArray_BASE(array) = cap;
-%#else
- PyArray_SetBaseObject(array,cap);
-%#endif
-
- $result = SWIG_Python_AppendOutput($result,obj);
-}
-
-/* Typemap suite for (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2,
- DIM_TYPE* DIM3, DIM_TYPE* DIM4)
- */
-%typemap(in,numinputs=0)
- (DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1 , DIM_TYPE* DIM2 , DIM_TYPE* DIM3 , DIM_TYPE* DIM4 )
- (DATA_TYPE* data_temp = NULL , DIM_TYPE dim1_temp, DIM_TYPE dim2_temp, DIM_TYPE dim3_temp, DIM_TYPE dim4_temp)
-{
- $1 = &data_temp;
- $2 = &dim1_temp;
- $3 = &dim2_temp;
- $4 = &dim3_temp;
- $5 = &dim4_temp;
-}
-%typemap(argout,
- fragment="NumPy_Backward_Compatibility,NumPy_Array_Requirements,NumPy_Utilities")
(DATA_TYPE** ARGOUTVIEWM_FARRAY4, DIM_TYPE* DIM1, DIM_TYPE* DIM2, DIM_TYPE* DIM3, DIM_TYPE* DIM4)
{
npy_intp dims[4] = { *$2, *$3, *$4 , *$5 };
diff --git a/tools/travis-before-install.sh b/tools/travis-before-install.sh
index 81737af89..65aa4ad13 100755
--- a/tools/travis-before-install.sh
+++ b/tools/travis-before-install.sh
@@ -9,6 +9,7 @@ free -m
df -h
ulimit -a
+sudo apt update
sudo apt install gfortran eatmydata libgfortran5
if [ "$USE_DEBUG" ]
diff --git a/tools/travis-sorter.py b/tools/travis-sorter.py
index c13204f7e..416f9fe76 100755
--- a/tools/travis-sorter.py
+++ b/tools/travis-sorter.py
@@ -103,7 +103,7 @@ def summarise(jobs):
print(" " + "-" * end)
-class Job(object):
+class Job:
def __init__(self, length):
global count
self.id = count
diff --git a/tools/travis-test.sh b/tools/travis-test.sh
index e9ddae61a..4667db991 100755
--- a/tools/travis-test.sh
+++ b/tools/travis-test.sh
@@ -36,21 +36,33 @@ setup_base()
sysflags="$($PYTHON -c "from distutils import sysconfig; \
print (sysconfig.get_config_var('CFLAGS'))")"
export CFLAGS="$sysflags $werrors -Wlogical-op -Wno-sign-compare"
+ # SIMD extensions that need to be tested on both runtime and compile-time via (test_simd.py)
+ # any specified features will be ignored if they're not supported by compiler or platform
+ # note: it almost the same default value of --simd-test execpt adding policy `$werror` to treat all
+ # warnings as errors
+ simd_test="\$werror BASELINE SSE2 SSE42 XOP FMA4 (FMA3 AVX2) AVX512F AVX512_SKX VSX VSX2 VSX3 NEON ASIMD"
# We used to use 'setup.py install' here, but that has the terrible
# behaviour that if a copy of the package is already installed in the
# install location, then the new copy just gets dropped on top of it.
# Travis typically has a stable numpy release pre-installed, and if we
# don't remove it, then we can accidentally end up e.g. running old
# test modules that were in the stable release but have been removed
- # from master. (See gh-2765, gh-2768.) Using 'pip install' also has
+ # from main. (See gh-2765, gh-2768.) Using 'pip install' also has
# the advantage that it tests that numpy is 'pip install' compatible,
# see e.g. gh-2766...
if [ -z "$USE_DEBUG" ]; then
- $PIP install -v . 2>&1 | tee log
+ # activates '-Werror=undef' when DEBUG isn't enabled since _cffi_backend'
+ # extension breaks the build due to the following error:
+ #
+ # error: "HAVE_FFI_PREP_CIF_VAR" is not defined, evaluates to 0 [-Werror=undef]
+ # #if !HAVE_FFI_PREP_CIF_VAR && defined(__arm64__) && defined(__APPLE__)
+ #
+ export CFLAGS="$CFLAGS -Werror=undef"
+ $PYTHON setup.py build --simd-test "$simd_test" install 2>&1 | tee log
else
# The job run with USE_DEBUG=1 on travis needs this.
export CFLAGS=$CFLAGS" -Wno-maybe-uninitialized"
- $PYTHON setup.py build build_src --verbose-cfg build_ext --inplace 2>&1 | tee log
+ $PYTHON setup.py build --simd-test "$simd_test" build_src --verbose-cfg build_ext --inplace 2>&1 | tee log
fi
grep -v "_configtest" log \
| grep -vE "ld returned 1|no files found matching" \
diff --git a/tox.ini b/tox.ini
index e58dd6efe..9bc2bbac3 100644
--- a/tox.ini
+++ b/tox.ini
@@ -26,7 +26,7 @@
[tox]
envlist =
- py36,py37,py38,
+ py37,py38,py39,
py37-not-relaxed-strides
[testenv]
diff --git a/versioneer.py b/versioneer.py
new file mode 100644
index 000000000..7aa415ac8
--- /dev/null
+++ b/versioneer.py
@@ -0,0 +1,1852 @@
+
+# Version: 0.19
+
+"""The Versioneer - like a rocketeer, but for versions.
+
+The Versioneer
+==============
+
+* like a rocketeer, but for versions!
+* https://github.com/python-versioneer/python-versioneer
+* Brian Warner
+* License: Public Domain
+* Compatible with: Python 3.6, 3.7, 3.8, 3.9 and pypy3
+* [![Latest Version][pypi-image]][pypi-url]
+* [![Build Status][travis-image]][travis-url]
+
+This is a tool for managing a recorded version number in distutils-based
+python projects. The goal is to remove the tedious and error-prone "update
+the embedded version string" step from your release process. Making a new
+release should be as easy as recording a new tag in your version-control
+system, and maybe making new tarballs.
+
+
+## Quick Install
+
+* `pip install versioneer` to somewhere in your $PATH
+* add a `[versioneer]` section to your setup.cfg (see [Install](INSTALL.md))
+* run `versioneer install` in your source tree, commit the results
+* Verify version information with `python setup.py version`
+
+## Version Identifiers
+
+Source trees come from a variety of places:
+
+* a version-control system checkout (mostly used by developers)
+* a nightly tarball, produced by build automation
+* a snapshot tarball, produced by a web-based VCS browser, like github's
+ "tarball from tag" feature
+* a release tarball, produced by "setup.py sdist", distributed through PyPI
+
+Within each source tree, the version identifier (either a string or a number,
+this tool is format-agnostic) can come from a variety of places:
+
+* ask the VCS tool itself, e.g. "git describe" (for checkouts), which knows
+ about recent "tags" and an absolute revision-id
+* the name of the directory into which the tarball was unpacked
+* an expanded VCS keyword ($Id$, etc)
+* a `_version.py` created by some earlier build step
+
+For released software, the version identifier is closely related to a VCS
+tag. Some projects use tag names that include more than just the version
+string (e.g. "myproject-1.2" instead of just "1.2"), in which case the tool
+needs to strip the tag prefix to extract the version identifier. For
+unreleased software (between tags), the version identifier should provide
+enough information to help developers recreate the same tree, while also
+giving them an idea of roughly how old the tree is (after version 1.2, before
+version 1.3). Many VCS systems can report a description that captures this,
+for example `git describe --tags --dirty --always` reports things like
+"0.7-1-g574ab98-dirty" to indicate that the checkout is one revision past the
+0.7 tag, has a unique revision id of "574ab98", and is "dirty" (it has
+uncommitted changes).
+
+The version identifier is used for multiple purposes:
+
+* to allow the module to self-identify its version: `myproject.__version__`
+* to choose a name and prefix for a 'setup.py sdist' tarball
+
+## Theory of Operation
+
+Versioneer works by adding a special `_version.py` file into your source
+tree, where your `__init__.py` can import it. This `_version.py` knows how to
+dynamically ask the VCS tool for version information at import time.
+
+`_version.py` also contains `$Revision$` markers, and the installation
+process marks `_version.py` to have this marker rewritten with a tag name
+during the `git archive` command. As a result, generated tarballs will
+contain enough information to get the proper version.
+
+To allow `setup.py` to compute a version too, a `versioneer.py` is added to
+the top level of your source tree, next to `setup.py` and the `setup.cfg`
+that configures it. This overrides several distutils/setuptools commands to
+compute the version when invoked, and changes `setup.py build` and `setup.py
+sdist` to replace `_version.py` with a small static file that contains just
+the generated version data.
+
+## Installation
+
+See [INSTALL.md](./INSTALL.md) for detailed installation instructions.
+
+## Version-String Flavors
+
+Code which uses Versioneer can learn about its version string at runtime by
+importing `_version` from your main `__init__.py` file and running the
+`get_versions()` function. From the "outside" (e.g. in `setup.py`), you can
+import the top-level `versioneer.py` and run `get_versions()`.
+
+Both functions return a dictionary with different flavors of version
+information:
+
+* `['version']`: A condensed version string, rendered using the selected
+ style. This is the most commonly used value for the project's version
+ string. The default "pep440" style yields strings like `0.11`,
+ `0.11+2.g1076c97`, or `0.11+2.g1076c97.dirty`. See the "Styles" section
+ below for alternative styles.
+
+* `['full-revisionid']`: detailed revision identifier. For Git, this is the
+ full SHA1 commit id, e.g. "1076c978a8d3cfc70f408fe5974aa6c092c949ac".
+
+* `['date']`: Date and time of the latest `HEAD` commit. For Git, it is the
+ commit date in ISO 8601 format. This will be None if the date is not
+ available.
+
+* `['dirty']`: a boolean, True if the tree has uncommitted changes. Note that
+ this is only accurate if run in a VCS checkout, otherwise it is likely to
+ be False or None
+
+* `['error']`: if the version string could not be computed, this will be set
+ to a string describing the problem, otherwise it will be None. It may be
+ useful to throw an exception in setup.py if this is set, to avoid e.g.
+ creating tarballs with a version string of "unknown".
+
+Some variants are more useful than others. Including `full-revisionid` in a
+bug report should allow developers to reconstruct the exact code being tested
+(or indicate the presence of local changes that should be shared with the
+developers). `version` is suitable for display in an "about" box or a CLI
+`--version` output: it can be easily compared against release notes and lists
+of bugs fixed in various releases.
+
+The installer adds the following text to your `__init__.py` to place a basic
+version in `YOURPROJECT.__version__`:
+
+ from ._version import get_versions
+ __version__ = get_versions()['version']
+ del get_versions
+
+## Styles
+
+The setup.cfg `style=` configuration controls how the VCS information is
+rendered into a version string.
+
+The default style, "pep440", produces a PEP440-compliant string, equal to the
+un-prefixed tag name for actual releases, and containing an additional "local
+version" section with more detail for in-between builds. For Git, this is
+TAG[+DISTANCE.gHEX[.dirty]] , using information from `git describe --tags
+--dirty --always`. For example "0.11+2.g1076c97.dirty" indicates that the
+tree is like the "1076c97" commit but has uncommitted changes (".dirty"), and
+that this commit is two revisions ("+2") beyond the "0.11" tag. For released
+software (exactly equal to a known tag), the identifier will only contain the
+stripped tag, e.g. "0.11".
+
+Other styles are available. See [details.md](details.md) in the Versioneer
+source tree for descriptions.
+
+## Debugging
+
+Versioneer tries to avoid fatal errors: if something goes wrong, it will tend
+to return a version of "0+unknown". To investigate the problem, run `setup.py
+version`, which will run the version-lookup code in a verbose mode, and will
+display the full contents of `get_versions()` (including the `error` string,
+which may help identify what went wrong).
+
+## Known Limitations
+
+Some situations are known to cause problems for Versioneer. This details the
+most significant ones. More can be found on Github
+[issues page](https://github.com/python-versioneer/python-versioneer/issues).
+
+### Subprojects
+
+Versioneer has limited support for source trees in which `setup.py` is not in
+the root directory (e.g. `setup.py` and `.git/` are *not* siblings). The are
+two common reasons why `setup.py` might not be in the root:
+
+* Source trees which contain multiple subprojects, such as
+ [Buildbot](https://github.com/buildbot/buildbot), which contains both
+ "master" and "slave" subprojects, each with their own `setup.py`,
+ `setup.cfg`, and `tox.ini`. Projects like these produce multiple PyPI
+ distributions (and upload multiple independently-installable tarballs).
+* Source trees whose main purpose is to contain a C library, but which also
+ provide bindings to Python (and perhaps other languages) in subdirectories.
+
+Versioneer will look for `.git` in parent directories, and most operations
+should get the right version string. However `pip` and `setuptools` have bugs
+and implementation details which frequently cause `pip install .` from a
+subproject directory to fail to find a correct version string (so it usually
+defaults to `0+unknown`).
+
+`pip install --editable .` should work correctly. `setup.py install` might
+work too.
+
+Pip-8.1.1 is known to have this problem, but hopefully it will get fixed in
+some later version.
+
+[Bug #38](https://github.com/python-versioneer/python-versioneer/issues/38) is tracking
+this issue. The discussion in
+[PR #61](https://github.com/python-versioneer/python-versioneer/pull/61) describes the
+issue from the Versioneer side in more detail.
+[pip PR#3176](https://github.com/pypa/pip/pull/3176) and
+[pip PR#3615](https://github.com/pypa/pip/pull/3615) contain work to improve
+pip to let Versioneer work correctly.
+
+Versioneer-0.16 and earlier only looked for a `.git` directory next to the
+`setup.cfg`, so subprojects were completely unsupported with those releases.
+
+### Editable installs with setuptools <= 18.5
+
+`setup.py develop` and `pip install --editable .` allow you to install a
+project into a virtualenv once, then continue editing the source code (and
+test) without re-installing after every change.
+
+"Entry-point scripts" (`setup(entry_points={"console_scripts": ..})`) are a
+convenient way to specify executable scripts that should be installed along
+with the python package.
+
+These both work as expected when using modern setuptools. When using
+setuptools-18.5 or earlier, however, certain operations will cause
+`pkg_resources.DistributionNotFound` errors when running the entrypoint
+script, which must be resolved by re-installing the package. This happens
+when the install happens with one version, then the egg_info data is
+regenerated while a different version is checked out. Many setup.py commands
+cause egg_info to be rebuilt (including `sdist`, `wheel`, and installing into
+a different virtualenv), so this can be surprising.
+
+[Bug #83](https://github.com/python-versioneer/python-versioneer/issues/83) describes
+this one, but upgrading to a newer version of setuptools should probably
+resolve it.
+
+
+## Updating Versioneer
+
+To upgrade your project to a new release of Versioneer, do the following:
+
+* install the new Versioneer (`pip install -U versioneer` or equivalent)
+* edit `setup.cfg`, if necessary, to include any new configuration settings
+ indicated by the release notes. See [UPGRADING](./UPGRADING.md) for details.
+* re-run `versioneer install` in your source tree, to replace
+ `SRC/_version.py`
+* commit any changed files
+
+## Future Directions
+
+This tool is designed to make it easily extended to other version-control
+systems: all VCS-specific components are in separate directories like
+src/git/ . The top-level `versioneer.py` script is assembled from these
+components by running make-versioneer.py . In the future, make-versioneer.py
+will take a VCS name as an argument, and will construct a version of
+`versioneer.py` that is specific to the given VCS. It might also take the
+configuration arguments that are currently provided manually during
+installation by editing setup.py . Alternatively, it might go the other
+direction and include code from all supported VCS systems, reducing the
+number of intermediate scripts.
+
+## Similar projects
+
+* [setuptools_scm](https://github.com/pypa/setuptools_scm/) - a non-vendored build-time
+ dependency
+* [minver](https://github.com/jbweston/miniver) - a lightweight reimplementation of
+ versioneer
+
+## License
+
+To make Versioneer easier to embed, all its code is dedicated to the public
+domain. The `_version.py` that it creates is also in the public domain.
+Specifically, both are released under the Creative Commons "Public Domain
+Dedication" license (CC0-1.0), as described in
+https://creativecommons.org/publicdomain/zero/1.0/ .
+
+[pypi-image]: https://img.shields.io/pypi/v/versioneer.svg
+[pypi-url]: https://pypi.python.org/pypi/versioneer/
+[travis-image]:
+https://img.shields.io/travis/com/python-versioneer/python-versioneer.svg
+[travis-url]: https://travis-ci.com/github/python-versioneer/python-versioneer
+
+"""
+
+import configparser
+import errno
+import json
+import os
+import re
+import subprocess
+import sys
+
+
+class VersioneerConfig:
+ """Container for Versioneer configuration parameters."""
+
+
+def get_root():
+ """Get the project root directory.
+
+ We require that all commands are run from the project root, i.e. the
+ directory that contains setup.py, setup.cfg, and versioneer.py .
+ """
+ root = os.path.realpath(os.path.abspath(os.getcwd()))
+ setup_py = os.path.join(root, "setup.py")
+ versioneer_py = os.path.join(root, "versioneer.py")
+ if not (os.path.exists(setup_py) or os.path.exists(versioneer_py)):
+ # allow 'python path/to/setup.py COMMAND'
+ root = os.path.dirname(os.path.realpath(os.path.abspath(sys.argv[0])))
+ setup_py = os.path.join(root, "setup.py")
+ versioneer_py = os.path.join(root, "versioneer.py")
+ if not (os.path.exists(setup_py) or os.path.exists(versioneer_py)):
+ err = ("Versioneer was unable to run the project root directory. "
+ "Versioneer requires setup.py to be executed from "
+ "its immediate directory (like 'python setup.py COMMAND'), "
+ "or in a way that lets it use sys.argv[0] to find the root "
+ "(like 'python path/to/setup.py COMMAND').")
+ raise VersioneerBadRootError(err)
+ try:
+ # Certain runtime workflows (setup.py install/develop in a setuptools
+ # tree) execute all dependencies in a single python process, so
+ # "versioneer" may be imported multiple times, and python's shared
+ # module-import table will cache the first one. So we can't use
+ # os.path.dirname(__file__), as that will find whichever
+ # versioneer.py was first imported, even in later projects.
+ me = os.path.realpath(os.path.abspath(__file__))
+ me_dir = os.path.normcase(os.path.splitext(me)[0])
+ vsr_dir = os.path.normcase(os.path.splitext(versioneer_py)[0])
+ if me_dir != vsr_dir:
+ print("Warning: build in %s is using versioneer.py from %s"
+ % (os.path.dirname(me), versioneer_py))
+ except NameError:
+ pass
+ return root
+
+
+def get_config_from_root(root):
+ """Read the project setup.cfg file to determine Versioneer config."""
+ # This might raise EnvironmentError (if setup.cfg is missing), or
+ # configparser.NoSectionError (if it lacks a [versioneer] section), or
+ # configparser.NoOptionError (if it lacks "VCS="). See the docstring at
+ # the top of versioneer.py for instructions on writing your setup.cfg .
+ setup_cfg = os.path.join(root, "setup.cfg")
+ parser = configparser.ConfigParser()
+ with open(setup_cfg, "r") as f:
+ parser.read_file(f)
+ VCS = parser.get("versioneer", "VCS") # mandatory
+
+ def get(parser, name):
+ if parser.has_option("versioneer", name):
+ return parser.get("versioneer", name)
+ return None
+ cfg = VersioneerConfig()
+ cfg.VCS = VCS
+ cfg.style = get(parser, "style") or ""
+ cfg.versionfile_source = get(parser, "versionfile_source")
+ cfg.versionfile_build = get(parser, "versionfile_build")
+ cfg.tag_prefix = get(parser, "tag_prefix")
+ if cfg.tag_prefix in ("''", '""'):
+ cfg.tag_prefix = ""
+ cfg.parentdir_prefix = get(parser, "parentdir_prefix")
+ cfg.verbose = get(parser, "verbose")
+ return cfg
+
+
+class NotThisMethod(Exception):
+ """Exception raised if a method is not valid for the current scenario."""
+
+
+# these dictionaries contain VCS-specific tools
+LONG_VERSION_PY = {}
+HANDLERS = {}
+
+
+def register_vcs_handler(vcs, method): # decorator
+ """Create decorator to mark a method as the handler of a VCS."""
+ def decorate(f):
+ """Store f in HANDLERS[vcs][method]."""
+ if vcs not in HANDLERS:
+ HANDLERS[vcs] = {}
+ HANDLERS[vcs][method] = f
+ return f
+ return decorate
+
+
+def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False,
+ env=None):
+ """Call the given command(s)."""
+ assert isinstance(commands, list)
+ p = None
+ for c in commands:
+ try:
+ dispcmd = str([c] + args)
+ # remember shell=False, so use git.cmd on windows, not just git
+ p = subprocess.Popen([c] + args, cwd=cwd, env=env,
+ stdout=subprocess.PIPE,
+ stderr=(subprocess.PIPE if hide_stderr
+ else None))
+ break
+ except EnvironmentError:
+ e = sys.exc_info()[1]
+ if e.errno == errno.ENOENT:
+ continue
+ if verbose:
+ print("unable to run %s" % dispcmd)
+ print(e)
+ return None, None
+ else:
+ if verbose:
+ print("unable to find command, tried %s" % (commands,))
+ return None, None
+ stdout = p.communicate()[0].strip().decode()
+ if p.returncode != 0:
+ if verbose:
+ print("unable to run %s (error)" % dispcmd)
+ print("stdout was %s" % stdout)
+ return None, p.returncode
+ return stdout, p.returncode
+
+
+LONG_VERSION_PY['git'] = r'''
+# This file helps to compute a version number in source trees obtained from
+# git-archive tarball (such as those provided by githubs download-from-tag
+# feature). Distribution tarballs (built by setup.py sdist) and build
+# directories (produced by setup.py build) will contain a much shorter file
+# that just contains the computed version number.
+
+# This file is released into the public domain. Generated by
+# versioneer-0.19 (https://github.com/python-versioneer/python-versioneer)
+
+"""Git implementation of _version.py."""
+
+import errno
+import os
+import re
+import subprocess
+import sys
+
+
+def get_keywords():
+ """Get the keywords needed to look up the version information."""
+ # these strings will be replaced by git during git-archive.
+ # setup.py/versioneer.py will grep for the variable names, so they must
+ # each be defined on a line of their own. _version.py will just call
+ # get_keywords().
+ git_refnames = "%(DOLLAR)sFormat:%%d%(DOLLAR)s"
+ git_full = "%(DOLLAR)sFormat:%%H%(DOLLAR)s"
+ git_date = "%(DOLLAR)sFormat:%%ci%(DOLLAR)s"
+ keywords = {"refnames": git_refnames, "full": git_full, "date": git_date}
+ return keywords
+
+
+class VersioneerConfig:
+ """Container for Versioneer configuration parameters."""
+
+
+def get_config():
+ """Create, populate and return the VersioneerConfig() object."""
+ # these strings are filled in when 'setup.py versioneer' creates
+ # _version.py
+ cfg = VersioneerConfig()
+ cfg.VCS = "git"
+ cfg.style = "%(STYLE)s"
+ cfg.tag_prefix = "%(TAG_PREFIX)s"
+ cfg.parentdir_prefix = "%(PARENTDIR_PREFIX)s"
+ cfg.versionfile_source = "%(VERSIONFILE_SOURCE)s"
+ cfg.verbose = False
+ return cfg
+
+
+class NotThisMethod(Exception):
+ """Exception raised if a method is not valid for the current scenario."""
+
+
+LONG_VERSION_PY = {}
+HANDLERS = {}
+
+
+def register_vcs_handler(vcs, method): # decorator
+ """Create decorator to mark a method as the handler of a VCS."""
+ def decorate(f):
+ """Store f in HANDLERS[vcs][method]."""
+ if vcs not in HANDLERS:
+ HANDLERS[vcs] = {}
+ HANDLERS[vcs][method] = f
+ return f
+ return decorate
+
+
+def run_command(commands, args, cwd=None, verbose=False, hide_stderr=False,
+ env=None):
+ """Call the given command(s)."""
+ assert isinstance(commands, list)
+ p = None
+ for c in commands:
+ try:
+ dispcmd = str([c] + args)
+ # remember shell=False, so use git.cmd on windows, not just git
+ p = subprocess.Popen([c] + args, cwd=cwd, env=env,
+ stdout=subprocess.PIPE,
+ stderr=(subprocess.PIPE if hide_stderr
+ else None))
+ break
+ except EnvironmentError:
+ e = sys.exc_info()[1]
+ if e.errno == errno.ENOENT:
+ continue
+ if verbose:
+ print("unable to run %%s" %% dispcmd)
+ print(e)
+ return None, None
+ else:
+ if verbose:
+ print("unable to find command, tried %%s" %% (commands,))
+ return None, None
+ stdout = p.communicate()[0].strip().decode()
+ if p.returncode != 0:
+ if verbose:
+ print("unable to run %%s (error)" %% dispcmd)
+ print("stdout was %%s" %% stdout)
+ return None, p.returncode
+ return stdout, p.returncode
+
+
+def versions_from_parentdir(parentdir_prefix, root, verbose):
+ """Try to determine the version from the parent directory name.
+
+ Source tarballs conventionally unpack into a directory that includes both
+ the project name and a version string. We will also support searching up
+ two directory levels for an appropriately named parent directory
+ """
+ rootdirs = []
+
+ for i in range(3):
+ dirname = os.path.basename(root)
+ if dirname.startswith(parentdir_prefix):
+ return {"version": dirname[len(parentdir_prefix):],
+ "full-revisionid": None,
+ "dirty": False, "error": None, "date": None}
+ else:
+ rootdirs.append(root)
+ root = os.path.dirname(root) # up a level
+
+ if verbose:
+ print("Tried directories %%s but none started with prefix %%s" %%
+ (str(rootdirs), parentdir_prefix))
+ raise NotThisMethod("rootdir doesn't start with parentdir_prefix")
+
+
+@register_vcs_handler("git", "get_keywords")
+def git_get_keywords(versionfile_abs):
+ """Extract version information from the given file."""
+ # the code embedded in _version.py can just fetch the value of these
+ # keywords. When used from setup.py, we don't want to import _version.py,
+ # so we do it with a regexp instead. This function is not used from
+ # _version.py.
+ keywords = {}
+ try:
+ f = open(versionfile_abs, "r")
+ for line in f.readlines():
+ if line.strip().startswith("git_refnames ="):
+ mo = re.search(r'=\s*"(.*)"', line)
+ if mo:
+ keywords["refnames"] = mo.group(1)
+ if line.strip().startswith("git_full ="):
+ mo = re.search(r'=\s*"(.*)"', line)
+ if mo:
+ keywords["full"] = mo.group(1)
+ if line.strip().startswith("git_date ="):
+ mo = re.search(r'=\s*"(.*)"', line)
+ if mo:
+ keywords["date"] = mo.group(1)
+ f.close()
+ except EnvironmentError:
+ pass
+ return keywords
+
+
+@register_vcs_handler("git", "keywords")
+def git_versions_from_keywords(keywords, tag_prefix, verbose):
+ """Get version information from git keywords."""
+ if not keywords:
+ raise NotThisMethod("no keywords at all, weird")
+ date = keywords.get("date")
+ if date is not None:
+ # Use only the last line. Previous lines may contain GPG signature
+ # information.
+ date = date.splitlines()[-1]
+
+ # git-2.2.0 added "%%cI", which expands to an ISO-8601 -compliant
+ # datestamp. However we prefer "%%ci" (which expands to an "ISO-8601
+ # -like" string, which we must then edit to make compliant), because
+ # it's been around since git-1.5.3, and it's too difficult to
+ # discover which version we're using, or to work around using an
+ # older one.
+ date = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
+ refnames = keywords["refnames"].strip()
+ if refnames.startswith("$Format"):
+ if verbose:
+ print("keywords are unexpanded, not using")
+ raise NotThisMethod("unexpanded keywords, not a git-archive tarball")
+ refs = set([r.strip() for r in refnames.strip("()").split(",")])
+ # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of
+ # just "foo-1.0". If we see a "tag: " prefix, prefer those.
+ TAG = "tag: "
+ tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)])
+ if not tags:
+ # Either we're using git < 1.8.3, or there really are no tags. We use
+ # a heuristic: assume all version tags have a digit. The old git %%d
+ # expansion behaves like git log --decorate=short and strips out the
+ # refs/heads/ and refs/tags/ prefixes that would let us distinguish
+ # between branches and tags. By ignoring refnames without digits, we
+ # filter out many common branch names like "release" and
+ # "stabilization", as well as "HEAD" and "master".
+ tags = set([r for r in refs if re.search(r'\d', r)])
+ if verbose:
+ print("discarding '%%s', no digits" %% ",".join(refs - tags))
+ if verbose:
+ print("likely tags: %%s" %% ",".join(sorted(tags)))
+ for ref in sorted(tags):
+ # sorting will prefer e.g. "2.0" over "2.0rc1"
+ if ref.startswith(tag_prefix):
+ r = ref[len(tag_prefix):]
+ if verbose:
+ print("picking %%s" %% r)
+ return {"version": r,
+ "full-revisionid": keywords["full"].strip(),
+ "dirty": False, "error": None,
+ "date": date}
+ # no suitable tags, so version is "0+unknown", but full hex is still there
+ if verbose:
+ print("no suitable tags, using unknown + full revision id")
+ return {"version": "0+unknown",
+ "full-revisionid": keywords["full"].strip(),
+ "dirty": False, "error": "no suitable tags", "date": None}
+
+
+@register_vcs_handler("git", "pieces_from_vcs")
+def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command):
+ """Get version from 'git describe' in the root of the source tree.
+
+ This only gets called if the git-archive 'subst' keywords were *not*
+ expanded, and _version.py hasn't already been rewritten with a short
+ version string, meaning we're inside a checked out source tree.
+ """
+ GITS = ["git"]
+ if sys.platform == "win32":
+ GITS = ["git.cmd", "git.exe"]
+
+ out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root,
+ hide_stderr=True)
+ if rc != 0:
+ if verbose:
+ print("Directory %%s not under git control" %% root)
+ raise NotThisMethod("'git rev-parse --git-dir' returned error")
+
+ # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty]
+ # if there isn't one, this yields HEX[-dirty] (no NUM)
+ describe_out, rc = run_command(GITS, ["describe", "--tags", "--dirty=",
+ "--always", "--long",
+ "--match", "%%s*" %% tag_prefix],
+ cwd=root)
+ # --long was added in git-1.5.5
+ if describe_out is None:
+ raise NotThisMethod("'git describe' failed")
+ describe_out = describe_out.strip()
+ full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root)
+ if full_out is None:
+ raise NotThisMethod("'git rev-parse' failed")
+ full_out = full_out.strip()
+
+ pieces = {}
+ pieces["long"] = full_out
+ pieces["short"] = full_out[:7] # maybe improved later
+ pieces["error"] = None
+
+ # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty]
+ # TAG might have hyphens.
+ git_describe = describe_out
+
+ # look for -dirty suffix
+ dirty = git_describe.endswith("-dirty")
+ pieces["dirty"] = dirty
+ if dirty:
+ git_describe = git_describe[:git_describe.rindex("-dirty")]
+
+ # now we have TAG-NUM-gHEX or HEX
+
+ if "-" in git_describe:
+ # TAG-NUM-gHEX
+ mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe)
+ if not mo:
+ # unparseable. Maybe git-describe is misbehaving?
+ pieces["error"] = ("unable to parse git-describe output: '%%s'"
+ %% describe_out)
+ return pieces
+
+ # tag
+ full_tag = mo.group(1)
+ if not full_tag.startswith(tag_prefix):
+ if verbose:
+ fmt = "tag '%%s' doesn't start with prefix '%%s'"
+ print(fmt %% (full_tag, tag_prefix))
+ pieces["error"] = ("tag '%%s' doesn't start with prefix '%%s'"
+ %% (full_tag, tag_prefix))
+ return pieces
+ pieces["closest-tag"] = full_tag[len(tag_prefix):]
+
+ # distance: number of commits since tag
+ pieces["distance"] = int(mo.group(2))
+
+ # commit: short hex revision ID
+ pieces["short"] = mo.group(3)
+
+ else:
+ # HEX: no tags
+ pieces["closest-tag"] = None
+ count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"],
+ cwd=root)
+ pieces["distance"] = int(count_out) # total number of commits
+
+ # commit date: see ISO-8601 comment in git_versions_from_keywords()
+ date = run_command(GITS, ["show", "-s", "--format=%%ci", "HEAD"],
+ cwd=root)[0].strip()
+ # Use only the last line. Previous lines may contain GPG signature
+ # information.
+ date = date.splitlines()[-1]
+ pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
+
+ return pieces
+
+
+def plus_or_dot(pieces):
+ """Return a + if we don't already have one, else return a ."""
+ if "+" in pieces.get("closest-tag", ""):
+ return "."
+ return "+"
+
+
+def render_pep440(pieces):
+ """Build up version string, with post-release "local version identifier".
+
+ Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you
+ get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty
+
+ Exceptions:
+ 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty]
+ """
+ if pieces["closest-tag"]:
+ rendered = pieces["closest-tag"]
+ if pieces["distance"] or pieces["dirty"]:
+ rendered += plus_or_dot(pieces)
+ rendered += "%%d.g%%s" %% (pieces["distance"], pieces["short"])
+ if pieces["dirty"]:
+ rendered += ".dirty"
+ else:
+ # exception #1
+ rendered = "0+untagged.%%d.g%%s" %% (pieces["distance"],
+ pieces["short"])
+ if pieces["dirty"]:
+ rendered += ".dirty"
+ return rendered
+
+
+def render_pep440_pre(pieces):
+ """TAG[.post0.devDISTANCE] -- No -dirty.
+
+ Exceptions:
+ 1: no tags. 0.post0.devDISTANCE
+ """
+ if pieces["closest-tag"]:
+ rendered = pieces["closest-tag"]
+ if pieces["distance"]:
+ rendered += ".post0.dev%%d" %% pieces["distance"]
+ else:
+ # exception #1
+ rendered = "0.post0.dev%%d" %% pieces["distance"]
+ return rendered
+
+
+def render_pep440_post(pieces):
+ """TAG[.postDISTANCE[.dev0]+gHEX] .
+
+ The ".dev0" means dirty. Note that .dev0 sorts backwards
+ (a dirty tree will appear "older" than the corresponding clean one),
+ but you shouldn't be releasing software with -dirty anyways.
+
+ Exceptions:
+ 1: no tags. 0.postDISTANCE[.dev0]
+ """
+ if pieces["closest-tag"]:
+ rendered = pieces["closest-tag"]
+ if pieces["distance"] or pieces["dirty"]:
+ rendered += ".post%%d" %% pieces["distance"]
+ if pieces["dirty"]:
+ rendered += ".dev0"
+ rendered += plus_or_dot(pieces)
+ rendered += "g%%s" %% pieces["short"]
+ else:
+ # exception #1
+ rendered = "0.post%%d" %% pieces["distance"]
+ if pieces["dirty"]:
+ rendered += ".dev0"
+ rendered += "+g%%s" %% pieces["short"]
+ return rendered
+
+
+def render_pep440_old(pieces):
+ """TAG[.postDISTANCE[.dev0]] .
+
+ The ".dev0" means dirty.
+
+ Exceptions:
+ 1: no tags. 0.postDISTANCE[.dev0]
+ """
+ if pieces["closest-tag"]:
+ rendered = pieces["closest-tag"]
+ if pieces["distance"] or pieces["dirty"]:
+ rendered += ".post%%d" %% pieces["distance"]
+ if pieces["dirty"]:
+ rendered += ".dev0"
+ else:
+ # exception #1
+ rendered = "0.post%%d" %% pieces["distance"]
+ if pieces["dirty"]:
+ rendered += ".dev0"
+ return rendered
+
+
+def render_git_describe(pieces):
+ """TAG[-DISTANCE-gHEX][-dirty].
+
+ Like 'git describe --tags --dirty --always'.
+
+ Exceptions:
+ 1: no tags. HEX[-dirty] (note: no 'g' prefix)
+ """
+ if pieces["closest-tag"]:
+ rendered = pieces["closest-tag"]
+ if pieces["distance"]:
+ rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"])
+ else:
+ # exception #1
+ rendered = pieces["short"]
+ if pieces["dirty"]:
+ rendered += "-dirty"
+ return rendered
+
+
+def render_git_describe_long(pieces):
+ """TAG-DISTANCE-gHEX[-dirty].
+
+ Like 'git describe --tags --dirty --always -long'.
+ The distance/hash is unconditional.
+
+ Exceptions:
+ 1: no tags. HEX[-dirty] (note: no 'g' prefix)
+ """
+ if pieces["closest-tag"]:
+ rendered = pieces["closest-tag"]
+ rendered += "-%%d-g%%s" %% (pieces["distance"], pieces["short"])
+ else:
+ # exception #1
+ rendered = pieces["short"]
+ if pieces["dirty"]:
+ rendered += "-dirty"
+ return rendered
+
+
+def render(pieces, style):
+ """Render the given version pieces into the requested style."""
+ if pieces["error"]:
+ return {"version": "unknown",
+ "full-revisionid": pieces.get("long"),
+ "dirty": None,
+ "error": pieces["error"],
+ "date": None}
+
+ if not style or style == "default":
+ style = "pep440" # the default
+
+ if style == "pep440":
+ rendered = render_pep440(pieces)
+ elif style == "pep440-pre":
+ rendered = render_pep440_pre(pieces)
+ elif style == "pep440-post":
+ rendered = render_pep440_post(pieces)
+ elif style == "pep440-old":
+ rendered = render_pep440_old(pieces)
+ elif style == "git-describe":
+ rendered = render_git_describe(pieces)
+ elif style == "git-describe-long":
+ rendered = render_git_describe_long(pieces)
+ else:
+ raise ValueError("unknown style '%%s'" %% style)
+
+ return {"version": rendered, "full-revisionid": pieces["long"],
+ "dirty": pieces["dirty"], "error": None,
+ "date": pieces.get("date")}
+
+
+def get_versions():
+ """Get version information or return default if unable to do so."""
+ # I am in _version.py, which lives at ROOT/VERSIONFILE_SOURCE. If we have
+ # __file__, we can work backwards from there to the root. Some
+ # py2exe/bbfreeze/non-CPython implementations don't do __file__, in which
+ # case we can only use expanded keywords.
+
+ cfg = get_config()
+ verbose = cfg.verbose
+
+ try:
+ return git_versions_from_keywords(get_keywords(), cfg.tag_prefix,
+ verbose)
+ except NotThisMethod:
+ pass
+
+ try:
+ root = os.path.realpath(__file__)
+ # versionfile_source is the relative path from the top of the source
+ # tree (where the .git directory might live) to this file. Invert
+ # this to find the root from __file__.
+ for i in cfg.versionfile_source.split('/'):
+ root = os.path.dirname(root)
+ except NameError:
+ return {"version": "0+unknown", "full-revisionid": None,
+ "dirty": None,
+ "error": "unable to find root of source tree",
+ "date": None}
+
+ try:
+ pieces = git_pieces_from_vcs(cfg.tag_prefix, root, verbose)
+ return render(pieces, cfg.style)
+ except NotThisMethod:
+ pass
+
+ try:
+ if cfg.parentdir_prefix:
+ return versions_from_parentdir(cfg.parentdir_prefix, root, verbose)
+ except NotThisMethod:
+ pass
+
+ return {"version": "0+unknown", "full-revisionid": None,
+ "dirty": None,
+ "error": "unable to compute version", "date": None}
+'''
+
+
+@register_vcs_handler("git", "get_keywords")
+def git_get_keywords(versionfile_abs):
+ """Extract version information from the given file."""
+ # the code embedded in _version.py can just fetch the value of these
+ # keywords. When used from setup.py, we don't want to import _version.py,
+ # so we do it with a regexp instead. This function is not used from
+ # _version.py.
+ keywords = {}
+ try:
+ with open(versionfile_abs, "r") as f:
+ for line in f.readlines():
+ if line.strip().startswith("git_refnames ="):
+ mo = re.search(r'=\s*"(.*)"', line)
+ if mo:
+ keywords["refnames"] = mo.group(1)
+ if line.strip().startswith("git_full ="):
+ mo = re.search(r'=\s*"(.*)"', line)
+ if mo:
+ keywords["full"] = mo.group(1)
+ if line.strip().startswith("git_date ="):
+ mo = re.search(r'=\s*"(.*)"', line)
+ if mo:
+ keywords["date"] = mo.group(1)
+ except EnvironmentError:
+ pass
+ return keywords
+
+
+@register_vcs_handler("git", "keywords")
+def git_versions_from_keywords(keywords, tag_prefix, verbose):
+ """Get version information from git keywords."""
+ if not keywords:
+ raise NotThisMethod("no keywords at all, weird")
+ date = keywords.get("date")
+ if date is not None:
+ # Use only the last line. Previous lines may contain GPG signature
+ # information.
+ date = date.splitlines()[-1]
+
+ # git-2.2.0 added "%cI", which expands to an ISO-8601 -compliant
+ # datestamp. However we prefer "%ci" (which expands to an "ISO-8601
+ # -like" string, which we must then edit to make compliant), because
+ # it's been around since git-1.5.3, and it's too difficult to
+ # discover which version we're using, or to work around using an
+ # older one.
+ date = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
+ refnames = keywords["refnames"].strip()
+ if refnames.startswith("$Format"):
+ if verbose:
+ print("keywords are unexpanded, not using")
+ raise NotThisMethod("unexpanded keywords, not a git-archive tarball")
+ refs = set([r.strip() for r in refnames.strip("()").split(",")])
+ # starting in git-1.8.3, tags are listed as "tag: foo-1.0" instead of
+ # just "foo-1.0". If we see a "tag: " prefix, prefer those.
+ TAG = "tag: "
+ tags = set([r[len(TAG):] for r in refs if r.startswith(TAG)])
+ if not tags:
+ # Either we're using git < 1.8.3, or there really are no tags. We use
+ # a heuristic: assume all version tags have a digit. The old git %d
+ # expansion behaves like git log --decorate=short and strips out the
+ # refs/heads/ and refs/tags/ prefixes that would let us distinguish
+ # between branches and tags. By ignoring refnames without digits, we
+ # filter out many common branch names like "release" and
+ # "stabilization", as well as "HEAD" and "master".
+ tags = set([r for r in refs if re.search(r'\d', r)])
+ if verbose:
+ print("discarding '%s', no digits" % ",".join(refs - tags))
+ if verbose:
+ print("likely tags: %s" % ",".join(sorted(tags)))
+ for ref in sorted(tags):
+ # sorting will prefer e.g. "2.0" over "2.0rc1"
+ if ref.startswith(tag_prefix):
+ r = ref[len(tag_prefix):]
+ if verbose:
+ print("picking %s" % r)
+ return {"version": r,
+ "full-revisionid": keywords["full"].strip(),
+ "dirty": False, "error": None,
+ "date": date}
+ # no suitable tags, so version is "0+unknown", but full hex is still there
+ if verbose:
+ print("no suitable tags, using unknown + full revision id")
+ return {"version": "0+unknown",
+ "full-revisionid": keywords["full"].strip(),
+ "dirty": False, "error": "no suitable tags", "date": None}
+
+
+@register_vcs_handler("git", "pieces_from_vcs")
+def git_pieces_from_vcs(tag_prefix, root, verbose, run_command=run_command):
+ """Get version from 'git describe' in the root of the source tree.
+
+ This only gets called if the git-archive 'subst' keywords were *not*
+ expanded, and _version.py hasn't already been rewritten with a short
+ version string, meaning we're inside a checked out source tree.
+ """
+ GITS = ["git"]
+ if sys.platform == "win32":
+ GITS = ["git.cmd", "git.exe"]
+
+ out, rc = run_command(GITS, ["rev-parse", "--git-dir"], cwd=root,
+ hide_stderr=True)
+ if rc != 0:
+ if verbose:
+ print("Directory %s not under git control" % root)
+ raise NotThisMethod("'git rev-parse --git-dir' returned error")
+
+ # if there is a tag matching tag_prefix, this yields TAG-NUM-gHEX[-dirty]
+ # if there isn't one, this yields HEX[-dirty] (no NUM)
+ describe_out, rc = run_command(GITS, ["describe", "--tags", "--dirty=",
+ "--always", "--long",
+ "--match", "%s*" % tag_prefix],
+ cwd=root)
+ # --long was added in git-1.5.5
+ if describe_out is None:
+ raise NotThisMethod("'git describe' failed")
+ describe_out = describe_out.strip()
+ full_out, rc = run_command(GITS, ["rev-parse", "HEAD"], cwd=root)
+ if full_out is None:
+ raise NotThisMethod("'git rev-parse' failed")
+ full_out = full_out.strip()
+
+ pieces = {}
+ pieces["long"] = full_out
+ pieces["short"] = full_out[:7] # maybe improved later
+ pieces["error"] = None
+
+ # parse describe_out. It will be like TAG-NUM-gHEX[-dirty] or HEX[-dirty]
+ # TAG might have hyphens.
+ git_describe = describe_out
+
+ # look for -dirty suffix
+ dirty = git_describe.endswith("-dirty")
+ pieces["dirty"] = dirty
+ if dirty:
+ git_describe = git_describe[:git_describe.rindex("-dirty")]
+
+ # now we have TAG-NUM-gHEX or HEX
+
+ if "-" in git_describe:
+ # TAG-NUM-gHEX
+ mo = re.search(r'^(.+)-(\d+)-g([0-9a-f]+)$', git_describe)
+ if not mo:
+ # unparseable. Maybe git-describe is misbehaving?
+ pieces["error"] = ("unable to parse git-describe output: '%s'"
+ % describe_out)
+ return pieces
+
+ # tag
+ full_tag = mo.group(1)
+ if not full_tag.startswith(tag_prefix):
+ if verbose:
+ fmt = "tag '%s' doesn't start with prefix '%s'"
+ print(fmt % (full_tag, tag_prefix))
+ pieces["error"] = ("tag '%s' doesn't start with prefix '%s'"
+ % (full_tag, tag_prefix))
+ return pieces
+ pieces["closest-tag"] = full_tag[len(tag_prefix):]
+
+ # distance: number of commits since tag
+ pieces["distance"] = int(mo.group(2))
+
+ # commit: short hex revision ID
+ pieces["short"] = mo.group(3)
+
+ else:
+ # HEX: no tags
+ pieces["closest-tag"] = None
+ count_out, rc = run_command(GITS, ["rev-list", "HEAD", "--count"],
+ cwd=root)
+ pieces["distance"] = int(count_out) # total number of commits
+
+ # commit date: see ISO-8601 comment in git_versions_from_keywords()
+ date = run_command(GITS, ["show", "-s", "--format=%ci", "HEAD"],
+ cwd=root)[0].strip()
+ # Use only the last line. Previous lines may contain GPG signature
+ # information.
+ date = date.splitlines()[-1]
+ pieces["date"] = date.strip().replace(" ", "T", 1).replace(" ", "", 1)
+
+ return pieces
+
+
+def do_vcs_install(manifest_in, versionfile_source, ipy):
+ """Git-specific installation logic for Versioneer.
+
+ For Git, this means creating/changing .gitattributes to mark _version.py
+ for export-subst keyword substitution.
+ """
+ GITS = ["git"]
+ if sys.platform == "win32":
+ GITS = ["git.cmd", "git.exe"]
+ files = [manifest_in, versionfile_source]
+ if ipy:
+ files.append(ipy)
+ try:
+ me = __file__
+ if me.endswith(".pyc") or me.endswith(".pyo"):
+ me = os.path.splitext(me)[0] + ".py"
+ versioneer_file = os.path.relpath(me)
+ except NameError:
+ versioneer_file = "versioneer.py"
+ files.append(versioneer_file)
+ present = False
+ try:
+ with open(".gitattributes", "r") as f:
+ for line in f.readlines():
+ if line.strip().startswith(versionfile_source):
+ if "export-subst" in line.strip().split()[1:]:
+ present = True
+ except EnvironmentError:
+ pass
+ if not present:
+ with open(".gitattributes", "a+") as f:
+ f.write("%s export-subst\n" % versionfile_source)
+ files.append(".gitattributes")
+ run_command(GITS, ["add", "--"] + files)
+
+
+def versions_from_parentdir(parentdir_prefix, root, verbose):
+ """Try to determine the version from the parent directory name.
+
+ Source tarballs conventionally unpack into a directory that includes both
+ the project name and a version string. We will also support searching up
+ two directory levels for an appropriately named parent directory
+ """
+ rootdirs = []
+
+ for i in range(3):
+ dirname = os.path.basename(root)
+ if dirname.startswith(parentdir_prefix):
+ return {"version": dirname[len(parentdir_prefix):],
+ "full-revisionid": None,
+ "dirty": False, "error": None, "date": None}
+ else:
+ rootdirs.append(root)
+ root = os.path.dirname(root) # up a level
+
+ if verbose:
+ print("Tried directories %s but none started with prefix %s" %
+ (str(rootdirs), parentdir_prefix))
+ raise NotThisMethod("rootdir doesn't start with parentdir_prefix")
+
+
+SHORT_VERSION_PY = """
+# This file was generated by 'versioneer.py' (0.19) from
+# revision-control system data, or from the parent directory name of an
+# unpacked source archive. Distribution tarballs contain a pre-generated copy
+# of this file.
+
+import json
+
+version_json = '''
+%s
+''' # END VERSION_JSON
+
+
+def get_versions():
+ return json.loads(version_json)
+"""
+
+
+def versions_from_file(filename):
+ """Try to determine the version from _version.py if present."""
+ try:
+ with open(filename) as f:
+ contents = f.read()
+ except EnvironmentError:
+ raise NotThisMethod("unable to read _version.py")
+ mo = re.search(r"version_json = '''\n(.*)''' # END VERSION_JSON",
+ contents, re.M | re.S)
+ if not mo:
+ mo = re.search(r"version_json = '''\r\n(.*)''' # END VERSION_JSON",
+ contents, re.M | re.S)
+ if not mo:
+ raise NotThisMethod("no version_json in _version.py")
+ return json.loads(mo.group(1))
+
+
+def write_to_version_file(filename, versions):
+ """Write the given version number to the given _version.py file."""
+ os.unlink(filename)
+ contents = json.dumps(versions, sort_keys=True,
+ indent=1, separators=(",", ": "))
+ with open(filename, "w") as f:
+ f.write(SHORT_VERSION_PY % contents)
+
+ print("set %s to '%s'" % (filename, versions["version"]))
+
+
+def plus_or_dot(pieces):
+ """Return a + if we don't already have one, else return a ."""
+ if "+" in pieces.get("closest-tag", ""):
+ return "."
+ return "+"
+
+
+def render_pep440(pieces):
+ """Build up version string, with post-release "local version identifier".
+
+ Our goal: TAG[+DISTANCE.gHEX[.dirty]] . Note that if you
+ get a tagged build and then dirty it, you'll get TAG+0.gHEX.dirty
+
+ Exceptions:
+ 1: no tags. git_describe was just HEX. 0+untagged.DISTANCE.gHEX[.dirty]
+ """
+ if pieces["closest-tag"]:
+ rendered = pieces["closest-tag"]
+ if pieces["distance"] or pieces["dirty"]:
+ rendered += plus_or_dot(pieces)
+ rendered += "%d.g%s" % (pieces["distance"], pieces["short"])
+ if pieces["dirty"]:
+ rendered += ".dirty"
+ else:
+ # exception #1
+ rendered = "0+untagged.%d.g%s" % (pieces["distance"],
+ pieces["short"])
+ if pieces["dirty"]:
+ rendered += ".dirty"
+ return rendered
+
+
+def render_pep440_pre(pieces):
+ """TAG[.post0.devDISTANCE] -- No -dirty.
+
+ Exceptions:
+ 1: no tags. 0.post0.devDISTANCE
+ """
+ if pieces["closest-tag"]:
+ rendered = pieces["closest-tag"]
+ if pieces["distance"]:
+ rendered += ".post0.dev%d" % pieces["distance"]
+ else:
+ # exception #1
+ rendered = "0.post0.dev%d" % pieces["distance"]
+ return rendered
+
+
+def render_pep440_post(pieces):
+ """TAG[.postDISTANCE[.dev0]+gHEX] .
+
+ The ".dev0" means dirty. Note that .dev0 sorts backwards
+ (a dirty tree will appear "older" than the corresponding clean one),
+ but you shouldn't be releasing software with -dirty anyways.
+
+ Exceptions:
+ 1: no tags. 0.postDISTANCE[.dev0]
+ """
+ if pieces["closest-tag"]:
+ rendered = pieces["closest-tag"]
+ if pieces["distance"] or pieces["dirty"]:
+ rendered += ".post%d" % pieces["distance"]
+ if pieces["dirty"]:
+ rendered += ".dev0"
+ rendered += plus_or_dot(pieces)
+ rendered += "g%s" % pieces["short"]
+ else:
+ # exception #1
+ rendered = "0.post%d" % pieces["distance"]
+ if pieces["dirty"]:
+ rendered += ".dev0"
+ rendered += "+g%s" % pieces["short"]
+ return rendered
+
+
+def render_pep440_old(pieces):
+ """TAG[.postDISTANCE[.dev0]] .
+
+ The ".dev0" means dirty.
+
+ Exceptions:
+ 1: no tags. 0.postDISTANCE[.dev0]
+ """
+ if pieces["closest-tag"]:
+ rendered = pieces["closest-tag"]
+ if pieces["distance"] or pieces["dirty"]:
+ rendered += ".post%d" % pieces["distance"]
+ if pieces["dirty"]:
+ rendered += ".dev0"
+ else:
+ # exception #1
+ rendered = "0.post%d" % pieces["distance"]
+ if pieces["dirty"]:
+ rendered += ".dev0"
+ return rendered
+
+
+def render_git_describe(pieces):
+ """TAG[-DISTANCE-gHEX][-dirty].
+
+ Like 'git describe --tags --dirty --always'.
+
+ Exceptions:
+ 1: no tags. HEX[-dirty] (note: no 'g' prefix)
+ """
+ if pieces["closest-tag"]:
+ rendered = pieces["closest-tag"]
+ if pieces["distance"]:
+ rendered += "-%d-g%s" % (pieces["distance"], pieces["short"])
+ else:
+ # exception #1
+ rendered = pieces["short"]
+ if pieces["dirty"]:
+ rendered += "-dirty"
+ return rendered
+
+
+def render_git_describe_long(pieces):
+ """TAG-DISTANCE-gHEX[-dirty].
+
+ Like 'git describe --tags --dirty --always -long'.
+ The distance/hash is unconditional.
+
+ Exceptions:
+ 1: no tags. HEX[-dirty] (note: no 'g' prefix)
+ """
+ if pieces["closest-tag"]:
+ rendered = pieces["closest-tag"]
+ rendered += "-%d-g%s" % (pieces["distance"], pieces["short"])
+ else:
+ # exception #1
+ rendered = pieces["short"]
+ if pieces["dirty"]:
+ rendered += "-dirty"
+ return rendered
+
+
+def render(pieces, style):
+ """Render the given version pieces into the requested style."""
+ if pieces["error"]:
+ return {"version": "unknown",
+ "full-revisionid": pieces.get("long"),
+ "dirty": None,
+ "error": pieces["error"],
+ "date": None}
+
+ if not style or style == "default":
+ style = "pep440" # the default
+
+ if style == "pep440":
+ rendered = render_pep440(pieces)
+ elif style == "pep440-pre":
+ rendered = render_pep440_pre(pieces)
+ elif style == "pep440-post":
+ rendered = render_pep440_post(pieces)
+ elif style == "pep440-old":
+ rendered = render_pep440_old(pieces)
+ elif style == "git-describe":
+ rendered = render_git_describe(pieces)
+ elif style == "git-describe-long":
+ rendered = render_git_describe_long(pieces)
+ else:
+ raise ValueError("unknown style '%s'" % style)
+
+ return {"version": rendered, "full-revisionid": pieces["long"],
+ "dirty": pieces["dirty"], "error": None,
+ "date": pieces.get("date")}
+
+
+class VersioneerBadRootError(Exception):
+ """The project root directory is unknown or missing key files."""
+
+
+def get_versions(verbose=False):
+ """Get the project version from whatever source is available.
+
+ Returns dict with two keys: 'version' and 'full'.
+ """
+ if "versioneer" in sys.modules:
+ # see the discussion in cmdclass.py:get_cmdclass()
+ del sys.modules["versioneer"]
+
+ root = get_root()
+ cfg = get_config_from_root(root)
+
+ assert cfg.VCS is not None, "please set [versioneer]VCS= in setup.cfg"
+ handlers = HANDLERS.get(cfg.VCS)
+ assert handlers, "unrecognized VCS '%s'" % cfg.VCS
+ verbose = verbose or cfg.verbose
+ assert cfg.versionfile_source is not None, \
+ "please set versioneer.versionfile_source"
+ assert cfg.tag_prefix is not None, "please set versioneer.tag_prefix"
+
+ versionfile_abs = os.path.join(root, cfg.versionfile_source)
+
+ # extract version from first of: _version.py, VCS command (e.g. 'git
+ # describe'), parentdir. This is meant to work for developers using a
+ # source checkout, for users of a tarball created by 'setup.py sdist',
+ # and for users of a tarball/zipball created by 'git archive' or github's
+ # download-from-tag feature or the equivalent in other VCSes.
+
+ get_keywords_f = handlers.get("get_keywords")
+ from_keywords_f = handlers.get("keywords")
+ if get_keywords_f and from_keywords_f:
+ try:
+ keywords = get_keywords_f(versionfile_abs)
+ ver = from_keywords_f(keywords, cfg.tag_prefix, verbose)
+ if verbose:
+ print("got version from expanded keyword %s" % ver)
+ return ver
+ except NotThisMethod:
+ pass
+
+ try:
+ ver = versions_from_file(versionfile_abs)
+ if verbose:
+ print("got version from file %s %s" % (versionfile_abs, ver))
+ return ver
+ except NotThisMethod:
+ pass
+
+ from_vcs_f = handlers.get("pieces_from_vcs")
+ if from_vcs_f:
+ try:
+ pieces = from_vcs_f(cfg.tag_prefix, root, verbose)
+ ver = render(pieces, cfg.style)
+ if verbose:
+ print("got version from VCS %s" % ver)
+ return ver
+ except NotThisMethod:
+ pass
+
+ try:
+ if cfg.parentdir_prefix:
+ ver = versions_from_parentdir(cfg.parentdir_prefix, root, verbose)
+ if verbose:
+ print("got version from parentdir %s" % ver)
+ return ver
+ except NotThisMethod:
+ pass
+
+ if verbose:
+ print("unable to compute version")
+
+ return {"version": "0+unknown", "full-revisionid": None,
+ "dirty": None, "error": "unable to compute version",
+ "date": None}
+
+
+def get_version():
+ """Get the short version string for this project."""
+ return get_versions()["version"]
+
+
+def get_cmdclass(cmdclass=None):
+ """Get the custom setuptools/distutils subclasses used by Versioneer.
+
+ If the package uses a different cmdclass (e.g. one from numpy), it
+ should be provide as an argument.
+ """
+ if "versioneer" in sys.modules:
+ del sys.modules["versioneer"]
+ # this fixes the "python setup.py develop" case (also 'install' and
+ # 'easy_install .'), in which subdependencies of the main project are
+ # built (using setup.py bdist_egg) in the same python process. Assume
+ # a main project A and a dependency B, which use different versions
+ # of Versioneer. A's setup.py imports A's Versioneer, leaving it in
+ # sys.modules by the time B's setup.py is executed, causing B to run
+ # with the wrong versioneer. Setuptools wraps the sub-dep builds in a
+ # sandbox that restores sys.modules to it's pre-build state, so the
+ # parent is protected against the child's "import versioneer". By
+ # removing ourselves from sys.modules here, before the child build
+ # happens, we protect the child from the parent's versioneer too.
+ # Also see https://github.com/python-versioneer/python-versioneer/issues/52
+
+ cmds = {} if cmdclass is None else cmdclass.copy()
+
+ # we add "version" to both distutils and setuptools
+ from distutils.core import Command
+
+ class cmd_version(Command):
+ description = "report generated version string"
+ user_options = []
+ boolean_options = []
+
+ def initialize_options(self):
+ pass
+
+ def finalize_options(self):
+ pass
+
+ def run(self):
+ vers = get_versions(verbose=True)
+ print("Version: %s" % vers["version"])
+ print(" full-revisionid: %s" % vers.get("full-revisionid"))
+ print(" dirty: %s" % vers.get("dirty"))
+ print(" date: %s" % vers.get("date"))
+ if vers["error"]:
+ print(" error: %s" % vers["error"])
+ cmds["version"] = cmd_version
+
+ # we override "build_py" in both distutils and setuptools
+ #
+ # most invocation pathways end up running build_py:
+ # distutils/build -> build_py
+ # distutils/install -> distutils/build ->..
+ # setuptools/bdist_wheel -> distutils/install ->..
+ # setuptools/bdist_egg -> distutils/install_lib -> build_py
+ # setuptools/install -> bdist_egg ->..
+ # setuptools/develop -> ?
+ # pip install:
+ # copies source tree to a tempdir before running egg_info/etc
+ # if .git isn't copied too, 'git describe' will fail
+ # then does setup.py bdist_wheel, or sometimes setup.py install
+ # setup.py egg_info -> ?
+
+ # we override different "build_py" commands for both environments
+ if 'build_py' in cmds:
+ _build_py = cmds['build_py']
+ elif "setuptools" in sys.modules:
+ from setuptools.command.build_py import build_py as _build_py
+ else:
+ from distutils.command.build_py import build_py as _build_py
+
+ class cmd_build_py(_build_py):
+ def run(self):
+ root = get_root()
+ cfg = get_config_from_root(root)
+ versions = get_versions()
+ _build_py.run(self)
+ # now locate _version.py in the new build/ directory and replace
+ # it with an updated value
+ if cfg.versionfile_build:
+ target_versionfile = os.path.join(self.build_lib,
+ cfg.versionfile_build)
+ print("UPDATING %s" % target_versionfile)
+ write_to_version_file(target_versionfile, versions)
+ cmds["build_py"] = cmd_build_py
+
+ if "setuptools" in sys.modules:
+ from setuptools.command.build_ext import build_ext as _build_ext
+ else:
+ from distutils.command.build_ext import build_ext as _build_ext
+
+ class cmd_build_ext(_build_ext):
+ def run(self):
+ root = get_root()
+ cfg = get_config_from_root(root)
+ versions = get_versions()
+ _build_ext.run(self)
+ if self.inplace:
+ # build_ext --inplace will only build extensions in
+ # build/lib<..> dir with no _version.py to write to.
+ # As in place builds will already have a _version.py
+ # in the module dir, we do not need to write one.
+ return
+ # now locate _version.py in the new build/ directory and replace
+ # it with an updated value
+ target_versionfile = os.path.join(self.build_lib,
+ cfg.versionfile_source)
+ print("UPDATING %s" % target_versionfile)
+ write_to_version_file(target_versionfile, versions)
+ cmds["build_ext"] = cmd_build_ext
+
+ if "cx_Freeze" in sys.modules: # cx_freeze enabled?
+ from cx_Freeze.dist import build_exe as _build_exe
+ # nczeczulin reports that py2exe won't like the pep440-style string
+ # as FILEVERSION, but it can be used for PRODUCTVERSION, e.g.
+ # setup(console=[{
+ # "version": versioneer.get_version().split("+", 1)[0], # FILEVERSION
+ # "product_version": versioneer.get_version(),
+ # ...
+
+ class cmd_build_exe(_build_exe):
+ def run(self):
+ root = get_root()
+ cfg = get_config_from_root(root)
+ versions = get_versions()
+ target_versionfile = cfg.versionfile_source
+ print("UPDATING %s" % target_versionfile)
+ write_to_version_file(target_versionfile, versions)
+
+ _build_exe.run(self)
+ os.unlink(target_versionfile)
+ with open(cfg.versionfile_source, "w") as f:
+ LONG = LONG_VERSION_PY[cfg.VCS]
+ f.write(LONG %
+ {"DOLLAR": "$",
+ "STYLE": cfg.style,
+ "TAG_PREFIX": cfg.tag_prefix,
+ "PARENTDIR_PREFIX": cfg.parentdir_prefix,
+ "VERSIONFILE_SOURCE": cfg.versionfile_source,
+ })
+ cmds["build_exe"] = cmd_build_exe
+ del cmds["build_py"]
+
+ if 'py2exe' in sys.modules: # py2exe enabled?
+ from py2exe.distutils_buildexe import py2exe as _py2exe
+
+ class cmd_py2exe(_py2exe):
+ def run(self):
+ root = get_root()
+ cfg = get_config_from_root(root)
+ versions = get_versions()
+ target_versionfile = cfg.versionfile_source
+ print("UPDATING %s" % target_versionfile)
+ write_to_version_file(target_versionfile, versions)
+
+ _py2exe.run(self)
+ os.unlink(target_versionfile)
+ with open(cfg.versionfile_source, "w") as f:
+ LONG = LONG_VERSION_PY[cfg.VCS]
+ f.write(LONG %
+ {"DOLLAR": "$",
+ "STYLE": cfg.style,
+ "TAG_PREFIX": cfg.tag_prefix,
+ "PARENTDIR_PREFIX": cfg.parentdir_prefix,
+ "VERSIONFILE_SOURCE": cfg.versionfile_source,
+ })
+ cmds["py2exe"] = cmd_py2exe
+
+ # we override different "sdist" commands for both environments
+ if 'sdist' in cmds:
+ _sdist = cmds['sdist']
+ elif "setuptools" in sys.modules:
+ from setuptools.command.sdist import sdist as _sdist
+ else:
+ from distutils.command.sdist import sdist as _sdist
+
+ class cmd_sdist(_sdist):
+ def run(self):
+ versions = get_versions()
+ self._versioneer_generated_versions = versions
+ # unless we update this, the command will keep using the old
+ # version
+ self.distribution.metadata.version = versions["version"]
+ return _sdist.run(self)
+
+ def make_release_tree(self, base_dir, files):
+ root = get_root()
+ cfg = get_config_from_root(root)
+ _sdist.make_release_tree(self, base_dir, files)
+ # now locate _version.py in the new base_dir directory
+ # (remembering that it may be a hardlink) and replace it with an
+ # updated value
+ target_versionfile = os.path.join(base_dir, cfg.versionfile_source)
+ print("UPDATING %s" % target_versionfile)
+ write_to_version_file(target_versionfile,
+ self._versioneer_generated_versions)
+ cmds["sdist"] = cmd_sdist
+
+ return cmds
+
+
+CONFIG_ERROR = """
+setup.cfg is missing the necessary Versioneer configuration. You need
+a section like:
+
+ [versioneer]
+ VCS = git
+ style = pep440
+ versionfile_source = src/myproject/_version.py
+ versionfile_build = myproject/_version.py
+ tag_prefix =
+ parentdir_prefix = myproject-
+
+You will also need to edit your setup.py to use the results:
+
+ import versioneer
+ setup(version=versioneer.get_version(),
+ cmdclass=versioneer.get_cmdclass(), ...)
+
+Please read the docstring in ./versioneer.py for configuration instructions,
+edit setup.cfg, and re-run the installer or 'python versioneer.py setup'.
+"""
+
+SAMPLE_CONFIG = """
+# See the docstring in versioneer.py for instructions. Note that you must
+# re-run 'versioneer.py setup' after changing this section, and commit the
+# resulting files.
+
+[versioneer]
+#VCS = git
+#style = pep440
+#versionfile_source =
+#versionfile_build =
+#tag_prefix =
+#parentdir_prefix =
+
+"""
+
+INIT_PY_SNIPPET = """
+from ._version import get_versions
+__version__ = get_versions()['version']
+del get_versions
+"""
+
+
+def do_setup():
+ """Do main VCS-independent setup function for installing Versioneer."""
+ root = get_root()
+ try:
+ cfg = get_config_from_root(root)
+ except (EnvironmentError, configparser.NoSectionError,
+ configparser.NoOptionError) as e:
+ if isinstance(e, (EnvironmentError, configparser.NoSectionError)):
+ print("Adding sample versioneer config to setup.cfg",
+ file=sys.stderr)
+ with open(os.path.join(root, "setup.cfg"), "a") as f:
+ f.write(SAMPLE_CONFIG)
+ print(CONFIG_ERROR, file=sys.stderr)
+ return 1
+
+ print(" creating %s" % cfg.versionfile_source)
+ with open(cfg.versionfile_source, "w") as f:
+ LONG = LONG_VERSION_PY[cfg.VCS]
+ f.write(LONG % {"DOLLAR": "$",
+ "STYLE": cfg.style,
+ "TAG_PREFIX": cfg.tag_prefix,
+ "PARENTDIR_PREFIX": cfg.parentdir_prefix,
+ "VERSIONFILE_SOURCE": cfg.versionfile_source,
+ })
+
+ ipy = os.path.join(os.path.dirname(cfg.versionfile_source),
+ "__init__.py")
+ if os.path.exists(ipy):
+ try:
+ with open(ipy, "r") as f:
+ old = f.read()
+ except EnvironmentError:
+ old = ""
+ if INIT_PY_SNIPPET not in old:
+ print(" appending to %s" % ipy)
+ with open(ipy, "a") as f:
+ f.write(INIT_PY_SNIPPET)
+ else:
+ print(" %s unmodified" % ipy)
+ else:
+ print(" %s doesn't exist, ok" % ipy)
+ ipy = None
+
+ # Make sure both the top-level "versioneer.py" and versionfile_source
+ # (PKG/_version.py, used by runtime code) are in MANIFEST.in, so
+ # they'll be copied into source distributions. Pip won't be able to
+ # install the package without this.
+ manifest_in = os.path.join(root, "MANIFEST.in")
+ simple_includes = set()
+ try:
+ with open(manifest_in, "r") as f:
+ for line in f:
+ if line.startswith("include "):
+ for include in line.split()[1:]:
+ simple_includes.add(include)
+ except EnvironmentError:
+ pass
+ # That doesn't cover everything MANIFEST.in can do
+ # (http://docs.python.org/2/distutils/sourcedist.html#commands), so
+ # it might give some false negatives. Appending redundant 'include'
+ # lines is safe, though.
+ if "versioneer.py" not in simple_includes:
+ print(" appending 'versioneer.py' to MANIFEST.in")
+ with open(manifest_in, "a") as f:
+ f.write("include versioneer.py\n")
+ else:
+ print(" 'versioneer.py' already in MANIFEST.in")
+ if cfg.versionfile_source not in simple_includes:
+ print(" appending versionfile_source ('%s') to MANIFEST.in" %
+ cfg.versionfile_source)
+ with open(manifest_in, "a") as f:
+ f.write("include %s\n" % cfg.versionfile_source)
+ else:
+ print(" versionfile_source already in MANIFEST.in")
+
+ # Make VCS-specific changes. For git, this means creating/changing
+ # .gitattributes to mark _version.py for export-subst keyword
+ # substitution.
+ do_vcs_install(manifest_in, cfg.versionfile_source, ipy)
+ return 0
+
+
+def scan_setup_py():
+ """Validate the contents of setup.py against Versioneer's expectations."""
+ found = set()
+ setters = False
+ errors = 0
+ with open("setup.py", "r") as f:
+ for line in f.readlines():
+ if "import versioneer" in line:
+ found.add("import")
+ if "versioneer.get_cmdclass()" in line:
+ found.add("cmdclass")
+ if "versioneer.get_version()" in line:
+ found.add("get_version")
+ if "versioneer.VCS" in line:
+ setters = True
+ if "versioneer.versionfile_source" in line:
+ setters = True
+ if len(found) != 3:
+ print("")
+ print("Your setup.py appears to be missing some important items")
+ print("(but I might be wrong). Please make sure it has something")
+ print("roughly like the following:")
+ print("")
+ print(" import versioneer")
+ print(" setup( version=versioneer.get_version(),")
+ print(" cmdclass=versioneer.get_cmdclass(), ...)")
+ print("")
+ errors += 1
+ if setters:
+ print("You should remove lines like 'versioneer.VCS = ' and")
+ print("'versioneer.versionfile_source = ' . This configuration")
+ print("now lives in setup.cfg, and should be removed from setup.py")
+ print("")
+ errors += 1
+ return errors
+
+
+if __name__ == "__main__":
+ cmd = sys.argv[1]
+ if cmd == "setup":
+ errors = do_setup()
+ errors += scan_setup_py()
+ if errors:
+ sys.exit(1)